From 863646a9e1695c85119eda068196264a9f3e0038 Mon Sep 17 00:00:00 2001 From: Ryan McDonough Date: Thu, 6 Feb 2025 08:22:05 -0500 Subject: [PATCH 1/6] Fix Rendering Issue in PBRTerrain This PR attempts to fix a rendering bug that a few jme have experienced on certain devices, as discussed in this thread: https://hub.jmonkeyengine.org/t/requesting-help-troubleshooting-pbrterrain-bug/47895 I believe the issue was due to a combination of things that were wrong with the process of reading normal maps, calculating tangents, and then blending them. The order of these operations is important, and I believe it is also important to normalize the normal value prior to blending each layer, which I previously was not doing. There's also some code that puts a normal map in the proper range, and this was being done improperly for tri-planar normal mapping. Once this PR is done I'll post back to that thread and request testing from the users who were experiencing the bug on their device. --- .../Common/ShaderLib/TriPlanarUtils.glsllib | 48 ++++++++++++++++--- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/jme3-core/src/main/resources/Common/ShaderLib/TriPlanarUtils.glsllib b/jme3-core/src/main/resources/Common/ShaderLib/TriPlanarUtils.glsllib index 2b00eb7be3..7b79a4181b 100644 --- a/jme3-core/src/main/resources/Common/ShaderLib/TriPlanarUtils.glsllib +++ b/jme3-core/src/main/resources/Common/ShaderLib/TriPlanarUtils.glsllib @@ -1,8 +1,8 @@ #ifndef __TRIPLANAR_UTILS_MODULE__ #define __TRIPLANAR_UTILS_MODULE__ - vec3 triBlending; - + vec3 triBlending; + void TriPlanarUtils_calculateBlending(vec3 geometryNormal){ triBlending = abs( geometryNormal ); triBlending = (triBlending -0.2) * 0.7; @@ -11,7 +11,8 @@ triBlending /= vec3(b, b, b); } - vec4 getTriPlanarBlend(in vec4 coords, in sampler2D map, in float scale) { + // basic triplanar blend: + vec4 getTriPlanarBlend(in vec3 coords, in sampler2D map, in float scale) { vec4 col1 = texture2D( map, coords.yz * scale); vec4 col2 = texture2D( map, coords.xz * scale); vec4 col3 = texture2D( map, coords.xy * scale); @@ -21,7 +22,8 @@ return tex; } - vec4 getTriPlanarBlendFromTexArray(in vec4 coords, in int idInTexArray, in float scale, in sampler2DArray texArray) { + // basic triplanar blend for TextureArrays: + vec4 getTriPlanarBlendFromTexArray(in vec3 coords, in int idInTexArray, in float scale, in sampler2DArray texArray) { vec4 col1 = texture2DArray( texArray, vec3((coords.yz * scale), idInTexArray ) ); vec4 col2 = texture2DArray( texArray, vec3((coords.xz * scale), idInTexArray ) ); vec4 col3 = texture2DArray( texArray, vec3((coords.xy * scale), idInTexArray ) ); @@ -29,6 +31,38 @@ vec4 tex = col1 * triBlending.x + col2 * triBlending.y + col3 * triBlending.z; return tex; - } - -#endif \ No newline at end of file + } + + // triplanar blend for Normal maps: + vec4 getTriPlanarNormalBlend(in vec3 coords, in sampler2D map, in float scale) { + vec4 col1 = texture2D( map, coords.yz * scale); + vec4 col2 = texture2D( map, coords.xz * scale); + vec4 col3 = texture2D( map, coords.xy * scale); + + col1.xyz = col1.xyz * vec3(2.0) - vec3(1.0); + col2.xyz = col2.xyz * vec3(2.0) - vec3(1.0); + col3.xyz = col3.xyz * vec3(2.0) - vec3(1.0); + + // blend the results of the 3 planar projections. + vec4 tex = normalize(col1 * triBlending.x + col2 * triBlending.y + col3 * triBlending.z); + + return tex; + } + + // triplanar blend for Normal maps in a TextureArray: + vec4 getTriPlanarNormalBlendFromTexArray(in vec3 coords, in int idInTexArray, in float scale, in sampler2DArray texArray) { + vec4 col1 = texture2DArray( texArray, vec3((coords.yz * scale), idInTexArray ) ); + vec4 col2 = texture2DArray( texArray, vec3((coords.xz * scale), idInTexArray ) ); + vec4 col3 = texture2DArray( texArray, vec3((coords.xy * scale), idInTexArray ) ); + + col1.xyz = col1.xyz * vec3(2.0) - vec3(1.0); + col2.xyz = col2.xyz * vec3(2.0) - vec3(1.0); + col3.xyz = col3.xyz * vec3(2.0) - vec3(1.0); + + // blend the results of the 3 planar projections. + vec4 tex = normalize(col1 * triBlending.x + col2 * triBlending.y + col3 * triBlending.z); + + return tex; + } + +#endif From 44961d5522d1eadd591294ebe674b20f6ec5da2b Mon Sep 17 00:00:00 2001 From: Ryan McDonough Date: Thu, 6 Feb 2025 08:25:15 -0500 Subject: [PATCH 2/6] Remove code putting normal map in proper range. This should not have been coupled in the tangent calculation --- .../src/main/resources/Common/ShaderLib/TangentUtils.glsllib | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/jme3-core/src/main/resources/Common/ShaderLib/TangentUtils.glsllib b/jme3-core/src/main/resources/Common/ShaderLib/TangentUtils.glsllib index 6b3be2fb40..54b2356161 100644 --- a/jme3-core/src/main/resources/Common/ShaderLib/TangentUtils.glsllib +++ b/jme3-core/src/main/resources/Common/ShaderLib/TangentUtils.glsllib @@ -6,7 +6,6 @@ //primarily used for terrains, since jme terrains do not store pre-calculated tangents by default (thus the tbnMat cannot be used for PBR light calculation like it is in jme's stock PBR shader) vec3 calculateTangentsAndApplyToNormals(in vec3 normalIn, in vec3 worldNorm){ - vec3 returnNorm = normalize((normalIn.xyz * vec3(2.0) - vec3(1.0))); vec3 baseNorm = worldNorm.rgb + vec3(0, 0, 1); returnNorm *= vec3(-1, -1, 1); @@ -18,4 +17,4 @@ return returnNorm; } -#endif \ No newline at end of file +#endif From 0e78a629c1780cc3736122e918abfdf5d667e850 Mon Sep 17 00:00:00 2001 From: Ryan McDonough Date: Thu, 6 Feb 2025 08:35:08 -0500 Subject: [PATCH 3/6] Update TangentUtils.glsllib --- .../Common/ShaderLib/TangentUtils.glsllib | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/jme3-core/src/main/resources/Common/ShaderLib/TangentUtils.glsllib b/jme3-core/src/main/resources/Common/ShaderLib/TangentUtils.glsllib index 54b2356161..b07c9c197c 100644 --- a/jme3-core/src/main/resources/Common/ShaderLib/TangentUtils.glsllib +++ b/jme3-core/src/main/resources/Common/ShaderLib/TangentUtils.glsllib @@ -1,20 +1,13 @@ #ifndef __TANGENT_UTILS_MODULE__ #define __TANGENT_UTILS_MODULE__ - //used for calculating tangents in-shader - - - //primarily used for terrains, since jme terrains do not store pre-calculated tangents by default (thus the tbnMat cannot be used for PBR light calculation like it is in jme's stock PBR shader) - vec3 calculateTangentsAndApplyToNormals(in vec3 normalIn, in vec3 worldNorm){ - + //used for calculating tangents in-shader for axis-aligned quads/planes/terrains + //primarily used for PBR terrains, since jme terrains do not store pre-calculated tangents by default (thus the tbnMat cannot be used for PBR light calculation like it is in jme's stock PBR shader) + vec3 calculateTangentsAndApplyToNormals(in vec3 normalIn, in vec3 worldNorm){ vec3 baseNorm = worldNorm.rgb + vec3(0, 0, 1); - returnNorm *= vec3(-1, -1, 1); - returnNorm = baseNorm.rgb*dot(baseNorm.rgb, returnNorm.rgb)/baseNorm.z - returnNorm.rgb; - - returnNorm = normalize(returnNorm); + normalIn = baseNorm.rgb*dot(baseNorm.rgb, normalIn.rgb)/baseNorm.z - normalIn.rgb; + normalIn = normalize(normalIn); - - return returnNorm; + return normalIn; } - #endif From 100e9d1716ea074a605e45c3458778e887914ebf Mon Sep 17 00:00:00 2001 From: Ryan McDonough Date: Thu, 6 Feb 2025 08:51:30 -0500 Subject: [PATCH 4/6] Update PBRLighting.vert --- .../src/main/resources/Common/MatDefs/Light/PBRLighting.vert | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.vert b/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.vert index 5e574fa8fc..23427c0795 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.vert +++ b/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.vert @@ -30,7 +30,7 @@ attribute vec3 inNormal; varying vec3 wNormal; varying vec3 wPosition; -varying vec4 lPosition; +varying vec3 lPosition; attribute vec4 inTangent; varying vec4 wTangent; @@ -46,7 +46,7 @@ void main(){ vec3 modelSpaceNorm = inNormal; vec3 modelSpaceTan = inTangent.xyz; - lPosition = modelSpacePos; + lPosition = modelSpacePos.xyz; #ifdef USE_VERTEX_COLORS_AS_SUN_INTENSITY From 36b00557917166699b81bae017e36abf4934540a Mon Sep 17 00:00:00 2001 From: Ryan McDonough Date: Thu, 6 Feb 2025 08:52:46 -0500 Subject: [PATCH 5/6] Change varying lPos from vec4 to vec3 --- .../ShaderLib/module/pbrlighting/PBRLightingUtils.glsllib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jme3-core/src/main/resources/Common/ShaderLib/module/pbrlighting/PBRLightingUtils.glsllib b/jme3-core/src/main/resources/Common/ShaderLib/module/pbrlighting/PBRLightingUtils.glsllib index d943e8df67..f5136cbe74 100644 --- a/jme3-core/src/main/resources/Common/ShaderLib/module/pbrlighting/PBRLightingUtils.glsllib +++ b/jme3-core/src/main/resources/Common/ShaderLib/module/pbrlighting/PBRLightingUtils.glsllib @@ -41,7 +41,7 @@ #endif #if defined(ENABLE_PBRLightingUtils_getLocalPosition) - varying vec4 lPosition; + varying vec3 lPosition; #endif From b8277ef8592ea6186f61eb5c9a55d3064a02d29a Mon Sep 17 00:00:00 2001 From: Ryan McDonough Date: Thu, 6 Feb 2025 08:54:01 -0500 Subject: [PATCH 6/6] Update PBRTerrain.vert --- .../main/resources/Common/MatDefs/Terrain/PBRTerrain.vert | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/PBRTerrain.vert b/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/PBRTerrain.vert index 0763ff5fec..8096ca9724 100644 --- a/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/PBRTerrain.vert +++ b/jme3-terrain/src/main/resources/Common/MatDefs/Terrain/PBRTerrain.vert @@ -8,7 +8,7 @@ attribute vec2 inTexCoord; varying vec2 texCoord; varying vec3 wPosition; varying vec3 wNormal; - +varying vec3 lPosition; uniform vec4 g_AmbientLightColor; @@ -17,9 +17,6 @@ uniform vec4 g_AmbientLightColor; uniform vec3 g_CameraPosition; #endif - -varying vec4 lPosition; - void main(){ vec4 modelSpacePos = vec4(inPosition, 1.0); @@ -31,7 +28,7 @@ void main(){ wNormal = normalize(TransformWorldNormal(inNormal)); - lPosition = vec4(inPosition, 0.0); + lPosition = modelSpacePos.xyz; #ifdef USE_FOG fogDistance = distance(g_CameraPosition, (g_WorldMatrix * modelSpacePos).xyz);