From fe2a8faab6d66b11adcc2e977b1b3e425e3899b1 Mon Sep 17 00:00:00 2001 From: kgv Date: Tue, 19 Jan 2021 18:19:26 +0300 Subject: [PATCH] 0032067: Visualization, TKOpenGl - shadowmap GLSL compilation error on WebGL 3.0 Shadowmap sampler is now passed as a dedicated argument to occDirectionalLightShadow() to workaround strict GLSL syntax validator. Fixed texture coordinates clamping range. Shadow antialiasing is disabled on OpenGL ES 2.0. --- src/OpenGl/OpenGl_ShaderManager.cxx | 2 +- src/Shaders/DirectionalLightShadow.glsl | 24 +++++++++++++++---- .../Shaders_DirectionalLightShadow_glsl.pxx | 24 +++++++++++++++---- 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/OpenGl/OpenGl_ShaderManager.cxx b/src/OpenGl/OpenGl_ShaderManager.cxx index b722f7bfe2..ae07acb046 100644 --- a/src/OpenGl/OpenGl_ShaderManager.cxx +++ b/src/OpenGl/OpenGl_ShaderManager.cxx @@ -2250,7 +2250,7 @@ TCollection_AsciiString OpenGl_ShaderManager::stdComputeLighting (Standard_Integ && aLightIter.Value()->ToCastShadows()) { aLightsLoop = aLightsLoop + EOL" occDirectionalLight (" + anIndex + ", theNormal, theView, theIsFront," - EOL" occDirectionalLightShadow (" + anIndex + ", theNormal));"; + EOL" occDirectionalLightShadow (occShadowMapSamplers[" + anIndex + "], " + anIndex + ", theNormal));"; ++anIndex; } } diff --git a/src/Shaders/DirectionalLightShadow.glsl b/src/Shaders/DirectionalLightShadow.glsl index 555de1e651..80c9a1e27f 100644 --- a/src/Shaders/DirectionalLightShadow.glsl +++ b/src/Shaders/DirectionalLightShadow.glsl @@ -1,27 +1,43 @@ -//! Coefficients for gathering close samples. +#if (__VERSION__ >= 120) +//! Coefficients for gathering close samples for antialiasing. +//! Use only with decent OpenGL (array constants cannot be initialized with GLSL 1.1 / GLSL ES 1.1) const vec2 occPoissonDisk16[16] = vec2[]( vec2(-0.94201624,-0.39906216), vec2( 0.94558609,-0.76890725), vec2(-0.09418410,-0.92938870), vec2( 0.34495938, 0.29387760), vec2(-0.91588581, 0.45771432), vec2(-0.81544232,-0.87912464), vec2(-0.38277543, 0.27676845), vec2( 0.97484398, 0.75648379), vec2( 0.44323325,-0.97511554), vec2( 0.53742981,-0.47373420), vec2(-0.26496911,-0.41893023), vec2( 0.79197514, 0.19090188), vec2(-0.24188840, 0.99706507), vec2(-0.81409955, 0.91437590), vec2( 0.19984126, 0.78641367), vec2( 0.14383161,-0.14100790) ); +#endif //! Function computes directional light shadow attenuation (1.0 means no shadow). -float occDirectionalLightShadow (in int theId, +float occDirectionalLightShadow (in sampler2D theShadow, + in int theId, in vec3 theNormal) { vec4 aPosLightSpace = PosLightSpace[theId]; vec3 aLightDir = vec3 (occWorldViewMatrix * vec4 (occLight_Position (theId), 0.0)); vec3 aProjCoords = (aPosLightSpace.xyz / aPosLightSpace.w) * 0.5 + vec3 (0.5); float aCurrentDepth = aProjCoords.z; - if (abs(aProjCoords.x) > 1.0 || abs(aProjCoords.y) > 1.0 || aCurrentDepth > 1.0) { return 1.0; } + if (aProjCoords.x < 0.0 || aProjCoords.x > 1.0 + || aProjCoords.y < 0.0 || aProjCoords.y > 1.0 + || aCurrentDepth > 1.0) + { + return 1.0; + } + vec2 aTexelSize = vec2 (occShadowMapSizeBias.x); float aBias = max (occShadowMapSizeBias.y * (1.0 - dot (theNormal, aLightDir)), occShadowMapSizeBias.y * 0.1); +#if (__VERSION__ >= 120) float aShadow = 0.0; for (int aPosIter = 0; aPosIter < 16; ++aPosIter) { - float aClosestDepth = occTexture2D (occShadowMapSamplers[theId], aProjCoords.xy + occPoissonDisk16[aPosIter] * aTexelSize).r; + float aClosestDepth = occTexture2D (theShadow, aProjCoords.xy + occPoissonDisk16[aPosIter] * aTexelSize).r; aShadow += (aCurrentDepth - aBias) > aClosestDepth ? 1.0 : 0.0; } return 1.0 - aShadow / 16.0; +#else + float aClosestDepth = occTexture2D (theShadow, aProjCoords.xy).r; + float aShadow = (aCurrentDepth - aBias) > aClosestDepth ? 1.0 : 0.0; + return 1.0 - aShadow; +#endif } diff --git a/src/Shaders/Shaders_DirectionalLightShadow_glsl.pxx b/src/Shaders/Shaders_DirectionalLightShadow_glsl.pxx index 58f5a96fad..1aff57dfba 100644 --- a/src/Shaders/Shaders_DirectionalLightShadow_glsl.pxx +++ b/src/Shaders/Shaders_DirectionalLightShadow_glsl.pxx @@ -1,30 +1,46 @@ // This file has been automatically generated from resource file src/Shaders/DirectionalLightShadow.glsl static const char Shaders_DirectionalLightShadow_glsl[] = - "//! Coefficients for gathering close samples.\n" + "#if (__VERSION__ >= 120)\n" + "//! Coefficients for gathering close samples for antialiasing.\n" + "//! Use only with decent OpenGL (array constants cannot be initialized with GLSL 1.1 / GLSL ES 1.1)\n" "const vec2 occPoissonDisk16[16] = vec2[](\n" " vec2(-0.94201624,-0.39906216), vec2( 0.94558609,-0.76890725), vec2(-0.09418410,-0.92938870), vec2( 0.34495938, 0.29387760),\n" " vec2(-0.91588581, 0.45771432), vec2(-0.81544232,-0.87912464), vec2(-0.38277543, 0.27676845), vec2( 0.97484398, 0.75648379),\n" " vec2( 0.44323325,-0.97511554), vec2( 0.53742981,-0.47373420), vec2(-0.26496911,-0.41893023), vec2( 0.79197514, 0.19090188),\n" " vec2(-0.24188840, 0.99706507), vec2(-0.81409955, 0.91437590), vec2( 0.19984126, 0.78641367), vec2( 0.14383161,-0.14100790)\n" ");\n" + "#endif\n" "\n" "//! Function computes directional light shadow attenuation (1.0 means no shadow).\n" - "float occDirectionalLightShadow (in int theId,\n" + "float occDirectionalLightShadow (in sampler2D theShadow,\n" + " in int theId,\n" " in vec3 theNormal)\n" "{\n" " vec4 aPosLightSpace = PosLightSpace[theId];\n" " vec3 aLightDir = vec3 (occWorldViewMatrix * vec4 (occLight_Position (theId), 0.0));\n" " vec3 aProjCoords = (aPosLightSpace.xyz / aPosLightSpace.w) * 0.5 + vec3 (0.5);\n" " float aCurrentDepth = aProjCoords.z;\n" - " if (abs(aProjCoords.x) > 1.0 || abs(aProjCoords.y) > 1.0 || aCurrentDepth > 1.0) { return 1.0; }\n" + " if (aProjCoords.x < 0.0 || aProjCoords.x > 1.0\n" + " || aProjCoords.y < 0.0 || aProjCoords.y > 1.0\n" + " || aCurrentDepth > 1.0)\n" + " {\n" + " return 1.0;\n" + " }\n" + "\n" " vec2 aTexelSize = vec2 (occShadowMapSizeBias.x);\n" " float aBias = max (occShadowMapSizeBias.y * (1.0 - dot (theNormal, aLightDir)), occShadowMapSizeBias.y * 0.1);\n" + "#if (__VERSION__ >= 120)\n" " float aShadow = 0.0;\n" " for (int aPosIter = 0; aPosIter < 16; ++aPosIter)\n" " {\n" - " float aClosestDepth = occTexture2D (occShadowMapSamplers[theId], aProjCoords.xy + occPoissonDisk16[aPosIter] * aTexelSize).r;\n" + " float aClosestDepth = occTexture2D (theShadow, aProjCoords.xy + occPoissonDisk16[aPosIter] * aTexelSize).r;\n" " aShadow += (aCurrentDepth - aBias) > aClosestDepth ? 1.0 : 0.0;\n" " }\n" " return 1.0 - aShadow / 16.0;\n" + "#else\n" + " float aClosestDepth = occTexture2D (theShadow, aProjCoords.xy).r;\n" + " float aShadow = (aCurrentDepth - aBias) > aClosestDepth ? 1.0 : 0.0;\n" + " return 1.0 - aShadow;\n" + "#endif\n" "}\n";