1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-03 17:56:21 +03:00

0031196: Visualization, TKOpenGl - enable Ray-Tracing using OpenGL ES 3.2

OpenGl_Context now activates Ray-Tracing and arbTboRGB32 for GLES 3.2.
Removed initialization of some uniforms from GLSL code.
Fixed implicit casts within Ray-Tracing shaders.
This commit is contained in:
kgv 2021-02-20 15:01:16 +03:00 committed by bugmaster
parent 127330f9d7
commit 93cdaa76da
16 changed files with 133 additions and 161 deletions

View File

@ -391,7 +391,7 @@ Ray tracing requires OpenGL 4.0+ or OpenGL 3.3+ with *GL_ARB_texture_buffer_obje
Textures within ray tracing will be available only when *GL_ARB_bindless_texture extension* is provided by driver.
On mobile platforms, OpenGL ES 2.0+ is required for 3D viewer (OpenGL ES 3.1+ is recommended).
The ray tracing is not yet available on mobile platforms.
Ray tracing requires OpenGL ES 3.2.
Some old hardware might be unable to execute complex GLSL programs (e.g. with high number of light sources, clipping planes).
OCCT 3D Viewer, in general, supports wide range of graphics hardware - from very old to new.

View File

@ -1619,7 +1619,13 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
// get number of maximum clipping planes
glGetIntegerv (GL_MAX_CLIP_PLANES, &myMaxClipPlanes);
#endif
#if defined(GL_ES_VERSION_2_0)
// check whether ray tracing mode is supported
myHasRayTracing = IsGlGreaterEqual (3, 2);
myHasRayTracingTextures = myHasRayTracingAdaptiveSampling = myHasRayTracingAdaptiveSamplingAtomic = false;
#else
// check whether ray tracing mode is supported
myHasRayTracing = IsGlGreaterEqual (3, 1)
&& arbTboRGB32

View File

@ -1103,7 +1103,7 @@ public: //! @name extensions
OpenGl_ArbSamplerObject* arbSamplerObject; //!< GL_ARB_sampler_objects (on desktop OpenGL - since 3.3 or as extension GL_ARB_sampler_objects; on OpenGL ES - since 3.0)
OpenGl_ArbTexBindless* arbTexBindless; //!< GL_ARB_bindless_texture
OpenGl_ArbTBO* arbTBO; //!< GL_ARB_texture_buffer_object (on desktop OpenGL - since 3.1 or as extension GL_ARB_texture_buffer_object; on OpenGL ES - since 3.2)
Standard_Boolean arbTboRGB32; //!< GL_ARB_texture_buffer_object_rgb32 (3-component TBO), in core since 4.0
Standard_Boolean arbTboRGB32; //!< GL_ARB_texture_buffer_object_rgb32 (3-component TBO), in core since 4.0 (on OpenGL ES - since 3.2)
OpenGl_ArbIns* arbIns; //!< GL_ARB_draw_instanced (on desktop OpenGL - since 3.1 or as extension GL_ARB_draw_instanced; on OpenGL ES - since 3.0 or as extension GL_ANGLE_instanced_arrays to WebGL 1.0)
OpenGl_ArbDbg* arbDbg; //!< GL_ARB_debug_output (on desktop OpenGL - since 4.3 or as extension GL_ARB_debug_output; on OpenGL ES - since 3.2 or as extension GL_KHR_debug)
OpenGl_ArbFBO* arbFBO; //!< GL_ARB_framebuffer_object

View File

@ -440,6 +440,7 @@ void OpenGl_GlFunctions::load (OpenGl_Context& theCtx,
theCtx.checkWrongVersion (3, 2, aLastFailedProc);
}
theCtx.arbTboRGB32 = isGlGreaterEqualShort (3, 2); // OpenGL ES 3.2 introduces TBO already supporting RGB32 format
theCtx.extDrawBuffers = checkExtensionShort ("GL_EXT_draw_buffers") && theCtx.FindProc ("glDrawBuffersEXT", this->glDrawBuffers);
theCtx.arbDrawBuffers = checkExtensionShort ("GL_ARB_draw_buffers") && theCtx.FindProc ("glDrawBuffersARB", this->glDrawBuffers);

View File

@ -660,8 +660,7 @@ protected: //! @name data types related to ray-tracing
OpenGl_RT_uFrameRndSeed,
// adaptive FSAA params
OpenGl_RT_uOffsetX,
OpenGl_RT_uOffsetY,
OpenGl_RT_uFsaaOffset,
OpenGl_RT_uSamples,
// images used by ISS mode
@ -721,7 +720,8 @@ protected: //! @name data types related to ray-tracing
}
//! Returns shader source combined with prefix.
TCollection_AsciiString Source() const;
TCollection_AsciiString Source (const Handle(OpenGl_Context)& theCtx,
const GLenum theType) const;
//! Loads shader source from specified files.
Standard_Boolean LoadFromFiles (const TCollection_AsciiString* theFileNames, const TCollection_AsciiString& thePrefix = EMPTY_PREFIX);

View File

@ -1023,16 +1023,37 @@ const TCollection_AsciiString OpenGl_View::ShaderSource::EMPTY_PREFIX;
// function : Source
// purpose : Returns shader source combined with prefix
// =======================================================================
TCollection_AsciiString OpenGl_View::ShaderSource::Source() const
TCollection_AsciiString OpenGl_View::ShaderSource::Source (const Handle(OpenGl_Context)& theCtx,
const GLenum theType) const
{
const TCollection_AsciiString aVersion = "#version 140";
TCollection_AsciiString aVersion =
#if defined(GL_ES_VERSION_2_0)
"#version 320 es\n";
#else
"#version 140\n";
#endif
TCollection_AsciiString aPrecisionHeader;
if (theType == GL_FRAGMENT_SHADER)
{
#if defined(GL_ES_VERSION_2_0)
aPrecisionHeader = theCtx->hasHighp
? "precision highp float;\n"
"precision highp int;\n"
"precision highp samplerBuffer;\n"
"precision highp isamplerBuffer;\n"
: "precision mediump float;\n"
"precision mediump int;\n"
"precision mediump samplerBuffer;\n"
"precision mediump isamplerBuffer;\n";
#else
(void )theCtx;
#endif
}
if (myPrefix.IsEmpty())
{
return aVersion + "\n" + mySource;
return aVersion + aPrecisionHeader + mySource;
}
return aVersion + "\n" + myPrefix + "\n" + mySource;
return aVersion + aPrecisionHeader + myPrefix + "\n" + mySource;
}
// =======================================================================
@ -1220,7 +1241,7 @@ Handle(OpenGl_ShaderObject) OpenGl_View::initShader (const GLenum
return Handle(OpenGl_ShaderObject)();
}
if (!aShader->LoadAndCompile (theGlContext, "", theSource.Source()))
if (!aShader->LoadAndCompile (theGlContext, "", theSource.Source (theGlContext, theType)))
{
aShader->Release (theGlContext.get());
return Handle(OpenGl_ShaderObject)();
@ -1416,18 +1437,15 @@ Standard_Boolean OpenGl_View::initRaytraceResources (const Standard_Integer theS
myToUpdateEnvironmentMap = Standard_True;
const TCollection_AsciiString aPrefixString = generateShaderPrefix (theGlContext);
#ifdef RAY_TRACE_PRINT_INFO
std::cout << "GLSL prefix string:" << std::endl << aPrefixString << std::endl;
Message::SendTrace() << "GLSL prefix string:" << std::endl << aPrefixString;
#endif
myRaytraceShaderSource.SetPrefix (aPrefixString);
myPostFSAAShaderSource.SetPrefix (aPrefixString);
myOutImageShaderSource.SetPrefix (aPrefixString);
if (!myRaytraceShader->LoadAndCompile (theGlContext, myRaytraceProgram->ResourceId(), myRaytraceShaderSource.Source())
|| !myPostFSAAShader->LoadAndCompile (theGlContext, myPostFSAAProgram->ResourceId(), myPostFSAAShaderSource.Source())
|| !myOutImageShader->LoadAndCompile (theGlContext, myOutImageProgram->ResourceId(), myOutImageShaderSource.Source()))
if (!myRaytraceShader->LoadAndCompile (theGlContext, myRaytraceProgram->ResourceId(), myRaytraceShaderSource.Source (theGlContext, GL_FRAGMENT_SHADER))
|| !myPostFSAAShader->LoadAndCompile (theGlContext, myPostFSAAProgram->ResourceId(), myPostFSAAShaderSource.Source (theGlContext, GL_FRAGMENT_SHADER))
|| !myOutImageShader->LoadAndCompile (theGlContext, myOutImageProgram->ResourceId(), myOutImageShaderSource.Source (theGlContext, GL_FRAGMENT_SHADER)))
{
return safeFailBack ("Failed to compile ray-tracing fragment shaders", theGlContext);
}
@ -1435,7 +1453,6 @@ Standard_Boolean OpenGl_View::initRaytraceResources (const Standard_Integer theS
myRaytraceProgram->SetAttributeName (theGlContext, Graphic3d_TOA_POS, "occVertex");
myPostFSAAProgram->SetAttributeName (theGlContext, Graphic3d_TOA_POS, "occVertex");
myOutImageProgram->SetAttributeName (theGlContext, Graphic3d_TOA_POS, "occVertex");
if (!myRaytraceProgram->Link (theGlContext)
|| !myPostFSAAProgram->Link (theGlContext)
|| !myOutImageProgram->Link (theGlContext))
@ -1449,6 +1466,12 @@ Standard_Boolean OpenGl_View::initRaytraceResources (const Standard_Integer theS
{
myAccumFrames = 0; // accumulation should be restarted
#if defined(GL_ES_VERSION_2_0)
if (!theGlContext->IsGlGreaterEqual (3, 2))
{
return safeFailBack ("Ray-tracing requires OpenGL ES 3.2 and higher", theGlContext);
}
#else
if (!theGlContext->IsGlGreaterEqual (3, 1))
{
return safeFailBack ("Ray-tracing requires OpenGL 3.1 and higher", theGlContext);
@ -1461,6 +1484,7 @@ Standard_Boolean OpenGl_View::initRaytraceResources (const Standard_Integer theS
{
return safeFailBack ("Ray-tracing requires EXT_framebuffer_blit extension", theGlContext);
}
#endif
myRaytraceParameters.NbBounces = myRenderParams.RaytracingDepth;
@ -1474,7 +1498,7 @@ Standard_Boolean OpenGl_View::initRaytraceResources (const Standard_Integer theS
const TCollection_AsciiString aPrefixString = generateShaderPrefix (theGlContext);
#ifdef RAY_TRACE_PRINT_INFO
std::cout << "GLSL prefix string:" << std::endl << aPrefixString << std::endl;
Message::SendTrace() << "GLSL prefix string:" << std::endl << aPrefixString;
#endif
ShaderSource aBasicVertShaderSrc;
@ -1684,10 +1708,8 @@ Standard_Boolean OpenGl_View::initRaytraceResources (const Standard_Integer theS
myUniformLocations[anIndex][OpenGl_RT_uLightAmbnt] =
aShaderProgram->GetUniformLocation (theGlContext, "uGlobalAmbient");
myUniformLocations[anIndex][OpenGl_RT_uOffsetX] =
aShaderProgram->GetUniformLocation (theGlContext, "uOffsetX");
myUniformLocations[anIndex][OpenGl_RT_uOffsetY] =
aShaderProgram->GetUniformLocation (theGlContext, "uOffsetY");
myUniformLocations[anIndex][OpenGl_RT_uFsaaOffset] =
aShaderProgram->GetUniformLocation (theGlContext, "uFsaaOffset");
myUniformLocations[anIndex][OpenGl_RT_uSamples] =
aShaderProgram->GetUniformLocation (theGlContext, "uSamples");
@ -2083,13 +2105,19 @@ void OpenGl_View::updatePerspCameraPT (const OpenGl_Mat4& theOrientati
// =======================================================================
Standard_Boolean OpenGl_View::uploadRaytraceData (const Handle(OpenGl_Context)& theGlContext)
{
if (!theGlContext->IsGlGreaterEqual (3, 1))
#if defined(GL_ES_VERSION_2_0)
if (!theGlContext->IsGlGreaterEqual (3, 2))
{
#ifdef RAY_TRACE_PRINT_INFO
std::cout << "Error: OpenGL version is less than 3.1" << std::endl;
#endif
Message::SendFail() << "Error: OpenGL ES version is less than 3.2";
return Standard_False;
}
#else
if (!theGlContext->IsGlGreaterEqual (3, 1))
{
Message::SendFail() << "Error: OpenGL version is less than 3.1";
return Standard_False;
}
#endif
myAccumFrames = 0; // accumulation should be restarted
@ -2102,9 +2130,7 @@ Standard_Boolean OpenGl_View::uploadRaytraceData (const Handle(OpenGl_Context)&
// to get unique 64- bit handles for using on the GPU
if (!myRaytraceGeometry.UpdateTextureHandles (theGlContext))
{
#ifdef RAY_TRACE_PRINT_INFO
std::cout << "Error: Failed to get OpenGL texture handles" << std::endl;
#endif
Message::SendTrace() << "Error: Failed to get OpenGL texture handles";
return Standard_False;
}
}
@ -2124,9 +2150,7 @@ Standard_Boolean OpenGl_View::uploadRaytraceData (const Handle(OpenGl_Context)&
|| !mySceneMaxPointTexture->Create (theGlContext)
|| !mySceneTransformTexture->Create (theGlContext))
{
#ifdef RAY_TRACE_PRINT_INFO
std::cout << "Error: Failed to create scene BVH buffers" << std::endl;
#endif
Message::SendTrace() << "Error: Failed to create scene BVH buffers";
return Standard_False;
}
}
@ -2143,22 +2167,17 @@ Standard_Boolean OpenGl_View::uploadRaytraceData (const Handle(OpenGl_Context)&
|| !myGeometryTexCrdTexture->Create (theGlContext)
|| !myGeometryTriangTexture->Create (theGlContext))
{
#ifdef RAY_TRACE_PRINT_INFO
std::cout << "Error: Failed to create buffers for triangulation data" << std::endl;
#endif
Message::SendTrace() << "\nError: Failed to create buffers for triangulation data";
return Standard_False;
}
}
if (myRaytraceMaterialTexture.IsNull()) // create material buffer
{
myRaytraceMaterialTexture = new OpenGl_TextureBufferArb;
myRaytraceMaterialTexture = new OpenGl_TextureBufferArb();
if (!myRaytraceMaterialTexture->Create (theGlContext))
{
#ifdef RAY_TRACE_PRINT_INFO
std::cout << "Error: Failed to create buffers for material data" << std::endl;
#endif
Message::SendTrace() << "Error: Failed to create buffers for material data";
return Standard_False;
}
}
@ -2225,9 +2244,7 @@ Standard_Boolean OpenGl_View::uploadRaytraceData (const Handle(OpenGl_Context)&
if (!aResult)
{
#ifdef RAY_TRACE_PRINT_INFO
std::cout << "Error: Failed to upload buffers for bottom-level scene BVH" << std::endl;
#endif
Message::SendTrace() << "Error: Failed to upload buffers for bottom-level scene BVH";
return Standard_False;
}
@ -2249,9 +2266,7 @@ Standard_Boolean OpenGl_View::uploadRaytraceData (const Handle(OpenGl_Context)&
if (!aResult)
{
#ifdef RAY_TRACE_PRINT_INFO
std::cout << "Error: Failed to upload buffers for scene geometry" << std::endl;
#endif
Message::SendTrace() << "Error: Failed to upload buffers for scene geometry";
return Standard_False;
}
@ -2295,9 +2310,7 @@ Standard_Boolean OpenGl_View::uploadRaytraceData (const Handle(OpenGl_Context)&
if (!aResult)
{
#ifdef RAY_TRACE_PRINT_INFO
std::cout << "Error: Failed to upload buffers for bottom-level scene BVHs" << std::endl;
#endif
Message::SendTrace() << "Error: Failed to upload buffers for bottom-level scene BVHs";
return Standard_False;
}
}
@ -2330,9 +2343,7 @@ Standard_Boolean OpenGl_View::uploadRaytraceData (const Handle(OpenGl_Context)&
if (!aResult)
{
#ifdef RAY_TRACE_PRINT_INFO
std::cout << "Error: Failed to upload triangulation buffers for OpenGL element" << std::endl;
#endif
Message::SendTrace() << "Error: Failed to upload triangulation buffers for OpenGL element";
return Standard_False;
}
}
@ -2347,9 +2358,7 @@ Standard_Boolean OpenGl_View::uploadRaytraceData (const Handle(OpenGl_Context)&
if (!aResult)
{
#ifdef RAY_TRACE_PRINT_INFO
std::cout << "Error: Failed to upload material buffer" << std::endl;
#endif
Message::SendTrace() << "Error: Failed to upload material buffer";
return Standard_False;
}
}
@ -2506,9 +2515,7 @@ Standard_Boolean OpenGl_View::updateRaytraceLightSources (const OpenGl_Mat4& the
const GLfloat* aDataPtr = myRaytraceGeometry.Sources.front().Packed();
if (!myRaytraceLightSrcTexture->Init (theGlContext, 4, GLsizei (myRaytraceGeometry.Sources.size() * 2), aDataPtr))
{
#ifdef RAY_TRACE_PRINT_INFO
std::cout << "Error: Failed to upload light source buffer" << std::endl;
#endif
Message::SendTrace() << "Error: Failed to upload light source buffer";
return Standard_False;
}
@ -2866,31 +2873,27 @@ Standard_Boolean OpenGl_View::runRaytrace (const Standard_Integer theSize
// available from initial ray-traced image).
for (Standard_Integer anIt = 1; anIt < 4; ++anIt)
{
GLfloat aOffsetX = 1.f / theSizeX;
GLfloat aOffsetY = 1.f / theSizeY;
OpenGl_Vec2 aFsaaOffset (1.f / theSizeX, 1.f / theSizeY);
if (anIt == 1)
{
aOffsetX *= -0.55f;
aOffsetY *= 0.55f;
aFsaaOffset.x() *= -0.55f;
aFsaaOffset.y() *= 0.55f;
}
else if (anIt == 2)
{
aOffsetX *= 0.00f;
aOffsetY *= -0.55f;
aFsaaOffset.x() *= 0.00f;
aFsaaOffset.y() *= -0.55f;
}
else if (anIt == 3)
{
aOffsetX *= 0.55f;
aOffsetY *= 0.00f;
aFsaaOffset.x() *= 0.55f;
aFsaaOffset.y() *= 0.00f;
}
aResult &= myPostFSAAProgram->SetUniform (theGlContext,
myUniformLocations[1][OpenGl_RT_uSamples], anIt + 1);
aResult &= myPostFSAAProgram->SetUniform (theGlContext,
myUniformLocations[1][OpenGl_RT_uOffsetX], aOffsetX);
aResult &= myPostFSAAProgram->SetUniform (theGlContext,
myUniformLocations[1][OpenGl_RT_uOffsetY], aOffsetY);
myUniformLocations[1][OpenGl_RT_uFsaaOffset], aFsaaOffset);
Handle(OpenGl_FrameBuffer)& aFramebuffer = anIt % 2
? myRaytraceFBO2[aFBOIdx]

View File

@ -126,11 +126,9 @@ void main (void)
else // showing number of samples
{
vec2 aRatio = vec2 (1.f, 1.f);
#ifdef GL_ARB_shader_image_size
aRatio = vec2 (imageSize (uRenderImage)) / vec2 (3.f * 512.f, 2.f * 512.f);
#endif
aColor = vec4 (0.5f * aColor.rgb * aSampleWeight + vec3 (0.f, sqrt (aRatio.x * aRatio.y) * aColor.w / uAccumFrames * 0.35f, 0.f), 1.0);
}
@ -138,7 +136,7 @@ void main (void)
#ifdef PATH_TRACING
aColor *= pow (2, uExposure);
aColor *= pow (2.0, uExposure);
#ifdef TONE_MAPPING_FILMIC
aColor = ToneMappingFilmic (aColor, uWhitePoint);

View File

@ -643,25 +643,18 @@ float HandleDistantLight (in vec3 theInput, in vec3 theToLight, in float theCosM
vec3 IntersectLight (in SRay theRay, in int theDepth, in float theHitDistance, out float thePDF)
{
vec3 aTotalRadiance = ZERO;
thePDF = 0.f; // PDF of sampling light sources
for (int aLightIdx = 0; aLightIdx < uLightCount; ++aLightIdx)
{
vec4 aLight = texelFetch (
uRaytraceLightSrcTexture, LIGHT_POS (aLightIdx));
vec4 aParam = texelFetch (
uRaytraceLightSrcTexture, LIGHT_PWR (aLightIdx));
vec4 aLight = texelFetch (uRaytraceLightSrcTexture, LIGHT_POS (aLightIdx));
vec4 aParam = texelFetch (uRaytraceLightSrcTexture, LIGHT_PWR (aLightIdx));
// W component: 0 for infinite light and 1 for point light
aLight.xyz -= mix (ZERO, theRay.Origin, aLight.w);
float aPDF = 1.f / uLightCount;
float aPDF = 1.0 / float(uLightCount);
if (aLight.w != 0.f) // point light source
{
float aCenterDst = length (aLight.xyz);
if (aCenterDst < theHitDistance)
{
float aVisibility = HandlePointLight (
@ -909,14 +902,12 @@ vec4 PathTrace (in SRay theRay, in vec3 theInverse, in int theNbSamples)
if (uLightCount > 0 && IsNotZero (aBSDF, aThroughput))
{
aExpPDF = 1.f / uLightCount;
aExpPDF = 1.0 / float(uLightCount);
int aLightIdx = min (int (floor (RandFloat() * uLightCount)), uLightCount - 1);
int aLightIdx = min (int (floor (RandFloat() * float(uLightCount))), uLightCount - 1);
vec4 aLight = texelFetch (
uRaytraceLightSrcTexture, LIGHT_POS (aLightIdx));
vec4 aParam = texelFetch (
uRaytraceLightSrcTexture, LIGHT_PWR (aLightIdx));
vec4 aLight = texelFetch (uRaytraceLightSrcTexture, LIGHT_POS (aLightIdx));
vec4 aParam = texelFetch (uRaytraceLightSrcTexture, LIGHT_PWR (aLightIdx));
// 'w' component is 0 for infinite light and 1 for point light
aLight.xyz -= mix (ZERO, theRay.Origin, aLight.w);
@ -971,7 +962,9 @@ vec4 PathTrace (in SRay theRay, in vec3 theInverse, in int theNbSamples)
#endif
// here, we additionally increase path length for non-diffuse bounces
if (RandFloat() > aSurvive || all (lessThan (aThroughput, MIN_THROUGHPUT)) || aDepth >= theNbSamples / FRAME_STEP + step (1.f / M_PI, aImpPDF))
if (RandFloat() > aSurvive
|| all (lessThan (aThroughput, MIN_THROUGHPUT))
|| aDepth >= (theNbSamples / FRAME_STEP + int(step (1.0 / M_PI, aImpPDF))))
{
aDepth = INVALID_BOUNCES; // terminate path
}

View File

@ -12,10 +12,10 @@
//! Normalized pixel coordinates.
in vec2 vPixel;
//! Sub-pixel offset in X direction for FSAA.
uniform float uOffsetX = 0.f;
//! Sub-pixel offset in for FSAA.
uniform vec2 uFsaaOffset;
//! Sub-pixel offset in Y direction for FSAA.
uniform float uOffsetY = 0.f;
uniform float uOffsetY;
//! Origin of viewing ray in left-top corner.
uniform vec3 uOriginLT;
@ -124,15 +124,15 @@ uniform float uSceneEpsilon;
#endif
//! Top color of gradient background.
uniform vec4 uBackColorTop = vec4 (0.0);
uniform vec4 uBackColorTop;
//! Bottom color of gradient background.
uniform vec4 uBackColorBot = vec4 (0.0);
uniform vec4 uBackColorBot;
//! Aperture radius of camera used for depth-of-field
uniform float uApertureRadius = 0.f;
uniform float uApertureRadius;
//! Focal distance of camera used for depth-of field
uniform float uFocalPlaneDist = 10.f;
uniform float uFocalPlaneDist;
//! Camera position used for projective mode
uniform vec3 uEyeOrig;
@ -156,7 +156,6 @@ uniform vec2 uEyeSize;
struct SRay
{
vec3 Origin;
vec3 Direct;
};
@ -164,9 +163,7 @@ struct SRay
struct SIntersect
{
float Time;
vec2 UV;
vec3 Normal;
};
@ -174,7 +171,6 @@ struct SIntersect
struct STriangle
{
ivec4 TriIndex;
vec3 Points[3];
};

View File

@ -18,7 +18,7 @@ uniform int uAccumSamples;
//! Maximum radiance that can be added to the pixel.
//! Decreases noise level, but introduces some bias.
uniform float uMaxRadiance = 50.f;
uniform float uMaxRadiance;
#ifdef ADAPTIVE_SAMPLING
//! Wrapper over imageLoad()+imageStore() having similar syntax as imageAtomicAdd().
@ -77,8 +77,8 @@ void main (void)
#endif // ADAPTIVE_SAMPLING
vec2 aPnt = vec2 (aFragCoord.x + RandFloat(),
aFragCoord.y + RandFloat());
vec2 aPnt = vec2 (float(aFragCoord.x) + RandFloat(),
float(aFragCoord.y) + RandFloat());
SRay aRay = GenerateRay (aPnt / vec2 (uWinSizeX, uWinSizeY));
@ -89,21 +89,16 @@ void main (void)
#ifdef PATH_TRACING
#ifndef ADAPTIVE_SAMPLING
vec4 aColor = PathTrace (aRay, aInvDirect, uAccumSamples);
#else
float aNbSamples = addRenderImageComp (aFragCoord, ivec2 (0, 1), 1.0);
vec4 aColor = PathTrace (aRay, aInvDirect, int (aNbSamples));
#endif
if (any (isnan (aColor.rgb)))
{
aColor.rgb = ZERO;
}
aColor.rgb = min (aColor.rgb, vec3 (uMaxRadiance));
#ifdef ADAPTIVE_SAMPLING
@ -113,7 +108,6 @@ void main (void)
addRenderImageComp (aFragCoord, ivec2 (1, 0), aColor.g);
addRenderImageComp (aFragCoord, ivec2 (1, 1), aColor.b);
addRenderImageComp (aFragCoord, ivec2 (2, 1), aColor.w);
if (int (aNbSamples) % 2 == 0) // accumulate luminance for even samples only
{
addRenderImageComp (aFragCoord, ivec2 (2, 0), dot (LUMA, aColor.rgb));
@ -127,7 +121,7 @@ void main (void)
}
else
{
OutColor = mix (texture (uAccumTexture, vPixel), aColor, 1.f / (uAccumSamples + 1));
OutColor = mix (texture (uAccumTexture, vPixel), aColor, 1.0 / float(uAccumSamples + 1));
}
#endif // ADAPTIVE_SAMPLING

View File

@ -21,8 +21,8 @@ void main (void)
int aPixelY = int (gl_FragCoord.y);
// Adjust FLIPTRI pattern used for adaptive FSAA
float anOffsetX = mix (uOffsetX, -uOffsetX, float (aPixelX % 2));
float anOffsetY = mix (uOffsetY, -uOffsetY, float (aPixelY % 2));
float anOffsetX = mix (uFsaaOffset.x, -uFsaaOffset.x, float (aPixelX % 2));
float anOffsetY = mix (uFsaaOffset.y, -uFsaaOffset.y, float (aPixelY % 2));
vec4 aClr0 = texelFetch (uFSAAInputTexture, ivec2 (aPixelX + 0, aPixelY + 0), 0);
vec4 aClr1 = texelFetch (uFSAAInputTexture, ivec2 (aPixelX + 0, aPixelY - 1), 0);
@ -71,7 +71,7 @@ void main (void)
aRay.Direct.y < 0.f ? -aInvDirect.y : aInvDirect.y,
aRay.Direct.z < 0.f ? -aInvDirect.z : aInvDirect.z);
aColor = mix (aClr0, clamp (Radiance (aRay, aInvDirect), 0.f, 1.f), 1.f / uSamples);
aColor = mix (aClr0, clamp (Radiance (aRay, aInvDirect), 0.0, 1.0), 1.0 / float(uSamples));
}
OutColor = aColor;

View File

@ -129,11 +129,9 @@ static const char Shaders_Display_fs[] =
" else // showing number of samples\n"
" {\n"
" vec2 aRatio = vec2 (1.f, 1.f);\n"
"\n"
"#ifdef GL_ARB_shader_image_size\n"
" aRatio = vec2 (imageSize (uRenderImage)) / vec2 (3.f * 512.f, 2.f * 512.f);\n"
"#endif\n"
"\n"
" aColor = vec4 (0.5f * aColor.rgb * aSampleWeight + vec3 (0.f, sqrt (aRatio.x * aRatio.y) * aColor.w / uAccumFrames * 0.35f, 0.f), 1.0);\n"
" }\n"
"\n"
@ -141,7 +139,7 @@ static const char Shaders_Display_fs[] =
"\n"
"#ifdef PATH_TRACING\n"
"\n"
" aColor *= pow (2, uExposure);\n"
" aColor *= pow (2.0, uExposure);\n"
"\n"
"#ifdef TONE_MAPPING_FILMIC\n"
" aColor = ToneMappingFilmic (aColor, uWhitePoint);\n"

View File

@ -646,25 +646,18 @@ static const char Shaders_PathtraceBase_fs[] =
"vec3 IntersectLight (in SRay theRay, in int theDepth, in float theHitDistance, out float thePDF)\n"
"{\n"
" vec3 aTotalRadiance = ZERO;\n"
"\n"
" thePDF = 0.f; // PDF of sampling light sources\n"
"\n"
" for (int aLightIdx = 0; aLightIdx < uLightCount; ++aLightIdx)\n"
" {\n"
" vec4 aLight = texelFetch (\n"
" uRaytraceLightSrcTexture, LIGHT_POS (aLightIdx));\n"
" vec4 aParam = texelFetch (\n"
" uRaytraceLightSrcTexture, LIGHT_PWR (aLightIdx));\n"
" vec4 aLight = texelFetch (uRaytraceLightSrcTexture, LIGHT_POS (aLightIdx));\n"
" vec4 aParam = texelFetch (uRaytraceLightSrcTexture, LIGHT_PWR (aLightIdx));\n"
"\n"
" // W component: 0 for infinite light and 1 for point light\n"
" aLight.xyz -= mix (ZERO, theRay.Origin, aLight.w);\n"
"\n"
" float aPDF = 1.f / uLightCount;\n"
"\n"
" float aPDF = 1.0 / float(uLightCount);\n"
" if (aLight.w != 0.f) // point light source\n"
" {\n"
" float aCenterDst = length (aLight.xyz);\n"
"\n"
" if (aCenterDst < theHitDistance)\n"
" {\n"
" float aVisibility = HandlePointLight (\n"
@ -912,14 +905,12 @@ static const char Shaders_PathtraceBase_fs[] =
"\n"
" if (uLightCount > 0 && IsNotZero (aBSDF, aThroughput))\n"
" {\n"
" aExpPDF = 1.f / uLightCount;\n"
" aExpPDF = 1.0 / float(uLightCount);\n"
"\n"
" int aLightIdx = min (int (floor (RandFloat() * uLightCount)), uLightCount - 1);\n"
" int aLightIdx = min (int (floor (RandFloat() * float(uLightCount))), uLightCount - 1);\n"
"\n"
" vec4 aLight = texelFetch (\n"
" uRaytraceLightSrcTexture, LIGHT_POS (aLightIdx));\n"
" vec4 aParam = texelFetch (\n"
" uRaytraceLightSrcTexture, LIGHT_PWR (aLightIdx));\n"
" vec4 aLight = texelFetch (uRaytraceLightSrcTexture, LIGHT_POS (aLightIdx));\n"
" vec4 aParam = texelFetch (uRaytraceLightSrcTexture, LIGHT_PWR (aLightIdx));\n"
"\n"
" // 'w' component is 0 for infinite light and 1 for point light\n"
" aLight.xyz -= mix (ZERO, theRay.Origin, aLight.w);\n"
@ -974,7 +965,9 @@ static const char Shaders_PathtraceBase_fs[] =
"#endif\n"
"\n"
" // here, we additionally increase path length for non-diffuse bounces\n"
" if (RandFloat() > aSurvive || all (lessThan (aThroughput, MIN_THROUGHPUT)) || aDepth >= theNbSamples / FRAME_STEP + step (1.f / M_PI, aImpPDF))\n"
" if (RandFloat() > aSurvive\n"
" || all (lessThan (aThroughput, MIN_THROUGHPUT))\n"
" || aDepth >= (theNbSamples / FRAME_STEP + int(step (1.0 / M_PI, aImpPDF))))\n"
" {\n"
" aDepth = INVALID_BOUNCES; // terminate path\n"
" }\n"

View File

@ -15,10 +15,10 @@ static const char Shaders_RaytraceBase_fs[] =
"//! Normalized pixel coordinates.\n"
"in vec2 vPixel;\n"
"\n"
"//! Sub-pixel offset in X direction for FSAA.\n"
"uniform float uOffsetX = 0.f;\n"
"//! Sub-pixel offset in for FSAA.\n"
"uniform vec2 uFsaaOffset;\n"
"//! Sub-pixel offset in Y direction for FSAA.\n"
"uniform float uOffsetY = 0.f;\n"
"uniform float uOffsetY;\n"
"\n"
"//! Origin of viewing ray in left-top corner.\n"
"uniform vec3 uOriginLT;\n"
@ -127,15 +127,15 @@ static const char Shaders_RaytraceBase_fs[] =
"#endif\n"
"\n"
"//! Top color of gradient background.\n"
"uniform vec4 uBackColorTop = vec4 (0.0);\n"
"uniform vec4 uBackColorTop;\n"
"//! Bottom color of gradient background.\n"
"uniform vec4 uBackColorBot = vec4 (0.0);\n"
"uniform vec4 uBackColorBot;\n"
"\n"
"//! Aperture radius of camera used for depth-of-field\n"
"uniform float uApertureRadius = 0.f;\n"
"uniform float uApertureRadius;\n"
"\n"
"//! Focal distance of camera used for depth-of field\n"
"uniform float uFocalPlaneDist = 10.f;\n"
"uniform float uFocalPlaneDist;\n"
"\n"
"//! Camera position used for projective mode\n"
"uniform vec3 uEyeOrig;\n"
@ -159,7 +159,6 @@ static const char Shaders_RaytraceBase_fs[] =
"struct SRay\n"
"{\n"
" vec3 Origin;\n"
"\n"
" vec3 Direct;\n"
"};\n"
"\n"
@ -167,9 +166,7 @@ static const char Shaders_RaytraceBase_fs[] =
"struct SIntersect\n"
"{\n"
" float Time;\n"
"\n"
" vec2 UV;\n"
"\n"
" vec3 Normal;\n"
"};\n"
"\n"
@ -177,7 +174,6 @@ static const char Shaders_RaytraceBase_fs[] =
"struct STriangle\n"
"{\n"
" ivec4 TriIndex;\n"
"\n"
" vec3 Points[3];\n"
"};\n"
"\n"

View File

@ -21,7 +21,7 @@ static const char Shaders_RaytraceRender_fs[] =
"\n"
"//! Maximum radiance that can be added to the pixel.\n"
"//! Decreases noise level, but introduces some bias.\n"
"uniform float uMaxRadiance = 50.f;\n"
"uniform float uMaxRadiance;\n"
"\n"
"#ifdef ADAPTIVE_SAMPLING\n"
"//! Wrapper over imageLoad()+imageStore() having similar syntax as imageAtomicAdd().\n"
@ -80,8 +80,8 @@ static const char Shaders_RaytraceRender_fs[] =
"\n"
"#endif // ADAPTIVE_SAMPLING\n"
"\n"
" vec2 aPnt = vec2 (aFragCoord.x + RandFloat(),\n"
" aFragCoord.y + RandFloat());\n"
" vec2 aPnt = vec2 (float(aFragCoord.x) + RandFloat(),\n"
" float(aFragCoord.y) + RandFloat());\n"
"\n"
" SRay aRay = GenerateRay (aPnt / vec2 (uWinSizeX, uWinSizeY));\n"
"\n"
@ -92,21 +92,16 @@ static const char Shaders_RaytraceRender_fs[] =
"#ifdef PATH_TRACING\n"
"\n"
"#ifndef ADAPTIVE_SAMPLING\n"
"\n"
" vec4 aColor = PathTrace (aRay, aInvDirect, uAccumSamples);\n"
"\n"
"#else\n"
"\n"
" float aNbSamples = addRenderImageComp (aFragCoord, ivec2 (0, 1), 1.0);\n"
" vec4 aColor = PathTrace (aRay, aInvDirect, int (aNbSamples));\n"
"\n"
"#endif\n"
"\n"
" if (any (isnan (aColor.rgb)))\n"
" {\n"
" aColor.rgb = ZERO;\n"
" }\n"
"\n"
" aColor.rgb = min (aColor.rgb, vec3 (uMaxRadiance));\n"
"\n"
"#ifdef ADAPTIVE_SAMPLING\n"
@ -116,7 +111,6 @@ static const char Shaders_RaytraceRender_fs[] =
" addRenderImageComp (aFragCoord, ivec2 (1, 0), aColor.g);\n"
" addRenderImageComp (aFragCoord, ivec2 (1, 1), aColor.b);\n"
" addRenderImageComp (aFragCoord, ivec2 (2, 1), aColor.w);\n"
"\n"
" if (int (aNbSamples) % 2 == 0) // accumulate luminance for even samples only\n"
" {\n"
" addRenderImageComp (aFragCoord, ivec2 (2, 0), dot (LUMA, aColor.rgb));\n"
@ -130,7 +124,7 @@ static const char Shaders_RaytraceRender_fs[] =
" }\n"
" else\n"
" {\n"
" OutColor = mix (texture (uAccumTexture, vPixel), aColor, 1.f / (uAccumSamples + 1));\n"
" OutColor = mix (texture (uAccumTexture, vPixel), aColor, 1.0 / float(uAccumSamples + 1));\n"
" }\n"
"\n"
"#endif // ADAPTIVE_SAMPLING\n"

View File

@ -24,8 +24,8 @@ static const char Shaders_RaytraceSmooth_fs[] =
" int aPixelY = int (gl_FragCoord.y);\n"
"\n"
" // Adjust FLIPTRI pattern used for adaptive FSAA\n"
" float anOffsetX = mix (uOffsetX, -uOffsetX, float (aPixelX % 2));\n"
" float anOffsetY = mix (uOffsetY, -uOffsetY, float (aPixelY % 2));\n"
" float anOffsetX = mix (uFsaaOffset.x, -uFsaaOffset.x, float (aPixelX % 2));\n"
" float anOffsetY = mix (uFsaaOffset.y, -uFsaaOffset.y, float (aPixelY % 2));\n"
"\n"
" vec4 aClr0 = texelFetch (uFSAAInputTexture, ivec2 (aPixelX + 0, aPixelY + 0), 0);\n"
" vec4 aClr1 = texelFetch (uFSAAInputTexture, ivec2 (aPixelX + 0, aPixelY - 1), 0);\n"
@ -74,7 +74,7 @@ static const char Shaders_RaytraceSmooth_fs[] =
" aRay.Direct.y < 0.f ? -aInvDirect.y : aInvDirect.y,\n"
" aRay.Direct.z < 0.f ? -aInvDirect.z : aInvDirect.z);\n"
"\n"
" aColor = mix (aClr0, clamp (Radiance (aRay, aInvDirect), 0.f, 1.f), 1.f / uSamples);\n"
" aColor = mix (aClr0, clamp (Radiance (aRay, aInvDirect), 0.0, 1.0), 1.0 / float(uSamples));\n"
" }\n"
"\n"
" OutColor = aColor;\n"