1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-04 18:06:22 +03:00

0028762: Visualization, Ray tracing - Implement depth-of-field effect

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
This commit is contained in:
duv 2017-06-27 11:22:31 +03:00 committed by bugmaster
parent 475c2302d4
commit b27ab03d09
9 changed files with 588 additions and 45 deletions

View File

@ -68,6 +68,8 @@ public:
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),
@ -119,6 +121,8 @@ public:
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

View File

@ -94,7 +94,9 @@ OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr,
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);

View File

@ -645,8 +645,10 @@ protected: //! @name data types related to ray-tracing
{
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.
@ -742,6 +744,9 @@ protected: //! @name data types related to ray-tracing
//! 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;
@ -758,6 +763,7 @@ protected: //! @name data types related to ray-tracing
RadianceClampingValue (30.0),
NbTilesX (16),
NbTilesY (16),
DepthOfField (Standard_False),
ToneMappingMethod (Graphic3d_ToneMappingMethod_Disabled) { }
};
@ -900,6 +906,7 @@ protected: //! @name methods related to ray-tracing
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,
@ -907,6 +914,15 @@ protected: //! @name methods related to ray-tracing
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);
@ -917,6 +933,7 @@ protected: //! @name methods related to ray-tracing
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.
@ -1027,12 +1044,12 @@ protected: //! @name fields related to ray-tracing
//! 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;
@ -1070,6 +1087,27 @@ protected: //! @name fields related to ray-tracing
//! 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

View File

@ -1149,6 +1149,11 @@ TCollection_AsciiString OpenGl_View::generateShaderPrefix (const Handle(OpenGl_C
}
}
if (myRaytraceParameters.DepthOfField)
{
aPrefixString += TCollection_AsciiString("\n#define DEPTH_OF_FIELD");
}
return aPrefixString;
}
@ -1411,6 +1416,13 @@ Standard_Boolean OpenGl_View::initRaytraceResources (const Handle(OpenGl_Context
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;
@ -1830,8 +1842,10 @@ void OpenGl_View::releaseRaytraceResources (const Handle(OpenGl_Context)& theGlC
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);
@ -1914,13 +1928,16 @@ Standard_Boolean OpenGl_View::updateRaytraceBuffers (const Standard_Integer
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
@ -1941,13 +1958,13 @@ Standard_Boolean OpenGl_View::updateRaytraceBuffers (const Standard_Integer
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);
}
@ -1958,6 +1975,15 @@ Standard_Boolean OpenGl_View::updateRaytraceBuffers (const Standard_Integer
{
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
@ -1994,7 +2020,7 @@ void OpenGl_View::updateCamera (const OpenGl_Mat4& theOrientation,
{
OpenGl_Vec4 aOrigin (GLfloat(aX),
GLfloat(aY),
-1.0f,
-1.0f,
1.0f);
aOrigin = theUnview * aOrigin;
@ -2027,6 +2053,79 @@ void OpenGl_View::updateCamera (const OpenGl_Mat4& theOrientation,
}
}
// =======================================================================
// 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
@ -2463,6 +2562,7 @@ Standard_Boolean OpenGl_View::updateRaytraceLightSources (const OpenGl_Mat4& the
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
@ -2473,12 +2573,26 @@ Standard_Boolean OpenGl_View::setUniformState (const Standard_Integer the
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
@ -2488,7 +2602,16 @@ Standard_Boolean OpenGl_View::setUniformState (const Standard_Integer the
{
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]);
@ -2614,11 +2737,15 @@ void OpenGl_View::bindRaytraceTextures (const Handle(OpenGl_Context)& theGlConte
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())
@ -2673,6 +2800,7 @@ Standard_Boolean OpenGl_View::runRaytraceShaders (const Standard_Integer
aResult &= setUniformState (0,
theSizeX,
theSizeY,
theProjection,
theGlContext);
if (myRaytraceParameters.GlobalIllumination) // path tracing
@ -2728,6 +2856,7 @@ Standard_Boolean OpenGl_View::runRaytrace (const Standard_Integer theSize
aResult &= setUniformState (1 /* FSAA ID */,
theSizeX,
theSizeY,
theProjection,
theGlContext);
// Perform multi-pass adaptive FSAA using ping-pong technique.
@ -2830,20 +2959,33 @@ Standard_Boolean OpenGl_View::runPathtrace (const Standard_Integer
{
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);
@ -2852,13 +2994,18 @@ Standard_Boolean OpenGl_View::runPathtrace (const Standard_Integer
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];
@ -2878,12 +3025,12 @@ Standard_Boolean OpenGl_View::runPathtrace (const Standard_Integer
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
}
@ -2899,11 +3046,12 @@ Standard_Boolean OpenGl_View::runPathtrace (const Standard_Integer
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,
@ -2914,7 +3062,8 @@ Standard_Boolean OpenGl_View::runPathtrace (const Standard_Integer
// 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,
@ -2930,7 +3079,7 @@ Standard_Boolean OpenGl_View::runPathtrace (const Standard_Integer
// 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);
}
@ -2969,11 +3118,17 @@ Standard_Boolean OpenGl_View::runPathtrace (const Standard_Integer
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);

View File

@ -108,6 +108,27 @@ uniform vec4 uBackColorTop = vec4 (0.0);
//! 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
@ -271,12 +292,43 @@ vec4 BackgroundColor()
/////////////////////////////////////////////////////////////////////////////////////////
// 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);
@ -286,6 +338,27 @@ SRay GenerateRay (in vec2 thePixel)
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
}
// =======================================================================

View File

@ -111,6 +111,27 @@ static const char Shaders_RaytraceBase_fs[] =
"//! 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"
@ -274,12 +295,43 @@ static const char Shaders_RaytraceBase_fs[] =
"/////////////////////////////////////////////////////////////////////////////////////////\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"
@ -289,6 +341,27 @@ static const char Shaders_RaytraceBase_fs[] =
" 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"

View File

@ -9647,6 +9647,56 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
}
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)
@ -11205,6 +11255,8 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
"\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)"

View File

@ -0,0 +1,70 @@
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

View File

@ -0,0 +1,76 @@
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