mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-09 18:50:54 +03:00
0026437: Visualization - Improve path tracing rendering engine
Fix compile warnings.
This commit is contained in:
parent
c14cd5a20e
commit
8c820969cc
78
samples/tcl/pathtrace.tcl
Normal file
78
samples/tcl/pathtrace.tcl
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
#########################################################################
|
||||||
|
# 26437: Visualization - Improve path tracing rendering engine
|
||||||
|
#########################################################################
|
||||||
|
|
||||||
|
pload ALL
|
||||||
|
|
||||||
|
# setup 3D viewer content
|
||||||
|
vinit name=View1 w=512 h=512
|
||||||
|
vglinfo
|
||||||
|
|
||||||
|
vvbo 0
|
||||||
|
vsetdispmode 1
|
||||||
|
vcamera -persp
|
||||||
|
|
||||||
|
box b 1 1 1
|
||||||
|
explode b FACE
|
||||||
|
vdisplay b_1 b_2 b_3 b_5 b_6
|
||||||
|
|
||||||
|
vright
|
||||||
|
vfit
|
||||||
|
|
||||||
|
vsetmaterial b_1 plastic
|
||||||
|
vsetmaterial b_2 plastic
|
||||||
|
vsetmaterial b_3 plastic
|
||||||
|
vsetmaterial b_5 plastic
|
||||||
|
vsetmaterial b_6 plastic
|
||||||
|
|
||||||
|
vbsdf b_1 -kd 1 -ks 0
|
||||||
|
vbsdf b_2 -kd 1 -ks 0
|
||||||
|
vbsdf b_3 -kd 1 -ks 0
|
||||||
|
vbsdf b_5 -kd 1 -ks 0
|
||||||
|
vbsdf b_6 -kd 1 -ks 0
|
||||||
|
|
||||||
|
vbsdf b_2 -kd 0.3 0.5 1
|
||||||
|
vbsdf b_1 -kd 1 0.3 0.3
|
||||||
|
|
||||||
|
vsetlocation b_1 1 0 0
|
||||||
|
vsetlocation b_2 -1 0 0
|
||||||
|
vsetlocation b_5 0 0 1
|
||||||
|
vsetlocation b_6 0 0 -1
|
||||||
|
vsetlocation b_3 0 1 0
|
||||||
|
|
||||||
|
vlight del 0
|
||||||
|
vlight del 1
|
||||||
|
vlight add positional head 0 pos 0.5 0.5 0.85
|
||||||
|
vlight change 0 sm 0.06
|
||||||
|
vlight change 0 int 60.0
|
||||||
|
|
||||||
|
psphere s 0.2
|
||||||
|
vdisplay s
|
||||||
|
vsetlocation s 0.21 0.3 0.2
|
||||||
|
vsetmaterial s glass
|
||||||
|
vbsdf s -absorpcolor 0.8 0.8 1.0
|
||||||
|
vbsdf s -absorpcoeff 6
|
||||||
|
|
||||||
|
box c 0.3 0.3 0.2
|
||||||
|
vdisplay c
|
||||||
|
vsetlocation c 0.55 0.3 0.0
|
||||||
|
vlocrotate c 0 0 0 0 0 1 -30
|
||||||
|
vsetmaterial c plastic
|
||||||
|
vbsdf c -kd 1.0 0.8 0.2 -ks 0.3 -n
|
||||||
|
|
||||||
|
box g 0.15 0.15 0.3
|
||||||
|
vdisplay g
|
||||||
|
vsetlocation g 0.7 0.25 0.2
|
||||||
|
vlocrotate g 0 0 0 0 0 1 10
|
||||||
|
vsetmaterial g glass
|
||||||
|
vbsdf g -absorpcolor 0.8 1.0 0.8
|
||||||
|
vbsdf g -absorpcoeff 6
|
||||||
|
|
||||||
|
psphere r 0.1
|
||||||
|
vdisplay r
|
||||||
|
vsetmaterial r plastic
|
||||||
|
vbsdf r -kd 0.5 0.9 0.3 -ks 0.0 -kr 0.3 -n
|
||||||
|
vbsdf r -fresnel Constant 1.0
|
||||||
|
vsetlocation r 0.5 0.65 0.1
|
||||||
|
|
||||||
|
vrenderparams -ray -gi -rayDepth 8
|
@ -55,8 +55,9 @@ public:
|
|||||||
IsReflectionEnabled (Standard_False),
|
IsReflectionEnabled (Standard_False),
|
||||||
IsAntialiasingEnabled (Standard_False),
|
IsAntialiasingEnabled (Standard_False),
|
||||||
IsTransparentShadowEnabled (Standard_False),
|
IsTransparentShadowEnabled (Standard_False),
|
||||||
|
|
||||||
UseEnvironmentMapBackground (Standard_False),
|
UseEnvironmentMapBackground (Standard_False),
|
||||||
|
CoherentPathTracingMode (Standard_False),
|
||||||
|
|
||||||
StereoMode (Graphic3d_StereoMode_QuadBuffer),
|
StereoMode (Graphic3d_StereoMode_QuadBuffer),
|
||||||
AnaglyphFilter (Anaglyph_RedCyan_Optimized),
|
AnaglyphFilter (Anaglyph_RedCyan_Optimized),
|
||||||
ToReverseStereo (Standard_False)
|
ToReverseStereo (Standard_False)
|
||||||
@ -84,6 +85,7 @@ public:
|
|||||||
Standard_Boolean IsAntialiasingEnabled; //!< enables/disables adaptive anti-aliasing, False by default
|
Standard_Boolean IsAntialiasingEnabled; //!< enables/disables adaptive anti-aliasing, False by default
|
||||||
Standard_Boolean IsTransparentShadowEnabled; //!< enables/disables light propagation through transparent media, False by default
|
Standard_Boolean IsTransparentShadowEnabled; //!< enables/disables light propagation through transparent media, False by default
|
||||||
Standard_Boolean UseEnvironmentMapBackground; //!< enables/disables environment map background
|
Standard_Boolean UseEnvironmentMapBackground; //!< enables/disables environment map background
|
||||||
|
Standard_Boolean CoherentPathTracingMode; //!< enables/disables 'coherent' tracing mode (single RNG seed within 16x16 image blocks)
|
||||||
|
|
||||||
Graphic3d_StereoMode StereoMode; //!< stereoscopic output mode, Graphic3d_StereoMode_QuadBuffer by default
|
Graphic3d_StereoMode StereoMode; //!< stereoscopic output mode, Graphic3d_StereoMode_QuadBuffer by default
|
||||||
Anaglyph AnaglyphFilter; //!< filter for anaglyph output, Anaglyph_RedCyan_Optimized by default
|
Anaglyph AnaglyphFilter; //!< filter for anaglyph output, Anaglyph_RedCyan_Optimized by default
|
||||||
|
@ -170,7 +170,6 @@ class OpenGl_View : public MMgt_TShared
|
|||||||
const Aspect_CLayer2d& theCOverLayer,
|
const Aspect_CLayer2d& theCOverLayer,
|
||||||
const Standard_Boolean theToDrawImmediate);
|
const Standard_Boolean theToDrawImmediate);
|
||||||
|
|
||||||
|
|
||||||
void DrawBackground (const Handle(OpenGl_Workspace)& theWorkspace);
|
void DrawBackground (const Handle(OpenGl_Workspace)& theWorkspace);
|
||||||
|
|
||||||
//! Returns list of OpenGL Z-layers.
|
//! Returns list of OpenGL Z-layers.
|
||||||
@ -334,6 +333,7 @@ protected: //! @name data types related to ray-tracing
|
|||||||
OpenGl_RT_uSphereMapEnabled,
|
OpenGl_RT_uSphereMapEnabled,
|
||||||
OpenGl_RT_uSphereMapForBack,
|
OpenGl_RT_uSphereMapForBack,
|
||||||
OpenGl_RT_uTexSamplersArray,
|
OpenGl_RT_uTexSamplersArray,
|
||||||
|
OpenGl_RT_uBlockedRngEnabled,
|
||||||
|
|
||||||
// sampled frame params
|
// sampled frame params
|
||||||
OpenGl_RT_uSampleWeight,
|
OpenGl_RT_uSampleWeight,
|
||||||
@ -502,10 +502,10 @@ protected: //! @name methods related to ray-tracing
|
|||||||
const Handle(OpenGl_Context)& theGlContext);
|
const Handle(OpenGl_Context)& theGlContext);
|
||||||
|
|
||||||
//! Adds OpenGL groups to ray-traced scene geometry.
|
//! Adds OpenGL groups to ray-traced scene geometry.
|
||||||
Standard_Boolean addRaytraceGroups (const OpenGl_Structure* theStructure,
|
Standard_Boolean addRaytraceGroups (const OpenGl_Structure* theStructure,
|
||||||
const Standard_Integer theStructMat,
|
const OpenGl_RaytraceMaterial& theStructMat,
|
||||||
const Standard_ShortReal* theTransform,
|
const Standard_ShortReal* theTransform,
|
||||||
const Handle(OpenGl_Context)& theGlContext);
|
const Handle(OpenGl_Context)& theGlContext);
|
||||||
|
|
||||||
//! Creates ray-tracing material properties.
|
//! Creates ray-tracing material properties.
|
||||||
OpenGl_RaytraceMaterial convertMaterial (const OpenGl_AspectFace* theAspect,
|
OpenGl_RaytraceMaterial convertMaterial (const OpenGl_AspectFace* theAspect,
|
||||||
|
@ -407,15 +407,11 @@ Standard_Boolean OpenGl_View::addRaytraceStructure (const OpenGl_Structure*
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get structure material
|
// Get structure material
|
||||||
Standard_Integer aStructMatID = -1;
|
OpenGl_RaytraceMaterial aStructMaterial;
|
||||||
|
|
||||||
if (theStructure->AspectFace() != NULL)
|
if (theStructure->AspectFace() != NULL)
|
||||||
{
|
{
|
||||||
aStructMatID = static_cast<Standard_Integer> (myRaytraceGeometry.Materials.size());
|
aStructMaterial = convertMaterial (theStructure->AspectFace(), theGlContext);
|
||||||
|
|
||||||
OpenGl_RaytraceMaterial aStructMaterial = convertMaterial (theStructure->AspectFace(), theGlContext);
|
|
||||||
|
|
||||||
myRaytraceGeometry.Materials.push_back (aStructMaterial);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Standard_ShortReal aStructTransform[16];
|
Standard_ShortReal aStructTransform[16];
|
||||||
@ -431,7 +427,7 @@ Standard_Boolean OpenGl_View::addRaytraceStructure (const OpenGl_Structure*
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Standard_Boolean aResult = addRaytraceGroups (theStructure, aStructMatID,
|
Standard_Boolean aResult = addRaytraceGroups (theStructure, aStructMaterial,
|
||||||
theStructure->Transformation()->mat ? aStructTransform : NULL, theGlContext);
|
theStructure->Transformation()->mat ? aStructTransform : NULL, theGlContext);
|
||||||
|
|
||||||
// Process all connected OpenGL structures
|
// Process all connected OpenGL structures
|
||||||
@ -439,7 +435,7 @@ Standard_Boolean OpenGl_View::addRaytraceStructure (const OpenGl_Structure*
|
|||||||
|
|
||||||
if (anInstanced != NULL && anInstanced->IsRaytracable())
|
if (anInstanced != NULL && anInstanced->IsRaytracable())
|
||||||
{
|
{
|
||||||
aResult &= addRaytraceGroups (anInstanced, aStructMatID,
|
aResult &= addRaytraceGroups (anInstanced, aStructMaterial,
|
||||||
theStructure->Transformation()->mat ? aStructTransform : NULL, theGlContext);
|
theStructure->Transformation()->mat ? aStructTransform : NULL, theGlContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -452,32 +448,26 @@ Standard_Boolean OpenGl_View::addRaytraceStructure (const OpenGl_Structure*
|
|||||||
// function : addRaytraceGroups
|
// function : addRaytraceGroups
|
||||||
// purpose : Adds OpenGL groups to ray-traced scene geometry
|
// purpose : Adds OpenGL groups to ray-traced scene geometry
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
Standard_Boolean OpenGl_View::addRaytraceGroups (const OpenGl_Structure* theStructure,
|
Standard_Boolean OpenGl_View::addRaytraceGroups (const OpenGl_Structure* theStructure,
|
||||||
const Standard_Integer theStructMat,
|
const OpenGl_RaytraceMaterial& theStructMat,
|
||||||
const Standard_ShortReal* theTransform,
|
const Standard_ShortReal* theTransform,
|
||||||
const Handle(OpenGl_Context)& theGlContext)
|
const Handle(OpenGl_Context)& theGlContext)
|
||||||
{
|
{
|
||||||
for (OpenGl_Structure::GroupIterator aGroupIter (theStructure->DrawGroups()); aGroupIter.More(); aGroupIter.Next())
|
for (OpenGl_Structure::GroupIterator aGroupIter (theStructure->DrawGroups()); aGroupIter.More(); aGroupIter.Next())
|
||||||
{
|
{
|
||||||
// Get group material
|
// Get group material
|
||||||
Standard_Integer aGroupMatID = -1;
|
OpenGl_RaytraceMaterial aGroupMaterial;
|
||||||
if (aGroupIter.Value()->AspectFace() != NULL)
|
if (aGroupIter.Value()->AspectFace() != NULL)
|
||||||
{
|
{
|
||||||
aGroupMatID = static_cast<Standard_Integer> (myRaytraceGeometry.Materials.size());
|
aGroupMaterial = convertMaterial (
|
||||||
|
|
||||||
OpenGl_RaytraceMaterial aGroupMaterial = convertMaterial (
|
|
||||||
aGroupIter.Value()->AspectFace(), theGlContext);
|
aGroupIter.Value()->AspectFace(), theGlContext);
|
||||||
|
|
||||||
myRaytraceGeometry.Materials.push_back (aGroupMaterial);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Standard_Integer aMatID = aGroupMatID < 0 ? theStructMat : aGroupMatID;
|
Standard_Integer aMatID = static_cast<Standard_Integer> (myRaytraceGeometry.Materials.size());
|
||||||
if (aMatID < 0)
|
|
||||||
{
|
|
||||||
aMatID = static_cast<Standard_Integer> (myRaytraceGeometry.Materials.size());
|
|
||||||
|
|
||||||
myRaytraceGeometry.Materials.push_back (OpenGl_RaytraceMaterial());
|
// Use group material if available, otherwise use structure material
|
||||||
}
|
myRaytraceGeometry.Materials.push_back (
|
||||||
|
aGroupIter.Value()->AspectFace() != NULL ? aGroupMaterial : theStructMat);
|
||||||
|
|
||||||
// Add OpenGL elements from group (extract primitives arrays and aspects)
|
// Add OpenGL elements from group (extract primitives arrays and aspects)
|
||||||
for (const OpenGl_ElementNode* aNode = aGroupIter.Value()->FirstNode(); aNode != NULL; aNode = aNode->next)
|
for (const OpenGl_ElementNode* aNode = aGroupIter.Value()->FirstNode(); aNode != NULL; aNode = aNode->next)
|
||||||
@ -1573,6 +1563,8 @@ Standard_Boolean OpenGl_View::initRaytraceResources (const Graphic3d_CView& theC
|
|||||||
aShaderProgram->GetUniformLocation (theGlContext, "uSphereMapEnabled");
|
aShaderProgram->GetUniformLocation (theGlContext, "uSphereMapEnabled");
|
||||||
myUniformLocations[anIndex][OpenGl_RT_uSphereMapForBack] =
|
myUniformLocations[anIndex][OpenGl_RT_uSphereMapForBack] =
|
||||||
aShaderProgram->GetUniformLocation (theGlContext, "uSphereMapForBack");
|
aShaderProgram->GetUniformLocation (theGlContext, "uSphereMapForBack");
|
||||||
|
myUniformLocations[anIndex][OpenGl_RT_uBlockedRngEnabled] =
|
||||||
|
aShaderProgram->GetUniformLocation (theGlContext, "uBlockedRngEnabled");
|
||||||
|
|
||||||
myUniformLocations[anIndex][OpenGl_RT_uSampleWeight] =
|
myUniformLocations[anIndex][OpenGl_RT_uSampleWeight] =
|
||||||
aShaderProgram->GetUniformLocation (theGlContext, "uSampleWeight");
|
aShaderProgram->GetUniformLocation (theGlContext, "uSampleWeight");
|
||||||
@ -2256,6 +2248,12 @@ Standard_Boolean OpenGl_View::setUniformState (const Graphic3d_CView& the
|
|||||||
theProgram->SetUniform (theGlContext,
|
theProgram->SetUniform (theGlContext,
|
||||||
myUniformLocations[theProgramId][OpenGl_RT_uReflectEnabled], theCView.RenderParams.IsReflectionEnabled ? 1 : 0);
|
myUniformLocations[theProgramId][OpenGl_RT_uReflectEnabled], theCView.RenderParams.IsReflectionEnabled ? 1 : 0);
|
||||||
|
|
||||||
|
if (theCView.RenderParams.IsGlobalIlluminationEnabled)
|
||||||
|
{
|
||||||
|
theProgram->SetUniform (theGlContext,
|
||||||
|
myUniformLocations[theProgramId][OpenGl_RT_uBlockedRngEnabled], theCView.RenderParams.CoherentPathTracingMode ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
// Set array of 64-bit texture handles
|
// Set array of 64-bit texture handles
|
||||||
if (theGlContext->arbTexBindless != NULL && myRaytraceGeometry.HasTextures())
|
if (theGlContext->arbTexBindless != NULL && myRaytraceGeometry.HasTextures())
|
||||||
{
|
{
|
||||||
|
@ -301,17 +301,6 @@ vec3 handleMaterial (in SMaterial theMaterial, in vec3 theInput, in vec3 theOutp
|
|||||||
theMaterial.Ks.rgb * handleBlinnReflection (theInput, theOutput, theMaterial.Fresnel, theMaterial.Ks.w);
|
theMaterial.Ks.rgb * handleBlinnReflection (theInput, theOutput, theMaterial.Fresnel, theMaterial.Ks.w);
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
|
||||||
// function : sampleSpecularReflection
|
|
||||||
// purpose : Samples specular BRDF, W = BRDF * cos(N, PSI) / PDF(PSI)
|
|
||||||
//=======================================================================
|
|
||||||
void sampleSpecularReflection (in vec3 theOutput, out vec3 theInput)
|
|
||||||
{
|
|
||||||
theInput = vec3 (-theOutput.x,
|
|
||||||
-theOutput.y,
|
|
||||||
theOutput.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
// function : sampleLambertianReflection
|
// function : sampleLambertianReflection
|
||||||
// purpose : Samples Lambertian BRDF, W = BRDF * cos(N, PSI) / PDF(PSI)
|
// purpose : Samples Lambertian BRDF, W = BRDF * cos(N, PSI) / PDF(PSI)
|
||||||
@ -327,38 +316,51 @@ void sampleLambertianReflection (in vec3 theOutput, out vec3 theInput)
|
|||||||
aTemp * sin (2.f * M_PI * aKsi1),
|
aTemp * sin (2.f * M_PI * aKsi1),
|
||||||
sqrt (1.f - aKsi2));
|
sqrt (1.f - aKsi2));
|
||||||
|
|
||||||
if (theOutput.z < 0.f)
|
theInput.z = mix (-theInput.z, theInput.z, step (0.f, theOutput.z));
|
||||||
theInput.z = -theInput.z;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Types of bounces
|
||||||
|
#define NON_SPECULAR_BOUNCE 0
|
||||||
|
#define SPEC_REFLECT_BOUNCE 1
|
||||||
|
#define SPEC_REFRACT_BOUNCE 2
|
||||||
|
|
||||||
|
#define IS_NON_SPEC_BOUNCE(theBounce) (theBounce == 0)
|
||||||
|
#define IS_ANY_SPEC_BOUNCE(theBounce) (theBounce != 0)
|
||||||
|
#define IS_REFL_SPEC_BOUNCE(theBounce) (theBounce == 1)
|
||||||
|
#define IS_REFR_SPEC_BOUNCE(theBounce) (theBounce == 2)
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
// function : sampleSpecularTransmission
|
// function : sampleSpecularTransmission
|
||||||
// purpose : Samples specular BTDF, W = BRDF * cos(N, PSI) / PDF(PSI)
|
// purpose : Samples specular BTDF, W = BRDF * cos(N, PSI) / PDF(PSI)
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
vec3 sampleSpecularTransmission (in vec3 theOutput, out vec3 theInput,
|
vec3 sampleSpecularTransmission (in vec3 theOutput, out vec3 theInput,
|
||||||
out bool isTransmit, in vec3 theThroughput, in vec3 theFresnelCoeffs)
|
out int theBounce, in vec3 theWeight, in vec3 theFresnelCoeffs)
|
||||||
{
|
{
|
||||||
vec3 aFresnel = fresnelMedia (theOutput.z, theFresnelCoeffs);
|
vec3 aFresnel = fresnelMedia (theOutput.z, theFresnelCoeffs);
|
||||||
|
|
||||||
float aProbability = convolve (aFresnel, theThroughput);
|
float aProbability = convolve (aFresnel, theWeight);
|
||||||
|
|
||||||
|
// Check if transmission takes place
|
||||||
|
theBounce = RandFloat() <= aProbability ?
|
||||||
|
SPEC_REFLECT_BOUNCE : SPEC_REFRACT_BOUNCE;
|
||||||
|
|
||||||
// Sample input direction
|
// Sample input direction
|
||||||
if (RandFloat() <= aProbability)
|
if (theBounce == SPEC_REFLECT_BOUNCE)
|
||||||
{
|
{
|
||||||
theInput = vec3 (-theOutput.x,
|
theInput = vec3 (-theOutput.x,
|
||||||
-theOutput.y,
|
-theOutput.y,
|
||||||
theOutput.z);
|
theOutput.z);
|
||||||
|
|
||||||
isTransmit = false;
|
theWeight = aFresnel * (1.f / aProbability);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
transmitted (theFresnelCoeffs.y, theOutput, theInput);
|
||||||
|
|
||||||
return aFresnel * (1.f / aProbability);
|
theWeight = (UNIT - aFresnel) * (1.f / (1.f - aProbability));
|
||||||
}
|
}
|
||||||
|
|
||||||
transmitted (theFresnelCoeffs.y, theOutput, theInput);
|
return theWeight;
|
||||||
|
|
||||||
isTransmit = true;
|
|
||||||
|
|
||||||
return (UNIT - aFresnel) * (1.f / (1.f - aProbability));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
@ -430,98 +432,55 @@ vec3 sampleBlinnReflection (in vec3 theOutput, out vec3 theInput, in vec3 theFre
|
|||||||
return aFresnel * ((theExponent + 2.f) / (theExponent + 1.f) * aGeom / aCosThetaO);
|
return aFresnel * ((theExponent + 2.f) / (theExponent + 1.f) * aGeom / aCosThetaO);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enables expiremental russian roulette sampling
|
|
||||||
// #define RUSSIAN_ROULETTE
|
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
// function : sampleMaterial
|
// function : sampleMaterial
|
||||||
// purpose : Samples specified composite material (BSDF)
|
// purpose : Samples specified composite material (BSDF)
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
bool sampleMaterial (in SMaterial theMaterial,
|
void sampleMaterial (in SMaterial theMaterial,
|
||||||
in vec3 theOutput,
|
in vec3 theOutput,
|
||||||
in vec3 theFactor,
|
|
||||||
out vec3 theInput,
|
out vec3 theInput,
|
||||||
out vec3 theWeight,
|
inout vec3 theWeight,
|
||||||
inout bool isTransmit)
|
inout int theBounce)
|
||||||
{
|
{
|
||||||
theWeight = ZERO;
|
|
||||||
|
|
||||||
// Compute the probability of ray reflection
|
// Compute the probability of ray reflection
|
||||||
float aPd = convolve (theMaterial.Kd.rgb, theFactor);
|
float aPd = convolve (theMaterial.Kd.rgb, theWeight);
|
||||||
float aPs = convolve (theMaterial.Ks.rgb, theFactor);
|
float aPs = convolve (theMaterial.Ks.rgb, theWeight);
|
||||||
float aPr = convolve (theMaterial.Kr.rgb, theFactor);
|
float aPr = convolve (theMaterial.Kr.rgb, theWeight);
|
||||||
float aPt = convolve (theMaterial.Kt.rgb, theFactor);
|
float aPt = convolve (theMaterial.Kt.rgb, theWeight);
|
||||||
|
|
||||||
float aReflection = aPd + aPs + aPr + aPt;
|
float aReflection = aPd + aPs + aPr + aPt;
|
||||||
|
|
||||||
#ifndef RUSSIAN_ROULETTE
|
|
||||||
if (aReflection < 1e-2f)
|
|
||||||
{
|
|
||||||
return false; // path termination
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
float aSurvival = max (dot (theFactor, LUMA), 0.1f);
|
|
||||||
|
|
||||||
if (RandFloat() > aSurvival)
|
|
||||||
{
|
|
||||||
return false; // path termination
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
isTransmit = false;
|
|
||||||
|
|
||||||
// Choose BSDF component to sample
|
// Choose BSDF component to sample
|
||||||
float aKsi = aReflection * RandFloat();
|
float aKsi = aReflection * RandFloat();
|
||||||
|
|
||||||
|
theBounce = NON_SPECULAR_BOUNCE;
|
||||||
|
|
||||||
if (aKsi < aPd) // diffuse reflection
|
if (aKsi < aPd) // diffuse reflection
|
||||||
{
|
{
|
||||||
sampleLambertianReflection (theOutput, theInput);
|
sampleLambertianReflection (theOutput, theInput);
|
||||||
|
|
||||||
#ifndef RUSSIAN_ROULETTE
|
theWeight *= theMaterial.Kd.rgb * (aReflection / aPd);
|
||||||
theWeight = theMaterial.Kd.rgb * (aReflection / aPd);
|
|
||||||
#else
|
|
||||||
theWeight = theMaterial.Kd.rgb * (aReflection / aPd / aSurvival);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return false; // non-specular bounce
|
|
||||||
}
|
}
|
||||||
else if (aKsi < aPd + aPs) // glossy reflection
|
else if (aKsi < aPd + aPs) // glossy reflection
|
||||||
{
|
{
|
||||||
theWeight = sampleBlinnReflection (theOutput, theInput, theMaterial.Fresnel, theMaterial.Ks.w);
|
theWeight *= theMaterial.Ks.rgb * (aReflection / aPs) *
|
||||||
|
sampleBlinnReflection (theOutput, theInput, theMaterial.Fresnel, theMaterial.Ks.w);
|
||||||
#ifndef RUSSIAN_ROULETTE
|
|
||||||
theWeight *= theMaterial.Ks.rgb * (aReflection / aPs);
|
|
||||||
#else
|
|
||||||
theWeight *= theMaterial.Ks.rgb * (aReflection / aPs / aSurvival);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return false; // non-specular bounce
|
|
||||||
}
|
}
|
||||||
else if (aKsi < aPd + aPs + aPr) // specular reflection
|
else if (aKsi < aPd + aPs + aPr) // specular reflection
|
||||||
{
|
{
|
||||||
theWeight = sampleSpecularReflection (theOutput, theInput, theMaterial.Fresnel);
|
theWeight *= theMaterial.Kr.rgb * (aReflection / aPr) *
|
||||||
|
sampleSpecularReflection (theOutput, theInput, theMaterial.Fresnel);
|
||||||
|
|
||||||
#ifndef RUSSIAN_ROULETTE
|
theBounce = SPEC_REFLECT_BOUNCE; // specular bounce
|
||||||
theWeight *= theMaterial.Kr.rgb * (aReflection / aPr);
|
|
||||||
#else
|
|
||||||
theWeight *= theMaterial.Kr.rgb * (aReflection / aPr / aSurvival);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return true; // specular bounce
|
|
||||||
}
|
}
|
||||||
else // specular transmission
|
else // specular transmission
|
||||||
{
|
{
|
||||||
theWeight = sampleSpecularTransmission (theOutput, theInput,
|
theWeight *= theMaterial.Kt.rgb * (aReflection / aPt) *
|
||||||
isTransmit, theFactor, theMaterial.Fresnel);
|
sampleSpecularTransmission (theOutput, theInput, theBounce, theWeight, theMaterial.Fresnel);
|
||||||
|
|
||||||
#ifndef RUSSIAN_ROULETTE
|
|
||||||
theWeight *= theMaterial.Kt.rgb * (aReflection / aPt);
|
|
||||||
#else
|
|
||||||
theWeight *= theMaterial.Kt.rgb * (aReflection / aPt / aSurvival);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return true; // specular bounce
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// path termination for extra small weights
|
||||||
|
theWeight = mix (theWeight, ZERO, float (aReflection < 1e-3f));
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -532,11 +491,14 @@ bool sampleMaterial (in SMaterial theMaterial,
|
|||||||
// function : handlePointLight
|
// function : handlePointLight
|
||||||
// purpose :
|
// purpose :
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
float handlePointLight (in vec3 theInput, in vec3 theToLight, in float theRadius)
|
float handlePointLight (in vec3 theInput, in vec3 theToLight, in float theRadius, in float theDistance)
|
||||||
{
|
{
|
||||||
float aCosMax = sqrt (1.f - theRadius * theRadius / dot (theToLight, theToLight));
|
float aDistance = dot (theToLight, theToLight);
|
||||||
|
|
||||||
return step (aCosMax, dot (theInput, theToLight));
|
float aCosMax = inversesqrt (1.f + theRadius * theRadius / aDistance);
|
||||||
|
|
||||||
|
return float (aDistance < theDistance * theDistance) *
|
||||||
|
step (aCosMax, dot (theToLight, theInput) * inversesqrt (aDistance));
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
@ -549,47 +511,29 @@ float handleDirectLight (in vec3 theInput, in vec3 theToLight, in float theCosMa
|
|||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
// function : samplePointLight
|
// function : sampleLight
|
||||||
// purpose :
|
// purpose : general sampling function for directional and point lights
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
vec3 samplePointLight (in vec3 theToLight, in float theRadius, inout float thePDF)
|
vec3 sampleLight (in vec3 theToLight, in bool isDirectional, in float theSmoothness, inout float thePDF)
|
||||||
{
|
{
|
||||||
SLocalSpace aSpace = LocalSpace (theToLight);
|
SLocalSpace aSpace = LocalSpace (theToLight);
|
||||||
|
|
||||||
float aCosMax = sqrt (1.f - theRadius * theRadius / dot (theToLight, theToLight));
|
// for point lights smoothness defines radius
|
||||||
|
float aCosMax = isDirectional ? theSmoothness :
|
||||||
|
inversesqrt (1.f + theSmoothness * theSmoothness / dot (theToLight, theToLight));
|
||||||
|
|
||||||
float aKsi1 = RandFloat();
|
float aKsi1 = RandFloat();
|
||||||
float aKsi2 = RandFloat();
|
float aKsi2 = RandFloat();
|
||||||
|
|
||||||
float aTmp = 1.f - aKsi2 * (1.f - aCosMax);
|
float aTmp = 1.f - aKsi2 * (1.f - aCosMax);
|
||||||
|
|
||||||
vec3 anInput = vec3 (sqrt (1.f - aTmp * aTmp) * cos (2.f * M_PI * aKsi1),
|
vec3 anInput = vec3 (cos (2.f * M_PI * aKsi1),
|
||||||
sqrt (1.f - aTmp * aTmp) * sin (2.f * M_PI * aKsi1),
|
sin (2.f * M_PI * aKsi1),
|
||||||
aTmp);
|
aTmp);
|
||||||
|
|
||||||
thePDF *= (theRadius > 0.f) ? 1.f / (2.f * M_PI) / (1.f - aCosMax) : 1.f;
|
anInput.xy *= sqrt (1.f - aTmp * aTmp);
|
||||||
|
|
||||||
return normalize (fromLocalSpace (anInput, aSpace));
|
thePDF *= (aCosMax < 1.f) ? 1.f / (2.f * M_PI) / (1.f - aCosMax) : 1.f;
|
||||||
}
|
|
||||||
|
|
||||||
//=======================================================================
|
|
||||||
// function : sampleDirectLight
|
|
||||||
// purpose :
|
|
||||||
//=======================================================================
|
|
||||||
vec3 sampleDirectLight (in vec3 theToLight, in float theCosMax, inout float thePDF)
|
|
||||||
{
|
|
||||||
SLocalSpace aSpace = LocalSpace (theToLight);
|
|
||||||
|
|
||||||
float aKsi1 = RandFloat();
|
|
||||||
float aKsi2 = RandFloat();
|
|
||||||
|
|
||||||
float aTmp = 1.f - aKsi2 * (1.f - theCosMax);
|
|
||||||
|
|
||||||
vec3 anInput = vec3 (sqrt (1.f - aTmp * aTmp) * cos (2.f * M_PI * aKsi1),
|
|
||||||
sqrt (1.f - aTmp * aTmp) * sin (2.f * M_PI * aKsi1),
|
|
||||||
aTmp);
|
|
||||||
|
|
||||||
thePDF *= (theCosMax < 1.f) ? 1.f / (2.f * M_PI) / (1.f - theCosMax) : 1.f;
|
|
||||||
|
|
||||||
return normalize (fromLocalSpace (anInput, aSpace));
|
return normalize (fromLocalSpace (anInput, aSpace));
|
||||||
}
|
}
|
||||||
@ -609,26 +553,26 @@ vec2 Latlong (in vec3 thePoint)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
// function : EnvironmentRadiance
|
// function: intersectLight
|
||||||
// purpose :
|
// purpose : Checks intersections with light sources
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
vec3 EnvironmentRadiance (in SRay theRay, in bool isSpecular, in bool isBackground)
|
vec3 intersectLight (in SRay theRay, in bool isViewRay, in int theBounce, in float theDistance)
|
||||||
{
|
{
|
||||||
vec3 aRadiance = ZERO;
|
vec3 aRadiance = ZERO;
|
||||||
|
|
||||||
if (uSphereMapForBack != 0 || !isBackground)
|
if ((isViewRay || IS_REFR_SPEC_BOUNCE(theBounce)) && uSphereMapForBack == 0)
|
||||||
{
|
{
|
||||||
aRadiance += FetchEnvironment (Latlong (theRay.Direct)).xyz;
|
aRadiance = BackgroundColor().xyz;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
aRadiance += BackgroundColor().xyz;
|
aRadiance = FetchEnvironment (Latlong (theRay.Direct)).xyz;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply gamma correction (gamma is 2)
|
// Apply gamma correction (gamma is 2)
|
||||||
aRadiance *= aRadiance;
|
aRadiance = aRadiance * aRadiance * float (theDistance == MAXFLOAT);
|
||||||
|
|
||||||
for (int aLightIdx = 0; aLightIdx < uLightCount && isSpecular; ++aLightIdx)
|
for (int aLightIdx = 0; aLightIdx < uLightCount && (isViewRay || IS_ANY_SPEC_BOUNCE(theBounce)); ++aLightIdx)
|
||||||
{
|
{
|
||||||
vec4 aLight = texelFetch (
|
vec4 aLight = texelFetch (
|
||||||
uRaytraceLightSrcTexture, LIGHT_POS (aLightIdx));
|
uRaytraceLightSrcTexture, LIGHT_POS (aLightIdx));
|
||||||
@ -637,9 +581,10 @@ vec3 EnvironmentRadiance (in SRay theRay, in bool isSpecular, in bool isBackgrou
|
|||||||
|
|
||||||
if (aLight.w != 0.f) // point light source
|
if (aLight.w != 0.f) // point light source
|
||||||
{
|
{
|
||||||
aRadiance += aParam.rgb * handlePointLight (theRay.Direct, aLight.xyz - theRay.Origin, aParam.w /* radius */);
|
aRadiance += aParam.rgb * handlePointLight (
|
||||||
|
theRay.Direct, aLight.xyz - theRay.Origin, aParam.w /* radius */, theDistance);
|
||||||
}
|
}
|
||||||
else // directional light source
|
else if (theDistance == MAXFLOAT) // directional light source
|
||||||
{
|
{
|
||||||
aRadiance += aParam.rgb * handleDirectLight (theRay.Direct, aLight.xyz, aParam.w /* angle cosine */);
|
aRadiance += aParam.rgb * handleDirectLight (theRay.Direct, aLight.xyz, aParam.w /* angle cosine */);
|
||||||
}
|
}
|
||||||
@ -659,6 +604,9 @@ vec3 EnvironmentRadiance (in SRay theRay, in bool isSpecular, in bool isBackgrou
|
|||||||
#define MATERIAL_FRESNEL(index) (18 * index + 16)
|
#define MATERIAL_FRESNEL(index) (18 * index + 16)
|
||||||
#define MATERIAL_ABSORPT(index) (18 * index + 17)
|
#define MATERIAL_ABSORPT(index) (18 * index + 17)
|
||||||
|
|
||||||
|
// Enables expiremental russian roulette sampling
|
||||||
|
#define RUSSIAN_ROULETTE
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
// function : PathTrace
|
// function : PathTrace
|
||||||
// purpose : Calculates radiance along the given ray
|
// purpose : Calculates radiance along the given ray
|
||||||
@ -670,28 +618,31 @@ vec4 PathTrace (in SRay theRay, in vec3 theInverse)
|
|||||||
vec3 aRadiance = ZERO;
|
vec3 aRadiance = ZERO;
|
||||||
vec3 aThroughput = UNIT;
|
vec3 aThroughput = UNIT;
|
||||||
|
|
||||||
bool isInMedium = false;
|
int aBounce = 0; // type of previous hit point
|
||||||
bool isSpecular = false;
|
int aTrsfId = 0; // offset of object transform
|
||||||
bool isTransmit = false;
|
|
||||||
|
|
||||||
int anObjectId; // ID of intersected triangle
|
bool isInMedium = false;
|
||||||
|
|
||||||
for (int aDepth = 0; aDepth < NB_BOUNCES; ++aDepth)
|
for (int aDepth = 0; aDepth < NB_BOUNCES; ++aDepth)
|
||||||
{
|
{
|
||||||
SIntersect aHit = SIntersect (MAXFLOAT, vec2 (ZERO), ZERO);
|
SIntersect aHit = SIntersect (MAXFLOAT, vec2 (ZERO), ZERO);
|
||||||
|
|
||||||
ivec4 aTriIndex = SceneNearestHit (theRay, theInverse, aHit, anObjectId);
|
ivec4 aTriIndex = SceneNearestHit (theRay, theInverse, aHit, aTrsfId);
|
||||||
|
|
||||||
if (aTriIndex.x == -1)
|
// check implicit path
|
||||||
|
vec3 aLe = intersectLight (theRay,
|
||||||
|
aDepth == 0 /* is view ray */, aBounce, aHit.Time);
|
||||||
|
|
||||||
|
if (any (greaterThan (aLe, ZERO)) || aTriIndex.x == -1)
|
||||||
{
|
{
|
||||||
return vec4 (aRadiance + aThroughput *
|
aRadiance += aThroughput * aLe; break; // terminate path
|
||||||
EnvironmentRadiance (theRay, isSpecular, aDepth == 0 || isTransmit), 0.f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 aInvTransf0 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 0).xyz;
|
vec3 aInvTransf0 = texelFetch (uSceneTransformTexture, aTrsfId + 0).xyz;
|
||||||
vec3 aInvTransf1 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 1).xyz;
|
vec3 aInvTransf1 = texelFetch (uSceneTransformTexture, aTrsfId + 1).xyz;
|
||||||
vec3 aInvTransf2 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 2).xyz;
|
vec3 aInvTransf2 = texelFetch (uSceneTransformTexture, aTrsfId + 2).xyz;
|
||||||
|
|
||||||
|
// compute geometrical normal
|
||||||
aHit.Normal = normalize (vec3 (dot (aInvTransf0, aHit.Normal),
|
aHit.Normal = normalize (vec3 (dot (aInvTransf0, aHit.Normal),
|
||||||
dot (aInvTransf1, aHit.Normal),
|
dot (aInvTransf1, aHit.Normal),
|
||||||
dot (aInvTransf2, aHit.Normal)));
|
dot (aInvTransf2, aHit.Normal)));
|
||||||
@ -711,9 +662,9 @@ vec4 PathTrace (in SRay theRay, in vec3 theInverse)
|
|||||||
aThroughput *= aSrcColorRGBA.w;
|
aThroughput *= aSrcColorRGBA.w;
|
||||||
}
|
}
|
||||||
|
|
||||||
theRay.Origin += theRay.Direct * aHit.Time; // intersection point
|
theRay.Origin += theRay.Direct * aHit.Time; // get new intersection point
|
||||||
|
|
||||||
// Fetch material (BSDF)
|
// fetch material (BSDF)
|
||||||
SMaterial aMaterial = SMaterial (
|
SMaterial aMaterial = SMaterial (
|
||||||
vec4 (texelFetch (uRaytraceMaterialTexture, MATERIAL_KD (aTriIndex.w))),
|
vec4 (texelFetch (uRaytraceMaterialTexture, MATERIAL_KD (aTriIndex.w))),
|
||||||
vec3 (texelFetch (uRaytraceMaterialTexture, MATERIAL_KR (aTriIndex.w))),
|
vec3 (texelFetch (uRaytraceMaterialTexture, MATERIAL_KR (aTriIndex.w))),
|
||||||
@ -742,6 +693,7 @@ vec4 PathTrace (in SRay theRay, in vec3 theInverse)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// compute smooth normal
|
||||||
vec3 aNormal = SmoothNormal (aHit.UV, aTriIndex);
|
vec3 aNormal = SmoothNormal (aHit.UV, aTriIndex);
|
||||||
|
|
||||||
aNormal = normalize (vec3 (dot (aInvTransf0, aNormal),
|
aNormal = normalize (vec3 (dot (aInvTransf0, aNormal),
|
||||||
@ -750,7 +702,7 @@ vec4 PathTrace (in SRay theRay, in vec3 theInverse)
|
|||||||
|
|
||||||
SLocalSpace aSpace = LocalSpace (aNormal);
|
SLocalSpace aSpace = LocalSpace (aNormal);
|
||||||
|
|
||||||
// Account for self-emission (not stored in the material)
|
// account for self-emission (not stored in the material)
|
||||||
aRadiance += aThroughput * texelFetch (
|
aRadiance += aThroughput * texelFetch (
|
||||||
uRaytraceMaterialTexture, MATERIAL_LE (aTriIndex.w)).rgb;
|
uRaytraceMaterialTexture, MATERIAL_LE (aTriIndex.w)).rgb;
|
||||||
|
|
||||||
@ -763,18 +715,13 @@ vec4 PathTrace (in SRay theRay, in vec3 theInverse)
|
|||||||
vec4 aParam = texelFetch (
|
vec4 aParam = texelFetch (
|
||||||
uRaytraceLightSrcTexture, LIGHT_PWR (aLightIdx));
|
uRaytraceLightSrcTexture, LIGHT_PWR (aLightIdx));
|
||||||
|
|
||||||
float aPDF = 1.f / uLightCount, aDistance = MAXFLOAT;
|
// 'w' component is 0 for infinite light and 1 for point light
|
||||||
|
aLight.xyz -= mix (ZERO, theRay.Origin, aLight.w);
|
||||||
|
|
||||||
if (aLight.w != 0.f) // point light source
|
float aPDF = 1.f / uLightCount, aDistance = length (aLight.xyz);
|
||||||
{
|
|
||||||
aDistance = length (aLight.xyz -= theRay.Origin);
|
|
||||||
|
|
||||||
aLight.xyz = samplePointLight (aLight.xyz, aParam.w /* radius */, aPDF);
|
aLight.xyz = sampleLight (aLight.xyz * (1.f / aDistance),
|
||||||
}
|
aLight.w == 0.f /* is infinite */, aParam.w /* angle cosine */, aPDF);
|
||||||
else // directional light source
|
|
||||||
{
|
|
||||||
aLight.xyz = sampleDirectLight (aLight.xyz, aParam.w /* angle cosine */, aPDF);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 aContrib = (1.f / aPDF) * aParam.rgb /* Le */ * handleMaterial (
|
vec3 aContrib = (1.f / aPDF) * aParam.rgb /* Le */ * handleMaterial (
|
||||||
aMaterial, toLocalSpace (aLight.xyz, aSpace), toLocalSpace (-theRay.Direct, aSpace));
|
aMaterial, toLocalSpace (aLight.xyz, aSpace), toLocalSpace (-theRay.Direct, aSpace));
|
||||||
@ -787,17 +734,16 @@ vec4 PathTrace (in SRay theRay, in vec3 theInverse)
|
|||||||
-uSceneEpsilon, uSceneEpsilon, step (0.f, dot (aHit.Normal, aLight.xyz)));
|
-uSceneEpsilon, uSceneEpsilon, step (0.f, dot (aHit.Normal, aLight.xyz)));
|
||||||
|
|
||||||
float aVisibility = SceneAnyHit (aShadow,
|
float aVisibility = SceneAnyHit (aShadow,
|
||||||
InverseDirection (aLight.xyz), aDistance);
|
InverseDirection (aLight.xyz), aLight.w == 0.f ? MAXFLOAT : aDistance);
|
||||||
|
|
||||||
aRadiance += aVisibility * aThroughput * aContrib;
|
aRadiance += aVisibility * aThroughput * aContrib;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 anInput;
|
vec3 anInput;
|
||||||
vec3 aWeight;
|
|
||||||
|
|
||||||
isSpecular = sampleMaterial (aMaterial,
|
sampleMaterial (aMaterial,
|
||||||
toLocalSpace (-theRay.Direct, aSpace), aThroughput, anInput, aWeight, isTransmit);
|
toLocalSpace (-theRay.Direct, aSpace), anInput, aThroughput, aBounce);
|
||||||
|
|
||||||
if (isInMedium)
|
if (isInMedium)
|
||||||
{
|
{
|
||||||
@ -805,14 +751,23 @@ vec4 PathTrace (in SRay theRay, in vec3 theInverse)
|
|||||||
aMaterial.Absorption.w * (UNIT - aMaterial.Absorption.rgb));
|
aMaterial.Absorption.w * (UNIT - aMaterial.Absorption.rgb));
|
||||||
}
|
}
|
||||||
|
|
||||||
isInMedium = isTransmit ? !isInMedium : isInMedium;
|
isInMedium = IS_REFR_SPEC_BOUNCE(aBounce) ? !isInMedium : isInMedium;
|
||||||
|
|
||||||
aThroughput *= aWeight;
|
|
||||||
|
|
||||||
|
#ifndef RUSSIAN_ROULETTE
|
||||||
if (all (lessThan (aThroughput, MIN_THROUGHPUT)))
|
if (all (lessThan (aThroughput, MIN_THROUGHPUT)))
|
||||||
{
|
{
|
||||||
return vec4 (aRadiance, 0.f);
|
aDepth = INVALID_BOUNCES; // terminate path
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
float aSurvive = aDepth < 3 ? 1.f : min (dot (LUMA, aThroughput), 0.95f);
|
||||||
|
|
||||||
|
if (RandFloat() > aSurvive)
|
||||||
|
{
|
||||||
|
aDepth = INVALID_BOUNCES; // terminate path
|
||||||
|
}
|
||||||
|
|
||||||
|
aThroughput /= aSurvive;
|
||||||
|
#endif
|
||||||
|
|
||||||
anInput = normalize (fromLocalSpace (anInput, aSpace));
|
anInput = normalize (fromLocalSpace (anInput, aSpace));
|
||||||
|
|
||||||
|
@ -158,9 +158,9 @@ uint RandState;
|
|||||||
// purpose : Applies hash function by Thomas Wang to randomize seeds
|
// purpose : Applies hash function by Thomas Wang to randomize seeds
|
||||||
// (see http://www.burtleburtle.net/bob/hash/integer.html)
|
// (see http://www.burtleburtle.net/bob/hash/integer.html)
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
void SeedRand (in int theSeed, in int theSizeX)
|
void SeedRand (in int theSeed, in int theSizeX, in int theRadius)
|
||||||
{
|
{
|
||||||
RandState = uint (int (gl_FragCoord.y) * theSizeX + int (gl_FragCoord.x) + theSeed);
|
RandState = uint (int (gl_FragCoord.y) / theRadius * theSizeX + int (gl_FragCoord.x) / theRadius + theSeed);
|
||||||
|
|
||||||
RandState = (RandState + 0x479ab41du) + (RandState << 8);
|
RandState = (RandState + 0x479ab41du) + (RandState << 8);
|
||||||
RandState = (RandState ^ 0xe4aa10ceu) ^ (RandState >> 5);
|
RandState = (RandState ^ 0xe4aa10ceu) ^ (RandState >> 5);
|
||||||
@ -365,9 +365,7 @@ ivec4 ObjectNearestHit (in int theBVHOffset, in int theVrtOffset, in int theTrgO
|
|||||||
|
|
||||||
ivec4 aTriIndex = INALID_HIT;
|
ivec4 aTriIndex = INALID_HIT;
|
||||||
|
|
||||||
bool toContinue = true;
|
for (bool toContinue = true; toContinue;)
|
||||||
|
|
||||||
while (toContinue)
|
|
||||||
{
|
{
|
||||||
ivec3 aData = texelFetch (uSceneNodeInfoTexture, aNode).xyz;
|
ivec3 aData = texelFetch (uSceneNodeInfoTexture, aNode).xyz;
|
||||||
|
|
||||||
@ -487,11 +485,9 @@ float ObjectAnyHit (in int theBVHOffset, in int theVrtOffset, in int theTrgOffse
|
|||||||
int aHead = theSentinel; // stack pointer
|
int aHead = theSentinel; // stack pointer
|
||||||
int aNode = theBVHOffset; // node to visit
|
int aNode = theBVHOffset; // node to visit
|
||||||
|
|
||||||
#ifdef TRANSPARENT_SHADOWS
|
float aFactor = 1.f;
|
||||||
float aFactor = 1.0f;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
while (true)
|
for (bool toContinue = true; toContinue;)
|
||||||
{
|
{
|
||||||
ivec4 aData = texelFetch (uSceneNodeInfoTexture, aNode);
|
ivec4 aData = texelFetch (uSceneNodeInfoTexture, aNode);
|
||||||
|
|
||||||
@ -545,15 +541,10 @@ float ObjectAnyHit (in int theBVHOffset, in int theVrtOffset, in int theTrgOffse
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifdef TRANSPARENT_SHADOWS
|
toContinue = (aHead != theSentinel);
|
||||||
if (aHead == theSentinel)
|
|
||||||
return aFactor;
|
|
||||||
#else
|
|
||||||
if (aHead == theSentinel)
|
|
||||||
return 1.0f;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
aNode = Stack[aHead--];
|
if (toContinue)
|
||||||
|
aNode = Stack[aHead--];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -580,45 +571,38 @@ float ObjectAnyHit (in int theBVHOffset, in int theVrtOffset, in int theTrgOffse
|
|||||||
#ifdef TRANSPARENT_SHADOWS
|
#ifdef TRANSPARENT_SHADOWS
|
||||||
if (aTime < theDistance)
|
if (aTime < theDistance)
|
||||||
{
|
{
|
||||||
aFactor *= 1.0f - texelFetch (uRaytraceMaterialTexture, MATERIAL_TRAN (aTriangle.w)).x;
|
aFactor *= 1.f - texelFetch (uRaytraceMaterialTexture, MATERIAL_TRAN (aTriangle.w)).x;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (aTime < theDistance)
|
if (aTime < theDistance)
|
||||||
return 0.0f;
|
{
|
||||||
|
aFactor = 0.f;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TRANSPARENT_SHADOWS
|
toContinue = (aHead != theSentinel) && (aFactor > 0.1f);
|
||||||
if (aHead == theSentinel || aFactor < 0.1f)
|
|
||||||
return aFactor;
|
|
||||||
#else
|
|
||||||
if (aHead == theSentinel)
|
|
||||||
return 1.0f;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
aNode = Stack[aHead--];
|
if (toContinue)
|
||||||
|
aNode = Stack[aHead--];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TRANSPARENT_SHADOWS
|
|
||||||
return aFactor;
|
return aFactor;
|
||||||
#else
|
|
||||||
return 1.0f;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
// function : SceneNearestHit
|
// function : SceneNearestHit
|
||||||
// purpose : Finds intersection with nearest scene triangle
|
// purpose : Finds intersection with nearest scene triangle
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
ivec4 SceneNearestHit (in SRay theRay, in vec3 theInverse, inout SIntersect theHit, out int theObjectId)
|
ivec4 SceneNearestHit (in SRay theRay, in vec3 theInverse, inout SIntersect theHit, out int theTrsfId)
|
||||||
{
|
{
|
||||||
int aHead = -1; // stack pointer
|
int aHead = -1; // stack pointer
|
||||||
int aNode = 0; // node to visit
|
int aNode = 0; // node to visit
|
||||||
|
|
||||||
ivec4 aHitObject = INALID_HIT;
|
ivec4 aHitObject = INALID_HIT;
|
||||||
|
|
||||||
while (true)
|
for (bool toContinue = true; toContinue;)
|
||||||
{
|
{
|
||||||
ivec4 aData = texelFetch (uSceneNodeInfoTexture, aNode);
|
ivec4 aData = texelFetch (uSceneNodeInfoTexture, aNode);
|
||||||
|
|
||||||
@ -635,12 +619,12 @@ ivec4 SceneNearestHit (in SRay theRay, in vec3 theInverse, inout SIntersect theH
|
|||||||
if (max (aTimes.x, max (aTimes.y, aTimes.z)) < theHit.Time)
|
if (max (aTimes.x, max (aTimes.y, aTimes.z)) < theHit.Time)
|
||||||
{
|
{
|
||||||
// fetch object transformation
|
// fetch object transformation
|
||||||
int anObjectId = aData.x - 1;
|
int aTrsfId = (aData.x - 1) * 4;
|
||||||
|
|
||||||
vec4 aInvTransf0 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 0);
|
vec4 aInvTransf0 = texelFetch (uSceneTransformTexture, aTrsfId + 0);
|
||||||
vec4 aInvTransf1 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 1);
|
vec4 aInvTransf1 = texelFetch (uSceneTransformTexture, aTrsfId + 1);
|
||||||
vec4 aInvTransf2 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 2);
|
vec4 aInvTransf2 = texelFetch (uSceneTransformTexture, aTrsfId + 2);
|
||||||
vec4 aInvTransf3 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 3);
|
vec4 aInvTransf3 = texelFetch (uSceneTransformTexture, aTrsfId + 3);
|
||||||
|
|
||||||
SRay aTrsfRay = SRay (
|
SRay aTrsfRay = SRay (
|
||||||
MatrixColMultiplyPnt (theRay.Origin, aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3),
|
MatrixColMultiplyPnt (theRay.Origin, aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3),
|
||||||
@ -660,14 +644,14 @@ ivec4 SceneNearestHit (in SRay theRay, in vec3 theInverse, inout SIntersect theH
|
|||||||
aTriIndex.z, // vertex 2
|
aTriIndex.z, // vertex 2
|
||||||
aTriIndex.w); // material
|
aTriIndex.w); // material
|
||||||
|
|
||||||
theObjectId = anObjectId;
|
theTrsfId = aTrsfId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aHead < 0)
|
toContinue = aHead >= 0;
|
||||||
return aHitObject;
|
|
||||||
|
|
||||||
aNode = Stack[aHead--];
|
if (toContinue)
|
||||||
|
aNode = Stack[aHead--];
|
||||||
}
|
}
|
||||||
else // if inner node
|
else // if inner node
|
||||||
{
|
{
|
||||||
@ -716,10 +700,10 @@ ivec4 SceneNearestHit (in SRay theRay, in vec3 theInverse, inout SIntersect theH
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (aHead < 0)
|
toContinue = aHead >= 0;
|
||||||
return aHitObject;
|
|
||||||
|
|
||||||
aNode = Stack[aHead--];
|
if (toContinue)
|
||||||
|
aNode = Stack[aHead--];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -737,23 +721,21 @@ float SceneAnyHit (in SRay theRay, in vec3 theInverse, in float theDistance)
|
|||||||
int aHead = -1; // stack pointer
|
int aHead = -1; // stack pointer
|
||||||
int aNode = 0; // node to visit
|
int aNode = 0; // node to visit
|
||||||
|
|
||||||
#ifdef TRANSPARENT_SHADOWS
|
float aFactor = 1.f;
|
||||||
float aFactor = 1.0f;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
while (true)
|
for (bool toContinue = true; toContinue;)
|
||||||
{
|
{
|
||||||
ivec4 aData = texelFetch (uSceneNodeInfoTexture, aNode);
|
ivec4 aData = texelFetch (uSceneNodeInfoTexture, aNode);
|
||||||
|
|
||||||
if (aData.x != 0) // if leaf node
|
if (aData.x != 0) // if leaf node
|
||||||
{
|
{
|
||||||
// fetch object transformation
|
// fetch object transformation
|
||||||
int anObjectId = aData.x - 1;
|
int aTrsfId = (aData.x - 1) * 4;
|
||||||
|
|
||||||
vec4 aInvTransf0 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 0);
|
vec4 aInvTransf0 = texelFetch (uSceneTransformTexture, aTrsfId + 0);
|
||||||
vec4 aInvTransf1 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 1);
|
vec4 aInvTransf1 = texelFetch (uSceneTransformTexture, aTrsfId + 1);
|
||||||
vec4 aInvTransf2 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 2);
|
vec4 aInvTransf2 = texelFetch (uSceneTransformTexture, aTrsfId + 2);
|
||||||
vec4 aInvTransf3 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 3);
|
vec4 aInvTransf3 = texelFetch (uSceneTransformTexture, aTrsfId + 3);
|
||||||
|
|
||||||
SRay aTrsfRay = SRay (
|
SRay aTrsfRay = SRay (
|
||||||
MatrixColMultiplyPnt (theRay.Origin, aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3),
|
MatrixColMultiplyPnt (theRay.Origin, aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3),
|
||||||
@ -767,17 +749,16 @@ float SceneAnyHit (in SRay theRay, in vec3 theInverse, in float theDistance)
|
|||||||
aFactor *= ObjectAnyHit (
|
aFactor *= ObjectAnyHit (
|
||||||
aData.y, aData.z, aData.w, aTrsfRay, aTrsfInverse, theDistance, aHead);
|
aData.y, aData.z, aData.w, aTrsfRay, aTrsfInverse, theDistance, aHead);
|
||||||
|
|
||||||
if (aHead < 0 || aFactor < 0.1f)
|
toContinue = aHead >= 0 && aFactor >= 0.1f;
|
||||||
return aFactor;
|
|
||||||
#else
|
#else
|
||||||
bool isShadow = 0.0f == ObjectAnyHit (
|
aFactor = ObjectAnyHit (
|
||||||
aData.y, aData.z, aData.w, aTrsfRay, aTrsfInverse, theDistance, aHead);
|
aData.y, aData.z, aData.w, aTrsfRay, aTrsfInverse, theDistance, aHead);
|
||||||
|
|
||||||
if (aHead < 0 || isShadow)
|
toContinue = aHead >= 0 && aFactor != 0.0f;
|
||||||
return isShadow ? 0.0f : 1.0f;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
aNode = Stack[aHead--];
|
if (toContinue)
|
||||||
|
aNode = Stack[aHead--];
|
||||||
}
|
}
|
||||||
else // if inner node
|
else // if inner node
|
||||||
{
|
{
|
||||||
@ -826,25 +807,16 @@ float SceneAnyHit (in SRay theRay, in vec3 theInverse, in float theDistance)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifdef TRANSPARENT_SHADOWS
|
toContinue = aHead >= 0;
|
||||||
if (aHead < 0)
|
|
||||||
return aFactor;
|
|
||||||
#else
|
|
||||||
if (aHead < 0)
|
|
||||||
return 1.0f;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
aNode = Stack[aHead--];
|
if (toContinue)
|
||||||
|
aNode = Stack[aHead--];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TRANSPARENT_SHADOWS
|
|
||||||
return aFactor;
|
return aFactor;
|
||||||
#else
|
|
||||||
return 1.0f;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PI 3.1415926f
|
#define PI 3.1415926f
|
||||||
@ -955,7 +927,7 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
|
|||||||
vec3 aResult = vec3 (0.0f);
|
vec3 aResult = vec3 (0.0f);
|
||||||
vec4 aWeight = vec4 (1.0f);
|
vec4 aWeight = vec4 (1.0f);
|
||||||
|
|
||||||
int anObjectId;
|
int aTrsfId;
|
||||||
|
|
||||||
float anOpenGlDepth = ComputeOpenGlDepth (theRay);
|
float anOpenGlDepth = ComputeOpenGlDepth (theRay);
|
||||||
|
|
||||||
@ -963,7 +935,7 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
|
|||||||
{
|
{
|
||||||
SIntersect aHit = SIntersect (MAXFLOAT, vec2 (ZERO), ZERO);
|
SIntersect aHit = SIntersect (MAXFLOAT, vec2 (ZERO), ZERO);
|
||||||
|
|
||||||
ivec4 aTriIndex = SceneNearestHit (theRay, theInverse, aHit, anObjectId);
|
ivec4 aTriIndex = SceneNearestHit (theRay, theInverse, aHit, aTrsfId);
|
||||||
|
|
||||||
if (aTriIndex.x == -1)
|
if (aTriIndex.x == -1)
|
||||||
{
|
{
|
||||||
@ -982,12 +954,14 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
|
|||||||
aColor = vec4 (BackgroundColor().rgb * aGlColor.w + ComputeOpenGlColor().rgb, aGlColor.w);
|
aColor = vec4 (BackgroundColor().rgb * aGlColor.w + ComputeOpenGlColor().rgb, aGlColor.w);
|
||||||
}
|
}
|
||||||
|
|
||||||
return vec4 (aResult.xyz + aWeight.xyz * aColor.xyz, aWeight.w * aColor.w);
|
aResult += aWeight.xyz * aColor.xyz; aWeight.w *= aColor.w;
|
||||||
|
|
||||||
|
break; // terminate path
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 aInvTransf0 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 0).xyz;
|
vec3 aInvTransf0 = texelFetch (uSceneTransformTexture, aTrsfId + 0).xyz;
|
||||||
vec3 aInvTransf1 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 1).xyz;
|
vec3 aInvTransf1 = texelFetch (uSceneTransformTexture, aTrsfId + 1).xyz;
|
||||||
vec3 aInvTransf2 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 2).xyz;
|
vec3 aInvTransf2 = texelFetch (uSceneTransformTexture, aTrsfId + 2).xyz;
|
||||||
|
|
||||||
aHit.Normal = normalize (vec3 (dot (aInvTransf0, aHit.Normal),
|
aHit.Normal = normalize (vec3 (dot (aInvTransf0, aHit.Normal),
|
||||||
dot (aInvTransf1, aHit.Normal),
|
dot (aInvTransf1, aHit.Normal),
|
||||||
|
@ -9,6 +9,12 @@ uniform float uSampleWeight;
|
|||||||
//! Input accumulated image.
|
//! Input accumulated image.
|
||||||
uniform sampler2D uAccumTexture;
|
uniform sampler2D uAccumTexture;
|
||||||
|
|
||||||
|
//! Enabled/disbales using of single RNG seed for image 16x16 blocks.
|
||||||
|
//! Increases performance up to 4 times, but noise becomes structured.
|
||||||
|
uniform int uBlockedRngEnabled;
|
||||||
|
|
||||||
|
#define MAX_RADIANCE vec3 (10.f)
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
// function : main
|
// function : main
|
||||||
// purpose :
|
// purpose :
|
||||||
@ -20,7 +26,7 @@ void main (void)
|
|||||||
#else
|
#else
|
||||||
ivec2 aWinSize = textureSize (uAccumTexture, 0);
|
ivec2 aWinSize = textureSize (uAccumTexture, 0);
|
||||||
|
|
||||||
SeedRand (uFrameRndSeed, aWinSize.x);
|
SeedRand (uFrameRndSeed, aWinSize.x, uBlockedRngEnabled == 0 ? 1 : 16);
|
||||||
|
|
||||||
SRay aRay = GenerateRay (vPixel +
|
SRay aRay = GenerateRay (vPixel +
|
||||||
vec2 (RandFloat() + 1.f, RandFloat() + 1.f) / vec2 (aWinSize));
|
vec2 (RandFloat() + 1.f, RandFloat() + 1.f) / vec2 (aWinSize));
|
||||||
@ -33,19 +39,17 @@ void main (void)
|
|||||||
aRay.Direct.z < 0.f ? -aInvDirect.z : aInvDirect.z);
|
aRay.Direct.z < 0.f ? -aInvDirect.z : aInvDirect.z);
|
||||||
|
|
||||||
#ifdef PATH_TRACING
|
#ifdef PATH_TRACING
|
||||||
|
|
||||||
vec4 aColor = PathTrace (aRay, aInvDirect);
|
vec4 aColor = PathTrace (aRay, aInvDirect);
|
||||||
|
|
||||||
if (any (isnan (aColor.xyz)))
|
if (any (isnan (aColor.xyz)))
|
||||||
{
|
{
|
||||||
aColor.xyz = ZERO;
|
aColor.rgb = ZERO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
aColor.rgb = min (aColor.rgb, MAX_RADIANCE);
|
||||||
|
|
||||||
OutColor = mix (texture2D (uAccumTexture, vPixel), aColor, uSampleWeight);
|
OutColor = mix (texture2D (uAccumTexture, vPixel), aColor, uSampleWeight);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
OutColor = clamp (Radiance (aRay, aInvDirect), 0.f, 1.f);
|
OutColor = clamp (Radiance (aRay, aInvDirect), 0.f, 1.f);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
@ -5320,6 +5320,22 @@ static int VFps (Draw_Interpretor& theDI,
|
|||||||
theDI << "FPS: " << aFpsAver << "\n"
|
theDI << "FPS: " << aFpsAver << "\n"
|
||||||
<< "CPU: " << (1000.0 * aCpuAver) << " msec\n";
|
<< "CPU: " << (1000.0 * aCpuAver) << " msec\n";
|
||||||
|
|
||||||
|
// compute additional statistics in ray-tracing mode
|
||||||
|
Graphic3d_RenderingParams& aParams = aView->ChangeRenderingParams();
|
||||||
|
|
||||||
|
if (aParams.Method == Graphic3d_RM_RAYTRACING)
|
||||||
|
{
|
||||||
|
Standard_Integer aSizeX;
|
||||||
|
Standard_Integer aSizeY;
|
||||||
|
|
||||||
|
aView->Window()->Size (aSizeX, aSizeY);
|
||||||
|
|
||||||
|
// 1 shadow ray and 1 secondary ray pew each bounce
|
||||||
|
const Standard_Real aMRays = aSizeX * aSizeY * aFpsAver * aParams.RaytracingDepth * 2 / 1.0e6f;
|
||||||
|
|
||||||
|
theDI << "MRays/sec (upper bound): " << aMRays << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8389,6 +8405,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
|
|||||||
theDI << "rayDepth: " << aParams.RaytracingDepth << "\n";
|
theDI << "rayDepth: " << aParams.RaytracingDepth << "\n";
|
||||||
theDI << "gleam: " << (aParams.IsTransparentShadowEnabled ? "on" : "off") << "\n";
|
theDI << "gleam: " << (aParams.IsTransparentShadowEnabled ? "on" : "off") << "\n";
|
||||||
theDI << "GI: " << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << "\n";
|
theDI << "GI: " << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << "\n";
|
||||||
|
theDI << "blocked RNG: " << (aParams.CoherentPathTracingMode ? "on" : "off") << "\n";
|
||||||
theDI << "shadingModel: ";
|
theDI << "shadingModel: ";
|
||||||
switch (aView->ShadingModel())
|
switch (aView->ShadingModel())
|
||||||
{
|
{
|
||||||
@ -8573,6 +8590,23 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
|
|||||||
aParams.RaytracingDepth = Min (aParams.RaytracingDepth, 10);
|
aParams.RaytracingDepth = Min (aParams.RaytracingDepth, 10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (aFlag == "-blockedrng"
|
||||||
|
|| aFlag == "-brng")
|
||||||
|
{
|
||||||
|
if (toPrint)
|
||||||
|
{
|
||||||
|
theDI << (aParams.CoherentPathTracingMode ? "on" : "off") << " ";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Standard_Boolean toEnable = Standard_True;
|
||||||
|
if (++anArgIter < theArgNb
|
||||||
|
&& !parseOnOff (theArgVec[anArgIter], toEnable))
|
||||||
|
{
|
||||||
|
--anArgIter;
|
||||||
|
}
|
||||||
|
aParams.CoherentPathTracingMode = toEnable;
|
||||||
|
}
|
||||||
else if (aFlag == "-env")
|
else if (aFlag == "-env")
|
||||||
{
|
{
|
||||||
if (toPrint)
|
if (toPrint)
|
||||||
@ -9360,6 +9394,7 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
|
|||||||
"\n '-fsaa on|off' Enables/disables adaptive anti-aliasing"
|
"\n '-fsaa on|off' Enables/disables adaptive anti-aliasing"
|
||||||
"\n '-gleam on|off' Enables/disables transparency shadow effects"
|
"\n '-gleam on|off' Enables/disables transparency shadow effects"
|
||||||
"\n '-gi on|off' Enables/disables global illumination effects"
|
"\n '-gi on|off' Enables/disables global illumination effects"
|
||||||
|
"\n '-brng on|off' Enables/disables blocked RNG (fast coherent PT)"
|
||||||
"\n '-env on|off' Enables/disables environment map background"
|
"\n '-env on|off' Enables/disables environment map background"
|
||||||
"\n '-shadingModel model' Controls shading model from enumeration"
|
"\n '-shadingModel model' Controls shading model from enumeration"
|
||||||
"\n color, flat, gouraud, phong"
|
"\n color, flat, gouraud, phong"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user