IsAntialiasingEnabled (Standard_False),
IsTransparentShadowEnabled (Standard_False),
UseEnvironmentMapBackground (Standard_False),
+ IsGIFilteringEnabled (Standard_False),
CoherentPathTracingMode (Standard_False),
StereoMode (Graphic3d_StereoMode_QuadBuffer),
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 IsGIFilteringEnabled; //!< enables/disables post-processing of GI rendering results
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
// sampled frame params
OpenGl_RT_uSampleWeight,
OpenGl_RT_uFrameRndSeed,
+ OpenGl_RT_BilateralFilteringEnabled,
// adaptive FSAA params
OpenGl_RT_uOffsetX,
theGlContext->BindProgram (myOutImageProgram);
+ myUniformLocations[0][OpenGl_RT_BilateralFilteringEnabled] =
+ myOutImageProgram->GetUniformLocation (theGlContext, "uBilateralEnabled");
+
myOutImageProgram->SetSampler (theGlContext,
"uInputTexture", OpenGl_RT_PrevAccumTexture);
if (myRaytraceParameters.GlobalIllumination)
{
- // 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);
+ 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));
+
+ theGlContext->core20fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
+ ++myAccumFrames;
+ glFinish();
+ }
+ }
+ }
+ else
+ {
+ theGlContext->core20fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
+ ++myAccumFrames;
+ }
if (myRaytraceParameters.GlobalIllumination)
{
aRenderFramebuffer->ColorTexture()->Bind (
theGlContext, GL_TEXTURE0 + OpenGl_RT_PrevAccumTexture);
+ myOutImageProgram->SetUniform (theGlContext,
+ myUniformLocations[0][OpenGl_RT_BilateralFilteringEnabled], theCView.RenderParams.IsGIFilteringEnabled ? 1 : 0);
+
theGlContext->core20fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
- ++myAccumFrames;
}
else if (theCView.RenderParams.IsAntialiasingEnabled)
{
//! Input image.
uniform sampler2D uInputTexture;
+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);
+ }
// apply gamma correction (we use gamma = 2)
OutColor = vec4 (sqrt (aColor.rgb), aColor.a);
-}
+}
\ No newline at end of file
theDI << "gleam: " << (aParams.IsTransparentShadowEnabled ? "on" : "off") << "\n";
theDI << "GI: " << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << "\n";
theDI << "blocked RNG: " << (aParams.CoherentPathTracingMode ? "on" : "off") << "\n";
+ theDI << "samples: " << aParams.SamplesPerPixel << "\n";
+ theDI << "filtering: " << (aParams.IsGIFilteringEnabled ? "on" : "off") << "\n";
theDI << "shadingModel: ";
switch (aView->ShadingModel())
{
aParams.RaytracingDepth = aDepth;
}
}
+ 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.CoherentPathTracingMode = toEnable;
}
+ 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 == "-env")
{
if (toPrint)