mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-06 18:26:22 +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),
|
||||
IsAntialiasingEnabled (Standard_False),
|
||||
IsTransparentShadowEnabled (Standard_False),
|
||||
|
||||
UseEnvironmentMapBackground (Standard_False),
|
||||
CoherentPathTracingMode (Standard_False),
|
||||
|
||||
StereoMode (Graphic3d_StereoMode_QuadBuffer),
|
||||
AnaglyphFilter (Anaglyph_RedCyan_Optimized),
|
||||
ToReverseStereo (Standard_False)
|
||||
@ -84,6 +85,7 @@ public:
|
||||
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 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
|
||||
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 Standard_Boolean theToDrawImmediate);
|
||||
|
||||
|
||||
void DrawBackground (const Handle(OpenGl_Workspace)& theWorkspace);
|
||||
|
||||
//! Returns list of OpenGL Z-layers.
|
||||
@ -334,6 +333,7 @@ protected: //! @name data types related to ray-tracing
|
||||
OpenGl_RT_uSphereMapEnabled,
|
||||
OpenGl_RT_uSphereMapForBack,
|
||||
OpenGl_RT_uTexSamplersArray,
|
||||
OpenGl_RT_uBlockedRngEnabled,
|
||||
|
||||
// sampled frame params
|
||||
OpenGl_RT_uSampleWeight,
|
||||
@ -503,7 +503,7 @@ protected: //! @name methods related to ray-tracing
|
||||
|
||||
//! Adds OpenGL groups to ray-traced scene geometry.
|
||||
Standard_Boolean addRaytraceGroups (const OpenGl_Structure* theStructure,
|
||||
const Standard_Integer theStructMat,
|
||||
const OpenGl_RaytraceMaterial& theStructMat,
|
||||
const Standard_ShortReal* theTransform,
|
||||
const Handle(OpenGl_Context)& theGlContext);
|
||||
|
||||
|
@ -407,15 +407,11 @@ Standard_Boolean OpenGl_View::addRaytraceStructure (const OpenGl_Structure*
|
||||
}
|
||||
|
||||
// Get structure material
|
||||
Standard_Integer aStructMatID = -1;
|
||||
OpenGl_RaytraceMaterial aStructMaterial;
|
||||
|
||||
if (theStructure->AspectFace() != NULL)
|
||||
{
|
||||
aStructMatID = static_cast<Standard_Integer> (myRaytraceGeometry.Materials.size());
|
||||
|
||||
OpenGl_RaytraceMaterial aStructMaterial = convertMaterial (theStructure->AspectFace(), theGlContext);
|
||||
|
||||
myRaytraceGeometry.Materials.push_back (aStructMaterial);
|
||||
aStructMaterial = convertMaterial (theStructure->AspectFace(), theGlContext);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
// Process all connected OpenGL structures
|
||||
@ -439,7 +435,7 @@ Standard_Boolean OpenGl_View::addRaytraceStructure (const OpenGl_Structure*
|
||||
|
||||
if (anInstanced != NULL && anInstanced->IsRaytracable())
|
||||
{
|
||||
aResult &= addRaytraceGroups (anInstanced, aStructMatID,
|
||||
aResult &= addRaytraceGroups (anInstanced, aStructMaterial,
|
||||
theStructure->Transformation()->mat ? aStructTransform : NULL, theGlContext);
|
||||
}
|
||||
|
||||
@ -453,31 +449,25 @@ Standard_Boolean OpenGl_View::addRaytraceStructure (const OpenGl_Structure*
|
||||
// purpose : Adds OpenGL groups to ray-traced scene geometry
|
||||
// =======================================================================
|
||||
Standard_Boolean OpenGl_View::addRaytraceGroups (const OpenGl_Structure* theStructure,
|
||||
const Standard_Integer theStructMat,
|
||||
const OpenGl_RaytraceMaterial& theStructMat,
|
||||
const Standard_ShortReal* theTransform,
|
||||
const Handle(OpenGl_Context)& theGlContext)
|
||||
{
|
||||
for (OpenGl_Structure::GroupIterator aGroupIter (theStructure->DrawGroups()); aGroupIter.More(); aGroupIter.Next())
|
||||
{
|
||||
// Get group material
|
||||
Standard_Integer aGroupMatID = -1;
|
||||
OpenGl_RaytraceMaterial aGroupMaterial;
|
||||
if (aGroupIter.Value()->AspectFace() != NULL)
|
||||
{
|
||||
aGroupMatID = static_cast<Standard_Integer> (myRaytraceGeometry.Materials.size());
|
||||
|
||||
OpenGl_RaytraceMaterial aGroupMaterial = convertMaterial (
|
||||
aGroupMaterial = convertMaterial (
|
||||
aGroupIter.Value()->AspectFace(), theGlContext);
|
||||
|
||||
myRaytraceGeometry.Materials.push_back (aGroupMaterial);
|
||||
}
|
||||
|
||||
Standard_Integer aMatID = aGroupMatID < 0 ? theStructMat : aGroupMatID;
|
||||
if (aMatID < 0)
|
||||
{
|
||||
aMatID = static_cast<Standard_Integer> (myRaytraceGeometry.Materials.size());
|
||||
Standard_Integer 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)
|
||||
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");
|
||||
myUniformLocations[anIndex][OpenGl_RT_uSphereMapForBack] =
|
||||
aShaderProgram->GetUniformLocation (theGlContext, "uSphereMapForBack");
|
||||
myUniformLocations[anIndex][OpenGl_RT_uBlockedRngEnabled] =
|
||||
aShaderProgram->GetUniformLocation (theGlContext, "uBlockedRngEnabled");
|
||||
|
||||
myUniformLocations[anIndex][OpenGl_RT_uSampleWeight] =
|
||||
aShaderProgram->GetUniformLocation (theGlContext, "uSampleWeight");
|
||||
@ -2256,6 +2248,12 @@ Standard_Boolean OpenGl_View::setUniformState (const Graphic3d_CView& the
|
||||
theProgram->SetUniform (theGlContext,
|
||||
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
|
||||
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);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// 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
|
||||
// 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),
|
||||
sqrt (1.f - aKsi2));
|
||||
|
||||
if (theOutput.z < 0.f)
|
||||
theInput.z = -theInput.z;
|
||||
theInput.z = mix (-theInput.z, theInput.z, step (0.f, theOutput.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
|
||||
// purpose : Samples specular BTDF, W = BRDF * cos(N, PSI) / PDF(PSI)
|
||||
//=======================================================================
|
||||
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);
|
||||
|
||||
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
|
||||
if (RandFloat() <= aProbability)
|
||||
if (theBounce == SPEC_REFLECT_BOUNCE)
|
||||
{
|
||||
theInput = vec3 (-theOutput.x,
|
||||
-theOutput.y,
|
||||
theOutput.z);
|
||||
|
||||
isTransmit = false;
|
||||
|
||||
return aFresnel * (1.f / aProbability);
|
||||
theWeight = aFresnel * (1.f / aProbability);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
transmitted (theFresnelCoeffs.y, theOutput, theInput);
|
||||
|
||||
isTransmit = true;
|
||||
theWeight = (UNIT - aFresnel) * (1.f / (1.f - aProbability));
|
||||
}
|
||||
|
||||
return (UNIT - aFresnel) * (1.f / (1.f - aProbability));
|
||||
return theWeight;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@ -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);
|
||||
}
|
||||
|
||||
// Enables expiremental russian roulette sampling
|
||||
// #define RUSSIAN_ROULETTE
|
||||
|
||||
//=======================================================================
|
||||
// function : sampleMaterial
|
||||
// purpose : Samples specified composite material (BSDF)
|
||||
//=======================================================================
|
||||
bool sampleMaterial (in SMaterial theMaterial,
|
||||
void sampleMaterial (in SMaterial theMaterial,
|
||||
in vec3 theOutput,
|
||||
in vec3 theFactor,
|
||||
out vec3 theInput,
|
||||
out vec3 theWeight,
|
||||
inout bool isTransmit)
|
||||
inout vec3 theWeight,
|
||||
inout int theBounce)
|
||||
{
|
||||
theWeight = ZERO;
|
||||
|
||||
// Compute the probability of ray reflection
|
||||
float aPd = convolve (theMaterial.Kd.rgb, theFactor);
|
||||
float aPs = convolve (theMaterial.Ks.rgb, theFactor);
|
||||
float aPr = convolve (theMaterial.Kr.rgb, theFactor);
|
||||
float aPt = convolve (theMaterial.Kt.rgb, theFactor);
|
||||
float aPd = convolve (theMaterial.Kd.rgb, theWeight);
|
||||
float aPs = convolve (theMaterial.Ks.rgb, theWeight);
|
||||
float aPr = convolve (theMaterial.Kr.rgb, theWeight);
|
||||
float aPt = convolve (theMaterial.Kt.rgb, theWeight);
|
||||
|
||||
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
|
||||
float aKsi = aReflection * RandFloat();
|
||||
|
||||
theBounce = NON_SPECULAR_BOUNCE;
|
||||
|
||||
if (aKsi < aPd) // diffuse reflection
|
||||
{
|
||||
sampleLambertianReflection (theOutput, theInput);
|
||||
|
||||
#ifndef RUSSIAN_ROULETTE
|
||||
theWeight = theMaterial.Kd.rgb * (aReflection / aPd);
|
||||
#else
|
||||
theWeight = theMaterial.Kd.rgb * (aReflection / aPd / aSurvival);
|
||||
#endif
|
||||
|
||||
return false; // non-specular bounce
|
||||
theWeight *= theMaterial.Kd.rgb * (aReflection / aPd);
|
||||
}
|
||||
else if (aKsi < aPd + aPs) // glossy reflection
|
||||
{
|
||||
theWeight = 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
|
||||
theWeight *= theMaterial.Ks.rgb * (aReflection / aPs) *
|
||||
sampleBlinnReflection (theOutput, theInput, theMaterial.Fresnel, theMaterial.Ks.w);
|
||||
}
|
||||
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
|
||||
theWeight *= theMaterial.Kr.rgb * (aReflection / aPr);
|
||||
#else
|
||||
theWeight *= theMaterial.Kr.rgb * (aReflection / aPr / aSurvival);
|
||||
#endif
|
||||
|
||||
return true; // specular bounce
|
||||
theBounce = SPEC_REFLECT_BOUNCE; // specular bounce
|
||||
}
|
||||
else // specular transmission
|
||||
{
|
||||
theWeight = sampleSpecularTransmission (theOutput, theInput,
|
||||
isTransmit, theFactor, theMaterial.Fresnel);
|
||||
|
||||
#ifndef RUSSIAN_ROULETTE
|
||||
theWeight *= theMaterial.Kt.rgb * (aReflection / aPt);
|
||||
#else
|
||||
theWeight *= theMaterial.Kt.rgb * (aReflection / aPt / aSurvival);
|
||||
#endif
|
||||
|
||||
return true; // specular bounce
|
||||
theWeight *= theMaterial.Kt.rgb * (aReflection / aPt) *
|
||||
sampleSpecularTransmission (theOutput, theInput, theBounce, theWeight, theMaterial.Fresnel);
|
||||
}
|
||||
|
||||
// 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
|
||||
// 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
|
||||
// purpose :
|
||||
// function : sampleLight
|
||||
// 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);
|
||||
|
||||
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 aKsi2 = RandFloat();
|
||||
|
||||
float aTmp = 1.f - aKsi2 * (1.f - aCosMax);
|
||||
|
||||
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),
|
||||
vec3 anInput = vec3 (cos (2.f * M_PI * aKsi1),
|
||||
sin (2.f * M_PI * aKsi1),
|
||||
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));
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// 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;
|
||||
thePDF *= (aCosMax < 1.f) ? 1.f / (2.f * M_PI) / (1.f - aCosMax) : 1.f;
|
||||
|
||||
return normalize (fromLocalSpace (anInput, aSpace));
|
||||
}
|
||||
@ -609,26 +553,26 @@ vec2 Latlong (in vec3 thePoint)
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : EnvironmentRadiance
|
||||
// purpose :
|
||||
// function: intersectLight
|
||||
// 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;
|
||||
|
||||
if (uSphereMapForBack != 0 || !isBackground)
|
||||
if ((isViewRay || IS_REFR_SPEC_BOUNCE(theBounce)) && uSphereMapForBack == 0)
|
||||
{
|
||||
aRadiance += FetchEnvironment (Latlong (theRay.Direct)).xyz;
|
||||
aRadiance = BackgroundColor().xyz;
|
||||
}
|
||||
else
|
||||
{
|
||||
aRadiance += BackgroundColor().xyz;
|
||||
aRadiance = FetchEnvironment (Latlong (theRay.Direct)).xyz;
|
||||
}
|
||||
|
||||
// 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 (
|
||||
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
|
||||
{
|
||||
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 */);
|
||||
}
|
||||
@ -659,6 +604,9 @@ vec3 EnvironmentRadiance (in SRay theRay, in bool isSpecular, in bool isBackgrou
|
||||
#define MATERIAL_FRESNEL(index) (18 * index + 16)
|
||||
#define MATERIAL_ABSORPT(index) (18 * index + 17)
|
||||
|
||||
// Enables expiremental russian roulette sampling
|
||||
#define RUSSIAN_ROULETTE
|
||||
|
||||
//=======================================================================
|
||||
// function : PathTrace
|
||||
// purpose : Calculates radiance along the given ray
|
||||
@ -670,28 +618,31 @@ vec4 PathTrace (in SRay theRay, in vec3 theInverse)
|
||||
vec3 aRadiance = ZERO;
|
||||
vec3 aThroughput = UNIT;
|
||||
|
||||
bool isInMedium = false;
|
||||
bool isSpecular = false;
|
||||
bool isTransmit = false;
|
||||
int aBounce = 0; // type of previous hit point
|
||||
int aTrsfId = 0; // offset of object transform
|
||||
|
||||
int anObjectId; // ID of intersected triangle
|
||||
bool isInMedium = false;
|
||||
|
||||
for (int aDepth = 0; aDepth < NB_BOUNCES; ++aDepth)
|
||||
{
|
||||
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 *
|
||||
EnvironmentRadiance (theRay, isSpecular, aDepth == 0 || isTransmit), 0.f);
|
||||
aRadiance += aThroughput * aLe; break; // terminate path
|
||||
}
|
||||
|
||||
vec3 aInvTransf0 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 0).xyz;
|
||||
vec3 aInvTransf1 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 1).xyz;
|
||||
vec3 aInvTransf2 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 2).xyz;
|
||||
vec3 aInvTransf0 = texelFetch (uSceneTransformTexture, aTrsfId + 0).xyz;
|
||||
vec3 aInvTransf1 = texelFetch (uSceneTransformTexture, aTrsfId + 1).xyz;
|
||||
vec3 aInvTransf2 = texelFetch (uSceneTransformTexture, aTrsfId + 2).xyz;
|
||||
|
||||
// compute geometrical normal
|
||||
aHit.Normal = normalize (vec3 (dot (aInvTransf0, aHit.Normal),
|
||||
dot (aInvTransf1, aHit.Normal),
|
||||
dot (aInvTransf2, aHit.Normal)));
|
||||
@ -711,9 +662,9 @@ vec4 PathTrace (in SRay theRay, in vec3 theInverse)
|
||||
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 (
|
||||
vec4 (texelFetch (uRaytraceMaterialTexture, MATERIAL_KD (aTriIndex.w))),
|
||||
vec3 (texelFetch (uRaytraceMaterialTexture, MATERIAL_KR (aTriIndex.w))),
|
||||
@ -742,6 +693,7 @@ vec4 PathTrace (in SRay theRay, in vec3 theInverse)
|
||||
}
|
||||
#endif
|
||||
|
||||
// compute smooth normal
|
||||
vec3 aNormal = SmoothNormal (aHit.UV, aTriIndex);
|
||||
|
||||
aNormal = normalize (vec3 (dot (aInvTransf0, aNormal),
|
||||
@ -750,7 +702,7 @@ vec4 PathTrace (in SRay theRay, in vec3 theInverse)
|
||||
|
||||
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 (
|
||||
uRaytraceMaterialTexture, MATERIAL_LE (aTriIndex.w)).rgb;
|
||||
|
||||
@ -763,18 +715,13 @@ vec4 PathTrace (in SRay theRay, in vec3 theInverse)
|
||||
vec4 aParam = texelFetch (
|
||||
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
|
||||
{
|
||||
aDistance = length (aLight.xyz -= theRay.Origin);
|
||||
float aPDF = 1.f / uLightCount, aDistance = length (aLight.xyz);
|
||||
|
||||
aLight.xyz = samplePointLight (aLight.xyz, aParam.w /* radius */, aPDF);
|
||||
}
|
||||
else // directional light source
|
||||
{
|
||||
aLight.xyz = sampleDirectLight (aLight.xyz, aParam.w /* angle cosine */, aPDF);
|
||||
}
|
||||
aLight.xyz = sampleLight (aLight.xyz * (1.f / aDistance),
|
||||
aLight.w == 0.f /* is infinite */, aParam.w /* angle cosine */, aPDF);
|
||||
|
||||
vec3 aContrib = (1.f / aPDF) * aParam.rgb /* Le */ * handleMaterial (
|
||||
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)));
|
||||
|
||||
float aVisibility = SceneAnyHit (aShadow,
|
||||
InverseDirection (aLight.xyz), aDistance);
|
||||
InverseDirection (aLight.xyz), aLight.w == 0.f ? MAXFLOAT : aDistance);
|
||||
|
||||
aRadiance += aVisibility * aThroughput * aContrib;
|
||||
}
|
||||
}
|
||||
|
||||
vec3 anInput;
|
||||
vec3 aWeight;
|
||||
|
||||
isSpecular = sampleMaterial (aMaterial,
|
||||
toLocalSpace (-theRay.Direct, aSpace), aThroughput, anInput, aWeight, isTransmit);
|
||||
sampleMaterial (aMaterial,
|
||||
toLocalSpace (-theRay.Direct, aSpace), anInput, aThroughput, aBounce);
|
||||
|
||||
if (isInMedium)
|
||||
{
|
||||
@ -805,14 +751,23 @@ vec4 PathTrace (in SRay theRay, in vec3 theInverse)
|
||||
aMaterial.Absorption.w * (UNIT - aMaterial.Absorption.rgb));
|
||||
}
|
||||
|
||||
isInMedium = isTransmit ? !isInMedium : isInMedium;
|
||||
|
||||
aThroughput *= aWeight;
|
||||
isInMedium = IS_REFR_SPEC_BOUNCE(aBounce) ? !isInMedium : isInMedium;
|
||||
|
||||
#ifndef RUSSIAN_ROULETTE
|
||||
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));
|
||||
|
||||
|
@ -158,9 +158,9 @@ uint RandState;
|
||||
// purpose : Applies hash function by Thomas Wang to randomize seeds
|
||||
// (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 ^ 0xe4aa10ceu) ^ (RandState >> 5);
|
||||
@ -365,9 +365,7 @@ ivec4 ObjectNearestHit (in int theBVHOffset, in int theVrtOffset, in int theTrgO
|
||||
|
||||
ivec4 aTriIndex = INALID_HIT;
|
||||
|
||||
bool toContinue = true;
|
||||
|
||||
while (toContinue)
|
||||
for (bool toContinue = true; toContinue;)
|
||||
{
|
||||
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 aNode = theBVHOffset; // node to visit
|
||||
|
||||
#ifdef TRANSPARENT_SHADOWS
|
||||
float aFactor = 1.0f;
|
||||
#endif
|
||||
float aFactor = 1.f;
|
||||
|
||||
while (true)
|
||||
for (bool toContinue = true; toContinue;)
|
||||
{
|
||||
ivec4 aData = texelFetch (uSceneNodeInfoTexture, aNode);
|
||||
|
||||
@ -545,14 +541,9 @@ float ObjectAnyHit (in int theBVHOffset, in int theVrtOffset, in int theTrgOffse
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef TRANSPARENT_SHADOWS
|
||||
if (aHead == theSentinel)
|
||||
return aFactor;
|
||||
#else
|
||||
if (aHead == theSentinel)
|
||||
return 1.0f;
|
||||
#endif
|
||||
toContinue = (aHead != theSentinel);
|
||||
|
||||
if (toContinue)
|
||||
aNode = Stack[aHead--];
|
||||
}
|
||||
}
|
||||
@ -580,45 +571,38 @@ float ObjectAnyHit (in int theBVHOffset, in int theVrtOffset, in int theTrgOffse
|
||||
#ifdef TRANSPARENT_SHADOWS
|
||||
if (aTime < theDistance)
|
||||
{
|
||||
aFactor *= 1.0f - texelFetch (uRaytraceMaterialTexture, MATERIAL_TRAN (aTriangle.w)).x;
|
||||
aFactor *= 1.f - texelFetch (uRaytraceMaterialTexture, MATERIAL_TRAN (aTriangle.w)).x;
|
||||
}
|
||||
#else
|
||||
if (aTime < theDistance)
|
||||
return 0.0f;
|
||||
{
|
||||
aFactor = 0.f;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef TRANSPARENT_SHADOWS
|
||||
if (aHead == theSentinel || aFactor < 0.1f)
|
||||
return aFactor;
|
||||
#else
|
||||
if (aHead == theSentinel)
|
||||
return 1.0f;
|
||||
#endif
|
||||
toContinue = (aHead != theSentinel) && (aFactor > 0.1f);
|
||||
|
||||
if (toContinue)
|
||||
aNode = Stack[aHead--];
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TRANSPARENT_SHADOWS
|
||||
return aFactor;
|
||||
#else
|
||||
return 1.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : SceneNearestHit
|
||||
// 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 aNode = 0; // node to visit
|
||||
|
||||
ivec4 aHitObject = INALID_HIT;
|
||||
|
||||
while (true)
|
||||
for (bool toContinue = true; toContinue;)
|
||||
{
|
||||
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)
|
||||
{
|
||||
// fetch object transformation
|
||||
int anObjectId = aData.x - 1;
|
||||
int aTrsfId = (aData.x - 1) * 4;
|
||||
|
||||
vec4 aInvTransf0 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 0);
|
||||
vec4 aInvTransf1 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 1);
|
||||
vec4 aInvTransf2 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 2);
|
||||
vec4 aInvTransf3 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 3);
|
||||
vec4 aInvTransf0 = texelFetch (uSceneTransformTexture, aTrsfId + 0);
|
||||
vec4 aInvTransf1 = texelFetch (uSceneTransformTexture, aTrsfId + 1);
|
||||
vec4 aInvTransf2 = texelFetch (uSceneTransformTexture, aTrsfId + 2);
|
||||
vec4 aInvTransf3 = texelFetch (uSceneTransformTexture, aTrsfId + 3);
|
||||
|
||||
SRay aTrsfRay = SRay (
|
||||
MatrixColMultiplyPnt (theRay.Origin, aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3),
|
||||
@ -660,13 +644,13 @@ ivec4 SceneNearestHit (in SRay theRay, in vec3 theInverse, inout SIntersect theH
|
||||
aTriIndex.z, // vertex 2
|
||||
aTriIndex.w); // material
|
||||
|
||||
theObjectId = anObjectId;
|
||||
theTrsfId = aTrsfId;
|
||||
}
|
||||
}
|
||||
|
||||
if (aHead < 0)
|
||||
return aHitObject;
|
||||
toContinue = aHead >= 0;
|
||||
|
||||
if (toContinue)
|
||||
aNode = Stack[aHead--];
|
||||
}
|
||||
else // if inner node
|
||||
@ -716,9 +700,9 @@ ivec4 SceneNearestHit (in SRay theRay, in vec3 theInverse, inout SIntersect theH
|
||||
}
|
||||
else
|
||||
{
|
||||
if (aHead < 0)
|
||||
return aHitObject;
|
||||
toContinue = aHead >= 0;
|
||||
|
||||
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 aNode = 0; // node to visit
|
||||
|
||||
#ifdef TRANSPARENT_SHADOWS
|
||||
float aFactor = 1.0f;
|
||||
#endif
|
||||
float aFactor = 1.f;
|
||||
|
||||
while (true)
|
||||
for (bool toContinue = true; toContinue;)
|
||||
{
|
||||
ivec4 aData = texelFetch (uSceneNodeInfoTexture, aNode);
|
||||
|
||||
if (aData.x != 0) // if leaf node
|
||||
{
|
||||
// fetch object transformation
|
||||
int anObjectId = aData.x - 1;
|
||||
int aTrsfId = (aData.x - 1) * 4;
|
||||
|
||||
vec4 aInvTransf0 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 0);
|
||||
vec4 aInvTransf1 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 1);
|
||||
vec4 aInvTransf2 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 2);
|
||||
vec4 aInvTransf3 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 3);
|
||||
vec4 aInvTransf0 = texelFetch (uSceneTransformTexture, aTrsfId + 0);
|
||||
vec4 aInvTransf1 = texelFetch (uSceneTransformTexture, aTrsfId + 1);
|
||||
vec4 aInvTransf2 = texelFetch (uSceneTransformTexture, aTrsfId + 2);
|
||||
vec4 aInvTransf3 = texelFetch (uSceneTransformTexture, aTrsfId + 3);
|
||||
|
||||
SRay aTrsfRay = SRay (
|
||||
MatrixColMultiplyPnt (theRay.Origin, aInvTransf0, aInvTransf1, aInvTransf2, aInvTransf3),
|
||||
@ -767,16 +749,15 @@ float SceneAnyHit (in SRay theRay, in vec3 theInverse, in float theDistance)
|
||||
aFactor *= ObjectAnyHit (
|
||||
aData.y, aData.z, aData.w, aTrsfRay, aTrsfInverse, theDistance, aHead);
|
||||
|
||||
if (aHead < 0 || aFactor < 0.1f)
|
||||
return aFactor;
|
||||
toContinue = aHead >= 0 && aFactor >= 0.1f;
|
||||
#else
|
||||
bool isShadow = 0.0f == ObjectAnyHit (
|
||||
aFactor = ObjectAnyHit (
|
||||
aData.y, aData.z, aData.w, aTrsfRay, aTrsfInverse, theDistance, aHead);
|
||||
|
||||
if (aHead < 0 || isShadow)
|
||||
return isShadow ? 0.0f : 1.0f;
|
||||
toContinue = aHead >= 0 && aFactor != 0.0f;
|
||||
#endif
|
||||
|
||||
if (toContinue)
|
||||
aNode = Stack[aHead--];
|
||||
}
|
||||
else // if inner node
|
||||
@ -826,25 +807,16 @@ float SceneAnyHit (in SRay theRay, in vec3 theInverse, in float theDistance)
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef TRANSPARENT_SHADOWS
|
||||
if (aHead < 0)
|
||||
return aFactor;
|
||||
#else
|
||||
if (aHead < 0)
|
||||
return 1.0f;
|
||||
#endif
|
||||
toContinue = aHead >= 0;
|
||||
|
||||
if (toContinue)
|
||||
aNode = Stack[aHead--];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TRANSPARENT_SHADOWS
|
||||
return aFactor;
|
||||
#else
|
||||
return 1.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define PI 3.1415926f
|
||||
@ -955,7 +927,7 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
|
||||
vec3 aResult = vec3 (0.0f);
|
||||
vec4 aWeight = vec4 (1.0f);
|
||||
|
||||
int anObjectId;
|
||||
int aTrsfId;
|
||||
|
||||
float anOpenGlDepth = ComputeOpenGlDepth (theRay);
|
||||
|
||||
@ -963,7 +935,7 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -982,12 +954,14 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
|
||||
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 aInvTransf1 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 1).xyz;
|
||||
vec3 aInvTransf2 = texelFetch (uSceneTransformTexture, anObjectId * 4 + 2).xyz;
|
||||
vec3 aInvTransf0 = texelFetch (uSceneTransformTexture, aTrsfId + 0).xyz;
|
||||
vec3 aInvTransf1 = texelFetch (uSceneTransformTexture, aTrsfId + 1).xyz;
|
||||
vec3 aInvTransf2 = texelFetch (uSceneTransformTexture, aTrsfId + 2).xyz;
|
||||
|
||||
aHit.Normal = normalize (vec3 (dot (aInvTransf0, aHit.Normal),
|
||||
dot (aInvTransf1, aHit.Normal),
|
||||
|
@ -9,6 +9,12 @@ uniform float uSampleWeight;
|
||||
//! Input accumulated image.
|
||||
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
|
||||
// purpose :
|
||||
@ -20,7 +26,7 @@ void main (void)
|
||||
#else
|
||||
ivec2 aWinSize = textureSize (uAccumTexture, 0);
|
||||
|
||||
SeedRand (uFrameRndSeed, aWinSize.x);
|
||||
SeedRand (uFrameRndSeed, aWinSize.x, uBlockedRngEnabled == 0 ? 1 : 16);
|
||||
|
||||
SRay aRay = GenerateRay (vPixel +
|
||||
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);
|
||||
|
||||
#ifdef PATH_TRACING
|
||||
|
||||
vec4 aColor = PathTrace (aRay, aInvDirect);
|
||||
|
||||
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);
|
||||
|
||||
#else
|
||||
|
||||
OutColor = clamp (Radiance (aRay, aInvDirect), 0.f, 1.f);
|
||||
|
||||
#endif
|
||||
}
|
@ -5320,6 +5320,22 @@ static int VFps (Draw_Interpretor& theDI,
|
||||
theDI << "FPS: " << aFpsAver << "\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;
|
||||
}
|
||||
|
||||
@ -8389,6 +8405,7 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
|
||||
theDI << "rayDepth: " << aParams.RaytracingDepth << "\n";
|
||||
theDI << "gleam: " << (aParams.IsTransparentShadowEnabled ? "on" : "off") << "\n";
|
||||
theDI << "GI: " << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << "\n";
|
||||
theDI << "blocked RNG: " << (aParams.CoherentPathTracingMode ? "on" : "off") << "\n";
|
||||
theDI << "shadingModel: ";
|
||||
switch (aView->ShadingModel())
|
||||
{
|
||||
@ -8573,6 +8590,23 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
|
||||
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")
|
||||
{
|
||||
if (toPrint)
|
||||
@ -9360,6 +9394,7 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
|
||||
"\n '-fsaa on|off' Enables/disables adaptive anti-aliasing"
|
||||
"\n '-gleam on|off' Enables/disables transparency shadow 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 '-shadingModel model' Controls shading model from enumeration"
|
||||
"\n color, flat, gouraud, phong"
|
||||
|
Loading…
x
Reference in New Issue
Block a user