Samples per pixel parameter added. Simple filtering added. Lights fixed. Max radiance parameter.
IsTransparentShadowEnabled (Standard_False),
UseEnvironmentMapBackground (Standard_False),
CoherentPathTracingMode (Standard_False),
+ IsGIFilteringEnabled (Standard_False),
+ RadianceClampValue (10.0),
+
// stereoscopic parameters
StereoMode (Graphic3d_StereoMode_QuadBuffer),
AnaglyphFilter (Anaglyph_RedCyan_Optimized),
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)
+ Standard_Boolean IsGIFilteringEnabled; //!< enables/disables post-processing of GI rendering results
+ Standard_Real RadianceClampValue; //!< maximum radiance value which will not be clamped.
Graphic3d_StereoMode StereoMode; //!< stereoscopic output mode, Graphic3d_StereoMode_QuadBuffer by default
Anaglyph AnaglyphFilter; //!< filter for anaglyph output, Anaglyph_RedCyan_Optimized by default
OpenGl_RT_uSphereMapForBack,
OpenGl_RT_uTexSamplersArray,
OpenGl_RT_uBlockedRngEnabled,
+ OpenGl_RT_uMaxRadiance,
// sampled frame params
OpenGl_RT_uSampleWeight,
OpenGl_RT_uFrameRndSeed,
+ OpenGl_RT_uBilateralEnabled,
// adaptive FSAA params
OpenGl_RT_uOffsetX,
aShaderProgram->GetUniformLocation (theGlContext, "uSampleWeight");
myUniformLocations[anIndex][OpenGl_RT_uFrameRndSeed] =
aShaderProgram->GetUniformLocation (theGlContext, "uFrameRndSeed");
+ myUniformLocations[anIndex][OpenGl_RT_uMaxRadiance] =
+ aShaderProgram->GetUniformLocation (theGlContext, "uMaxRadiance");
myUniformLocations[anIndex][OpenGl_RT_uBackColorTop] =
aShaderProgram->GetUniformLocation (theGlContext, "uBackColorTop");
theGlContext->BindProgram (myOutImageProgram);
+ myUniformLocations[0][OpenGl_RT_uBilateralEnabled] =
+ myOutImageProgram->GetUniformLocation (theGlContext, "uBilateralEnabled");
+
myOutImageProgram->SetSampler (theGlContext,
"uInputTexture", OpenGl_RT_PrevAccumTexture);
// Set frame accumulation weight
myRaytraceProgram->SetUniform (theGlContext,
- myUniformLocations[0][OpenGl_RT_uSampleWeight], 1.f / (myAccumFrames + 1));
+ myUniformLocations[0][OpenGl_RT_uMaxRadiance], static_cast<Standard_ShortReal> (theCView.RenderParams.RadianceClampValue));
// Set random number generator seed
myRaytraceProgram->SetUniform (theGlContext,
myUniformLocations[0][OpenGl_RT_uFrameRndSeed], static_cast<Standard_Integer> (myRNG.NextInt() >> 2));
- }
- theGlContext->core20fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
+ Standard_Integer aSamplesPerPixel = theCView.RenderParams.SamplesPerPixel;
+
+ if (aSamplesPerPixel == 0)
+ {
+ // Set frame accumulation weight
+ myRaytraceProgram->SetUniform (theGlContext,
+ myUniformLocations[0][OpenGl_RT_uSampleWeight], 1.f / (myAccumFrames + 1));
+
+ theGlContext->core20fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
+ }
+ else
+ {
+ for (int aPassIndex = 0; aPassIndex < aSamplesPerPixel; ++aPassIndex)
+ {
+ aRenderFramebuffer = myAccumFrames % 2 ? myRaytraceFBO1 : myRaytraceFBO2;
+ anAccumFramebuffer = myAccumFrames % 2 ? myRaytraceFBO2 : myRaytraceFBO1;
+
+ aRenderFramebuffer->BindBuffer (theGlContext);
+
+ anAccumFramebuffer->ColorTexture()->Bind (
+ theGlContext, GL_TEXTURE0 + OpenGl_RT_PrevAccumTexture);
+
+ // Set frame accumulation weight
+ myRaytraceProgram->SetUniform (theGlContext,
+ myUniformLocations[0][OpenGl_RT_uSampleWeight], 1.f / (myAccumFrames + 1));
+
+ // Set random number generator seed
+ myRaytraceProgram->SetUniform (theGlContext,
+ myUniformLocations[0][OpenGl_RT_uFrameRndSeed], static_cast<Standard_Integer> (myRNG.NextInt() >> 2));
+
+ theGlContext->core20fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
+ ++myAccumFrames;
+ glFinish();
+ }
+ }
+ }
+ else
+ {
+ theGlContext->core20fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
+ ++myAccumFrames;
+ }
if (myRaytraceParameters.GlobalIllumination)
{
aRenderFramebuffer->DepthStencilTexture()->Bind (
theGlContext, GL_TEXTURE0 + OpenGl_RT_DepthTexture);
+ myOutImageProgram->SetUniform (theGlContext,
+ myUniformLocations[0][OpenGl_RT_uBilateralEnabled], theCView.RenderParams.IsGIFilteringEnabled ? 1 : 0);
+
theGlContext->core20fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
aRenderFramebuffer->DepthStencilTexture()->Unbind (
//! Ray tracing depth image.
uniform sampler2D uDepthTexture;
+uniform int uBilateralEnabled;
+
//! Output pixel color.
out vec4 OutColor;
+const float rI = 0.270 * 1.0f; // The intensity radius (in pixels).
+const float rL = 1.71 * 0.5f; // The geometric radius (in pixels).
+const int WindowSize = 8; // The window size (in pixels).
+
+float gaussian (float theL, float theR)
+{
+ return exp (-theL * theL / (2.0f * theR * theR));
+}
+
+vec4 bilateral()
+{
+ // Get the sizes
+ int aWindow = WindowSize / 2;
+ vec4 anOutCol = vec4 (0.f, 0.f, 0.f, 0.f);
+ vec4 aRefCol = texelFetch (uInputTexture, ivec2 (gl_FragCoord.xy), 0);
+ float aNorm = 0.f;
+
+ // Compute the kernel
+ for (int i = -aWindow; i <= aWindow; i++)
+ {
+ for (int j = -aWindow; j <= aWindow; j++)
+ {
+ vec4 aCol = texelFetch (uInputTexture, ivec2 (gl_FragCoord.xy) + ivec2 (j, i), 0);
+ float A = gaussian (distance (aCol, aRefCol), rI);
+ float B = gaussian (length (vec2(j, i)), rL);
+ anOutCol += aCol * A * B;
+ aNorm += A * B;
+ }
+ }
+ return anOutCol * (1.f / aNorm);
+}
+
void main (void)
{
- vec4 aColor = texelFetch (uInputTexture, ivec2 (gl_FragCoord.xy), 0);
+ vec4 aColor;
+
+ if (bool (uBilateralEnabled))
+ {
+ aColor = bilateral();
+ }
+ else
+ {
+ aColor = texelFetch (uInputTexture, ivec2 (gl_FragCoord.xy), 0);
+ }
float aDepth = texelFetch (uDepthTexture, ivec2 (gl_FragCoord.xy), 0).r;
gl_FragDepth = aDepth;
// apply gamma correction (we use gamma = 2)
OutColor = vec4 (sqrt (aColor.rgb), aColor.a);
-}
+}
\ No newline at end of file
theBounce = SPEC_REFLECT_BOUNCE; // specular bounce
}
- else // specular transmission
+ else if (aKsi < aReflection) // specular transmission\r
{
theWeight *= theMaterial.Kt.rgb * (aReflection / aPt) *
sampleSpecularTransmission (theOutput, theInput, theBounce, theWeight, theMaterial.Fresnel);
//=======================================================================
float handlePointLight (in vec3 theInput, in vec3 theToLight, in float theRadius, in float theDistance)
{
- float aDistance = dot (theToLight, theToLight);
+ float aSquareLightDist = dot (theToLight, theToLight);\r
- float aCosMax = inversesqrt (1.f + theRadius * theRadius / aDistance);
+ float aCosMax = inversesqrt (1.f + theRadius * theRadius / aSquareLightDist);\r
- return float (aDistance < theDistance * theDistance) *
- step (aCosMax, dot (theToLight, theInput) * inversesqrt (aDistance));
+ return float (aSquareLightDist < theDistance * theDistance) *\r
+ step (aCosMax, dot (theToLight, theInput) * inversesqrt (aSquareLightDist));\r
}
//=======================================================================
// function : sampleLight
// purpose : general sampling function for directional and point lights
//=======================================================================
-vec3 sampleLight (in vec3 theToLight, in bool isDirectional, in float theSmoothness, inout float thePDF)
+vec3 sampleLight (in vec3 theToLight, in float theDistance, in bool isDirectional, in float theSmoothness, inout float thePDF)\r
{
SLocalSpace aSpace = LocalSpace (theToLight);
// for point lights smoothness defines radius
- float aCosMax = isDirectional ? theSmoothness :
- inversesqrt (1.f + theSmoothness * theSmoothness / dot (theToLight, theToLight));
+ float aCosMax = inversesqrt (1.f + theSmoothness * theSmoothness / (theDistance * theDistance));\r
float aKsi1 = RandFloat();
float aKsi2 = RandFloat();
return aRadiance;
}
-#define MIN_THROUGHPUT vec3 (0.02f)
-#define MIN_CONTRIBUTION vec3 (0.01f)
+#define MIN_THROUGHPUT vec3 (2.0e-2f)\r
+#define MIN_CONTRIBUTION vec3 (0.5e-2f)\r
#define MATERIAL_KD(index) (18 * index + 11)
#define MATERIAL_KR(index) (18 * index + 12)
float aPDF = 1.f / uLightCount, aDistance = length (aLight.xyz);
- aLight.xyz = sampleLight (aLight.xyz * (1.f / aDistance),
+ aLight.xyz = sampleLight (aLight.xyz * (1.f / aDistance), aDistance,\r
aLight.w == 0.f /* is infinite */, aParam.w /* angle cosine */, aPDF);
vec3 aContrib = (1.f / aPDF) * aParam.rgb /* Le */ * handleMaterial (
//! Increases performance up to 4 times, but noise becomes structured.
uniform int uBlockedRngEnabled;
-#define MAX_RADIANCE vec3 (10.f)
+//! Maximum value for radiance clamping.
+uniform float uMaxRadiance;
// =======================================================================
// function : main
aColor.rgb = ZERO;
}
- aColor.rgb = min (aColor.rgb, MAX_RADIANCE);
+ aColor.rgb = min (aColor.rgb, vec3 (uMaxRadiance));
OutColor = mix (texture2D (uAccumTexture, vPixel), aColor, uSampleWeight);
#else
theDI << "reflections: " << (aParams.IsReflectionEnabled ? "on" : "off") << "\n";
theDI << "gleam: " << (aParams.IsTransparentShadowEnabled ? "on" : "off") << "\n";
theDI << "GI: " << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << "\n";
+ theDI << "samples: " << aParams.SamplesPerPixel << "\n";
+ theDI << "filtering: " << (aParams.IsGIFilteringEnabled ? "on" : "off") << "\n";
theDI << "blocked RNG: " << (aParams.CoherentPathTracingMode ? "on" : "off") << "\n";
theDI << "shadingModel: ";
switch (aView->ShadingModel())
aParams.RaytracingDepth = aDepth;
}
}
+ else if (aFlag == "-maxrad"
+ || aFlag == "-rclamp")
+ {
+ if (toPrint)
+ {
+ theDI << aParams.RadianceClampValue << " ";
+ continue;
+ }
+ else if (++anArgIter >= theArgNb)
+ {
+ std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
+ return 1;
+ }
+
+ aParams.RadianceClampValue = Draw::Atoi (theArgVec[anArgIter]);
+ }
+ else if (aFlag == "-samples"
+ || aFlag == "-spp")
+ {
+ if (toPrint)
+ {
+ theDI << aParams.SamplesPerPixel << " ";
+ continue;
+ }
+ else if (++anArgIter >= theArgNb)
+ {
+ std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
+ return 1;
+ }
+
+ const Standard_Integer aSamples = Draw::Atoi (theArgVec[anArgIter]);
+
+ if (aSamples < 0)
+ {
+ std::cerr << "Error: invalid ray-tracing samples per pixel " << aSamples << ". SPP should be a positive number.\n";
+ return 1;
+ }
+ else
+ {
+ aParams.SamplesPerPixel = aSamples;
+ }
+ }
else if (aFlag == "-shad"
|| aFlag == "-shadows")
{
aParams.RaytracingDepth = Min (aParams.RaytracingDepth, 10);
}
}
+ else if (aFlag == "-filter" || aFlag == "-pp" )
+ {
+ if (toPrint)
+ {
+ theDI << (aParams.IsGIFilteringEnabled ? "on" : "off") << " ";
+ continue;
+ }
+
+ Standard_Boolean toEnable = Standard_True;
+ if (++anArgIter < theArgNb
+ && !parseOnOff (theArgVec[anArgIter], toEnable))
+ {
+ --anArgIter;
+ }
+ aParams.IsGIFilteringEnabled = toEnable;
+ }
else if (aFlag == "-blockedrng"
|| aFlag == "-brng")
{
--- /dev/null
+puts "========"
+puts "Ray Tracing - check PT lights correctness"
+puts "========"
+
+pload ALL
+vinit
+vsetdispmode 1
+vvbo 0
+
+box b 500 500 1
+box b1 2 50 20
+
+vdisplay b
+vdisplay b1
+
+vsetlocation b -250 -250 0
+vsetlocation b1 -1 -25 0
+
+vlight del 0
+vlight del 0
+
+vlight add positional head 0 pos -10 0 20
+vlight change 0 sm 5.0
+
+vrenderparams -ray -gi
+vsetmaterial b plaster
+vsetmaterial b1 plaster
+
+vviewparams -scale 23.40302443511418 -proj 3.1690307533723025e-006 -0.053740375441171516 0.99855494192227556 -up 0.00011815109169240122 0.99855493498157033 0.05374037461975216 -at -0.039728087058276865 17.658749465576971 0.40052090530867673 -eye -0.038141096586915293 -9.2534108729671232 500.45788900604856
+
+vlight change 0 int 20
+
+psphere s 5.0
+vdisplay s
+vsetlocation s 10 0 20
+
+vbsdf s -Kd 0.0 -Ks 0.0 -Kr 0.0 -Kt 0.0
+vbsdf s -Le 20.0
+
+vfps 500
--- /dev/null
+puts "========"
+puts "Ray Tracing - check PT lights correctness"
+puts "========"
+
+pload ALL
+vinit
+vsetdispmode 1
+vvbo 0
+
+box b 500 500 1
+psphere s 6.0
+
+vdisplay b
+vdisplay s
+
+vsetlocation b -250 -250 0
+vsetlocation s 0.0 0.0 7.0
+
+vlight del 0
+vlight del 0
+
+vlight add positional head 0 pos -15 0 20 sm 4.0 int 20
+
+vrenderparams -ray -gi -rayDepth 12
+vsetmaterial b plaster
+vsetmaterial s glass
+
+psphere ls 4.0
+vdisplay ls
+vsetlocation ls 15 0 20
+
+vbsdf ls -Kd 0.0 -Ks 0.0 -Kr 0.0 -Kt 0.0
+vbsdf ls -Le 20.0
+
+vviewparams -scale 23.40302443511418 -proj 3.1690307533720754e-006 -0.053740375441171412 0.99855494192227556 -up 0.00011815108764545944 0.99855493500381731 0.053740374206389462 -at 0.062905867278332972 2.1147318213590474 -0.43602962811169049 -eye 0.064492857749694432 -24.79742851718504 499.62133847262908
+
+vfps 400