mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
0026432: Improving Path Tracing functionality
Samples per pixel parameter added. Simple filtering added. Lights fixed. Max radiance parameter. Conflicts: src/OpenGl/OpenGl_View_Raytrace.cxx src/Shaders/PathtraceBase.fs
This commit is contained in:
@@ -59,6 +59,8 @@ public:
|
||||
IsTransparentShadowEnabled (Standard_False),
|
||||
UseEnvironmentMapBackground (Standard_False),
|
||||
CoherentPathTracingMode (Standard_False),
|
||||
IsGIFilteringEnabled (Standard_False),
|
||||
RadianceClampValue (10.0),
|
||||
|
||||
StereoMode (Graphic3d_StereoMode_QuadBuffer),
|
||||
AnaglyphFilter (Anaglyph_RedCyan_Optimized),
|
||||
@@ -90,6 +92,8 @@ public:
|
||||
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
|
||||
|
@@ -667,10 +667,12 @@ protected: //! @name data types related to ray-tracing
|
||||
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,
|
||||
|
@@ -1566,6 +1566,8 @@ Standard_Boolean OpenGl_View::initRaytraceResources (const Handle(OpenGl_Context
|
||||
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");
|
||||
@@ -1575,6 +1577,9 @@ Standard_Boolean OpenGl_View::initRaytraceResources (const Handle(OpenGl_Context
|
||||
|
||||
theGlContext->BindProgram (myOutImageProgram);
|
||||
|
||||
myUniformLocations[0][OpenGl_RT_uBilateralEnabled] =
|
||||
myOutImageProgram->GetUniformLocation (theGlContext, "uBilateralEnabled");
|
||||
|
||||
myOutImageProgram->SetSampler (theGlContext,
|
||||
"uInputTexture", OpenGl_RT_PrevAccumTexture);
|
||||
|
||||
@@ -2421,14 +2426,53 @@ Standard_Boolean OpenGl_View::runRaytraceShaders (const Standard_Integer
|
||||
|
||||
// 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)
|
||||
{
|
||||
@@ -2449,6 +2493,9 @@ Standard_Boolean OpenGl_View::runRaytraceShaders (const Standard_Integer
|
||||
aRenderFramebuffer->ColorTexture()->Bind (
|
||||
theGlContext, GL_TEXTURE0 + OpenGl_RT_PrevAccumTexture);
|
||||
|
||||
myOutImageProgram->SetUniform (theGlContext,
|
||||
myUniformLocations[0][OpenGl_RT_uBilateralEnabled], theCView.RenderParams.IsGIFilteringEnabled ? 1 : 0);
|
||||
|
||||
theGlContext->core20fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
|
||||
}
|
||||
else if (myRenderParams.IsAntialiasingEnabled)
|
||||
|
@@ -1,13 +1,56 @@
|
||||
//! 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);
|
||||
}
|
||||
}
|
@@ -473,7 +473,7 @@ void sampleMaterial (in SMaterial theMaterial,
|
||||
|
||||
theBounce = SPEC_REFLECT_BOUNCE; // specular bounce
|
||||
}
|
||||
else // specular transmission
|
||||
else if (aKsi < aReflection) // specular transmission
|
||||
{
|
||||
theWeight *= theMaterial.Kt.rgb * (aReflection / aPt) *
|
||||
sampleSpecularTransmission (theOutput, theInput, theBounce, theWeight, theMaterial.Fresnel);
|
||||
@@ -493,12 +493,12 @@ void sampleMaterial (in SMaterial theMaterial,
|
||||
//=======================================================================
|
||||
float handlePointLight (in vec3 theInput, in vec3 theToLight, in float theRadius, in float theDistance)
|
||||
{
|
||||
float aDistance = dot (theToLight, theToLight);
|
||||
float aSquareLightDist = dot (theToLight, theToLight);
|
||||
|
||||
float aCosMax = inversesqrt (1.f + theRadius * theRadius / aDistance);
|
||||
float aCosMax = inversesqrt (1.f + theRadius * theRadius / aSquareLightDist);
|
||||
|
||||
return float (aDistance < theDistance * theDistance) *
|
||||
step (aCosMax, dot (theToLight, theInput) * inversesqrt (aDistance));
|
||||
return float (aSquareLightDist < theDistance * theDistance) *
|
||||
step (aCosMax, dot (theToLight, theInput) * inversesqrt (aSquareLightDist));
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -514,13 +514,12 @@ float handleDirectLight (in vec3 theInput, in vec3 theToLight, in float theCosMa
|
||||
// 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)
|
||||
{
|
||||
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));
|
||||
|
||||
float aKsi1 = RandFloat();
|
||||
float aKsi2 = RandFloat();
|
||||
@@ -593,8 +592,8 @@ vec3 intersectLight (in SRay theRay, in bool isViewRay, in int theBounce, in flo
|
||||
return aRadiance;
|
||||
}
|
||||
|
||||
#define MIN_THROUGHPUT vec3 (0.02f)
|
||||
#define MIN_CONTRIBUTION vec3 (0.01f)
|
||||
#define MIN_THROUGHPUT vec3 (2.0e-2f)
|
||||
#define MIN_CONTRIBUTION vec3 (0.5e-2f)
|
||||
|
||||
#define MATERIAL_KD(index) (18 * index + 11)
|
||||
#define MATERIAL_KR(index) (18 * index + 12)
|
||||
@@ -720,7 +719,7 @@ vec4 PathTrace (in SRay theRay, in vec3 theInverse)
|
||||
|
||||
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,
|
||||
aLight.w == 0.f /* is infinite */, aParam.w /* angle cosine */, aPDF);
|
||||
|
||||
vec3 aContrib = (1.f / aPDF) * aParam.rgb /* Le */ * handleMaterial (
|
||||
|
@@ -13,7 +13,8 @@ uniform sampler2D uAccumTexture;
|
||||
//! 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
|
||||
@@ -46,7 +47,7 @@ void main (void)
|
||||
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
|
||||
|
@@ -8273,6 +8273,8 @@ 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 << "samples: " << aParams.SamplesPerPixel << "\n";
|
||||
theDI << "filtering: " << (aParams.IsGIFilteringEnabled ? "on" : "off") << "\n";
|
||||
theDI << "blocked RNG: " << (aParams.CoherentPathTracingMode ? "on" : "off") << "\n";
|
||||
theDI << "shadingModel: ";
|
||||
switch (aView->ShadingModel())
|
||||
@@ -8372,6 +8374,48 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
|
||||
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")
|
||||
{
|
||||
@@ -8458,6 +8502,22 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
|
||||
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")
|
||||
{
|
||||
|
40
tests/v3d/raytrace/2_light_box
Normal file
40
tests/v3d/raytrace/2_light_box
Normal file
@@ -0,0 +1,40 @@
|
||||
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
|
37
tests/v3d/raytrace/2_light_sphere
Normal file
37
tests/v3d/raytrace/2_light_sphere
Normal file
@@ -0,0 +1,37 @@
|
||||
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
|
Reference in New Issue
Block a user