Graphic3d_RenderingParams - introduced new parameters CameraFocalPlaneDist and CameraApertureRadius managing DOF effect.
TKOpenGl - added new ray generation logic to RaytraceBase.fs.
vrenderparams command - added -focal and -aperture parameters.
OpenGl_View.hxx - function for ray generating was split into two functions (ray tracing and path tracing).
OpenGl_View_Raytrace.cxx - fixed interaction between adaptive sampling and stereo camera
RadianceClampingValue (30.0),
RebuildRayTracingShaders (Standard_False),
NbRayTracingTiles (16 * 16),
+ CameraApertureRadius (0.0f),
+ CameraFocalPlaneDist (1.0f),
ToneMappingMethod (Graphic3d_ToneMappingMethod_Disabled),
Exposure (0.f),
WhitePoint (1.f),
Standard_ShortReal RadianceClampingValue; //!< maximum radiance value used for clamping radiance estimation.
Standard_Boolean RebuildRayTracingShaders; //!< forces rebuilding ray tracing shaders at the next frame
Standard_Integer NbRayTracingTiles; //!< total number of screen tiles used in adaptive sampling mode (PT only)
+ Standard_ShortReal CameraApertureRadius; //!< aperture radius of perspective camera used for depth-of-field, 0.0 by default (no DOF) (path tracing only)
+ Standard_ShortReal CameraFocalPlaneDist; //!< focal distance of perspective camera used for depth-of field, 1.0 by default (path tracing only)
Graphic3d_ToneMappingMethod ToneMappingMethod; //!< specifies tone mapping method for path tracing, Graphic3d_ToneMappingMethod_Disabled by default
Standard_ShortReal Exposure; //!< exposure value used for tone mapping (path tracing), 0.0 by default
myRaytraceSceneRadius (0.0f),
myRaytraceSceneEpsilon (1.0e-6f),
myToUpdateEnvironmentMap (Standard_False),
- myRaytraceLayerListState (0)
+ myRaytraceLayerListState (0),
+ myPrevCameraApertureRadius(0.f),
+ myPrevCameraFocalPlaneDist(0.f)
{
myWorkspace = new OpenGl_Workspace (this, NULL);
{
OpenGl_RT_OutputImageLft = 0,
OpenGl_RT_OutputImageRgh = 1,
- OpenGl_RT_VisualErrorImage = 2,
- OpenGl_RT_TileOffsetsImage = 3
+ OpenGl_RT_VisualErrorImageLft = 2,
+ OpenGl_RT_VisualErrorImageRgh = 3,
+ OpenGl_RT_TileOffsetsImageLft = 4,
+ OpenGl_RT_TileOffsetsImageRgh = 5
};
//! Tool class for management of shader sources.
//! Number of tiles in Y dimension (in adaptive sampling mode).
Standard_Integer NbTilesY;
+ //! Enables/disables depth-of-field effect (path tracing, perspective camera).
+ Standard_Boolean DepthOfField;
+
//! Tone mapping method for path tracing.
Graphic3d_ToneMappingMethod ToneMappingMethod;
RadianceClampingValue (30.0),
NbTilesX (16),
NbTilesY (16),
+ DepthOfField (Standard_False),
ToneMappingMethod (Graphic3d_ToneMappingMethod_Disabled) { }
};
const Handle(OpenGl_Context)& theGlContext);
//! Generates viewing rays for corners of screen quad.
+ //! (ray tracing; path tracing for orthographic camera)
void updateCamera (const OpenGl_Mat4& theOrientation,
const OpenGl_Mat4& theViewMapping,
OpenGl_Vec3* theOrigins,
OpenGl_Mat4& theView,
OpenGl_Mat4& theUnView);
+ //! Generate viewing rays (path tracing, perspective camera).
+ void updatePerspCameraPT(const OpenGl_Mat4& theOrientation,
+ const OpenGl_Mat4& theViewMapping,
+ Graphic3d_Camera::Projection theProjection,
+ OpenGl_Mat4& theViewPr,
+ OpenGl_Mat4& theUnview,
+ const int theWinSizeX,
+ const int theWinSizeY);
+
//! Binds ray-trace textures to corresponding texture units.
void bindRaytraceTextures (const Handle(OpenGl_Context)& theGlContext);
Standard_Boolean setUniformState (const Standard_Integer theProgramId,
const Standard_Integer theSizeX,
const Standard_Integer theSizeY,
+ Graphic3d_Camera::Projection theProjection,
const Handle(OpenGl_Context)& theGlContext);
//! Runs ray-tracing shader programs.
//! Used if adaptive screen sampling is activated.
Handle(OpenGl_Texture) myRaytraceOutputTexture[2];
- //! Texture containing per-tile visual error estimation.
+ //! Texture containing per-tile visual error estimation (2 textures are used in stereo mode).
//! Used if adaptive screen sampling is activated.
- Handle(OpenGl_Texture) myRaytraceVisualErrorTexture;
- //! Texture containing offsets of sampled screen tiles.
+ Handle(OpenGl_Texture) myRaytraceVisualErrorTexture[2];
+ //! Texture containing offsets of sampled screen tiles (2 textures are used in stereo mode).
//! Used if adaptive screen sampling is activated.
- Handle(OpenGl_Texture) myRaytraceTileOffsetsTexture;
+ Handle(OpenGl_Texture) myRaytraceTileOffsetsTexture[2];
//! Vertex buffer (VBO) for drawing dummy quad.
OpenGl_VertexBuffer myRaytraceScreenQuad;
//! Tool object for sampling screen tiles in PT mode.
OpenGl_TileSampler myTileSampler;
+ //! Camera position used for projective mode
+ OpenGl_Vec3 myEyeOrig;
+
+ //! Camera view direction used for projective mode
+ OpenGl_Vec3 myEyeView;
+
+ //! Camera's screen vertical direction used for projective mode
+ OpenGl_Vec3 myEyeVert;
+
+ //! Camera's screen horizontal direction used for projective mode
+ OpenGl_Vec3 myEyeSide;
+
+ //! Camera's screen size used for projective mode
+ OpenGl_Vec2 myEyeSize;
+
+ //! Aperture radius of camera on previous frame used for depth-of-field (path tracing)
+ float myPrevCameraApertureRadius;
+
+ //! Focal distance of camera on previous frame used for depth-of-field (path tracing)
+ float myPrevCameraFocalPlaneDist;
+
public:
DEFINE_STANDARD_ALLOC
}
}
+ if (myRaytraceParameters.DepthOfField)
+ {
+ aPrefixString += TCollection_AsciiString("\n#define DEPTH_OF_FIELD");
+ }
+
return aPrefixString;
}
aToRebuildShaders = Standard_True;
}
+ const bool toEnableDof = !myCamera->IsOrthographic() && myRaytraceParameters.GlobalIllumination;
+ if (myRaytraceParameters.DepthOfField != toEnableDof)
+ {
+ myRaytraceParameters.DepthOfField = toEnableDof;
+ aToRebuildShaders = Standard_True;
+ }
+
if (myRenderParams.ToneMappingMethod != myRaytraceParameters.ToneMappingMethod)
{
myRaytraceParameters.ToneMappingMethod = myRenderParams.ToneMappingMethod;
nullifyResource (theGlContext, myRaytraceOutputTexture[0]);
nullifyResource (theGlContext, myRaytraceOutputTexture[1]);
- nullifyResource (theGlContext, myRaytraceTileOffsetsTexture);
- nullifyResource (theGlContext, myRaytraceVisualErrorTexture);
+ nullifyResource (theGlContext, myRaytraceTileOffsetsTexture[0]);
+ nullifyResource (theGlContext, myRaytraceTileOffsetsTexture[1]);
+ nullifyResource (theGlContext, myRaytraceVisualErrorTexture[0]);
+ nullifyResource (theGlContext, myRaytraceVisualErrorTexture[1]);
nullifyResource (theGlContext, mySceneNodeInfoTexture);
nullifyResource (theGlContext, mySceneMinPointTexture);
myTileSampler.SetSize (theSizeX, theSizeY);
- if (myRaytraceTileOffsetsTexture.IsNull())
+ if (myRaytraceTileOffsetsTexture[0].IsNull()
+ || myRaytraceTileOffsetsTexture[1].IsNull())
{
myRaytraceOutputTexture[0] = new OpenGl_Texture();
myRaytraceOutputTexture[1] = new OpenGl_Texture();
- myRaytraceTileOffsetsTexture = new OpenGl_Texture();
- myRaytraceVisualErrorTexture = new OpenGl_Texture();
+ myRaytraceTileOffsetsTexture[0] = new OpenGl_Texture();
+ myRaytraceTileOffsetsTexture[1] = new OpenGl_Texture();
+ myRaytraceVisualErrorTexture[0] = new OpenGl_Texture();
+ myRaytraceVisualErrorTexture[1] = new OpenGl_Texture();
}
if (myRaytraceOutputTexture[0]->SizeX() / 3 != theSizeX
theSizeX * 3, theSizeY * 2, OpenGl_TextureFormat::Create<GLfloat, 1>());
// workaround for some NVIDIA drivers
- myRaytraceVisualErrorTexture->Release (theGlContext.operator->());
- myRaytraceTileOffsetsTexture->Release (theGlContext.operator->());
+ myRaytraceVisualErrorTexture[0]->Release (theGlContext.operator->());
+ myRaytraceTileOffsetsTexture[0]->Release (theGlContext.operator->());
- myRaytraceVisualErrorTexture->Init (theGlContext,
+ myRaytraceVisualErrorTexture[0]->Init (theGlContext,
GL_R32I, GL_RED_INTEGER, GL_INT, myTileSampler.NbTilesX(), myTileSampler.NbTilesY(), Graphic3d_TOT_2D);
- myRaytraceTileOffsetsTexture->Init (theGlContext,
+ myRaytraceTileOffsetsTexture[0]->Init (theGlContext,
GL_RG32I, GL_RG_INTEGER, GL_INT, myTileSampler.NbTilesX(), myTileSampler.NbTilesY(), Graphic3d_TOT_2D);
}
{
myRaytraceOutputTexture[1]->InitRectangle (theGlContext,
theSizeX * 3, theSizeY * 2, OpenGl_TextureFormat::Create<GLfloat, 1>());
+
+ myRaytraceVisualErrorTexture[1]->Release (theGlContext.operator->());
+ myRaytraceTileOffsetsTexture[1]->Release (theGlContext.operator->());
+
+ myRaytraceVisualErrorTexture[1]->Init (theGlContext,
+ GL_R32I, GL_RED_INTEGER, GL_INT, myTileSampler.NbTilesX(), myTileSampler.NbTilesY(), Graphic3d_TOT_2D);
+
+ myRaytraceTileOffsetsTexture[1]->Init (theGlContext,
+ GL_RG32I, GL_RG_INTEGER, GL_INT, myTileSampler.NbTilesX(), myTileSampler.NbTilesY(), Graphic3d_TOT_2D);
}
}
else
{
OpenGl_Vec4 aOrigin (GLfloat(aX),
GLfloat(aY),
- -1.0f,
+ -1.0f,
1.0f);
aOrigin = theUnview * aOrigin;
}
}
+// =======================================================================
+// function : updatePerspCameraPT
+// purpose : Generates viewing rays (path tracing, perspective camera)
+// =======================================================================
+void OpenGl_View::updatePerspCameraPT (const OpenGl_Mat4& theOrientation,
+ const OpenGl_Mat4& theViewMapping,
+ Graphic3d_Camera::Projection theProjection,
+ OpenGl_Mat4& theViewPr,
+ OpenGl_Mat4& theUnview,
+ const int theWinSizeX,
+ const int theWinSizeY)
+{
+ // compute view-projection matrix
+ theViewPr = theViewMapping * theOrientation;
+
+ // compute inverse view-projection matrix
+ theViewPr.Inverted(theUnview);
+
+ // get camera stereo params
+ float anIOD = myCamera->GetIODType() == Graphic3d_Camera::IODType_Relative
+ ? static_cast<float> (myCamera->IOD() * myCamera->Distance())
+ : static_cast<float> (myCamera->IOD());
+
+ float aZFocus = myCamera->ZFocusType() == Graphic3d_Camera::FocusType_Relative
+ ? static_cast<float> (myCamera->ZFocus() * myCamera->Distance())
+ : static_cast<float> (myCamera->ZFocus());
+
+ // get camera view vectors
+ const gp_Pnt anOrig = myCamera->Eye();
+
+ myEyeOrig = OpenGl_Vec3 (static_cast<float> (anOrig.X()),
+ static_cast<float> (anOrig.Y()),
+ static_cast<float> (anOrig.Z()));
+
+ const gp_Dir aView = myCamera->Direction();
+
+ OpenGl_Vec3 anEyeViewMono = OpenGl_Vec3 (static_cast<float> (aView.X()),
+ static_cast<float> (aView.Y()),
+ static_cast<float> (aView.Z()));
+
+ const gp_Dir anUp = myCamera->Up();
+
+ myEyeVert = OpenGl_Vec3 (static_cast<float> (anUp.X()),
+ static_cast<float> (anUp.Y()),
+ static_cast<float> (anUp.Z()));
+
+ myEyeSide = OpenGl_Vec3::Cross (anEyeViewMono, myEyeVert);
+
+ const double aScaleY = tan (myCamera->FOVy() / 360 * M_PI);
+ const double aScaleX = theWinSizeX * aScaleY / theWinSizeY;
+
+ myEyeSize = OpenGl_Vec2 (static_cast<float> (aScaleX),
+ static_cast<float> (aScaleY));
+
+ if (theProjection == Graphic3d_Camera::Projection_Perspective)
+ {
+ myEyeView = anEyeViewMono;
+ }
+ else // stereo camera
+ {
+ // compute z-focus point
+ OpenGl_Vec3 aZFocusPoint = myEyeOrig + anEyeViewMono * aZFocus;
+
+ // compute stereo camera shift
+ float aDx = theProjection == Graphic3d_Camera::Projection_MonoRightEye ? 0.5f * anIOD : -0.5f * anIOD;
+ myEyeOrig += myEyeSide.Normalized() * aDx;
+
+ // estimate new camera direction vector and correct its length
+ myEyeView = (aZFocusPoint - myEyeOrig).Normalized();
+ myEyeView *= 1.f / anEyeViewMono.Dot (myEyeView);
+ }
+}
+
// =======================================================================
// function : uploadRaytraceData
// purpose : Uploads ray-trace data to the GPU
Standard_Boolean OpenGl_View::setUniformState (const Standard_Integer theProgramId,
const Standard_Integer theWinSizeX,
const Standard_Integer theWinSizeY,
+ Graphic3d_Camera::Projection theProjection,
const Handle(OpenGl_Context)& theGlContext)
{
// Get projection state
OpenGl_Vec3 aOrigins[4];
OpenGl_Vec3 aDirects[4];
- updateCamera (myCamera->OrientationMatrixF(),
- aCntxProjectionState.Current(),
- aOrigins,
- aDirects,
- aViewPrjMat,
- anUnviewMat);
+ if (myCamera->IsOrthographic()
+ || !myRenderParams.IsGlobalIlluminationEnabled)
+ {
+ updateCamera (myCamera->OrientationMatrixF(),
+ aCntxProjectionState.Current(),
+ aOrigins,
+ aDirects,
+ aViewPrjMat,
+ anUnviewMat);
+ }
+ else
+ {
+ updatePerspCameraPT (myCamera->OrientationMatrixF(),
+ aCntxProjectionState.Current(),
+ theProjection,
+ aViewPrjMat,
+ anUnviewMat,
+ theWinSizeX,
+ theWinSizeY);
+ }
Handle(OpenGl_ShaderProgram)& theProgram = theProgramId == 0
? myRaytraceProgram
{
return Standard_False;
}
-
+
+ theProgram->SetUniform(theGlContext, "uEyeOrig", myEyeOrig);
+ theProgram->SetUniform(theGlContext, "uEyeView", myEyeView);
+ theProgram->SetUniform(theGlContext, "uEyeVert", myEyeVert);
+ theProgram->SetUniform(theGlContext, "uEyeSide", myEyeSide);
+ theProgram->SetUniform(theGlContext, "uEyeSize", myEyeSize);
+
+ theProgram->SetUniform(theGlContext, "uApertureRadius", myRenderParams.CameraApertureRadius);
+ theProgram->SetUniform(theGlContext, "uFocalPlaneDist", myRenderParams.CameraFocalPlaneDist);
+
// Set camera state
theProgram->SetUniform (theGlContext,
myUniformLocations[theProgramId][OpenGl_RT_uOriginLB], aOrigins[0]);
theGlContext->core42->glBindImageTexture (OpenGl_RT_OutputImageRgh,
myRaytraceOutputTexture[1]->TextureId(), 0, GL_TRUE, 0, GL_READ_WRITE, GL_R32F);
- theGlContext->core42->glBindImageTexture (OpenGl_RT_VisualErrorImage,
- myRaytraceVisualErrorTexture->TextureId(), 0, GL_TRUE, 0, GL_READ_WRITE, GL_R32I);
- theGlContext->core42->glBindImageTexture (OpenGl_RT_TileOffsetsImage,
- myRaytraceTileOffsetsTexture->TextureId(), 0, GL_TRUE, 0, GL_READ_ONLY, GL_RG32I);
- #endif
+ theGlContext->core42->glBindImageTexture (OpenGl_RT_VisualErrorImageLft,
+ myRaytraceVisualErrorTexture[0]->TextureId(), 0, GL_TRUE, 0, GL_READ_WRITE, GL_R32I);
+ theGlContext->core42->glBindImageTexture (OpenGl_RT_VisualErrorImageRgh,
+ myRaytraceVisualErrorTexture[1]->TextureId(), 0, GL_TRUE, 0, GL_READ_WRITE, GL_R32I);
+ theGlContext->core42->glBindImageTexture (OpenGl_RT_TileOffsetsImageLft,
+ myRaytraceTileOffsetsTexture[0]->TextureId(), 0, GL_TRUE, 0, GL_READ_ONLY, GL_RG32I);
+ theGlContext->core42->glBindImageTexture (OpenGl_RT_TileOffsetsImageRgh,
+ myRaytraceTileOffsetsTexture[1]->TextureId(), 0, GL_TRUE, 0, GL_READ_ONLY, GL_RG32I);
+#endif
}
if (!myTextureEnv.IsNull() && myTextureEnv->IsValid())
aResult &= setUniformState (0,
theSizeX,
theSizeY,
+ theProjection,
theGlContext);
if (myRaytraceParameters.GlobalIllumination) // path tracing
aResult &= setUniformState (1 /* FSAA ID */,
theSizeX,
theSizeY,
+ theProjection,
theGlContext);
// Perform multi-pass adaptive FSAA using ping-pong technique.
{
myAccumFrames = myToUpdateEnvironmentMap = 0;
}
+
+ if (myRenderParams.CameraApertureRadius != myPrevCameraApertureRadius
+ || myRenderParams.CameraFocalPlaneDist != myPrevCameraFocalPlaneDist)
+ {
+
+ myPrevCameraApertureRadius = myRenderParams.CameraApertureRadius;
+ myPrevCameraFocalPlaneDist = myRenderParams.CameraFocalPlaneDist;
+
+ myAccumFrames = 0;
+ }
+
+ // Choose proper set of frame buffers for stereo rendering
+ const Standard_Integer aFBOIdx (theProjection == Graphic3d_Camera::Projection_MonoRightEye);
if (myRaytraceParameters.AdaptiveScreenSampling)
{
if (myAccumFrames == 0)
{
myTileSampler.Reset(); // reset tile sampler to its initial state
- }
- // Adaptive sampling is starting at the second frame
- myTileSampler.Upload (theGlContext,
- myRaytraceTileOffsetsTexture,
- myRaytraceParameters.NbTilesX,
- myRaytraceParameters.NbTilesY,
- myAccumFrames > 0);
+ // Adaptive sampling is starting at the second frame
+ myTileSampler.Upload (theGlContext,
+ myRaytraceTileOffsetsTexture[aFBOIdx],
+ myRaytraceParameters.NbTilesX,
+ myRaytraceParameters.NbTilesY,
+ false);
+ }
}
bindRaytraceTextures (theGlContext);
Handle(OpenGl_FrameBuffer) aDepthSourceFramebuffer;
Handle(OpenGl_FrameBuffer) anAccumImageFramebuffer;
- // Choose proper set of frame buffers for stereo rendering
- const Standard_Integer aFBOIdx (theProjection == Graphic3d_Camera::Projection_MonoRightEye);
-
const Standard_Integer anImageId = (aFBOIdx != 0)
? OpenGl_RT_OutputImageRgh
: OpenGl_RT_OutputImageLft;
+ const Standard_Integer anErrorId = (aFBOIdx != 0)
+ ? OpenGl_RT_VisualErrorImageRgh
+ : OpenGl_RT_VisualErrorImageLft;
+
+ const Standard_Integer anOffsetId = (aFBOIdx != 0)
+ ? OpenGl_RT_TileOffsetsImageRgh
+ : OpenGl_RT_TileOffsetsImageLft;
+
aRenderImageFramebuffer = myAccumFrames % 2 ? myRaytraceFBO1[aFBOIdx] : myRaytraceFBO2[aFBOIdx];
anAccumImageFramebuffer = myAccumFrames % 2 ? myRaytraceFBO2[aFBOIdx] : myRaytraceFBO1[aFBOIdx];
if (myRaytraceParameters.AdaptiveScreenSampling)
{
#if !defined(GL_ES_VERSION_2_0)
- if (myAccumFrames == 0)
+ if (myAccumFrames == 0 || (myAccumFrames == 1 && myCamera->IsStereo()))
{
theGlContext->core44->glClearTexImage (myRaytraceOutputTexture[aFBOIdx]->TextureId(), 0, GL_RED, GL_FLOAT, NULL);
}
- theGlContext->core44->glClearTexImage (myRaytraceVisualErrorTexture->TextureId(), 0, GL_RED_INTEGER, GL_INT, NULL);
+ theGlContext->core44->glClearTexImage (myRaytraceVisualErrorTexture[aFBOIdx]->TextureId(), 0, GL_RED_INTEGER, GL_INT, NULL);
#endif
}
myRaytraceProgram->SetUniform (theGlContext,
myUniformLocations[0][OpenGl_RT_uRenderImage], anImageId);
myRaytraceProgram->SetUniform (theGlContext,
- myUniformLocations[0][OpenGl_RT_uOffsetImage], OpenGl_RT_TileOffsetsImage);
+ myUniformLocations[0][OpenGl_RT_uOffsetImage], anOffsetId);
glDisable (GL_DEPTH_TEST);
- if (myRaytraceParameters.AdaptiveScreenSampling && myAccumFrames > 0)
+ if (myRaytraceParameters.AdaptiveScreenSampling
+ && ((myAccumFrames > 0 && !myCamera->IsStereo()) || myAccumFrames > 1))
{
glViewport (0,
0,
// Generate for the given RNG seed
theGlContext->core20fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
- if (myRaytraceParameters.AdaptiveScreenSampling && myAccumFrames > 0)
+ if (myRaytraceParameters.AdaptiveScreenSampling
+ && ((myAccumFrames > 0 && !myCamera->IsStereo()) || myAccumFrames > 1))
{
glViewport (0,
0,
// Set uniforms for display program
myOutImageProgram->SetUniform (theGlContext, "uRenderImage", anImageId);
myOutImageProgram->SetUniform (theGlContext, "uAccumFrames", myAccumFrames);
- myOutImageProgram->SetUniform (theGlContext, "uVarianceImage", OpenGl_RT_VisualErrorImage);
+ myOutImageProgram->SetUniform (theGlContext, "uVarianceImage", anErrorId);
myOutImageProgram->SetUniform (theGlContext, "uDebugAdaptive", myRenderParams.ShowSamplingTiles ? 1 : 0);
}
if (myRaytraceParameters.AdaptiveScreenSampling)
{
- myRaytraceVisualErrorTexture->Bind (theGlContext);
+ myRaytraceVisualErrorTexture[aFBOIdx]->Bind (theGlContext);
// Download visual error map from the GPU and build
// adjusted tile offsets for optimal image sampling
myTileSampler.GrabVarianceMap (theGlContext);
+
+ myTileSampler.Upload (theGlContext,
+ myRaytraceTileOffsetsTexture[aFBOIdx],
+ myRaytraceParameters.NbTilesX,
+ myRaytraceParameters.NbTilesY,
+ myAccumFrames > 0);
}
unbindRaytraceTextures (theGlContext);
//! Bottom color of gradient background.
uniform vec4 uBackColorBot = vec4 (0.0);
+//! Aperture radius of camera used for depth-of-field
+uniform float uApertureRadius = 0.f;
+
+//! Focal distance of camera used for depth-of field
+uniform float uFocalPlaneDist = 10.f;
+
+//! Camera position used for projective mode
+uniform vec3 uEyeOrig;
+
+//! Camera view direction used for projective mode
+uniform vec3 uEyeView;
+
+//! Camera's screen vertical direction used for projective mode
+uniform vec3 uEyeVert;
+
+//! Camera's screen horizontal direction used for projective mode
+uniform vec3 uEyeSide;
+
+//! Camera's screen size used for projective mode
+uniform vec2 uEyeSize;
+
/////////////////////////////////////////////////////////////////////////////////////////
// Specific data types
/////////////////////////////////////////////////////////////////////////////////////////
// Functions for compute ray-object intersection
+//=======================================================================
+// function : sampleUniformDisk
+// purpose :
+//=======================================================================
+vec2 sampleUniformDisk ()
+{
+ vec2 aPoint;
+
+ float aKsi1 = 2.f * RandFloat () - 1.f;
+ float aKsi2 = 2.f * RandFloat () - 1.f;
+
+ if (aKsi1 > -aKsi2)
+ {
+ if (aKsi1 > aKsi2)
+ aPoint = vec2 (aKsi1, (M_PI / 4.f) * (0.f + aKsi2 / aKsi1));
+ else
+ aPoint = vec2 (aKsi2, (M_PI / 4.f) * (2.f - aKsi1 / aKsi2));
+ }
+ else
+ {
+ if (aKsi1 < aKsi2)
+ aPoint = vec2 (-aKsi1, (M_PI / 4.f) * (4.f + aKsi2 / aKsi1));
+ else
+ aPoint = vec2 (-aKsi2, (M_PI / 4.f) * (6.f - aKsi1 / aKsi2));
+ }
+
+ return vec2 (sin (aPoint.y), cos (aPoint.y)) * aPoint.x;
+}
+
// =======================================================================
// function : GenerateRay
// purpose :
// =======================================================================
SRay GenerateRay (in vec2 thePixel)
{
+#ifndef DEPTH_OF_FIELD
+
vec3 aP0 = mix (uOriginLB, uOriginRB, thePixel.x);
vec3 aP1 = mix (uOriginLT, uOriginRT, thePixel.x);
vec3 aDirection = normalize (mix (aD0, aD1, thePixel.y));
return SRay (mix (aP0, aP1, thePixel.y), aDirection);
+
+#else
+
+ vec2 aPixel = uEyeSize * (thePixel - vec2 (0.5f)) * 2.f;
+
+ vec2 aAperturePnt = sampleUniformDisk () * uApertureRadius;
+
+ vec3 aLocalDir = normalize (vec3 (
+ aPixel * uFocalPlaneDist - aAperturePnt, uFocalPlaneDist));
+
+ vec3 aOrigin = uEyeOrig +
+ uEyeSide * aAperturePnt.x +
+ uEyeVert * aAperturePnt.y;
+
+ vec3 aDirect = uEyeView * aLocalDir.z +
+ uEyeSide * aLocalDir.x +
+ uEyeVert * aLocalDir.y;
+
+ return SRay (aOrigin, aDirect);
+
+#endif
}
// =======================================================================
"//! Bottom color of gradient background.\n"
"uniform vec4 uBackColorBot = vec4 (0.0);\n"
"\n"
+ "//! Aperture radius of camera used for depth-of-field\n"
+ "uniform float uApertureRadius = 0.f;\n"
+ "\n"
+ "//! Focal distance of camera used for depth-of field\n"
+ "uniform float uFocalPlaneDist = 10.f;\n"
+ "\n"
+ "//! Camera position used for projective mode\n"
+ "uniform vec3 uEyeOrig;\n"
+ "\n"
+ "//! Camera view direction used for projective mode\n"
+ "uniform vec3 uEyeView;\n"
+ "\n"
+ "//! Camera's screen vertical direction used for projective mode\n"
+ "uniform vec3 uEyeVert;\n"
+ "\n"
+ "//! Camera's screen horizontal direction used for projective mode\n"
+ "uniform vec3 uEyeSide;\n"
+ "\n"
+ "//! Camera's screen size used for projective mode\n"
+ "uniform vec2 uEyeSize;\n"
+ "\n"
"/////////////////////////////////////////////////////////////////////////////////////////\n"
"// Specific data types\n"
"\n"
"/////////////////////////////////////////////////////////////////////////////////////////\n"
"// Functions for compute ray-object intersection\n"
"\n"
+ "//=======================================================================\n"
+ "// function : sampleUniformDisk\n"
+ "// purpose :\n"
+ "//=======================================================================\n"
+ "vec2 sampleUniformDisk ()\n"
+ "{\n"
+ " vec2 aPoint;\n"
+ "\n"
+ " float aKsi1 = 2.f * RandFloat () - 1.f;\n"
+ " float aKsi2 = 2.f * RandFloat () - 1.f;\n"
+ "\n"
+ " if (aKsi1 > -aKsi2)\n"
+ " {\n"
+ " if (aKsi1 > aKsi2)\n"
+ " aPoint = vec2 (aKsi1, (M_PI / 4.f) * (0.f + aKsi2 / aKsi1));\n"
+ " else\n"
+ " aPoint = vec2 (aKsi2, (M_PI / 4.f) * (2.f - aKsi1 / aKsi2));\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " if (aKsi1 < aKsi2)\n"
+ " aPoint = vec2 (-aKsi1, (M_PI / 4.f) * (4.f + aKsi2 / aKsi1));\n"
+ " else\n"
+ " aPoint = vec2 (-aKsi2, (M_PI / 4.f) * (6.f - aKsi1 / aKsi2));\n"
+ " }\n"
+ "\n"
+ " return vec2 (sin (aPoint.y), cos (aPoint.y)) * aPoint.x;\n"
+ "}\n"
+ "\n"
"// =======================================================================\n"
"// function : GenerateRay\n"
"// purpose :\n"
"// =======================================================================\n"
"SRay GenerateRay (in vec2 thePixel)\n"
"{\n"
+ "#ifndef DEPTH_OF_FIELD\n"
+ "\n"
" vec3 aP0 = mix (uOriginLB, uOriginRB, thePixel.x);\n"
" vec3 aP1 = mix (uOriginLT, uOriginRT, thePixel.x);\n"
"\n"
" vec3 aDirection = normalize (mix (aD0, aD1, thePixel.y));\n"
"\n"
" return SRay (mix (aP0, aP1, thePixel.y), aDirection);\n"
+ "\n"
+ "#else\n"
+ "\n"
+ " vec2 aPixel = uEyeSize * (thePixel - vec2 (0.5f)) * 2.f;\n"
+ "\n"
+ " vec2 aAperturePnt = sampleUniformDisk () * uApertureRadius;\n"
+ "\n"
+ " vec3 aLocalDir = normalize (vec3 (\n"
+ " aPixel * uFocalPlaneDist - aAperturePnt, uFocalPlaneDist));\n"
+ "\n"
+ " vec3 aOrigin = uEyeOrig +\n"
+ " uEyeSide * aAperturePnt.x +\n"
+ " uEyeVert * aAperturePnt.y;\n"
+ "\n"
+ " vec3 aDirect = uEyeView * aLocalDir.z +\n"
+ " uEyeSide * aLocalDir.x +\n"
+ " uEyeVert * aLocalDir.y;\n"
+ "\n"
+ " return SRay (aOrigin, aDirect);\n"
+ "\n"
+ "#endif\n"
"}\n"
"\n"
"// =======================================================================\n"
}
aParams.RebuildRayTracingShaders = toEnable;
}
+ else if (aFlag == "-focal")
+ {
+ if (++anArgIter >= theArgNb)
+ {
+ std::cout << "Error: wrong syntax at argument '" << anArg << "'\n";
+ return 1;
+ }
+
+ TCollection_AsciiString aParam (theArgVec[anArgIter]);
+ if (aParam.IsRealValue())
+ {
+ float aFocalDist = static_cast<float> (aParam.RealValue());
+ if (aFocalDist < 0)
+ {
+ std::cout << "Error: parameter can't be negative at argument '" << anArg << "'.\n";
+ return 1;
+ }
+ aView->ChangeRenderingParams().CameraFocalPlaneDist = aFocalDist;
+ }
+ else
+ {
+ std::cout << "Error: wrong syntax at argument'" << anArg << "'.\n";
+ return 1;
+ }
+ }
+ else if (aFlag == "-aperture")
+ {
+ if (++anArgIter >= theArgNb)
+ {
+ std::cout << "Error: wrong syntax at argument '" << anArg << "'\n";
+ return 1;
+ }
+
+ TCollection_AsciiString aParam(theArgVec[anArgIter]);
+ if (aParam.IsRealValue())
+ {
+ float aApertureSize = static_cast<float> (aParam.RealValue());
+ if (aApertureSize < 0)
+ {
+ std::cout << "Error: parameter can't be negative at argument '" << anArg << "'.\n";
+ return 1;
+ }
+ aView->ChangeRenderingParams().CameraApertureRadius = aApertureSize;
+ }
+ else
+ {
+ std::cout << "Error: wrong syntax at argument'" << anArg << "'.\n";
+ return 1;
+ }
+ }
else if (aFlag == "-exposure")
{
if (++anArgIter >= theArgNb)
"\n '-shadingModel model' Controls shading model from enumeration"
"\n color, flat, gouraud, phong"
"\n '-resolution value' Sets a new pixels density (PPI), defines scaling factor for parameters like text size"
+ "\n '-aperture >= 0.0' Aperture size of perspective camera for depth-of-field effect (0 disables DOF)"
+ "\n '-focal >= 0.0' Focal distance of perspective camera for depth-of-field effect"
"\n '-exposure value' Exposure value for tone mapping (0.0 value disables the effect)"
"\n '-whitepoint value' White point value for filmic tone mapping"
"\n '-tonemapping mode' Tone mapping mode (disabled, filmic)"
--- /dev/null
+puts "========"
+puts "Ray Tracing - check depth-of-field"
+puts "========"
+
+pload MODELING VISUALIZATION
+
+vclear
+vinit View1
+
+vlight add positional head 0 pos 0.5 0.5 0.85
+vlight change 0 sm 0.06
+vlight change 0 int 25.0
+
+vsetdispmode 1
+vcamera -persp
+
+box b 1 1 1
+explode b FACE
+vdisplay -noupdate b_1 b_2 b_3 b_5 b_6
+vlocation -noupdate b_1 -setLocation 1 0 0
+vlocation -noupdate b_2 -setLocation -1 0 0
+vlocation -noupdate b_3 -setLocation 0 1 0
+vlocation -noupdate b_5 -setLocation 0 0 1
+vlocation -noupdate b_6 -setLocation 0 0 -1
+
+vsetmaterial -noupdate b_1 plastic
+vsetmaterial -noupdate b_2 plastic
+vsetmaterial -noupdate b_3 plastic
+vsetmaterial -noupdate b_5 plastic
+vsetmaterial -noupdate b_6 plastic
+vbsdf b_1 -kd 1 0.3 0.3 -ks 0
+vbsdf b_2 -kd 0.3 0.5 1 -ks 0
+vbsdf b_3 -kd 1 -ks 0
+vbsdf b_5 -kd 1 -ks 0
+vbsdf b_6 -kd 1 -ks 0
+
+vfront
+vfit
+
+psphere s 0.2
+vdisplay -noupdate s
+vlocation -noupdate s -setLocation 0.21 0.3 0.2
+vsetmaterial -noupdate s glass
+vbsdf s -absorpColor 0.8 0.8 1.0
+vbsdf s -absorpCoeff 6
+
+box c 0.3 0.3 0.2
+vdisplay -noupdate c
+vlocation -noupdate c -setLocation 0.55 0.3 0.0
+vlocation -noupdate c -rotate 0 0 0 0 0 1 -30
+vsetmaterial -noupdate c plastic
+vbsdf c -kd 1.0 0.8 0.2 -ks 0.3 -n
+
+box g 0.15 0.15 0.3
+vdisplay -noupdate g
+vlocation -noupdate g -setLocation 0.7 0.25 0.2
+vlocation -noupdate g -rotate 0 0 0 0 0 1 10
+vsetmaterial -noupdate g glass
+vbsdf g -absorpColor 0.8 1.0 0.8
+vbsdf g -absorpCoeff 6
+
+psphere r 0.1
+vdisplay -noupdate r
+vsetmaterial -noupdate r plastic
+vbsdf r -kd 0.5 0.9 0.3 -ks 0.3 -baseRoughness 0.0 -n
+vbsdf r -baseFresnel Constant 1.0
+vlocation r -setLocation 0.5 0.65 0.1
+
+vrenderparams -ray -gi -rayDepth 10 -iss
+vrenderparams -aperture 0.1 -focal 2.0
--- /dev/null
+puts "========"
+puts "Ray Tracing - check depth-of-field"
+puts "========"
+
+pload MODELING VISUALIZATION
+
+vclear
+vinit View1
+
+vlight add positional head 0 pos 0.5 0.5 0.85
+vlight change 0 sm 0.06
+vlight change 0 int 25.0
+
+vsetdispmode 1
+vcamera -persp
+
+box b 1 1 1
+explode b FACE
+vdisplay -noupdate b_1 b_2 b_3 b_5 b_6
+vlocation -noupdate b_1 -setLocation 1 0 0
+vlocation -noupdate b_2 -setLocation -1 0 0
+vlocation -noupdate b_3 -setLocation 0 1 0
+vlocation -noupdate b_5 -setLocation 0 0 1
+vlocation -noupdate b_6 -setLocation 0 0 -1
+
+vsetmaterial -noupdate b_1 plastic
+vsetmaterial -noupdate b_2 plastic
+vsetmaterial -noupdate b_3 plastic
+vsetmaterial -noupdate b_5 plastic
+vsetmaterial -noupdate b_6 plastic
+vbsdf b_1 -kd 1 0.3 0.3 -ks 0
+vbsdf b_2 -kd 0.3 0.5 1 -ks 0
+vbsdf b_3 -kd 1 -ks 0
+vbsdf b_5 -kd 1 -ks 0
+vbsdf b_6 -kd 1 -ks 0
+
+vfront
+vfit
+
+psphere s 0.2
+vdisplay -noupdate s
+vlocation -noupdate s -setLocation 0.21 0.3 0.2
+vsetmaterial -noupdate s glass
+vbsdf s -absorpColor 0.8 0.8 1.0
+vbsdf s -absorpCoeff 6
+
+box c 0.3 0.3 0.2
+vdisplay -noupdate c
+vlocation -noupdate c -setLocation 0.55 0.3 0.0
+vlocation -noupdate c -rotate 0 0 0 0 0 1 -30
+vsetmaterial -noupdate c plastic
+vbsdf c -kd 1.0 0.8 0.2 -ks 0.3 -n
+
+box g 0.15 0.15 0.3
+vdisplay -noupdate g
+vlocation -noupdate g -setLocation 0.7 0.25 0.2
+vlocation -noupdate g -rotate 0 0 0 0 0 1 10
+vsetmaterial -noupdate g glass
+vbsdf g -absorpColor 0.8 1.0 0.8
+vbsdf g -absorpCoeff 6
+
+psphere r 0.1
+vdisplay -noupdate r
+vsetmaterial -noupdate r plastic
+vbsdf r -kd 0.5 0.9 0.3 -ks 0.3 -baseRoughness 0.0 -n
+vbsdf r -baseFresnel Constant 1.0
+vlocation r -setLocation 0.5 0.65 0.1
+
+vrenderparams -ray -gi -rayDepth 10 -iss
+vrenderparams -aperture 0.1 -focal 2.0
+
+# activate stereo
+vstereo on
+vstereo -mode anaglyph
+vcamera -iod 0.1
+vfit