From 67cdede9f4b50541fea8e0366ee026a174681b88 Mon Sep 17 00:00:00 2001 From: Ryan McDonough Date: Fri, 2 Feb 2024 16:20:19 -0500 Subject: [PATCH 01/22] Modularize PBRLighting Addresses this issue: https://github.com/jMonkeyEngine/jmonkeyengine/issues/2122 To re-summarize: This PR extracts all of the texture reads and basematParam assignment into a .glslib file (currently named PBRLightingParamReads.glsllib) And then it also extracts all of the lighting calculation into a .glslib file (currently named PBRLighting.glsllib) I also fixed alot of formatting and indentation mistakes, and overall reorganized the shader. This should now make it as easy as possible for jme devs to fork PBRLighting to make changes, and they will no longer have to update the lighting or texReads to stay on par with master, as all future changes will all be in the glsllibs. This also reduces the chances that a lesser-skilled shader dev (or even skilled shader devs on a bad day) mistakenly mess up the lighting calculations when forking the shader. Any feedback and review is greatly appreciated. --- .../Common/MatDefs/Light/PBRLighting.frag | 400 +++--------------- 1 file changed, 59 insertions(+), 341 deletions(-) diff --git a/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag b/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag index 01276fbeaf..88d93c118b 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag +++ b/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag @@ -1,367 +1,85 @@ #import "Common/ShaderLib/GLSLCompat.glsllib" -#import "Common/ShaderLib/PBR.glsllib" -#import "Common/ShaderLib/Parallax.glsllib" -#import "Common/ShaderLib/Lighting.glsllib" varying vec2 texCoord; +vec2 newTexCoord; #ifdef SEPARATE_TEXCOORD - varying vec2 texCoord2; + varying vec2 texCoord2; #endif -varying vec4 Color; - -uniform vec4 g_LightData[NB_LIGHTS]; -uniform vec3 g_CameraPosition; -uniform vec4 g_AmbientLightColor; +#ifdef DISCARD_ALPHA + uniform float m_AlphaDiscardThreshold; +#endif -uniform float m_Roughness; -uniform float m_Metallic; varying vec3 wPosition; +varying vec3 wNormal; +varying vec4 wTangent; -#if NB_PROBES >= 1 - uniform samplerCube g_PrefEnvMap; - uniform vec3 g_ShCoeffs[9]; - uniform mat4 g_LightProbeData; -#endif -#if NB_PROBES >= 2 - uniform samplerCube g_PrefEnvMap2; - uniform vec3 g_ShCoeffs2[9]; - uniform mat4 g_LightProbeData2; -#endif -#if NB_PROBES == 3 - uniform samplerCube g_PrefEnvMap3; - uniform vec3 g_ShCoeffs3[9]; - uniform mat4 g_LightProbeData3; -#endif - -#ifdef BASECOLORMAP - uniform sampler2D m_BaseColorMap; -#endif +#import "MatDefs/ShaderLib/PBRLightingParamReads.glsllib" +#import "MatDefs/ShaderLib/PBRLighting.glsllib" +//Important that these 2 ^ glsllibs are referenced AFTER other variables are declared above. +// any variables above are declared there (rather than in a glslib) to reduce rendundancy, because these vars likely to used by more than 1 glslib. +// Only lighting vars are declared in PBRLighting.glslib, and only basePBR matParams are declared in PBRLightingParamReads.glslib +//This allows jme devs to fork this shader and make their own changes before the base PBR param-reads or before the final lighting calculation. +//For example, you could move texCoords based on g_Time prior to texReads for a simple moving water/lava effect. or blend values like albedo/roughness after tex reads but before the final lighting calculations to do things like dynamic texture splatting -#ifdef USE_PACKED_MR - uniform sampler2D m_MetallicRoughnessMap; -#else - #ifdef METALLICMAP - uniform sampler2D m_MetallicMap; - #endif - #ifdef ROUGHNESSMAP - uniform sampler2D m_RoughnessMap; - #endif -#endif +vec4 albedo = vec4(1.0); +float alpha = 1.0; -#ifdef EMISSIVE - uniform vec4 m_Emissive; -#endif -#ifdef EMISSIVEMAP - uniform sampler2D m_EmissiveMap; -#endif -#if defined(EMISSIVE) || defined(EMISSIVEMAP) - uniform float m_EmissivePower; - uniform float m_EmissiveIntensity; -#endif +float Metallic = 0.0; +float Roughness = 0.0; -#ifdef SPECGLOSSPIPELINE +float emissiveIntensity = 0.0; +float emissivePower = 0.0; +vec4 emissive = vec4(0.0); - uniform vec4 m_Specular; - uniform float m_Glossiness; - #ifdef USE_PACKED_SG - uniform sampler2D m_SpecularGlossinessMap; - #else - uniform sampler2D m_SpecularMap; - uniform sampler2D m_GlossinessMap; - #endif -#endif +vec3 ao = vec3(1.0); +vec3 lightMapColor = vec3(0.0); -#ifdef PARALLAXMAP - uniform sampler2D m_ParallaxMap; -#endif -#if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP))) - uniform float m_ParallaxHeight; -#endif - -#ifdef LIGHTMAP - uniform sampler2D m_LightMap; -#endif - -#ifdef AO_STRENGTH - uniform float m_AoStrength; -#endif - -#if defined(NORMALMAP) || defined(PARALLAXMAP) - uniform sampler2D m_NormalMap; - varying vec4 wTangent; -#endif -#ifdef NORMALSCALE - uniform float m_NormalScale; -#endif -varying vec3 wNormal; - -// Specular-AA -#ifdef SPECULAR_AA_SCREEN_SPACE_VARIANCE - uniform float m_SpecularAASigma; -#endif -#ifdef SPECULAR_AA_THRESHOLD - uniform float m_SpecularAAKappa; -#endif - -#ifdef DISCARD_ALPHA - uniform float m_AlphaDiscardThreshold; -#endif +float indoorSunLightExposure = 1.0; void main(){ - vec2 newTexCoord; - vec3 viewDir = normalize(g_CameraPosition - wPosition); - + vec3 norm = normalize(wNormal); - #if defined(NORMALMAP) || defined(PARALLAXMAP) - vec3 tan = normalize(wTangent.xyz); - mat3 tbnMat = mat3(tan, wTangent.w * cross( (norm), (tan)), norm); - #endif - - #if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP))) - vec3 vViewDir = viewDir * tbnMat; - #ifdef STEEP_PARALLAX - #ifdef NORMALMAP_PARALLAX - //parallax map is stored in the alpha channel of the normal map - newTexCoord = steepParallaxOffset(m_NormalMap, vViewDir, texCoord, m_ParallaxHeight); - #else - //parallax map is a texture - newTexCoord = steepParallaxOffset(m_ParallaxMap, vViewDir, texCoord, m_ParallaxHeight); - #endif - #else - #ifdef NORMALMAP_PARALLAX - //parallax map is stored in the alpha channel of the normal map - newTexCoord = classicParallaxOffset(m_NormalMap, vViewDir, texCoord, m_ParallaxHeight); - #else - //parallax map is a texture - newTexCoord = classicParallaxOffset(m_ParallaxMap, vViewDir, texCoord, m_ParallaxHeight); - #endif - #endif - #else - newTexCoord = texCoord; - #endif + vec3 normal = norm; + vec3 viewDir = normalize(g_CameraPosition - wPosition); - #ifdef BASECOLORMAP - vec4 albedo = texture2D(m_BaseColorMap, newTexCoord) * Color; - #else - vec4 albedo = Color; - #endif - - //ao in r channel, roughness in green channel, metallic in blue channel! - vec3 aoRoughnessMetallicValue = vec3(1.0, 1.0, 0.0); - #ifdef USE_PACKED_MR - aoRoughnessMetallicValue = texture2D(m_MetallicRoughnessMap, newTexCoord).rgb; - float Roughness = aoRoughnessMetallicValue.g * max(m_Roughness, 1e-4); - float Metallic = aoRoughnessMetallicValue.b * max(m_Metallic, 0.0); - #else - #ifdef ROUGHNESSMAP - float Roughness = texture2D(m_RoughnessMap, newTexCoord).r * max(m_Roughness, 1e-4); - #else - float Roughness = max(m_Roughness, 1e-4); - #endif - #ifdef METALLICMAP - float Metallic = texture2D(m_MetallicMap, newTexCoord).r * max(m_Metallic, 0.0); - #else - float Metallic = max(m_Metallic, 0.0); - #endif - #endif - - float alpha = albedo.a; - - #ifdef DISCARD_ALPHA - if(alpha < m_AlphaDiscardThreshold){ - discard; - } - #endif - - // *********************** - // Read from textures - // *********************** - #if defined(NORMALMAP) - vec4 normalHeight = texture2D(m_NormalMap, newTexCoord); - // Note we invert directx style normal maps to opengl style - - #ifdef NORMALSCALE - vec3 normal = normalize((normalHeight.xyz * vec3(2.0, NORMAL_TYPE * 2.0, 2.0) - vec3(1.0, NORMAL_TYPE * 1.0, 1.0)) * vec3(m_NormalScale, m_NormalScale, 1.0)); - #else - vec3 normal = normalize((normalHeight.xyz * vec3(2.0, NORMAL_TYPE * 2.0, 2.0) - vec3(1.0, NORMAL_TYPE * 1.0, 1.0))); - #endif - normal = normalize(tbnMat * normal); - //normal = normalize(normal * inverse(tbnMat)); - #else - vec3 normal = norm; - #endif - - #ifdef SPECGLOSSPIPELINE - - #ifdef USE_PACKED_SG - vec4 specularColor = texture2D(m_SpecularGlossinessMap, newTexCoord); - float glossiness = specularColor.a * m_Glossiness; - specularColor *= m_Specular; - #else - #ifdef SPECULARMAP - vec4 specularColor = texture2D(m_SpecularMap, newTexCoord); - #else - vec4 specularColor = vec4(1.0); - #endif - #ifdef GLOSSINESSMAP - float glossiness = texture2D(m_GlossinessMap, newTexCoord).r * m_Glossiness; - #else - float glossiness = m_Glossiness; - #endif - specularColor *= m_Specular; - #endif - vec4 diffuseColor = albedo;// * (1.0 - max(max(specularColor.r, specularColor.g), specularColor.b)); - Roughness = 1.0 - glossiness; - vec3 fZero = specularColor.xyz; - #else - float specular = 0.5; - float nonMetalSpec = 0.08 * specular; - vec4 specularColor = (nonMetalSpec - nonMetalSpec * Metallic) + albedo * Metallic; - vec4 diffuseColor = albedo - albedo * Metallic; - vec3 fZero = vec3(specular); - #endif - - gl_FragColor.rgb = vec3(0.0); - vec3 ao = vec3(1.0); - - #ifdef LIGHTMAP - vec3 lightMapColor; - #ifdef SEPARATE_TEXCOORD - lightMapColor = texture2D(m_LightMap, texCoord2).rgb; - #else - lightMapColor = texture2D(m_LightMap, texCoord).rgb; - #endif - #ifdef AO_MAP - lightMapColor.gb = lightMapColor.rr; - ao = lightMapColor; - #else - gl_FragColor.rgb += diffuseColor.rgb * lightMapColor; - #endif - specularColor.rgb *= lightMapColor; - #endif - - #if defined(AO_PACKED_IN_MR_MAP) && defined(USE_PACKED_MR) - ao = aoRoughnessMetallicValue.rrr; - #endif - - #ifdef AO_STRENGTH - ao = 1.0 + m_AoStrength * (ao - 1.0); - // sanity check - ao = clamp(ao, 0.0, 1.0); - #endif - - #ifdef SPECULAR_AA - float sigma = 1.0; - float kappa = 0.18; - #ifdef SPECULAR_AA_SCREEN_SPACE_VARIANCE - sigma = m_SpecularAASigma; - #endif - #ifdef SPECULAR_AA_THRESHOLD - kappa = m_SpecularAAKappa; - #endif - #endif - float ndotv = max( dot( normal, viewDir ),0.0); - for( int i = 0;i < NB_LIGHTS; i+=3){ - vec4 lightColor = g_LightData[i]; - vec4 lightData1 = g_LightData[i+1]; - vec4 lightDir; - vec3 lightVec; - lightComputeDir(wPosition, lightColor.w, lightData1, lightDir, lightVec); - - float fallOff = 1.0; - #if __VERSION__ >= 110 - // allow use of control flow - if(lightColor.w > 1.0){ - #endif - fallOff = computeSpotFalloff(g_LightData[i+2], lightVec); - #if __VERSION__ >= 110 - } - #endif - //point light attenuation - fallOff *= lightDir.w; + vec3 tan = normalize(wTangent.xyz); + mat3 tbnMat = mat3(tan, wTangent.w * cross( (norm), (tan)), norm); //note: these are intentionaly not surroudned by ifDefs relating to normal and parallax maps being defined, because + vec3 vViewDir = viewDir * tbnMat; //other .glslibs may require normal or parallax mapping even if the base model does not hvae those maps - lightDir.xyz = normalize(lightDir.xyz); - vec3 directDiffuse; - vec3 directSpecular; - - #ifdef SPECULAR_AA - float hdotv = PBR_ComputeDirectLightWithSpecularAA( - normal, lightDir.xyz, viewDir, - lightColor.rgb, fZero, Roughness, sigma, kappa, ndotv, - directDiffuse, directSpecular); - #else - float hdotv = PBR_ComputeDirectLight( - normal, lightDir.xyz, viewDir, - lightColor.rgb, fZero, Roughness, ndotv, - directDiffuse, directSpecular); - #endif - - vec3 directLighting = diffuseColor.rgb *directDiffuse + directSpecular; - - gl_FragColor.rgb += directLighting * fallOff; - } - - #if NB_PROBES >= 1 - vec3 color1 = vec3(0.0); - vec3 color2 = vec3(0.0); - vec3 color3 = vec3(0.0); - float weight1 = 1.0; - float weight2 = 0.0; - float weight3 = 0.0; - - float ndf = renderProbe(viewDir, wPosition, normal, norm, Roughness, diffuseColor, specularColor, ndotv, ao, g_LightProbeData, g_ShCoeffs, g_PrefEnvMap, color1); - #if NB_PROBES >= 2 - float ndf2 = renderProbe(viewDir, wPosition, normal, norm, Roughness, diffuseColor, specularColor, ndotv, ao, g_LightProbeData2, g_ShCoeffs2, g_PrefEnvMap2, color2); - #endif - #if NB_PROBES == 3 - float ndf3 = renderProbe(viewDir, wPosition, normal, norm, Roughness, diffuseColor, specularColor, ndotv, ao, g_LightProbeData3, g_ShCoeffs3, g_PrefEnvMap3, color3); - #endif - - #if NB_PROBES >= 2 - float invNdf = max(1.0 - ndf,0.0); - float invNdf2 = max(1.0 - ndf2,0.0); - float sumNdf = ndf + ndf2; - float sumInvNdf = invNdf + invNdf2; - #if NB_PROBES == 3 - float invNdf3 = max(1.0 - ndf3,0.0); - sumNdf += ndf3; - sumInvNdf += invNdf3; - weight3 = ((1.0 - (ndf3 / sumNdf)) / (NB_PROBES - 1)) * (invNdf3 / sumInvNdf); - #endif - - weight1 = ((1.0 - (ndf / sumNdf)) / (NB_PROBES - 1)) * (invNdf / sumInvNdf); - weight2 = ((1.0 - (ndf2 / sumNdf)) / (NB_PROBES - 1)) * (invNdf2 / sumInvNdf); - - float weightSum = weight1 + weight2 + weight3; - - weight1 /= weightSum; - weight2 /= weightSum; - weight3 /= weightSum; - #endif - - #ifdef USE_AMBIENT_LIGHT - color1.rgb *= g_AmbientLightColor.rgb; - color2.rgb *= g_AmbientLightColor.rgb; - color3.rgb *= g_AmbientLightColor.rgb; - #endif - gl_FragColor.rgb += color1 * clamp(weight1,0.0,1.0) + color2 * clamp(weight2,0.0,1.0) + color3 * clamp(weight3,0.0,1.0); + //base PBR params and tex reads: + readMatParamsAndTextures(tbnMat, vViewDir, albedo, Metallic, Roughness, lightMapColor, ao, normal, emissive, alpha); + + // Lighting calculation: + vec3 finalLightingValue = calculatePBRLighting(albedo, Metallic, Roughness, lightMapColor, ao, indoorSunLightExposure, normal, norm, viewDir); + gl_FragColor.rgb += finalLightingValue; - #endif + //apply final emissive value after lighting + gl_FragColor += emissive; //no need for #ifdef check because emissive will be 0,0,0,0 if emissive vars werent defined. - #if defined(EMISSIVE) || defined (EMISSIVEMAP) - #ifdef EMISSIVEMAP - vec4 emissive = texture2D(m_EmissiveMap, newTexCoord); - #ifdef EMISSIVE - emissive *= m_Emissive; - #endif - #else - vec4 emissive = m_Emissive; - #endif - gl_FragColor += emissive * pow(emissive.a, m_EmissivePower) * m_EmissiveIntensity; - #endif gl_FragColor.a = alpha; + //outputs the final value of the selected layer as a color for debug purposes. + #ifdef DEBUG_VALUES_MODE + if(m_DebugValuesMode == 0){ + gl_FragColor.rgb = vec3(albedo); + } + else if(m_DebugValuesMode == 1){ + gl_FragColor.rgb = vec3(normal); + } + else if(m_DebugValuesMode == 2){ + gl_FragColor.rgb = vec3(Roughness); + } + else if(m_DebugValuesMode == 3){ + gl_FragColor.rgb = vec3(Metallic); + } + else if(m_DebugValuesMode == 4){ + gl_FragColor.rgb = ao.rgb; + } + else if(m_DebugValuesMode == 5){ + gl_FragColor.rgb = vec3(emissive.rgb); + } + #endif } From 94701295a9466187ab5b6d2cdcd5b6910a997da3 Mon Sep 17 00:00:00 2001 From: Ryan McDonough Date: Fri, 2 Feb 2024 16:29:29 -0500 Subject: [PATCH 02/22] uploade both .glslibs --- .../Common/ShaderLib/PBRLighting.glsllib | 202 ++++++++++++++++++ .../ShaderLib/PBRLightingParamReads.glsllib | 184 ++++++++++++++++ 2 files changed, 386 insertions(+) create mode 100644 jme3-core/src/main/resources/Common/ShaderLib/PBRLighting.glsllib create mode 100644 jme3-core/src/main/resources/Common/ShaderLib/PBRLightingParamReads.glsllib diff --git a/jme3-core/src/main/resources/Common/ShaderLib/PBRLighting.glsllib b/jme3-core/src/main/resources/Common/ShaderLib/PBRLighting.glsllib new file mode 100644 index 0000000000..116798a63d --- /dev/null +++ b/jme3-core/src/main/resources/Common/ShaderLib/PBRLighting.glsllib @@ -0,0 +1,202 @@ +#import "Common/ShaderLib/Lighting.glsllib" +#import "Common/ShaderLib/PBR.glsllib" + +//declare PBR Lighting vars +uniform vec4 g_LightData[NB_LIGHTS]; +uniform vec3 g_CameraPosition; +uniform vec4 g_AmbientLightColor; + +#if NB_PROBES >= 1 + uniform samplerCube g_PrefEnvMap; + uniform vec3 g_ShCoeffs[9]; + uniform mat4 g_LightProbeData; +#endif +#if NB_PROBES >= 2 + uniform samplerCube g_PrefEnvMap2; + uniform vec3 g_ShCoeffs2[9]; + uniform mat4 g_LightProbeData2; +#endif +#if NB_PROBES == 3 + uniform samplerCube g_PrefEnvMap3; + uniform vec3 g_ShCoeffs3[9]; + uniform mat4 g_LightProbeData3; +#endif + +// Specular-AA +#ifdef SPECULAR_AA_SCREEN_SPACE_VARIANCE + uniform float m_SpecularAASigma; +#endif +#ifdef SPECULAR_AA_THRESHOLD + uniform float m_SpecularAAKappa; +#endif + +vec3 calculatePBRLighting(in vec4 albedo, in float Metallic, in float Roughness, in vec3 lightMapColor, in vec3 ao, in float indoorSunLightExposure, in vec3 normal, in vec3 norm, in vec3 viewDir){ + vec3 finalLightingValue; + + #ifdef SPECGLOSSPIPELINE + + #ifdef USE_PACKED_SG + vec4 specularColor = texture2D(m_SpecularGlossinessMap, newTexCoord); + float glossiness = specularColor.a * m_Glossiness; + specularColor *= m_Specular; + #else + #ifdef SPECULARMAP + vec4 specularColor = texture2D(m_SpecularMap, newTexCoord); + #else + vec4 specularColor = vec4(1.0); + #endif + #ifdef GLOSSINESSMAP + float glossiness = texture2D(m_GlossinessMap, newTexCoord).r * m_Glossiness; + #else + float glossiness = m_Glossiness; + #endif + specularColor *= m_Specular; + #endif + vec4 diffuseColor = albedo;// * (1.0 - max(max(specularColor.r, specularColor.g), specularColor.b)); + Roughness = 1.0 - glossiness; + vec3 fZero = specularColor.xyz; + #else + float specular = 0.5; + float nonMetalSpec = 0.08 * specular; + vec4 specularColor = (nonMetalSpec - nonMetalSpec * Metallic) + albedo * Metallic; + vec4 diffuseColor = albedo - albedo * Metallic; + vec3 fZero = vec3(specular); + #endif + + #ifdef LIGHTMAP + #if !defined(AO_MAP) + finalLightingValue.rgb += diffuseColor.rgb * lightMapColor; + #endif + specularColor.rgb *= lightMapColor; + #endif + + #ifdef SPECULAR_AA + float sigma = 1.0; + float kappa = 0.18; + #ifdef SPECULAR_AA_SCREEN_SPACE_VARIANCE + sigma = m_SpecularAASigma; + #endif + #ifdef SPECULAR_AA_THRESHOLD + kappa = m_SpecularAAKappa; + #endif + #endif + + float finalLightingScale = 1.0; + float brightestPointLight = 1.0; + + float ndotv = max( dot( normal, viewDir ),0.0); + for( int i = 0;i < NB_LIGHTS; i+=3){ + vec4 lightColor = g_LightData[i]; + vec4 lightData1 = g_LightData[i+1]; + vec4 lightDir; + vec3 lightVec; + lightComputeDir(wPosition, lightColor.w, lightData1, lightDir, lightVec); + + float fallOff = 1.0; + #if __VERSION__ >= 110 + // allow use of control flow + if(lightColor.w > 1.0){ + #endif + fallOff = computeSpotFalloff(g_LightData[i+2], lightVec); + #if __VERSION__ >= 110 + } + #endif + //point light attenuation + fallOff *= lightDir.w; + + lightDir.xyz = normalize(lightDir.xyz); + vec3 directDiffuse; + vec3 directSpecular; + + #ifdef SPECULAR_AA + float hdotv = PBR_ComputeDirectLightWithSpecularAA( + normal, lightDir.xyz, viewDir, + lightColor.rgb, fZero, Roughness, sigma, kappa, ndotv, + directDiffuse, directSpecular); + #else + float hdotv = PBR_ComputeDirectLight( + normal, lightDir.xyz, viewDir, + lightColor.rgb, fZero, Roughness, ndotv, + directDiffuse, directSpecular); + #endif + + vec3 directLighting = diffuseColor.rgb *directDiffuse + directSpecular; + + #if defined(USE_VERTEX_COLORS_AS_SUN_INTENSITY) || defined(STATIC_SUN_INTENSITY) + if(fallOff == 1.0){ + directLighting.rgb *= indoorSunLightExposure;// used to scale down how intense just the sun is indoors, and so the ambientLighting can be scaled back up indoors based on nearest pointlight intensity (ambient and direct light are 1.0 fallOff) + } + else{ + brightestPointLight = max(fallOff, brightestPointLight); + } + #endif + + finalLightingValue.rgb += directLighting * fallOff; + } + + float minVertLighting; + #ifdef BRIGHTEN_INDOOR_SHADOWS + minVertLighting = 0.0833; //enable this when using shadows, in order to brighten indoor areas (which are naturally covered from the DL shadows) so that indoor areas are not way too dark when using IndoorLighting with shadows compared to when shadows are off + #else + minVertLighting = 0.0533; + #endif + + finalLightingScale = max(finalLightingScale, brightestPointLight); + finalLightingScale = max(finalLightingScale, minVertLighting); //essentially just the vertColors.r (aka indoor light exposure) multiplied by the time of day scale. + + #if NB_PROBES >= 1 + vec3 color1 = vec3(0.0); + vec3 color2 = vec3(0.0); + vec3 color3 = vec3(0.0); + float weight1 = 1.0; + float weight2 = 0.0; + float weight3 = 0.0; + + float ndf = renderProbe(viewDir, wPosition, normal, norm, Roughness, diffuseColor, specularColor, ndotv, ao, g_LightProbeData, g_ShCoeffs, g_PrefEnvMap, color1); + #if NB_PROBES >= 2 + float ndf2 = renderProbe(viewDir, wPosition, normal, norm, Roughness, diffuseColor, specularColor, ndotv, ao, g_LightProbeData2, g_ShCoeffs2, g_PrefEnvMap2, color2); + #endif + #if NB_PROBES == 3 + float ndf3 = renderProbe(viewDir, wPosition, normal, norm, Roughness, diffuseColor, specularColor, ndotv, ao, g_LightProbeData3, g_ShCoeffs3, g_PrefEnvMap3, color3); + #endif + + #if NB_PROBES >= 2 + float invNdf = max(1.0 - ndf,0.0); + float invNdf2 = max(1.0 - ndf2,0.0); + float sumNdf = ndf + ndf2; + float sumInvNdf = invNdf + invNdf2; + #if NB_PROBES == 3 + float invNdf3 = max(1.0 - ndf3,0.0); + sumNdf += ndf3; + sumInvNdf += invNdf3; + weight3 = ((1.0 - (ndf3 / sumNdf)) / (NB_PROBES - 1)) * (invNdf3 / sumInvNdf); + #endif + + weight1 = ((1.0 - (ndf / sumNdf)) / (NB_PROBES - 1)) * (invNdf / sumInvNdf); + weight2 = ((1.0 - (ndf2 / sumNdf)) / (NB_PROBES - 1)) * (invNdf2 / sumInvNdf); + + float weightSum = weight1 + weight2 + weight3; + + weight1 /= weightSum; + weight2 /= weightSum; + weight3 /= weightSum; + #endif + + #ifdef USE_AMBIENT_LIGHT + color1.rgb *= g_AmbientLightColor.rgb; + color2.rgb *= g_AmbientLightColor.rgb; + color3.rgb *= g_AmbientLightColor.rgb; + #endif + + // multiply probes by the finalLightingScale, as determined by pixel's + // sunlightExposure and adjusted for nearby point/spot lights + color1.rgb *= finalLightingScale; + color2.rgb *= finalLightingScale; + color3.rgb *= finalLightingScale; + + finalLightingValue.rgb += color1 * clamp(weight1,0.0,1.0) + color2 * clamp(weight2,0.0,1.0) + color3 * clamp(weight3,0.0,1.0); + + #endif + + return finalLightingValue; +} \ No newline at end of file diff --git a/jme3-core/src/main/resources/Common/ShaderLib/PBRLightingParamReads.glsllib b/jme3-core/src/main/resources/Common/ShaderLib/PBRLightingParamReads.glsllib new file mode 100644 index 0000000000..539f6b7713 --- /dev/null +++ b/jme3-core/src/main/resources/Common/ShaderLib/PBRLightingParamReads.glsllib @@ -0,0 +1,184 @@ +#import "Common/ShaderLib/Parallax.glsllib" + +varying vec4 Color; + +#ifdef BASECOLORMAP + uniform sampler2D m_BaseColorMap; +#endif + +#ifdef USE_PACKED_MR + uniform sampler2D m_MetallicRoughnessMap; +#else + #ifdef METALLICMAP + uniform sampler2D m_MetallicMap; + #endif + #ifdef ROUGHNESSMAP + uniform sampler2D m_RoughnessMap; + #endif +#endif + +#ifdef EMISSIVE + uniform vec4 m_Emissive; +#endif +#ifdef EMISSIVEMAP + uniform sampler2D m_EmissiveMap; +#endif +#if defined(EMISSIVE) || defined(EMISSIVEMAP) + uniform float m_EmissivePower; + uniform float m_EmissiveIntensity; +#endif + +uniform float m_Roughness; +uniform float m_Metallic; + +#ifdef SPECGLOSSPIPELINE + uniform vec4 m_Specular; + uniform float m_Glossiness; + #ifdef USE_PACKED_SG + uniform sampler2D m_SpecularGlossinessMap; + #else + uniform sampler2D m_SpecularMap; + uniform sampler2D m_GlossinessMap; + #endif +#endif + +#ifdef PARALLAXMAP + uniform sampler2D m_ParallaxMap; +#endif +#if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP))) + uniform float m_ParallaxHeight; +#endif + +#ifdef LIGHTMAP + uniform sampler2D m_LightMap; +#endif + +#ifdef AO_STRENGTH + uniform float m_AoStrength; +#endif + +#if defined(NORMALMAP) || defined(PARALLAXMAP) + uniform sampler2D m_NormalMap; +#endif +#ifdef NORMALSCALE + uniform float m_NormalScale; +#endif + +#if defined(USE_VERTEX_COLORS_AS_SUN_INTENSITY) + varying vec4 vertColors; +#endif +#ifdef STATIC_SUN_INTENSITY + uniform float m_StaticSunIntensity; +#endif + +void readMatParamsAndTextures(in mat3 tbnMat, in vec3 vViewDir, inout vec4 albedo, inout float Metallic, inout float Roughness, inout vec3 lightMapColor, inout vec3 ao, inout vec3 normal, inout vec4 emissive, inout float alpha){ + #if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP))) + #ifdef STEEP_PARALLAX + #ifdef NORMALMAP_PARALLAX + //parallax map is stored in the alpha channel of the normal map + newTexCoord = steepParallaxOffset(m_NormalMap, vViewDir, texCoord, m_ParallaxHeight); + #else + //parallax map is a texture + newTexCoord = steepParallaxOffset(m_ParallaxMap, vViewDir, texCoord, m_ParallaxHeight); + #endif + #else + #ifdef NORMALMAP_PARALLAX + //parallax map is stored in the alpha channel of the normal map + newTexCoord = classicParallaxOffset(m_NormalMap, vViewDir, texCoord, m_ParallaxHeight); + #else + //parallax map is a texture + newTexCoord = classicParallaxOffset(m_ParallaxMap, vViewDir, texCoord, m_ParallaxHeight); + #endif + #endif + #else + newTexCoord = texCoord; + #endif + + #ifdef BASECOLORMAP + albedo = texture2D(m_BaseColorMap, newTexCoord) * Color; + #else + albedo = Color; + #endif + + alpha = albedo.a; + + #ifdef DISCARD_ALPHA + if(alpha < m_AlphaDiscardThreshold){ + discard; + } + #endif + + //ao in r channel, roughness in green channel, metallic in blue channel! + vec3 aoRoughnessMetallicValue = vec3(1.0, 1.0, 0.0); + #ifdef USE_PACKED_MR + aoRoughnessMetallicValue = texture2D(m_MetallicRoughnessMap, newTexCoord).rgb; + Roughness = aoRoughnessMetallicValue.g * max(m_Roughness, 1e-4); + Metallic = aoRoughnessMetallicValue.b * max(m_Metallic, 0.0); + #else + #ifdef ROUGHNESSMAP + Roughness = texture2D(m_RoughnessMap, newTexCoord).r * max(m_Roughness, 1e-4); + #else + Roughness = max(m_Roughness, 1e-4); + #endif + #ifdef METALLICMAP + Metallic = texture2D(m_MetallicMap, newTexCoord).r * max(m_Metallic, 0.0); + #else + Metallic = max(m_Metallic, 0.0); + #endif + #endif + + #if defined(NORMALMAP) + vec4 normalHeight = texture2D(m_NormalMap, newTexCoord); + // Note we invert directx style normal maps to opengl style + #ifdef NORMALSCALE + normal = normalize((normalHeight.xyz * vec3(2.0, NORMAL_TYPE * 2.0, 2.0) - vec3(1.0, NORMAL_TYPE * 1.0, 1.0)) * vec3(m_NormalScale, m_NormalScale, 1.0)); + #else + normal = normalize((normalHeight.xyz * vec3(2.0, NORMAL_TYPE * 2.0, 2.0) - vec3(1.0, NORMAL_TYPE * 1.0, 1.0))); + #endif + normal = normalize(tbnMat * normal); + //normal = normalize(normal * inverse(tbnMat)); + #else + normal = norm; + #endif + + #ifdef LIGHTMAP + #ifdef SEPARATE_TEXCOORD + lightMapColor = texture2D(m_LightMap, texCoord2).rgb; + #else + lightMapColor = texture2D(m_LightMap, texCoord).rgb; + #endif + + #ifdef AO_MAP + lightMapColor.gb = lightMapColor.rr; + ao = lightMapColor; + #endif + #endif + + #if defined(AO_PACKED_IN_MR_MAP) && defined(USE_PACKED_MR) + ao = aoRoughnessMetallicValue.rrr; //note that this will override the AO value if it was previously read from a lightMap that is being used as AO_Map above. so don't try to use an AO map packed in metallic roughness while also using lightmap as ao map + #endif + + #ifdef AO_STRENGTH + ao = 1.0 + m_AoStrength * (ao - 1.0); + // sanity check + ao = clamp(ao, 0.0, 1.0); + #endif + + #if defined(EMISSIVE) || defined (EMISSIVEMAP) + #ifdef EMISSIVEMAP + emissive = texture2D(m_EmissiveMap, newTexCoord); + #ifdef EMISSIVE + emissive *= m_Emissive; + #endif + #endif + emissive = emissive * pow(emissive.a, m_EmissivePower) * m_EmissiveIntensity; + #endif + + #ifdef STATIC_SUN_INTENSITY + indoorSunLightExposure = m_StaticSunIntensity; //single float value to indicate percentage of sunlight hitting the model (only suitable for small models or models with equal sunlight exposure accross the entire model + #endif + #ifdef USE_VERTEX_COLORS_AS_SUN_INTENSITY + indoorSunLightExposure = vertColors.r * indoorSunLightExposure; // use red channel of vertexColors for non-uniform sunlighting accross a single model + #endif + +} \ No newline at end of file From fd30ef40eab5266dff18d211ec3bab0ff1b47b39 Mon Sep 17 00:00:00 2001 From: Ryan McDonough Date: Sat, 3 Feb 2024 11:12:49 -0500 Subject: [PATCH 03/22] Update PBRLighting.frag Forgot about spec-gloss pipeline --- .../Common/MatDefs/Light/PBRLighting.frag | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag b/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag index 88d93c118b..50075e55e8 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag +++ b/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag @@ -10,7 +10,6 @@ vec2 newTexCoord; uniform float m_AlphaDiscardThreshold; #endif - varying vec3 wPosition; varying vec3 wNormal; @@ -27,9 +26,6 @@ varying vec4 wTangent; vec4 albedo = vec4(1.0); float alpha = 1.0; -float Metallic = 0.0; -float Roughness = 0.0; - float emissiveIntensity = 0.0; float emissivePower = 0.0; vec4 emissive = vec4(0.0); @@ -39,6 +35,14 @@ vec3 lightMapColor = vec3(0.0); float indoorSunLightExposure = 1.0; +//metallic pipeline vars: +float Metallic = 0.0; +float Roughness = 0.0; + +//spec gloss pipeline vars: +vec4 specularColor; +float glossiness; + void main(){ vec3 norm = normalize(wNormal); @@ -50,10 +54,10 @@ void main(){ vec3 vViewDir = viewDir * tbnMat; //other .glslibs may require normal or parallax mapping even if the base model does not hvae those maps //base PBR params and tex reads: - readMatParamsAndTextures(tbnMat, vViewDir, albedo, Metallic, Roughness, lightMapColor, ao, normal, emissive, alpha); + readMatParamsAndTextures(tbnMat, vViewDir, albedo, Metallic, Roughness, specularColor, glossiness, lightMapColor, ao, normal, emissive, alpha); // Lighting calculation: - vec3 finalLightingValue = calculatePBRLighting(albedo, Metallic, Roughness, lightMapColor, ao, indoorSunLightExposure, normal, norm, viewDir); + vec3 finalLightingValue = calculatePBRLighting(albedo, Metallic, Roughness, specularColor, glossiness, lightMapColor, ao, indoorSunLightExposure, normal, norm, viewDir); gl_FragColor.rgb += finalLightingValue; //apply final emissive value after lighting From dfa150ff2ee3ed6bd2d589c7ec5176a36136e530 Mon Sep 17 00:00:00 2001 From: Ryan McDonough Date: Sat, 3 Feb 2024 11:15:00 -0500 Subject: [PATCH 04/22] Update PBRLighting.glsllib Added spec-gloss vars --- .../Common/ShaderLib/PBRLighting.glsllib | 24 +++---------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/jme3-core/src/main/resources/Common/ShaderLib/PBRLighting.glsllib b/jme3-core/src/main/resources/Common/ShaderLib/PBRLighting.glsllib index 116798a63d..1b0c6e8609 100644 --- a/jme3-core/src/main/resources/Common/ShaderLib/PBRLighting.glsllib +++ b/jme3-core/src/main/resources/Common/ShaderLib/PBRLighting.glsllib @@ -30,35 +30,17 @@ uniform vec4 g_AmbientLightColor; uniform float m_SpecularAAKappa; #endif -vec3 calculatePBRLighting(in vec4 albedo, in float Metallic, in float Roughness, in vec3 lightMapColor, in vec3 ao, in float indoorSunLightExposure, in vec3 normal, in vec3 norm, in vec3 viewDir){ +vec3 calculatePBRLighting(in vec4 albedo, in float Metallic, in float Roughness, in vec4 specularColor, in float glossiness, in vec3 lightMapColor, in vec3 ao, in float indoorSunLightExposure, in vec3 normal, in vec3 norm, in vec3 viewDir){ vec3 finalLightingValue; #ifdef SPECGLOSSPIPELINE - - #ifdef USE_PACKED_SG - vec4 specularColor = texture2D(m_SpecularGlossinessMap, newTexCoord); - float glossiness = specularColor.a * m_Glossiness; - specularColor *= m_Specular; - #else - #ifdef SPECULARMAP - vec4 specularColor = texture2D(m_SpecularMap, newTexCoord); - #else - vec4 specularColor = vec4(1.0); - #endif - #ifdef GLOSSINESSMAP - float glossiness = texture2D(m_GlossinessMap, newTexCoord).r * m_Glossiness; - #else - float glossiness = m_Glossiness; - #endif - specularColor *= m_Specular; - #endif vec4 diffuseColor = albedo;// * (1.0 - max(max(specularColor.r, specularColor.g), specularColor.b)); Roughness = 1.0 - glossiness; vec3 fZero = specularColor.xyz; #else float specular = 0.5; float nonMetalSpec = 0.08 * specular; - vec4 specularColor = (nonMetalSpec - nonMetalSpec * Metallic) + albedo * Metallic; + specularColor = (nonMetalSpec - nonMetalSpec * Metallic) + albedo * Metallic; vec4 diffuseColor = albedo - albedo * Metallic; vec3 fZero = vec3(specular); #endif @@ -199,4 +181,4 @@ vec3 calculatePBRLighting(in vec4 albedo, in float Metallic, in float Roughness, #endif return finalLightingValue; -} \ No newline at end of file +} From 801d3d611c49d3915bad2c325d14eb62ca56f1e8 Mon Sep 17 00:00:00 2001 From: Ryan McDonough Date: Sat, 3 Feb 2024 11:19:13 -0500 Subject: [PATCH 05/22] Update PBRLightingParamReads.glsllib add inouts for specularColor and glossiness to account for specGloss pipeline --- .../ShaderLib/PBRLightingParamReads.glsllib | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/jme3-core/src/main/resources/Common/ShaderLib/PBRLightingParamReads.glsllib b/jme3-core/src/main/resources/Common/ShaderLib/PBRLightingParamReads.glsllib index 539f6b7713..1a22e6366a 100644 --- a/jme3-core/src/main/resources/Common/ShaderLib/PBRLightingParamReads.glsllib +++ b/jme3-core/src/main/resources/Common/ShaderLib/PBRLightingParamReads.glsllib @@ -71,7 +71,7 @@ uniform float m_Metallic; uniform float m_StaticSunIntensity; #endif -void readMatParamsAndTextures(in mat3 tbnMat, in vec3 vViewDir, inout vec4 albedo, inout float Metallic, inout float Roughness, inout vec3 lightMapColor, inout vec3 ao, inout vec3 normal, inout vec4 emissive, inout float alpha){ +void readMatParamsAndTextures(in mat3 tbnMat, in vec3 vViewDir, inout vec4 albedo, inout float Metallic, inout float Roughness, inout vec4 SpecularColor, inout float glossiness, inout vec3 lightMapColor, inout vec3 ao, inout vec3 normal, inout vec4 emissive, inout float alpha){ #if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP))) #ifdef STEEP_PARALLAX #ifdef NORMALMAP_PARALLAX @@ -141,6 +141,29 @@ void readMatParamsAndTextures(in mat3 tbnMat, in vec3 vViewDir, inout vec4 albed normal = norm; #endif + //spec gloss tex reads: + + #ifdef SPECGLOSSPIPELINE + #ifdef USE_PACKED_SG + specularColor = texture2D(m_SpecularGlossinessMap, newTexCoord); + glossiness = specularColor.a * m_Glossiness; + specularColor *= m_Specular; + #else + #ifdef SPECULARMAP + specularColor = texture2D(m_SpecularMap, newTexCoord); + #else + specularColor = vec4(1.0); + #endif + #ifdef GLOSSINESSMAP + glossiness = texture2D(m_GlossinesMap, newTexCoord).r * m_Glossiness; + #else + glossiness = m_Glossiness; + #endif + specularColor *= m_Specular; + #endif + #endif + + #ifdef LIGHTMAP #ifdef SEPARATE_TEXCOORD lightMapColor = texture2D(m_LightMap, texCoord2).rgb; @@ -181,4 +204,4 @@ void readMatParamsAndTextures(in mat3 tbnMat, in vec3 vViewDir, inout vec4 albed indoorSunLightExposure = vertColors.r * indoorSunLightExposure; // use red channel of vertexColors for non-uniform sunlighting accross a single model #endif -} \ No newline at end of file +} From da4326545312ab415f8278d96291ce581ac12478 Mon Sep 17 00:00:00 2001 From: Ryan McDonough Date: Sat, 3 Feb 2024 11:47:35 -0500 Subject: [PATCH 06/22] Update PBRLighting.vert removed ifDef checks around some things (like tangents) that could still be used by other glslibs even if the shader doesn't have a normal map. --- .../Common/MatDefs/Light/PBRLighting.vert | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 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 b910a8d4b2..0595e0629c 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.vert +++ b/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.vert @@ -18,23 +18,27 @@ attribute vec3 inPosition; attribute vec2 inTexCoord; attribute vec3 inNormal; -#ifdef VERTEX_COLOR - attribute vec4 inColor; +#if defined (VERTEX_COLOR) || defined(USE_VERTEX_COLORS_AS_SUN_INTENSITY) + attribute vec4 inColor; +#endif + +#if defined(USE_VERTEX_COLORS_AS_SUN_INTENSITY) + varying vec4 vertColors; #endif varying vec3 wNormal; varying vec3 wPosition; -#if defined(NORMALMAP) || defined(PARALLAXMAP) - attribute vec4 inTangent; - varying vec4 wTangent; -#endif + +attribute vec4 inTangent; +varying vec4 wTangent; void main(){ vec4 modelSpacePos = vec4(inPosition, 1.0); vec3 modelSpaceNorm = inNormal; + vec3 modelSpaceTan = inTangent.xyz; - #if ( defined(NORMALMAP) || defined(PARALLAXMAP)) && !defined(VERTEX_LIGHTING) - vec3 modelSpaceTan = inTangent.xyz; + #ifdef USE_VERTEX_COLORS_AS_SUN_INTENSITY + vertColors = inColor; #endif #ifdef NUM_MORPH_TARGETS @@ -61,10 +65,7 @@ void main(){ wPosition = TransformWorld(modelSpacePos).xyz; wNormal = TransformWorldNormal(modelSpaceNorm); - - #if defined(NORMALMAP) || defined(PARALLAXMAP) - wTangent = vec4(TransformWorldNormal(modelSpaceTan),inTangent.w); - #endif + wTangent = vec4(TransformWorldNormal(modelSpaceTan),inTangent.w); Color = m_BaseColor; From 458e3bd36350ce2e5677c87adbacdc8e3caab95b Mon Sep 17 00:00:00 2001 From: Ryan McDonough Date: Sat, 3 Feb 2024 11:55:37 -0500 Subject: [PATCH 07/22] Update PBRLighting.j3md add matDefs for indoor sunlight exposure and debugging final output. These features were previously not in PBRLighting.frag, but they are in PBRTerrain.frag which will eventually share the same glslib for lighting (after doing texture reads), so they both should be consistent. --- .../Common/MatDefs/Light/PBRLighting.j3md | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.j3md b/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.j3md index 1ee65eeb61..11b39f1d11 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.j3md +++ b/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.j3md @@ -132,6 +132,22 @@ MaterialDef PBR Lighting { Boolean UseVertexColor Boolean BackfaceShadows : false + + Boolean UseVertexColorsAsSunIntensity + Float StaticSunIntensity + Boolean BrightenIndoorShadows + + Int DebugValuesMode + // debugs the final value of the selected layer as a color output: + // Layers: + // 0 - albedo (un-shaded) + // 1 - normals + // 2 - roughness + // 3 - metallic + // 4 - ao + // 5 - emissive + + } Technique { @@ -182,6 +198,10 @@ MaterialDef PBR Lighting { NUM_MORPH_TARGETS: NumberOfMorphTargets NUM_TARGETS_BUFFERS: NumberOfTargetsBuffers HORIZON_FADE: HorizonFade + USE_VERTEX_COLORS_AS_SUN_INTENSITY : UseVertexColorsAsSunIntensity + STATIC_SUN_INTENSITY : StaticSunIntensity + BRIGHTEN_INDOOR_SHADOWS : BrightenIndoorShadows + DEBUG_VALUES_MODE : DebugValuesMode } } From 02156751c202effbdb35cc41f47da02849d54a43 Mon Sep 17 00:00:00 2001 From: Ryan McDonough Date: Sat, 3 Feb 2024 21:44:00 -0500 Subject: [PATCH 08/22] Update PBRLightingParamReads.glsllib remove unnecessary assignment of norm, as normal will already = norm if a normalMap is not assigned, and norm isn't used anywhere else in this glslib so no need to pass it in --- .../resources/Common/ShaderLib/PBRLightingParamReads.glsllib | 2 -- 1 file changed, 2 deletions(-) diff --git a/jme3-core/src/main/resources/Common/ShaderLib/PBRLightingParamReads.glsllib b/jme3-core/src/main/resources/Common/ShaderLib/PBRLightingParamReads.glsllib index 1a22e6366a..e6d14d84f1 100644 --- a/jme3-core/src/main/resources/Common/ShaderLib/PBRLightingParamReads.glsllib +++ b/jme3-core/src/main/resources/Common/ShaderLib/PBRLightingParamReads.glsllib @@ -137,8 +137,6 @@ void readMatParamsAndTextures(in mat3 tbnMat, in vec3 vViewDir, inout vec4 albed #endif normal = normalize(tbnMat * normal); //normal = normalize(normal * inverse(tbnMat)); - #else - normal = norm; #endif //spec gloss tex reads: From 6d29bbbf63421d9e0b99441e01d7ce74d45d42a4 Mon Sep 17 00:00:00 2001 From: Ryan McDonough Date: Mon, 5 Feb 2024 09:45:26 -0500 Subject: [PATCH 09/22] Update and rename PBRLightingParamReads.glsllib to PBRLightingParamsReader.glsllib renamed to PBRLightingParamsReader.glsllib --- ...LightingParamReads.glsllib => PBRLightingParamsReader.glsllib} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename jme3-core/src/main/resources/Common/ShaderLib/{PBRLightingParamReads.glsllib => PBRLightingParamsReader.glsllib} (100%) diff --git a/jme3-core/src/main/resources/Common/ShaderLib/PBRLightingParamReads.glsllib b/jme3-core/src/main/resources/Common/ShaderLib/PBRLightingParamsReader.glsllib similarity index 100% rename from jme3-core/src/main/resources/Common/ShaderLib/PBRLightingParamReads.glsllib rename to jme3-core/src/main/resources/Common/ShaderLib/PBRLightingParamsReader.glsllib From 436e7daa5bff9545207284138a649881b79c1581 Mon Sep 17 00:00:00 2001 From: Ryan McDonough Date: Mon, 5 Feb 2024 09:47:43 -0500 Subject: [PATCH 10/22] Update path for shader lib imports --- .../src/main/resources/Common/MatDefs/Light/PBRLighting.frag | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag b/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag index 50075e55e8..715ddd4900 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag +++ b/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag @@ -15,8 +15,8 @@ varying vec3 wPosition; varying vec3 wNormal; varying vec4 wTangent; -#import "MatDefs/ShaderLib/PBRLightingParamReads.glsllib" -#import "MatDefs/ShaderLib/PBRLighting.glsllib" +#import "Common/ShaderLib/PBRLightingParamsReader.glsllib" +#import "Common/ShaderLib/PBRLighting.glsllib" //Important that these 2 ^ glsllibs are referenced AFTER other variables are declared above. // any variables above are declared there (rather than in a glslib) to reduce rendundancy, because these vars likely to used by more than 1 glslib. // Only lighting vars are declared in PBRLighting.glslib, and only basePBR matParams are declared in PBRLightingParamReads.glslib From 05f61b2776e377349ac8b92c8c11a5c552038c22 Mon Sep 17 00:00:00 2001 From: Ryan McDonough Date: Mon, 5 Feb 2024 10:35:15 -0500 Subject: [PATCH 11/22] Fix typos in documentation --- .../Common/MatDefs/Light/PBRLighting.frag | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag b/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag index 715ddd4900..62b9009d85 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag +++ b/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag @@ -17,11 +17,12 @@ varying vec4 wTangent; #import "Common/ShaderLib/PBRLightingParamsReader.glsllib" #import "Common/ShaderLib/PBRLighting.glsllib" -//Important that these 2 ^ glsllibs are referenced AFTER other variables are declared above. -// any variables above are declared there (rather than in a glslib) to reduce rendundancy, because these vars likely to used by more than 1 glslib. -// Only lighting vars are declared in PBRLighting.glslib, and only basePBR matParams are declared in PBRLightingParamReads.glslib -//This allows jme devs to fork this shader and make their own changes before the base PBR param-reads or before the final lighting calculation. -//For example, you could move texCoords based on g_Time prior to texReads for a simple moving water/lava effect. or blend values like albedo/roughness after tex reads but before the final lighting calculations to do things like dynamic texture splatting +// It is important that these 2 glsllibs are referenced AFTER the other variables above have been declared. +// The above variables are declared here (rather than in a glsllib) to reduce redundancy, since these variables are likely to be used by more than one glsllib. +// Only lighting variables are declared in PBRLighting.glsllib, and only basic PBR material params are declared in PBRLightingParamsReader.glsllib. +// This allows jme developers to create a fork of this shader and make their own changes before reading the base PBR parameters or before the final lighting calculation. +// For example, you can move texCoords based on g_Time before texReads for a simple moving water/lava effect, or blend values like albedo/roughness after the param reads +// but before final lighting calculations to do things like dynamic texture splatting. vec4 albedo = vec4(1.0); float alpha = 1.0; @@ -48,10 +49,12 @@ void main(){ vec3 norm = normalize(wNormal); vec3 normal = norm; vec3 viewDir = normalize(g_CameraPosition - wPosition); - + + // Note: These are intentionally not surrounded by ifDefs relating to normal and parallax maps being defined, because + // other .glsllibs may require normal or parallax mapping even if the base model does not have those maps vec3 tan = normalize(wTangent.xyz); - mat3 tbnMat = mat3(tan, wTangent.w * cross( (norm), (tan)), norm); //note: these are intentionaly not surroudned by ifDefs relating to normal and parallax maps being defined, because - vec3 vViewDir = viewDir * tbnMat; //other .glslibs may require normal or parallax mapping even if the base model does not hvae those maps + mat3 tbnMat = mat3(tan, wTangent.w * cross( (norm), (tan)), norm); + vec3 vViewDir = viewDir * tbnMat; //base PBR params and tex reads: readMatParamsAndTextures(tbnMat, vViewDir, albedo, Metallic, Roughness, specularColor, glossiness, lightMapColor, ao, normal, emissive, alpha); From cb3f8a178699add39cd7d56b87a2542883f01f60 Mon Sep 17 00:00:00 2001 From: Ryan McDonough Date: Mon, 5 Feb 2024 10:55:54 -0500 Subject: [PATCH 12/22] Update PBRLighting.frag not sure why build failed after last commit that was only changing comments. resubmitting to try again... --- .../src/main/resources/Common/MatDefs/Light/PBRLighting.frag | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag b/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag index 62b9009d85..4c44c7fe1e 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag +++ b/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag @@ -10,8 +10,7 @@ vec2 newTexCoord; uniform float m_AlphaDiscardThreshold; #endif -varying vec3 wPosition; - +varying vec3 wPosition; varying vec3 wNormal; varying vec4 wTangent; From 1ae4b34a78d11db397058a4f8dda25caef63a003 Mon Sep 17 00:00:00 2001 From: Ryan McDonough Date: Mon, 5 Feb 2024 14:05:24 -0500 Subject: [PATCH 13/22] Update PBRLighting.j3md --- .../main/resources/Common/MatDefs/Light/PBRLighting.j3md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.j3md b/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.j3md index 11b39f1d11..ae81b34fe0 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.j3md +++ b/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.j3md @@ -140,14 +140,12 @@ MaterialDef PBR Lighting { Int DebugValuesMode // debugs the final value of the selected layer as a color output: // Layers: - // 0 - albedo (un-shaded) + // 0 - albedo (unshaded) // 1 - normals // 2 - roughness // 3 - metallic // 4 - ao - // 5 - emissive - - + // 5 - emissive } Technique { From 6bb4f6a33bbb16815929fab8273491e107d468da Mon Sep 17 00:00:00 2001 From: Ryan McDonough Date: Tue, 6 Feb 2024 20:27:31 -0500 Subject: [PATCH 14/22] remove 2 more unused vars --- .../src/main/resources/Common/MatDefs/Light/PBRLighting.frag | 2 -- 1 file changed, 2 deletions(-) diff --git a/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag b/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag index 4c44c7fe1e..7c1b5b68d2 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag +++ b/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag @@ -26,8 +26,6 @@ varying vec4 wTangent; vec4 albedo = vec4(1.0); float alpha = 1.0; -float emissiveIntensity = 0.0; -float emissivePower = 0.0; vec4 emissive = vec4(0.0); vec3 ao = vec3(1.0); From 191f8cb7bd87a0c288dc9f3253d806ee52a9f95a Mon Sep 17 00:00:00 2001 From: Ryan McDonough Date: Thu, 8 Feb 2024 13:26:11 -0500 Subject: [PATCH 15/22] Update PBRLighting.frag --- .../src/main/resources/Common/MatDefs/Light/PBRLighting.frag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag b/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag index 7c1b5b68d2..56b7bfdca0 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag +++ b/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag @@ -54,7 +54,7 @@ void main(){ vec3 vViewDir = viewDir * tbnMat; //base PBR params and tex reads: - readMatParamsAndTextures(tbnMat, vViewDir, albedo, Metallic, Roughness, specularColor, glossiness, lightMapColor, ao, normal, emissive, alpha); + readMatParamsAndTextures(tbnMat, vViewDir, albedo, Metallic, Roughness, specularColor, glossiness, lightMapColor, ao, indoorSunLightExposure, normal, emissive, alpha); // Lighting calculation: vec3 finalLightingValue = calculatePBRLighting(albedo, Metallic, Roughness, specularColor, glossiness, lightMapColor, ao, indoorSunLightExposure, normal, norm, viewDir); From 65bd8e7b3411a9264e39a9c47df5d0cefa7a1c40 Mon Sep 17 00:00:00 2001 From: Ryan McDonough Date: Thu, 8 Feb 2024 13:28:38 -0500 Subject: [PATCH 16/22] Update PBRLightingParamsReader.glsllib added missing in/out to readMatParamsAndTextures --- .../resources/Common/ShaderLib/PBRLightingParamsReader.glsllib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jme3-core/src/main/resources/Common/ShaderLib/PBRLightingParamsReader.glsllib b/jme3-core/src/main/resources/Common/ShaderLib/PBRLightingParamsReader.glsllib index e6d14d84f1..6d78bd432b 100644 --- a/jme3-core/src/main/resources/Common/ShaderLib/PBRLightingParamsReader.glsllib +++ b/jme3-core/src/main/resources/Common/ShaderLib/PBRLightingParamsReader.glsllib @@ -71,7 +71,7 @@ uniform float m_Metallic; uniform float m_StaticSunIntensity; #endif -void readMatParamsAndTextures(in mat3 tbnMat, in vec3 vViewDir, inout vec4 albedo, inout float Metallic, inout float Roughness, inout vec4 SpecularColor, inout float glossiness, inout vec3 lightMapColor, inout vec3 ao, inout vec3 normal, inout vec4 emissive, inout float alpha){ +void readMatParamsAndTextures(in mat3 tbnMat, in vec3 vViewDir, inout vec4 albedo, inout float Metallic, inout float Roughness, inout vec4 SpecularColor, inout float glossiness, inout vec3 lightMapColor, inout vec3 ao, inout float indoorSunLightExposure, inout vec3 normal, inout vec4 emissive, inout float alpha){ #if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP))) #ifdef STEEP_PARALLAX #ifdef NORMALMAP_PARALLAX From 0eaceb578a51d61b4d11bbe89741db3d6763b42d Mon Sep 17 00:00:00 2001 From: Ryan McDonough Date: Wed, 14 Feb 2024 00:33:00 -0500 Subject: [PATCH 17/22] Update PBRLighting.frag added missing uniform to .frag shader --- .../src/main/resources/Common/MatDefs/Light/PBRLighting.frag | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag b/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag index 56b7bfdca0..99b7155d60 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag +++ b/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag @@ -10,10 +10,15 @@ vec2 newTexCoord; uniform float m_AlphaDiscardThreshold; #endif +#ifdef DEBUG_VALUES_MODE + uniform int m_DebugValuesMode; +#endif + varying vec3 wPosition; varying vec3 wNormal; varying vec4 wTangent; + #import "Common/ShaderLib/PBRLightingParamsReader.glsllib" #import "Common/ShaderLib/PBRLighting.glsllib" // It is important that these 2 glsllibs are referenced AFTER the other variables above have been declared. From e3db2a3f754bf58fb6c953820db1c2c3dc7451ca Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Thu, 7 Mar 2024 11:58:59 +0100 Subject: [PATCH 18/22] Struct pre-preprocessor directive --- .../com/jme3/shader/GLSLPreprocessorTest.java | 48 ++++++++++ ...LSLPreprocessorTest.testStruct.validOutput | 8 ++ ...rocessorTest.testStructExtends.validOutput | 17 ++++ ...sorTest.testStructExtendsMulti.validOutput | 21 +++++ .../java/jme3tools/shader/Preprocessor.java | 93 +++++++++++++++++++ 5 files changed, 187 insertions(+) create mode 100644 jme3-core/src/test/resources/GLSLPreprocessorTest.testStruct.validOutput create mode 100644 jme3-core/src/test/resources/GLSLPreprocessorTest.testStructExtends.validOutput create mode 100644 jme3-core/src/test/resources/GLSLPreprocessorTest.testStructExtendsMulti.validOutput diff --git a/jme3-core/src/test/java/com/jme3/shader/GLSLPreprocessorTest.java b/jme3-core/src/test/java/com/jme3/shader/GLSLPreprocessorTest.java index 91ab893ad5..5ba4ecd2c7 100644 --- a/jme3-core/src/test/java/com/jme3/shader/GLSLPreprocessorTest.java +++ b/jme3-core/src/test/java/com/jme3/shader/GLSLPreprocessorTest.java @@ -75,4 +75,52 @@ public void testFOR() throws Exception{ String sourceCheck=readAllAsString(testData.openStream()); assertEquals(sourceCheck, processedSource); } + + @Test + public void testStruct() throws Exception { + String source = "// nothing\n#struct MyStruct \n" + " float x ;//nothing \n" + " float y;\n" + + "#endstruct\n//nothing"; + String processedSource = readAllAsString( + Preprocessor.apply(new ByteArrayInputStream(source.getBytes("UTF-8")))); + System.out.println(processedSource); + AssetInfo testData = TestUtil.createAssetManager() + .locateAsset(new AssetKey("GLSLPreprocessorTest.testStruct.validOutput")); + assertNotNull(testData); + String sourceCheck = readAllAsString(testData.openStream()); + assertEquals(sourceCheck, processedSource); + } + + @Test + public void testStructExtends() throws Exception { + String source = "// nothing\n#struct BaseStruct \n" + " float x0;\n" + " float y0;\n" + + "#endstruct\n//nothing\n"; + source += "//nothing\n#struct MyStruct extends BaseStruct \n" + " float x;\n" + " float y;\n" + + "#endstruct\n//nothing\n"; + String processedSource = readAllAsString( + Preprocessor.apply(new ByteArrayInputStream(source.getBytes("UTF-8")))); + System.out.println(processedSource); + AssetInfo testData = TestUtil.createAssetManager() + .locateAsset(new AssetKey("GLSLPreprocessorTest.testStructExtends.validOutput")); + assertNotNull(testData); + String sourceCheck = readAllAsString(testData.openStream()); + assertEquals(sourceCheck, processedSource); + } + + @Test + public void testStructExtendsMulti() throws Exception { + String source = "#struct BaseStruct \n" + " float x0;\n" + " float y0;\n" + "#endstruct\n"; + source += "#struct BaseStruct2 \n" + " float x1;\n" + " float y1;\n" + + "#endstruct\n//nothing\n"; + source += "#struct MyStruct extends BaseStruct, BaseStruct2\n" + " float x;\n" + " float y;\n" + + "#endstruct\n"; + String processedSource = readAllAsString( + Preprocessor.apply(new ByteArrayInputStream(source.getBytes("UTF-8")))); + System.out.println(processedSource); + AssetInfo testData = TestUtil.createAssetManager().locateAsset( + new AssetKey("GLSLPreprocessorTest.testStructExtendsMulti.validOutput")); + assertNotNull(testData); + String sourceCheck = readAllAsString(testData.openStream()); + assertEquals(sourceCheck, processedSource); + } + } diff --git a/jme3-core/src/test/resources/GLSLPreprocessorTest.testStruct.validOutput b/jme3-core/src/test/resources/GLSLPreprocessorTest.testStruct.validOutput new file mode 100644 index 0000000000..92c188d798 --- /dev/null +++ b/jme3-core/src/test/resources/GLSLPreprocessorTest.testStruct.validOutput @@ -0,0 +1,8 @@ +// nothing +#define STRUCT_MyStruct \ +float x ; \ +float y; +struct MyStruct { +STRUCT_MyStruct +}; +//nothing \ No newline at end of file diff --git a/jme3-core/src/test/resources/GLSLPreprocessorTest.testStructExtends.validOutput b/jme3-core/src/test/resources/GLSLPreprocessorTest.testStructExtends.validOutput new file mode 100644 index 0000000000..a12371192f --- /dev/null +++ b/jme3-core/src/test/resources/GLSLPreprocessorTest.testStructExtends.validOutput @@ -0,0 +1,17 @@ +// nothing +#define STRUCT_BaseStruct \ +float x0; \ +float y0; +struct BaseStruct { +STRUCT_BaseStruct +}; +//nothing +//nothing +#define STRUCT_MyStruct \ +STRUCT_BaseStruct \ +float x; \ +float y; +struct MyStruct { +STRUCT_MyStruct +}; +//nothing \ No newline at end of file diff --git a/jme3-core/src/test/resources/GLSLPreprocessorTest.testStructExtendsMulti.validOutput b/jme3-core/src/test/resources/GLSLPreprocessorTest.testStructExtendsMulti.validOutput new file mode 100644 index 0000000000..6cd2227924 --- /dev/null +++ b/jme3-core/src/test/resources/GLSLPreprocessorTest.testStructExtendsMulti.validOutput @@ -0,0 +1,21 @@ +#define STRUCT_BaseStruct \ +float x0; \ +float y0; +struct BaseStruct { +STRUCT_BaseStruct +}; +#define STRUCT_BaseStruct2 \ +float x1; \ +float y1; +struct BaseStruct2 { +STRUCT_BaseStruct2 +}; +//nothing +#define STRUCT_MyStruct \ +STRUCT_BaseStruct \ +STRUCT_BaseStruct2 \ +float x; \ +float y; +struct MyStruct { +STRUCT_MyStruct +}; \ No newline at end of file diff --git a/jme3-core/src/tools/java/jme3tools/shader/Preprocessor.java b/jme3-core/src/tools/java/jme3tools/shader/Preprocessor.java index e99c0a7ad4..7c429e1e7b 100644 --- a/jme3-core/src/tools/java/jme3tools/shader/Preprocessor.java +++ b/jme3-core/src/tools/java/jme3tools/shader/Preprocessor.java @@ -58,6 +58,7 @@ public static InputStream apply(InputStream in) throws IOException { String code = bos.toString("UTF-8"); code = Preprocessor.forMacro(code); + code = Preprocessor.structMacro(code); return new ByteArrayInputStream(code.getBytes("UTF-8")); } @@ -118,4 +119,96 @@ public static String forMacro(String code) { return code; } + /** + * + * #struct MyStruct extends BaseStruct, BaseStruct2 + * int i; + * int b; + * #endstruct + * + */ + // match #struct MyStruct extends BaseStruct, BaseStruct2 + // extends is optional + // private static final Pattern FOR_REGEX = Pattern + // .compile("([^=]+)=\\s*([0-9]+)\\s*\\.\\.\\s*([0-9]+)\\s*\\((.+)\\)"); + + private static final Pattern STRUCT_REGEX = Pattern + .compile("(\\w+)(?:\\s+extends\\s+(\\w+(?:,\\s*\\w+)*))?"); + + public static String structMacro(String code) { + StringBuilder expandedCode = new StringBuilder(); + StringBuilder currentStruct = null; + String structDec = null; + int skip = 0; + String[] codeLines = code.split("\n"); + boolean captured = false; + for (String line : codeLines) { + if (!captured) { + String trimmedLine = line.trim(); + if (trimmedLine.startsWith("#struct")) { + if (skip == 0) { + structDec = trimmedLine; + currentStruct = new StringBuilder(); + skip++; + continue; + } + skip++; + } else if (trimmedLine.startsWith("#endstruct")) { + skip--; + if (skip == 0) { + structDec = structDec.substring("#struct ".length()).trim(); + + Matcher matcher = STRUCT_REGEX.matcher(structDec); + if (matcher.matches()) { + String structName = matcher.group(1); + if (structName == null) structName = ""; + + String extendsStructs = matcher.group(2); + String extendedStructs[]; + if (extendsStructs != null) { + extendedStructs = extendsStructs.split(",\\s*"); + } else { + extendedStructs = new String[0]; + } + String structBody = currentStruct.toString(); + if (structBody == null) structBody = ""; + else { + // remove tail spaces + structBody = structBody.replaceAll("\\s+$", ""); + } + + currentStruct = null; + expandedCode.append("#define STRUCT_").append(structName).append(" \\\n"); + for (String extendedStruct : extendedStructs) { + expandedCode.append("STRUCT_").append(extendedStruct).append(" \\\n"); + } + String structBodyLines[] = structBody.split("\n"); + for (int i = 0; i < structBodyLines.length; i++) { + String structBodyLine = structBodyLines[i]; + structBodyLine = structBodyLine.trim(); + if (structBodyLine == "") continue; + // remove comments if any + int commentIndex = structBodyLine.indexOf("//"); + if (commentIndex >= 0) + structBodyLine = structBodyLine.substring(0, commentIndex); + expandedCode.append(structBodyLine); + if (i < structBodyLines.length - 1) expandedCode.append(" \\"); + expandedCode.append("\n"); + } + expandedCode.append("struct ").append(structName).append(" { \nSTRUCT_") + .append(structName).append("\n};\n"); + captured = true; + continue; + } + } + } + } + if (currentStruct != null) currentStruct.append(line).append("\n"); + else expandedCode.append(line).append("\n"); + } + code = expandedCode.toString(); + if (captured) code = structMacro(code); + return code; + } + } \ No newline at end of file From f0fbf7a56ff1dd524094c2f30eff3581f182252f Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Thu, 7 Mar 2024 14:44:15 +0100 Subject: [PATCH 19/22] Modular PBR Co-authored-by: Ryan McDonough --- .../MatDefs/Light/modular/PBRLighting.frag | 73 +++ .../MatDefs/Light/modular/PBRLighting.j3md | 321 ++++++++++ .../MatDefs/Light/modular/PBRLighting.vert | 75 +++ .../resources/Common/ShaderLib/Math.glsllib | 15 +- .../Common/ShaderLib/module/Light.glsl | 34 + .../Common/ShaderLib/module/PBRSurface.glsl | 39 ++ .../pbrlighting/PBRLightingUtils.glsllib | 600 ++++++++++++++++++ 7 files changed, 1156 insertions(+), 1 deletion(-) create mode 100644 jme3-core/src/main/resources/Common/MatDefs/Light/modular/PBRLighting.frag create mode 100644 jme3-core/src/main/resources/Common/MatDefs/Light/modular/PBRLighting.j3md create mode 100644 jme3-core/src/main/resources/Common/MatDefs/Light/modular/PBRLighting.vert create mode 100644 jme3-core/src/main/resources/Common/ShaderLib/module/Light.glsl create mode 100644 jme3-core/src/main/resources/Common/ShaderLib/module/PBRSurface.glsl create mode 100644 jme3-core/src/main/resources/Common/ShaderLib/module/pbrlighting/PBRLightingUtils.glsllib diff --git a/jme3-core/src/main/resources/Common/MatDefs/Light/modular/PBRLighting.frag b/jme3-core/src/main/resources/Common/MatDefs/Light/modular/PBRLighting.frag new file mode 100644 index 0000000000..3a1ed3ced3 --- /dev/null +++ b/jme3-core/src/main/resources/Common/MatDefs/Light/modular/PBRLighting.frag @@ -0,0 +1,73 @@ +#import "Common/ShaderLib/GLSLCompat.glsllib" + +// enable apis and import PBRLightingUtils +#define ENABLE_PBRLightingUtils_getWorldPosition 1 +#define ENABLE_PBRLightingUtils_getWorldNormal 1 +#define ENABLE_PBRLightingUtils_getWorldTangent 1 +#define ENABLE_PBRLightingUtils_getTexCoord 1 +#define ENABLE_PBRLightingUtils_readPBRSurface 1 +#define ENABLE_PBRLightingUtils_computeDirectLightContribution 1 +#define ENABLE_PBRLightingUtils_computeProbesContribution 1 + +#import "Common/ShaderLib/module/pbrlighting/PBRLightingUtils.glsllib" + +#ifdef DEBUG_VALUES_MODE + uniform int m_DebugValuesMode; +#endif + +uniform vec4 g_LightData[NB_LIGHTS]; +uniform vec3 g_CameraPosition; + +void main(){ + vec3 wpos = PBRLightingUtils_getWorldPosition(); + vec3 worldViewDir = normalize(g_CameraPosition - wpos); + + // Load surface data + PBRSurface surface=PBRLightingUtils_readPBRSurface(worldViewDir); + + // Calculate direct lights + for(int i = 0;i < NB_LIGHTS; i+=3){ + vec4 lightData0 = g_LightData[i]; + vec4 lightData1 = g_LightData[i+1]; + vec4 lightData2 = g_LightData[i+2]; + PBRLightingUtils_computeDirectLightContribution( + lightData0, lightData1, lightData2, + surface + ); + } + + + // Calculate env probes + PBRLightingUtils_computeProbesContribution(surface); + + // Put it all together + gl_FragColor.rgb = vec3(0.0); + gl_FragColor.rgb += surface.bakedLightContribution; + gl_FragColor.rgb += surface.directLightContribution; + gl_FragColor.rgb += surface.envLightContribution; + gl_FragColor.rgb += surface.emission; + gl_FragColor.a = surface.alpha; + + + // outputs the final value of the selected layer as a color for debug purposes. + #ifdef DEBUG_VALUES_MODE + if(m_DebugValuesMode == 0){ + gl_FragColor.rgb = vec3(surface.albedo); + } + else if(m_DebugValuesMode == 1){ + gl_FragColor.rgb = vec3(surface.normal); + } + else if(m_DebugValuesMode == 2){ + gl_FragColor.rgb = vec3(surface.roughness); + } + else if(m_DebugValuesMode == 3){ + gl_FragColor.rgb = vec3(surface.metallic); + } + else if(m_DebugValuesMode == 4){ + gl_FragColor.rgb = surface.ao.rgb; + } + else if(m_DebugValuesMode == 5){ + gl_FragColor.rgb = vec3(surface.emission.rgb); + } + #endif +} diff --git a/jme3-core/src/main/resources/Common/MatDefs/Light/modular/PBRLighting.j3md b/jme3-core/src/main/resources/Common/MatDefs/Light/modular/PBRLighting.j3md new file mode 100644 index 0000000000..78db36cca0 --- /dev/null +++ b/jme3-core/src/main/resources/Common/MatDefs/Light/modular/PBRLighting.j3md @@ -0,0 +1,321 @@ +MaterialDef PBR Lighting { + + MaterialParameters { + Int BoundDrawBuffer + + // Alpha threshold for fragment discarding + Float AlphaDiscardThreshold (AlphaTestFallOff) + + //metallicity of the material + Float Metallic : 1.0 + //Roughness of the material + Float Roughness : 1.0 + // Base material color + Color BaseColor : 1.0 1.0 1.0 1.0 + // The emissive color of the object + Color Emissive + // the emissive power + Float EmissivePower : 3.0 + // the emissive intensity + Float EmissiveIntensity : 2.0 + + // BaseColor map + Texture2D BaseColorMap + + // Metallic map + Texture2D MetallicMap -LINEAR + + // Roughness Map + Texture2D RoughnessMap -LINEAR + + //Metallic and Roughness are packed respectively in the b and g channel of a single map + // r: AO (if AoPackedInMRMap is true) + // g: Roughness + // b: Metallic + Texture2D MetallicRoughnessMap -LINEAR + + // Texture of the emissive parts of the material + Texture2D EmissiveMap + + // Normal map + Texture2D NormalMap -LINEAR + // The scalar parameter applied to each normal vector of the normal map + Float NormalScale + + //The type of normal map: -1.0 (DirectX), 1.0 (OpenGl) + Float NormalType : -1.0 + + // For Spec gloss pipeline + Boolean UseSpecGloss + Texture2D SpecularMap + Texture2D GlossinessMap + Texture2D SpecularGlossinessMap + Color Specular : 1.0 1.0 1.0 1.0 + Float Glossiness : 1.0 + + // Parallax/height map + Texture2D ParallaxMap -LINEAR + + // Specular-AA + Boolean UseSpecularAA : true + // screen space variance,Use the slider to set the strength of the geometric specular anti-aliasing effect between 0 and 1. Higher values produce a blurrier result with less aliasing. + Float SpecularAASigma + // clamping threshold,Use the slider to set a maximum value for the offset that HDRP subtracts from the smoothness value to reduce artifacts. + Float SpecularAAKappa + + //Set to true if parallax map is stored in the alpha channel of the normal map + Boolean PackedNormalParallax + + //Sets the relief height for parallax mapping + Float ParallaxHeight : 0.05 + + //Set to true to activate Steep Parallax mapping + Boolean SteepParallax + + //Horizon fade + Boolean HorizonFade + + // Set to Use Lightmap + Texture2D LightMap + + // A scalar multiplier controlling the amount of occlusion applied. + // A value of `0.0` means no occlusion. A value of `1.0` means full occlusion. + Float AoStrength + + // Set to use TexCoord2 for the lightmap sampling + Boolean SeparateTexCoord + // the light map is a grayscale ao map, only the r channel will be read. + Boolean LightMapAsAOMap + Boolean AoPackedInMRMap + //shadows + Int FilterMode + Boolean HardwareShadows + + Texture2D ShadowMap0 + Texture2D ShadowMap1 + Texture2D ShadowMap2 + Texture2D ShadowMap3 + //pointLights + Texture2D ShadowMap4 + Texture2D ShadowMap5 + + Float ShadowIntensity + Vector4 Splits + Vector2 FadeInfo + + Matrix4 LightViewProjectionMatrix0 + Matrix4 LightViewProjectionMatrix1 + Matrix4 LightViewProjectionMatrix2 + Matrix4 LightViewProjectionMatrix3 + //pointLight + Matrix4 LightViewProjectionMatrix4 + Matrix4 LightViewProjectionMatrix5 + Vector3 LightPos + Vector3 LightDir + + Float PCFEdge + Float ShadowMapSize + + // For hardware skinning + Int NumberOfBones + Matrix4Array BoneMatrices + + // For Morph animation + FloatArray MorphWeights + Int NumberOfMorphTargets + Int NumberOfTargetsBuffers + + // For instancing + Boolean UseInstancing + + // For Vertex Color + Boolean UseVertexColor + + Boolean BackfaceShadows : false + + Boolean UseVertexColorsAsSunIntensity + Float StaticSunIntensity + Boolean BrightenIndoorShadows + + Int DebugValuesMode + // debugs the final value of the selected layer as a color output: + // Layers: + // 0 - albedo (unshaded) + // 1 - normals + // 2 - roughness + // 3 - metallic + // 4 - ao + // 5 - emissive + } + + Technique { + LightMode SinglePassAndImageBased + + VertexShader GLSL300 GLSL150 GLSL110: Common/MatDefs/Light/modular/PBRLighting.vert + FragmentShader GLSL300 GLSL150 GLSL110: Common/MatDefs/Light/modular/PBRLighting.frag + + WorldParameters { + WorldViewProjectionMatrix + CameraPosition + WorldMatrix + WorldNormalMatrix + ViewProjectionMatrix + ViewMatrix + } + + Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer + BASECOLORMAP : BaseColorMap + NORMALMAP : NormalMap + NORMALSCALE : NormalScale + METALLICMAP : MetallicMap + ROUGHNESSMAP : RoughnessMap + EMISSIVEMAP : EmissiveMap + EMISSIVE : Emissive + SPECGLOSSPIPELINE : UseSpecGloss + PARALLAXMAP : ParallaxMap + NORMALMAP_PARALLAX : PackedNormalParallax + STEEP_PARALLAX : SteepParallax + LIGHTMAP : LightMap + SEPARATE_TEXCOORD : SeparateTexCoord + DISCARD_ALPHA : AlphaDiscardThreshold + NUM_BONES : NumberOfBones + INSTANCING : UseInstancing + USE_PACKED_MR: MetallicRoughnessMap + USE_PACKED_SG: SpecularGlossinessMap + SPECULARMAP : SpecularMap + SPECULAR_AA : UseSpecularAA + SPECULAR_AA_SCREEN_SPACE_VARIANCE : SpecularAASigma + SPECULAR_AA_THRESHOLD : SpecularAAKappa + GLOSSINESSMAP : GlossinessMap + NORMAL_TYPE: NormalType + VERTEX_COLOR : UseVertexColor + AO_MAP: LightMapAsAOMap + AO_PACKED_IN_MR_MAP : AoPackedInMRMap + AO_STRENGTH : AoStrength + NUM_MORPH_TARGETS: NumberOfMorphTargets + NUM_TARGETS_BUFFERS: NumberOfTargetsBuffers + HORIZON_FADE: HorizonFade + USE_VERTEX_COLORS_AS_SUN_INTENSITY : UseVertexColorsAsSunIntensity + STATIC_SUN_INTENSITY : StaticSunIntensity + BRIGHTEN_INDOOR_SHADOWS : BrightenIndoorShadows + DEBUG_VALUES_MODE : DebugValuesMode + } + } + + + Technique PreShadow { + + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PreShadow.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PreShadowPBR.frag + + WorldParameters { + WorldViewProjectionMatrix + WorldViewMatrix + ViewProjectionMatrix + ViewMatrix + } + + Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer + DISCARD_ALPHA : AlphaDiscardThreshold + NUM_BONES : NumberOfBones + INSTANCING : UseInstancing + NUM_MORPH_TARGETS: NumberOfMorphTargets + NUM_TARGETS_BUFFERS: NumberOfTargetsBuffers + } + + ForcedRenderState { + FaceCull Off + DepthTest On + DepthWrite On + PolyOffset 5 3 + ColorWrite Off + } + + } + + + Technique PostShadow { + VertexShader GLSL310 GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PostShadow.vert + FragmentShader GLSL310 GLSL300 GLSL150 GLSL100: Common/MatDefs/Shadow/PostShadowPBR.frag + + WorldParameters { + WorldViewProjectionMatrix + WorldMatrix + ViewProjectionMatrix + ViewMatrix + } + + Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer + HARDWARE_SHADOWS : HardwareShadows + FILTER_MODE : FilterMode + PCFEDGE : PCFEdge + DISCARD_ALPHA : AlphaDiscardThreshold + SHADOWMAP_SIZE : ShadowMapSize + FADE : FadeInfo + PSSM : Splits + POINTLIGHT : LightViewProjectionMatrix5 + NUM_BONES : NumberOfBones + INSTANCING : UseInstancing + BACKFACE_SHADOWS: BackfaceShadows + NUM_MORPH_TARGETS: NumberOfMorphTargets + NUM_TARGETS_BUFFERS: NumberOfTargetsBuffers + } + + ForcedRenderState { + Blend Modulate + DepthWrite Off + PolyOffset -0.1 0 + } + } + + Technique PreNormalPass { + + VertexShader GLSL300 GLSL150 GLSL100 : Common/MatDefs/SSAO/normal.vert + FragmentShader GLSL300 GLSL150 GLSL100 : Common/MatDefs/SSAO/normal.frag + + WorldParameters { + WorldViewProjectionMatrix + WorldViewMatrix + NormalMatrix + ViewProjectionMatrix + ViewMatrix + } + + Defines { + BOUND_DRAW_BUFFER: BoundDrawBuffer + BASECOLORMAP_ALPHA : BaseColorMap + NUM_BONES : NumberOfBones + INSTANCING : UseInstancing + NUM_MORPH_TARGETS: NumberOfMorphTargets + NUM_TARGETS_BUFFERS: NumberOfTargetsBuffers + } + + } + + Technique Glow { + + VertexShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Misc/Unshaded.vert + FragmentShader GLSL300 GLSL150 GLSL100: Common/MatDefs/Light/PBRGlow.frag + + WorldParameters { + WorldViewProjectionMatrix + ViewProjectionMatrix + ViewMatrix + } + + Defines { + HAS_EMISSIVEMAP : EmissiveMap + HAS_EMISSIVECOLOR : Emissive + BOUND_DRAW_BUFFER: BoundDrawBuffer + NEED_TEXCOORD1 + NUM_BONES : NumberOfBones + INSTANCING : UseInstancing + NUM_MORPH_TARGETS: NumberOfMorphTargets + NUM_TARGETS_BUFFERS: NumberOfTargetsBuffers + } + } + +} diff --git a/jme3-core/src/main/resources/Common/MatDefs/Light/modular/PBRLighting.vert b/jme3-core/src/main/resources/Common/MatDefs/Light/modular/PBRLighting.vert new file mode 100644 index 0000000000..0595e0629c --- /dev/null +++ b/jme3-core/src/main/resources/Common/MatDefs/Light/modular/PBRLighting.vert @@ -0,0 +1,75 @@ +#import "Common/ShaderLib/GLSLCompat.glsllib" +#import "Common/ShaderLib/Instancing.glsllib" +#import "Common/ShaderLib/Skinning.glsllib" +#import "Common/ShaderLib/MorphAnim.glsllib" + +uniform vec4 m_BaseColor; +uniform vec4 g_AmbientLightColor; +varying vec2 texCoord; + +#ifdef SEPARATE_TEXCOORD + varying vec2 texCoord2; + attribute vec2 inTexCoord2; +#endif + +varying vec4 Color; + +attribute vec3 inPosition; +attribute vec2 inTexCoord; +attribute vec3 inNormal; + +#if defined (VERTEX_COLOR) || defined(USE_VERTEX_COLORS_AS_SUN_INTENSITY) + attribute vec4 inColor; +#endif + +#if defined(USE_VERTEX_COLORS_AS_SUN_INTENSITY) + varying vec4 vertColors; +#endif + +varying vec3 wNormal; +varying vec3 wPosition; + +attribute vec4 inTangent; +varying vec4 wTangent; + +void main(){ + vec4 modelSpacePos = vec4(inPosition, 1.0); + vec3 modelSpaceNorm = inNormal; + vec3 modelSpaceTan = inTangent.xyz; + + #ifdef USE_VERTEX_COLORS_AS_SUN_INTENSITY + vertColors = inColor; + #endif + + #ifdef NUM_MORPH_TARGETS + #if defined(NORMALMAP) && !defined(VERTEX_LIGHTING) + Morph_Compute(modelSpacePos, modelSpaceNorm, modelSpaceTan); + #else + Morph_Compute(modelSpacePos, modelSpaceNorm); + #endif + #endif + + #ifdef NUM_BONES + #if defined(NORMALMAP) && !defined(VERTEX_LIGHTING) + Skinning_Compute(modelSpacePos, modelSpaceNorm, modelSpaceTan); + #else + Skinning_Compute(modelSpacePos, modelSpaceNorm); + #endif + #endif + + gl_Position = TransformWorldViewProjection(modelSpacePos); + texCoord = inTexCoord; + #ifdef SEPARATE_TEXCOORD + texCoord2 = inTexCoord2; + #endif + + wPosition = TransformWorld(modelSpacePos).xyz; + wNormal = TransformWorldNormal(modelSpaceNorm); + wTangent = vec4(TransformWorldNormal(modelSpaceTan),inTangent.w); + + Color = m_BaseColor; + + #ifdef VERTEX_COLOR + Color *= inColor; + #endif +} diff --git a/jme3-core/src/main/resources/Common/ShaderLib/Math.glsllib b/jme3-core/src/main/resources/Common/ShaderLib/Math.glsllib index 6f4cc9074f..d97132fbd2 100644 --- a/jme3-core/src/main/resources/Common/ShaderLib/Math.glsllib +++ b/jme3-core/src/main/resources/Common/ShaderLib/Math.glsllib @@ -1,4 +1,17 @@ +#ifndef __MATH_GLSLLIB__ +#define __MATH_GLSLLIB__ + /// Multiplies the vector by the quaternion, then returns the resultant vector. vec3 Math_QuaternionMult(in vec4 quat, in vec3 vec){ return vec + 2.0 * cross(quat.xyz, cross(quat.xyz, vec) + quat.w * vec); -} \ No newline at end of file +} + +void Math_lengthAndNormalize(in vec3 vec,out float outLength,out vec3 outNormal){ + float dotv=dot(vec,vec); + float invl=inversesqrt(dotv); + outNormal=vec*invl; + outLength=invl*dotv; +} + + +#endif \ No newline at end of file diff --git a/jme3-core/src/main/resources/Common/ShaderLib/module/Light.glsl b/jme3-core/src/main/resources/Common/ShaderLib/module/Light.glsl new file mode 100644 index 0000000000..1021e83772 --- /dev/null +++ b/jme3-core/src/main/resources/Common/ShaderLib/module/Light.glsl @@ -0,0 +1,34 @@ +#ifndef __LIGHT_MODULE__ +#define __LIGHT_MODULE__ + +/** +* Defines a light +*/ + + +#ifndef Light + #struct StdLight + vec4 color; + vec3 position; + float type; + + float invRadius; + float spotAngleCos; + vec3 spotDirection; + + bool ready; + + float NdotL; // cos angle between normal and light direction + float NdotH; // cos angle between normal and half vector + float LdotH; // cos angle between light direction and half vector + float HdotV; // cos angle between view direction and half vector + vec3 vector; + vec3 dir; + float fallOff; + #endstruct + #define Light StdLight +#endif + + + +#endif \ No newline at end of file diff --git a/jme3-core/src/main/resources/Common/ShaderLib/module/PBRSurface.glsl b/jme3-core/src/main/resources/Common/ShaderLib/module/PBRSurface.glsl new file mode 100644 index 0000000000..d8105ed543 --- /dev/null +++ b/jme3-core/src/main/resources/Common/ShaderLib/module/PBRSurface.glsl @@ -0,0 +1,39 @@ +#ifndef __SURFACE_MODULE__ +#define __SURFACE_MODULE__ + +#ifndef PBRSurface + #struct StdPBRSurface + // from geometry + vec3 position; // position in w space + vec3 viewDir; // view dir in worldSpace + vec3 geometryNormal; // normals w/o normalmap + vec3 normal; // normals w/ normalmap + bool frontFacing; //gl_FrontFacing + float depth; + + // from texture + vec3 albedo; + float alpha; + float metallic; // metallic value at the surface + float roughness; + vec3 diffuseColor; + vec3 specularColor; + vec3 fZero; + vec3 ao; + float exposure; + vec3 emission; + + + // computed + float NdotV; + + // from env + vec3 bakedLightContribution; // light from light map or other baked sources + vec3 directLightContribution; // light from direct light sources + vec3 envLightContribution; // light from environment + + float brightestLightStrength; + #endstruct + #define PBRSurface StdPBRSurface +#endif +#endif \ No newline at end of file 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 new file mode 100644 index 0000000000..5fb7f7a6f3 --- /dev/null +++ b/jme3-core/src/main/resources/Common/ShaderLib/module/pbrlighting/PBRLightingUtils.glsllib @@ -0,0 +1,600 @@ +#ifndef __PBR_LIGHT_UTILS_MODULE__ +#define __PBR_LIGHT_UTILS_MODULE__ + +#import "Common/ShaderLib/Math.glsllib" +#import "Common/ShaderLib/PBR.glsllib" +#import "Common/ShaderLib/Parallax.glsllib" + +#import "Common/ShaderLib/module/Light.glsl" +#import "Common/ShaderLib/module/PBRSurface.glsl" + +// enable all apis +// #define ENABLE_PBRLightingUtils_getWorldPosition 1 +// #define ENABLE_PBRLightingUtils_getWorldNormal 1 +// #define ENABLE_PBRLightingUtils_getWorldTangent 1 +// #define ENABLE_PBRLightingUtils_getTexCoord 1 +// #define ENABLE_PBRLightingUtils_newLight 1 +// #define ENABLE_PBRLightingUtils_computeLightInWorldSpace 1 +// #define ENABLE_PBRLightingUtils_readPBRSurface 1 +// #define ENABLE_PBRLightingUtils_computeDirectLight 1 +// #define ENABLE_PBRLightingUtils_computeDirectLightContribution 1 +// #define ENABLE_PBRLightingUtils_computeProbesContribution 1 + +#if defined(ENABLE_PBRLightingUtils_readPBRSurface) || + defined(ENABLE_PBRLightingUtils_getWorldPosition) + varying vec3 wPosition; +#endif + +#if defined(ENABLE_PBRLightingUtils_readPBRSurface) || + defined(ENABLE_PBRLightingUtils_getWorldNormal) + varying vec3 wNormal; +#endif + +#if (defined(ENABLE_PBRLightingUtils_readPBRSurface) && + (defined(NORMALMAP) || defined(PARALLAXMAP)) + ) || + defined(ENABLE_PBRLightingUtils_getWorldTangent) + varying vec3 wTangent; +#endif + +#if defined(ENABLE_PBRLightingUtils_readPBRSurface) || + defined(ENABLE_PBRLightingUtils_getTexCoord) + varying vec2 texCoord; + #ifdef SEPARATE_TEXCOORD + varying vec2 texCoord2; + #endif +#endif + + + +#ifdef ENABLE_PBRLightingUtils_readPBRSurface + + varying vec4 Color; + + + uniform vec4 g_AmbientLightColor; + uniform float m_Roughness; + uniform float m_Metallic; + + + #ifdef BASECOLORMAP + uniform sampler2D m_BaseColorMap; + #endif + + #ifdef USE_PACKED_MR + uniform sampler2D m_MetallicRoughnessMap; + #else + #ifdef METALLICMAP + uniform sampler2D m_MetallicMap; + #endif + #ifdef ROUGHNESSMAP + uniform sampler2D m_RoughnessMap; + #endif + #endif + + #ifdef EMISSIVE + uniform vec4 m_Emissive; + #endif + #ifdef EMISSIVEMAP + uniform sampler2D m_EmissiveMap; + #endif + #if defined(EMISSIVE) || defined(EMISSIVEMAP) + uniform float m_EmissivePower; + uniform float m_EmissiveIntensity; + #endif + + + + #ifdef SPECGLOSSPIPELINE + uniform vec4 m_Specular; + uniform float m_Glossiness; + #ifdef USE_PACKED_SG + uniform sampler2D m_SpecularGlossinessMap; + #else + uniform sampler2D m_SpecularMap; + uniform sampler2D m_GlossinessMap; + #endif + #endif + + #ifdef PARALLAXMAP + uniform sampler2D m_ParallaxMap; + #endif + #if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP))) + uniform float m_ParallaxHeight; + #endif + + #ifdef LIGHTMAP + uniform sampler2D m_LightMap; + #endif + + #ifdef AO_STRENGTH + uniform float m_AoStrength; + #endif + + #if defined(NORMALMAP) || defined(PARALLAXMAP) + uniform sampler2D m_NormalMap; + #endif + #ifdef NORMALSCALE + uniform float m_NormalScale; + #endif + + #ifdef DISCARD_ALPHA + uniform float m_AlphaDiscardThreshold; + #endif + + #if defined(USE_VERTEX_COLORS_AS_SUN_INTENSITY) + varying vec4 vertColors; + #endif + #ifdef STATIC_SUN_INTENSITY + uniform float m_StaticSunIntensity; + #endif + +#endif + +#if defined(ENABLE_PBRLightingUtils_computeDirectLight) || defined(ENABLE_PBRLightingUtils_computeDirectLightContribution) + // Specular-AA + #ifdef SPECULAR_AA_SCREEN_SPACE_VARIANCE + uniform float m_SpecularAASigma; + #endif + #ifdef SPECULAR_AA_THRESHOLD + uniform float m_SpecularAAKappa; + #endif +#endif + + + + +#ifdef ENABLE_PBRLightingUtils_computeProbesContribution + #if NB_PROBES >= 1 + uniform samplerCube g_PrefEnvMap; + uniform vec3 g_ShCoeffs[9]; + uniform mat4 g_LightProbeData; + #endif + #if NB_PROBES >= 2 + uniform samplerCube g_PrefEnvMap2; + uniform vec3 g_ShCoeffs2[9]; + uniform mat4 g_LightProbeData2; + #endif + #if NB_PROBES == 3 + uniform samplerCube g_PrefEnvMap3; + uniform vec3 g_ShCoeffs3[9]; + uniform mat4 g_LightProbeData3; + #endif +#endif + +#ifdef ENABLE_PBRLightingUtils_getWorldPosition + vec3 PBRLightingUtils_getWorldPosition(){ + return wPosition.xyz; + } +#endif + +#ifdef ENABLE_PBRLightingUtils_getWorldNormal + vec3 PBRLightingUtils_getWorldNormal(){ + return normalize(wNormal.xyz); + } +#endif + +#ifdef ENABLE_PBRLightingUtils_getWorldTangent + vec4 PBRLightingUtils_getWorldTangent(){ + return wTangent; + } +#endif + +#ifdef ENABLE_PBRLightingUtils_getTexCoord + vec2 PBRLightingUtils_getTexCoord(){ + return texCoord; + } + + #ifdef SEPARATE_TEXCOORD + vec2 PBRLightingUtils_getTexCoord2(){ + return texCoord2; + } + #endif +#endif + + + +#if defined(ENABLE_PBRLightingUtils_computeDirectLightContribution) || defined(ENABLE_PBRLightingUtils_newLight) + Light PBRLightingUtils_newLight(vec4 color, vec3 position, float type, float invRadius, float spotAngleCos, vec3 spotDirection){ + Light l; + l.color = color; + l.position = position; + l.type = type; + l.invRadius = invRadius; + l.spotAngleCos = spotAngleCos; + l.spotDirection = spotDirection; + l.ready = false; + return l; + } +#endif + + +#if defined(ENABLE_PBRLightingUtils_computeDirectLightContribution) || defined(ENABLE_PBRLightingUtils_computeLightInWorldSpace) + void PBRLightingUtils_computeLightInWorldSpace(vec3 worldPos,vec3 worldNormal, vec3 viewDir, inout Light light){ + if(light.ready) return; + + // lightComputeDir + float posLight = step(0.5, light.type); + light.vector = light.position.xyz * sign(posLight - 0.5) - (worldPos * posLight); //tempVec lightVec + + vec3 L; // lightDir + float dist; + Math_lengthAndNormalize(light.vector,dist,L); + + float invRange=light.invRadius; // position.w + const float light_threshold=0.01; + + #ifdef SRGB + light.fallOff = (1.0 - invRange * dist) / (1.0 + invRange * dist * dist); // lightDir.w + light.fallOff = clamp(light.fallOff, 1.0 - posLight, 1.0); + #else + light.fallOff = clamp(1.0 - invRange * dist * posLight, 0.0, 1.0); + #endif + + // computeSpotFalloff + if(light.type>1.){ + vec3 spotdir = normalize(light.spotDirection); + float curAngleCos = dot(-L, spotdir); + float innerAngleCos = floor(light.spotAngleCos) * 0.001; + float outerAngleCos = fract(light.spotAngleCos); + float innerMinusOuter = innerAngleCos - outerAngleCos; + float falloff = clamp((curAngleCos - outerAngleCos) / innerMinusOuter, 0.0, 1.0); + #ifdef SRGB + // Use quadratic falloff (notice the ^4) + falloff = pow(clamp((curAngleCos - outerAngleCos) / innerMinusOuter, 0.0, 1.0), 4.0); + #endif + light.fallOff*=falloff; + } + + + vec3 h=normalize(L+viewDir); + light.dir=L; + light.NdotL = max(dot(worldNormal, L), 0.0); + light.NdotH = max(dot(worldNormal, h), 0.0); + light.LdotH = max(dot(L, h), 0.0); + light.HdotV = max(dot(viewDir,h), 0.); + } +#endif + + +#ifdef ENABLE_PBRLightingUtils_readPBRSurface + PBRSurface PBRLightingUtils_readPBRSurface( + in vec3 wViewDir + ){ + + PBRSurface surface; + surface.position = wPosition; + surface.viewDir = wViewDir; + surface.geometryNormal = normalize(wNormal); + + surface.bakedLightContribution = vec3(0); + surface.directLightContribution = vec3(0); + surface.envLightContribution = vec3(0); + + #if defined(NORMALMAP) || defined(PARALLAXMAP) + vec3 tan = normalize(wTangent.xyz); + mat3 tbnMat = mat3(tan, wTangent.w * cross( surface.geometryNormal, tan), surface.geometryNormal); + #endif + + vec2 newTexCoord; + #if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP))) + vec3 vViewDir = wViewDir * tbnMat; + #ifdef STEEP_PARALLAX + #ifdef NORMALMAP_PARALLAX + //parallax map is stored in the alpha channel of the normal map + newTexCoord = steepParallaxOffset(m_NormalMap, vViewDir, texCoord, m_ParallaxHeight); + #else + //parallax map is a texture + newTexCoord = steepParallaxOffset(m_ParallaxMap, vViewDir, texCoord, m_ParallaxHeight); + #endif + #else + #ifdef NORMALMAP_PARALLAX + //parallax map is stored in the alpha channel of the normal map + newTexCoord = classicParallaxOffset(m_NormalMap, vViewDir, texCoord, m_ParallaxHeight); + #else + //parallax map is a texture + newTexCoord = classicParallaxOffset(m_ParallaxMap, vViewDir, texCoord, m_ParallaxHeight); + #endif + #endif + #else + newTexCoord = texCoord; + #endif + + #ifdef BASECOLORMAP + vec4 baseColor = texture2D(m_BaseColorMap, newTexCoord) * Color; + #else + vec4 baseColor = Color; + #endif + + #ifdef DISCARD_ALPHA + if( baseColor.a < m_AlphaDiscardThreshold) discard; + #endif + + surface.albedo = baseColor.rgb; + surface.alpha = baseColor.a; + + + + //ao in r channel, roughness in green channel, metallic in blue channel! + vec3 aoRoughnessMetallicValue = vec3(1.0, 1.0, 0.0); + #ifdef USE_PACKED_MR + aoRoughnessMetallicValue = texture2D(m_MetallicRoughnessMap, newTexCoord).rgb; + surface.roughness = aoRoughnessMetallicValue.g * max(m_Roughness, 1e-4); + surface.metallic = aoRoughnessMetallicValue.b * max(m_Metallic, 0.0); + #else + #ifdef ROUGHNESSMAP + surface.roughness = texture2D(m_RoughnessMap, newTexCoord).r * max(m_Roughness, 1e-4); + #else + surface.roughness = max(m_Roughness, 1e-4); + #endif + #ifdef METALLICMAP + surface.metallic = texture2D(m_MetallicMap, newTexCoord).r * max(m_Metallic, 0.0); + #else + surface.metallic = max(m_Metallic, 0.0); + #endif + #endif + + + + #if defined(NORMALMAP) + vec4 normalHeight = texture2D(m_NormalMap, newTexCoord); + // Note we invert directx style normal maps to opengl style + #ifdef NORMALSCALE + vec3 normal = normalize((normalHeight.xyz * vec3(2.0, NORMAL_TYPE * 2.0, 2.0) - vec3(1.0, NORMAL_TYPE * 1.0, 1.0)) * vec3(m_NormalScale, m_NormalScale, 1.0)); + #else + vec3 normal = normalize((normalHeight.xyz * vec3(2.0, NORMAL_TYPE * 2.0, 2.0) - vec3(1.0, NORMAL_TYPE * 1.0, 1.0))); + #endif + surface.normal = normalize(tbnMat * normal); + #else + surface.normal = normal; + #endif + + //spec gloss tex reads: + + #ifdef SPECGLOSSPIPELINE + #ifdef USE_PACKED_SG + vec4 specularColor = texture2D(m_SpecularGlossinessMap, newTexCoord); + float glossiness = specularColor.a * m_Glossiness; + specularColor *= m_Specular; + #else + #ifdef SPECULARMAP + vec4 specularColor = texture2D(m_SpecularMap, newTexCoord); + #else + vec4 specularColor = vec4(1.0); + #endif + #ifdef GLOSSINESSMAP + float glossiness = texture2D(m_GlossinesMap, newTexCoord).r * m_Glossiness; + #else + float glossiness = m_Glossiness; + #endif + specularColor *= m_Specular; + #endif + surface.diffuseColor = surface.albedo;// * (1.0 - max(max(specularColor.r, specularColor.g), specularColor.b)); + surface.roughness = 1.0 - glossiness; + surface.fZero = specularColor.xyz; + surface.specularColor = specularColor; + #else + float specular = 0.5; + float nonMetalSpec = 0.08 * specular; + surface.specularColor = (nonMetalSpec - nonMetalSpec * surface.metallic) + surface.albedo * surface.metallic; + surface.diffuseColor = surface.albedo - surface.albedo * surface.metallic; + surface.fZero = vec3(specular); + #endif + + + vec3 ao=vec3(1.0); + #ifdef LIGHTMAP + vec3 lightMapColor; + #ifdef SEPARATE_TEXCOORD + lightMapColor = texture2D(m_LightMap, texCoord2).rgb; + #else + lightMapColor = texture2D(m_LightMap, texCoord).rgb; + #endif + #ifdef AO_MAP + lightMapColor.gb = lightMapColor.rr; + ao = lightMapColor; + #else + surface.bakedLightContribution += diffuseColor.rgb * lightMapColor; + #endif + surface.specularColor.rgb *= lightMapColor; + #endif + + #if defined(AO_PACKED_IN_MR_MAP) && defined(USE_PACKED_MR) + ao = aoRoughnessMetallicValue.rrr; //note that this will override the AO value if it was previously read from a lightMap that is being used as AO_Map above. so don't try to use an AO map packed in metallic roughness while also using lightmap as ao map + #endif + + #ifdef AO_STRENGTH + ao = 1.0 + m_AoStrength * (ao - 1.0); + // sanity check + ao = clamp(ao, 0.0, 1.0); + #endif + surface.ao=ao; + + #if defined(EMISSIVE) || defined (EMISSIVEMAP) + #ifdef EMISSIVEMAP + vec4 emissive = texture2D(m_EmissiveMap, newTexCoord); + #ifdef EMISSIVE + emissive *= m_Emissive; + #endif + #else + vec4 emissive = m_Emissive; + #endif + surface.emission = emissive.rgb * pow(emissive.a, m_EmissivePower) * m_EmissiveIntensity; + #else + surface.emission = vec3(0); + #endif + + #if defined(STATIC_SUN_INTENSITY) + surface.exposure = m_StaticSunIntensity; //single float value to indicate percentage of sunlight hitting the model (only suitable for small models or models with equal sunlight exposure accross the entire model + #elif defined(USE_VERTEX_COLORS_AS_SUN_INTENSITY) + surface.exposure = vertColors.r; // use red channel of vertexColors for non-uniform sunlighting accross a single model + #else + surface.exposure = 1.0; //default value + #endif + + surface.frontFacing = gl_FrontFacing; + surface.depth = gl_FragCoord.z; + + + // surface.alphaRoughness = clamp(surface.roughness * surface.roughness, minRoughness, 1.0); + surface.NdotV = clamp(abs(dot(!surface.frontFacing?-surface.normal:surface.normal, surface.viewDir)), 0.001, 1.0); + // surface.reflectedVec = normalize(reflect(-surface.viewDir, surface.normal)); + + surface.brightestLightStrength=0.0; + return surface; + } +#endif + + +#if defined(ENABLE_PBRLightingUtils_computeDirectLight) || defined(ENABLE_PBRLightingUtils_computeDirectLightContribution) + void PBRLightingUtils_computeDirectLight(in Light light, in PBRSurface surface, inout vec3 directDiffuse, inout vec3 directSpecular, out float hdotv){ + + #ifdef SPECULAR_AA + #ifdef SPECULAR_AA_SCREEN_SPACE_VARIANCE + float sigma = m_SpecularAASigma; + #else + float sigma = 1.0; + #endif + + #ifdef SPECULAR_AA_THRESHOLD + float kappa = m_SpecularAAKappa; + #else + float kappa = 0.18; + #endif + + hdotv = PBR_ComputeDirectLightWithSpecularAA( + surface.normal, + light.dir.xyz, + surface.viewDir, + light.color.rgb, + surface.fZero, + surface.roughness, + sigma, + kappa, + surface.NdotV, + directDiffuse, + directSpecular + ); + #else + hdotv = PBR_ComputeDirectLight( + surface.normal, + light.dir.xyz, + surface.viewDir, + light.color.rgb, + surface.fZero, + surface.roughness, + surface.NdotV, + directDiffuse, + directSpecular + ); + #endif + + } +#endif + + +#ifdef ENABLE_PBRLightingUtils_computeDirectLightContribution + void PBRLightingUtils_computeDirectLightContribution( + in vec4 lightData0, + in vec4 lightData1, + in vec4 lightData2, + inout PBRSurface surface + ){ + vec4 lightColor = vec4(lightData0.rgb,1.0); + float lightType = lightData0.w; + + vec3 lightPosition = lightData1.xyz; + float lightInvRadius = lightData1.w; + + vec3 spotDirection = lightData2.xyz; + float spotAngleCos = lightData2.w; + + Light light = PBRLightingUtils_newLight(lightColor, lightPosition, lightType, lightInvRadius, spotAngleCos, spotDirection); + PBRLightingUtils_computeLightInWorldSpace(surface.position, surface.normal, surface.viewDir, light); + + vec3 directDiffuse; + vec3 directSpecular; + float hdotv; + PBRLightingUtils_computeDirectLight(light, surface, directDiffuse, directSpecular, hdotv); + + vec3 directLighting = surface.diffuseColor.rgb * directDiffuse + directSpecular; + + #if defined(USE_VERTEX_COLORS_AS_SUN_INTENSITY) || defined(STATIC_SUN_INTENSITY) + if(light.fallOff == 1.0){ + directLighting.rgb *= surface.exposure;// used to scale down how intense just the sun is indoors, and so the ambientLighting can be scaled back up indoors based on nearest pointlight intensity (ambient and direct light are 1.0 fallOff) + } else{ + surface.brightestLightStrength = max(light.fallOff, surface.brightestLightStrength); + } + #endif + + surface.directLightContribution.rgb += directLighting * light.fallOff; + } +#endif + +#ifdef ENABLE_PBRLightingUtils_computeProbesContribution + void PBRLightingUtils_computeProbesContribution(inout PBRSurface surface){ + + #ifdef BRIGHTEN_INDOOR_SHADOWS + float minVertLighting = 0.0833; //enable this when using shadows, in order to brighten indoor areas (which are naturally covered from the DL shadows) so that indoor areas are not way too dark when using IndoorLighting with shadows compared to when shadows are off + #else + float minVertLighting = 0.0533; + #endif + + float finalLightingScale=1.0; + finalLightingScale = max(finalLightingScale, surface.brightestLightStrength); + finalLightingScale = max(finalLightingScale, minVertLighting); //essentially just the vertColors.r (aka indoor light exposure) multiplied by the time of day scale. + + + #if NB_PROBES > 0 + float probeNdfSum=0; + float invProbeNdfSum=0; + + #for i=1..4 ( #if NB_PROBES >= $i $0 #endif ) + vec3 probeColor$i; + float probeNdf$i = renderProbe( + surface.viewDir, + surface.position, + surface.normal, + surface.geometryNormal, + surface.roughness, + vec4(surface.diffuseColor,1.0), + vec4(surface.specularColor,1.0), + surface.NdotV, + surface.ao, + #if $i == 1 + g_LightProbeData, + #else + g_LightProbeData$i, + #endif + g_ShCoeffs, + g_PrefEnvMap, + probeColor$i + ); + float probeInvNdf$i = max(1.0 - probeNdf$i,0.0); + probeNdfSum += probeNdf$i; + invProbeNdfSum += probeInvNdf$i; + #ifdef USE_AMBIENT_LIGHT + probeColor$i.rgb *= g_AmbientLightColor.rgb; + #endif + probeColor$i.rgb *= finalLightingScale; + #endfor + + #if NB_PROBES > 1 + float probeWeightSum=0; + #for i=1..4 ( #if NB_PROBES >= $i $0 #endif ) + float probeWeight$i = ((1.0 - (probeNdf$i / probeNdfSum)) / (NB_PROBES - 1)) * ( probeInvNdf$i / invProbeNdfSum); + probeWeightSum += probeWeight$i; + #endfor + + #for i=1..4 ( #if NB_PROBES >= $i $0 #endif ) + surface.envLightContribution.rgb += probeColor$i * clamp( probeWeight$i / probeWeightSum, 0., 1.); + #endfor + #else + surface.envLightContribution.rgb += probeColor1; + #endif + #endif + } +#endif + + +#endif \ No newline at end of file From 35532e063d07a8b0211d66083b5915e889d2aa0b Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Fri, 8 Mar 2024 14:11:42 +0100 Subject: [PATCH 20/22] Revert "Modularize PBRLighting" --- .../Common/MatDefs/Light/PBRLighting.frag | 403 +++++++++++++++--- .../Common/MatDefs/Light/PBRLighting.j3md | 18 - .../Common/MatDefs/Light/PBRLighting.vert | 25 +- .../Common/ShaderLib/PBRLighting.glsllib | 184 -------- .../ShaderLib/PBRLightingParamsReader.glsllib | 205 --------- 5 files changed, 350 insertions(+), 485 deletions(-) delete mode 100644 jme3-core/src/main/resources/Common/ShaderLib/PBRLighting.glsllib delete mode 100644 jme3-core/src/main/resources/Common/ShaderLib/PBRLightingParamsReader.glsllib diff --git a/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag b/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag index 99b7155d60..01276fbeaf 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag +++ b/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.frag @@ -1,94 +1,367 @@ #import "Common/ShaderLib/GLSLCompat.glsllib" +#import "Common/ShaderLib/PBR.glsllib" +#import "Common/ShaderLib/Parallax.glsllib" +#import "Common/ShaderLib/Lighting.glsllib" varying vec2 texCoord; -vec2 newTexCoord; #ifdef SEPARATE_TEXCOORD - varying vec2 texCoord2; + varying vec2 texCoord2; #endif -#ifdef DISCARD_ALPHA - uniform float m_AlphaDiscardThreshold; +varying vec4 Color; + +uniform vec4 g_LightData[NB_LIGHTS]; +uniform vec3 g_CameraPosition; +uniform vec4 g_AmbientLightColor; + +uniform float m_Roughness; +uniform float m_Metallic; + +varying vec3 wPosition; + + +#if NB_PROBES >= 1 + uniform samplerCube g_PrefEnvMap; + uniform vec3 g_ShCoeffs[9]; + uniform mat4 g_LightProbeData; +#endif +#if NB_PROBES >= 2 + uniform samplerCube g_PrefEnvMap2; + uniform vec3 g_ShCoeffs2[9]; + uniform mat4 g_LightProbeData2; +#endif +#if NB_PROBES == 3 + uniform samplerCube g_PrefEnvMap3; + uniform vec3 g_ShCoeffs3[9]; + uniform mat4 g_LightProbeData3; #endif -#ifdef DEBUG_VALUES_MODE - uniform int m_DebugValuesMode; +#ifdef BASECOLORMAP + uniform sampler2D m_BaseColorMap; #endif -varying vec3 wPosition; -varying vec3 wNormal; -varying vec4 wTangent; +#ifdef USE_PACKED_MR + uniform sampler2D m_MetallicRoughnessMap; +#else + #ifdef METALLICMAP + uniform sampler2D m_MetallicMap; + #endif + #ifdef ROUGHNESSMAP + uniform sampler2D m_RoughnessMap; + #endif +#endif +#ifdef EMISSIVE + uniform vec4 m_Emissive; +#endif +#ifdef EMISSIVEMAP + uniform sampler2D m_EmissiveMap; +#endif +#if defined(EMISSIVE) || defined(EMISSIVEMAP) + uniform float m_EmissivePower; + uniform float m_EmissiveIntensity; +#endif -#import "Common/ShaderLib/PBRLightingParamsReader.glsllib" -#import "Common/ShaderLib/PBRLighting.glsllib" -// It is important that these 2 glsllibs are referenced AFTER the other variables above have been declared. -// The above variables are declared here (rather than in a glsllib) to reduce redundancy, since these variables are likely to be used by more than one glsllib. -// Only lighting variables are declared in PBRLighting.glsllib, and only basic PBR material params are declared in PBRLightingParamsReader.glsllib. -// This allows jme developers to create a fork of this shader and make their own changes before reading the base PBR parameters or before the final lighting calculation. -// For example, you can move texCoords based on g_Time before texReads for a simple moving water/lava effect, or blend values like albedo/roughness after the param reads -// but before final lighting calculations to do things like dynamic texture splatting. +#ifdef SPECGLOSSPIPELINE -vec4 albedo = vec4(1.0); -float alpha = 1.0; + uniform vec4 m_Specular; + uniform float m_Glossiness; + #ifdef USE_PACKED_SG + uniform sampler2D m_SpecularGlossinessMap; + #else + uniform sampler2D m_SpecularMap; + uniform sampler2D m_GlossinessMap; + #endif +#endif -vec4 emissive = vec4(0.0); +#ifdef PARALLAXMAP + uniform sampler2D m_ParallaxMap; +#endif +#if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP))) + uniform float m_ParallaxHeight; +#endif -vec3 ao = vec3(1.0); -vec3 lightMapColor = vec3(0.0); +#ifdef LIGHTMAP + uniform sampler2D m_LightMap; +#endif -float indoorSunLightExposure = 1.0; +#ifdef AO_STRENGTH + uniform float m_AoStrength; +#endif + +#if defined(NORMALMAP) || defined(PARALLAXMAP) + uniform sampler2D m_NormalMap; + varying vec4 wTangent; +#endif +#ifdef NORMALSCALE + uniform float m_NormalScale; +#endif +varying vec3 wNormal; -//metallic pipeline vars: -float Metallic = 0.0; -float Roughness = 0.0; +// Specular-AA +#ifdef SPECULAR_AA_SCREEN_SPACE_VARIANCE + uniform float m_SpecularAASigma; +#endif +#ifdef SPECULAR_AA_THRESHOLD + uniform float m_SpecularAAKappa; +#endif -//spec gloss pipeline vars: -vec4 specularColor; -float glossiness; +#ifdef DISCARD_ALPHA + uniform float m_AlphaDiscardThreshold; +#endif void main(){ - - vec3 norm = normalize(wNormal); - vec3 normal = norm; + vec2 newTexCoord; vec3 viewDir = normalize(g_CameraPosition - wPosition); - // Note: These are intentionally not surrounded by ifDefs relating to normal and parallax maps being defined, because - // other .glsllibs may require normal or parallax mapping even if the base model does not have those maps - vec3 tan = normalize(wTangent.xyz); - mat3 tbnMat = mat3(tan, wTangent.w * cross( (norm), (tan)), norm); - vec3 vViewDir = viewDir * tbnMat; + vec3 norm = normalize(wNormal); + #if defined(NORMALMAP) || defined(PARALLAXMAP) + vec3 tan = normalize(wTangent.xyz); + mat3 tbnMat = mat3(tan, wTangent.w * cross( (norm), (tan)), norm); + #endif - //base PBR params and tex reads: - readMatParamsAndTextures(tbnMat, vViewDir, albedo, Metallic, Roughness, specularColor, glossiness, lightMapColor, ao, indoorSunLightExposure, normal, emissive, alpha); + #if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP))) + vec3 vViewDir = viewDir * tbnMat; + #ifdef STEEP_PARALLAX + #ifdef NORMALMAP_PARALLAX + //parallax map is stored in the alpha channel of the normal map + newTexCoord = steepParallaxOffset(m_NormalMap, vViewDir, texCoord, m_ParallaxHeight); + #else + //parallax map is a texture + newTexCoord = steepParallaxOffset(m_ParallaxMap, vViewDir, texCoord, m_ParallaxHeight); + #endif + #else + #ifdef NORMALMAP_PARALLAX + //parallax map is stored in the alpha channel of the normal map + newTexCoord = classicParallaxOffset(m_NormalMap, vViewDir, texCoord, m_ParallaxHeight); + #else + //parallax map is a texture + newTexCoord = classicParallaxOffset(m_ParallaxMap, vViewDir, texCoord, m_ParallaxHeight); + #endif + #endif + #else + newTexCoord = texCoord; + #endif - // Lighting calculation: - vec3 finalLightingValue = calculatePBRLighting(albedo, Metallic, Roughness, specularColor, glossiness, lightMapColor, ao, indoorSunLightExposure, normal, norm, viewDir); - gl_FragColor.rgb += finalLightingValue; + #ifdef BASECOLORMAP + vec4 albedo = texture2D(m_BaseColorMap, newTexCoord) * Color; + #else + vec4 albedo = Color; + #endif - //apply final emissive value after lighting - gl_FragColor += emissive; //no need for #ifdef check because emissive will be 0,0,0,0 if emissive vars werent defined. + //ao in r channel, roughness in green channel, metallic in blue channel! + vec3 aoRoughnessMetallicValue = vec3(1.0, 1.0, 0.0); + #ifdef USE_PACKED_MR + aoRoughnessMetallicValue = texture2D(m_MetallicRoughnessMap, newTexCoord).rgb; + float Roughness = aoRoughnessMetallicValue.g * max(m_Roughness, 1e-4); + float Metallic = aoRoughnessMetallicValue.b * max(m_Metallic, 0.0); + #else + #ifdef ROUGHNESSMAP + float Roughness = texture2D(m_RoughnessMap, newTexCoord).r * max(m_Roughness, 1e-4); + #else + float Roughness = max(m_Roughness, 1e-4); + #endif + #ifdef METALLICMAP + float Metallic = texture2D(m_MetallicMap, newTexCoord).r * max(m_Metallic, 0.0); + #else + float Metallic = max(m_Metallic, 0.0); + #endif + #endif + + float alpha = albedo.a; - gl_FragColor.a = alpha; - - //outputs the final value of the selected layer as a color for debug purposes. - #ifdef DEBUG_VALUES_MODE - if(m_DebugValuesMode == 0){ - gl_FragColor.rgb = vec3(albedo); - } - else if(m_DebugValuesMode == 1){ - gl_FragColor.rgb = vec3(normal); - } - else if(m_DebugValuesMode == 2){ - gl_FragColor.rgb = vec3(Roughness); - } - else if(m_DebugValuesMode == 3){ - gl_FragColor.rgb = vec3(Metallic); + #ifdef DISCARD_ALPHA + if(alpha < m_AlphaDiscardThreshold){ + discard; } - else if(m_DebugValuesMode == 4){ - gl_FragColor.rgb = ao.rgb; + #endif + + // *********************** + // Read from textures + // *********************** + #if defined(NORMALMAP) + vec4 normalHeight = texture2D(m_NormalMap, newTexCoord); + // Note we invert directx style normal maps to opengl style + + #ifdef NORMALSCALE + vec3 normal = normalize((normalHeight.xyz * vec3(2.0, NORMAL_TYPE * 2.0, 2.0) - vec3(1.0, NORMAL_TYPE * 1.0, 1.0)) * vec3(m_NormalScale, m_NormalScale, 1.0)); + #else + vec3 normal = normalize((normalHeight.xyz * vec3(2.0, NORMAL_TYPE * 2.0, 2.0) - vec3(1.0, NORMAL_TYPE * 1.0, 1.0))); + #endif + normal = normalize(tbnMat * normal); + //normal = normalize(normal * inverse(tbnMat)); + #else + vec3 normal = norm; + #endif + + #ifdef SPECGLOSSPIPELINE + + #ifdef USE_PACKED_SG + vec4 specularColor = texture2D(m_SpecularGlossinessMap, newTexCoord); + float glossiness = specularColor.a * m_Glossiness; + specularColor *= m_Specular; + #else + #ifdef SPECULARMAP + vec4 specularColor = texture2D(m_SpecularMap, newTexCoord); + #else + vec4 specularColor = vec4(1.0); + #endif + #ifdef GLOSSINESSMAP + float glossiness = texture2D(m_GlossinessMap, newTexCoord).r * m_Glossiness; + #else + float glossiness = m_Glossiness; + #endif + specularColor *= m_Specular; + #endif + vec4 diffuseColor = albedo;// * (1.0 - max(max(specularColor.r, specularColor.g), specularColor.b)); + Roughness = 1.0 - glossiness; + vec3 fZero = specularColor.xyz; + #else + float specular = 0.5; + float nonMetalSpec = 0.08 * specular; + vec4 specularColor = (nonMetalSpec - nonMetalSpec * Metallic) + albedo * Metallic; + vec4 diffuseColor = albedo - albedo * Metallic; + vec3 fZero = vec3(specular); + #endif + + gl_FragColor.rgb = vec3(0.0); + vec3 ao = vec3(1.0); + + #ifdef LIGHTMAP + vec3 lightMapColor; + #ifdef SEPARATE_TEXCOORD + lightMapColor = texture2D(m_LightMap, texCoord2).rgb; + #else + lightMapColor = texture2D(m_LightMap, texCoord).rgb; + #endif + #ifdef AO_MAP + lightMapColor.gb = lightMapColor.rr; + ao = lightMapColor; + #else + gl_FragColor.rgb += diffuseColor.rgb * lightMapColor; + #endif + specularColor.rgb *= lightMapColor; + #endif + + #if defined(AO_PACKED_IN_MR_MAP) && defined(USE_PACKED_MR) + ao = aoRoughnessMetallicValue.rrr; + #endif + + #ifdef AO_STRENGTH + ao = 1.0 + m_AoStrength * (ao - 1.0); + // sanity check + ao = clamp(ao, 0.0, 1.0); + #endif + + #ifdef SPECULAR_AA + float sigma = 1.0; + float kappa = 0.18; + #ifdef SPECULAR_AA_SCREEN_SPACE_VARIANCE + sigma = m_SpecularAASigma; + #endif + #ifdef SPECULAR_AA_THRESHOLD + kappa = m_SpecularAAKappa; + #endif + #endif + float ndotv = max( dot( normal, viewDir ),0.0); + for( int i = 0;i < NB_LIGHTS; i+=3){ + vec4 lightColor = g_LightData[i]; + vec4 lightData1 = g_LightData[i+1]; + vec4 lightDir; + vec3 lightVec; + lightComputeDir(wPosition, lightColor.w, lightData1, lightDir, lightVec); + + float fallOff = 1.0; + #if __VERSION__ >= 110 + // allow use of control flow + if(lightColor.w > 1.0){ + #endif + fallOff = computeSpotFalloff(g_LightData[i+2], lightVec); + #if __VERSION__ >= 110 } - else if(m_DebugValuesMode == 5){ - gl_FragColor.rgb = vec3(emissive.rgb); - } - #endif + #endif + //point light attenuation + fallOff *= lightDir.w; + + lightDir.xyz = normalize(lightDir.xyz); + vec3 directDiffuse; + vec3 directSpecular; + + #ifdef SPECULAR_AA + float hdotv = PBR_ComputeDirectLightWithSpecularAA( + normal, lightDir.xyz, viewDir, + lightColor.rgb, fZero, Roughness, sigma, kappa, ndotv, + directDiffuse, directSpecular); + #else + float hdotv = PBR_ComputeDirectLight( + normal, lightDir.xyz, viewDir, + lightColor.rgb, fZero, Roughness, ndotv, + directDiffuse, directSpecular); + #endif + + vec3 directLighting = diffuseColor.rgb *directDiffuse + directSpecular; + + gl_FragColor.rgb += directLighting * fallOff; + } + + #if NB_PROBES >= 1 + vec3 color1 = vec3(0.0); + vec3 color2 = vec3(0.0); + vec3 color3 = vec3(0.0); + float weight1 = 1.0; + float weight2 = 0.0; + float weight3 = 0.0; + + float ndf = renderProbe(viewDir, wPosition, normal, norm, Roughness, diffuseColor, specularColor, ndotv, ao, g_LightProbeData, g_ShCoeffs, g_PrefEnvMap, color1); + #if NB_PROBES >= 2 + float ndf2 = renderProbe(viewDir, wPosition, normal, norm, Roughness, diffuseColor, specularColor, ndotv, ao, g_LightProbeData2, g_ShCoeffs2, g_PrefEnvMap2, color2); + #endif + #if NB_PROBES == 3 + float ndf3 = renderProbe(viewDir, wPosition, normal, norm, Roughness, diffuseColor, specularColor, ndotv, ao, g_LightProbeData3, g_ShCoeffs3, g_PrefEnvMap3, color3); + #endif + + #if NB_PROBES >= 2 + float invNdf = max(1.0 - ndf,0.0); + float invNdf2 = max(1.0 - ndf2,0.0); + float sumNdf = ndf + ndf2; + float sumInvNdf = invNdf + invNdf2; + #if NB_PROBES == 3 + float invNdf3 = max(1.0 - ndf3,0.0); + sumNdf += ndf3; + sumInvNdf += invNdf3; + weight3 = ((1.0 - (ndf3 / sumNdf)) / (NB_PROBES - 1)) * (invNdf3 / sumInvNdf); + #endif + + weight1 = ((1.0 - (ndf / sumNdf)) / (NB_PROBES - 1)) * (invNdf / sumInvNdf); + weight2 = ((1.0 - (ndf2 / sumNdf)) / (NB_PROBES - 1)) * (invNdf2 / sumInvNdf); + + float weightSum = weight1 + weight2 + weight3; + + weight1 /= weightSum; + weight2 /= weightSum; + weight3 /= weightSum; + #endif + + #ifdef USE_AMBIENT_LIGHT + color1.rgb *= g_AmbientLightColor.rgb; + color2.rgb *= g_AmbientLightColor.rgb; + color3.rgb *= g_AmbientLightColor.rgb; + #endif + gl_FragColor.rgb += color1 * clamp(weight1,0.0,1.0) + color2 * clamp(weight2,0.0,1.0) + color3 * clamp(weight3,0.0,1.0); + + #endif + + #if defined(EMISSIVE) || defined (EMISSIVEMAP) + #ifdef EMISSIVEMAP + vec4 emissive = texture2D(m_EmissiveMap, newTexCoord); + #ifdef EMISSIVE + emissive *= m_Emissive; + #endif + #else + vec4 emissive = m_Emissive; + #endif + gl_FragColor += emissive * pow(emissive.a, m_EmissivePower) * m_EmissiveIntensity; + #endif + gl_FragColor.a = alpha; + } diff --git a/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.j3md b/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.j3md index ae81b34fe0..1ee65eeb61 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.j3md +++ b/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.j3md @@ -132,20 +132,6 @@ MaterialDef PBR Lighting { Boolean UseVertexColor Boolean BackfaceShadows : false - - Boolean UseVertexColorsAsSunIntensity - Float StaticSunIntensity - Boolean BrightenIndoorShadows - - Int DebugValuesMode - // debugs the final value of the selected layer as a color output: - // Layers: - // 0 - albedo (unshaded) - // 1 - normals - // 2 - roughness - // 3 - metallic - // 4 - ao - // 5 - emissive } Technique { @@ -196,10 +182,6 @@ MaterialDef PBR Lighting { NUM_MORPH_TARGETS: NumberOfMorphTargets NUM_TARGETS_BUFFERS: NumberOfTargetsBuffers HORIZON_FADE: HorizonFade - USE_VERTEX_COLORS_AS_SUN_INTENSITY : UseVertexColorsAsSunIntensity - STATIC_SUN_INTENSITY : StaticSunIntensity - BRIGHTEN_INDOOR_SHADOWS : BrightenIndoorShadows - DEBUG_VALUES_MODE : DebugValuesMode } } 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 0595e0629c..b910a8d4b2 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.vert +++ b/jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.vert @@ -18,27 +18,23 @@ attribute vec3 inPosition; attribute vec2 inTexCoord; attribute vec3 inNormal; -#if defined (VERTEX_COLOR) || defined(USE_VERTEX_COLORS_AS_SUN_INTENSITY) - attribute vec4 inColor; -#endif - -#if defined(USE_VERTEX_COLORS_AS_SUN_INTENSITY) - varying vec4 vertColors; +#ifdef VERTEX_COLOR + attribute vec4 inColor; #endif varying vec3 wNormal; varying vec3 wPosition; - -attribute vec4 inTangent; -varying vec4 wTangent; +#if defined(NORMALMAP) || defined(PARALLAXMAP) + attribute vec4 inTangent; + varying vec4 wTangent; +#endif void main(){ vec4 modelSpacePos = vec4(inPosition, 1.0); vec3 modelSpaceNorm = inNormal; - vec3 modelSpaceTan = inTangent.xyz; - #ifdef USE_VERTEX_COLORS_AS_SUN_INTENSITY - vertColors = inColor; + #if ( defined(NORMALMAP) || defined(PARALLAXMAP)) && !defined(VERTEX_LIGHTING) + vec3 modelSpaceTan = inTangent.xyz; #endif #ifdef NUM_MORPH_TARGETS @@ -65,7 +61,10 @@ void main(){ wPosition = TransformWorld(modelSpacePos).xyz; wNormal = TransformWorldNormal(modelSpaceNorm); - wTangent = vec4(TransformWorldNormal(modelSpaceTan),inTangent.w); + + #if defined(NORMALMAP) || defined(PARALLAXMAP) + wTangent = vec4(TransformWorldNormal(modelSpaceTan),inTangent.w); + #endif Color = m_BaseColor; diff --git a/jme3-core/src/main/resources/Common/ShaderLib/PBRLighting.glsllib b/jme3-core/src/main/resources/Common/ShaderLib/PBRLighting.glsllib deleted file mode 100644 index 1b0c6e8609..0000000000 --- a/jme3-core/src/main/resources/Common/ShaderLib/PBRLighting.glsllib +++ /dev/null @@ -1,184 +0,0 @@ -#import "Common/ShaderLib/Lighting.glsllib" -#import "Common/ShaderLib/PBR.glsllib" - -//declare PBR Lighting vars -uniform vec4 g_LightData[NB_LIGHTS]; -uniform vec3 g_CameraPosition; -uniform vec4 g_AmbientLightColor; - -#if NB_PROBES >= 1 - uniform samplerCube g_PrefEnvMap; - uniform vec3 g_ShCoeffs[9]; - uniform mat4 g_LightProbeData; -#endif -#if NB_PROBES >= 2 - uniform samplerCube g_PrefEnvMap2; - uniform vec3 g_ShCoeffs2[9]; - uniform mat4 g_LightProbeData2; -#endif -#if NB_PROBES == 3 - uniform samplerCube g_PrefEnvMap3; - uniform vec3 g_ShCoeffs3[9]; - uniform mat4 g_LightProbeData3; -#endif - -// Specular-AA -#ifdef SPECULAR_AA_SCREEN_SPACE_VARIANCE - uniform float m_SpecularAASigma; -#endif -#ifdef SPECULAR_AA_THRESHOLD - uniform float m_SpecularAAKappa; -#endif - -vec3 calculatePBRLighting(in vec4 albedo, in float Metallic, in float Roughness, in vec4 specularColor, in float glossiness, in vec3 lightMapColor, in vec3 ao, in float indoorSunLightExposure, in vec3 normal, in vec3 norm, in vec3 viewDir){ - vec3 finalLightingValue; - - #ifdef SPECGLOSSPIPELINE - vec4 diffuseColor = albedo;// * (1.0 - max(max(specularColor.r, specularColor.g), specularColor.b)); - Roughness = 1.0 - glossiness; - vec3 fZero = specularColor.xyz; - #else - float specular = 0.5; - float nonMetalSpec = 0.08 * specular; - specularColor = (nonMetalSpec - nonMetalSpec * Metallic) + albedo * Metallic; - vec4 diffuseColor = albedo - albedo * Metallic; - vec3 fZero = vec3(specular); - #endif - - #ifdef LIGHTMAP - #if !defined(AO_MAP) - finalLightingValue.rgb += diffuseColor.rgb * lightMapColor; - #endif - specularColor.rgb *= lightMapColor; - #endif - - #ifdef SPECULAR_AA - float sigma = 1.0; - float kappa = 0.18; - #ifdef SPECULAR_AA_SCREEN_SPACE_VARIANCE - sigma = m_SpecularAASigma; - #endif - #ifdef SPECULAR_AA_THRESHOLD - kappa = m_SpecularAAKappa; - #endif - #endif - - float finalLightingScale = 1.0; - float brightestPointLight = 1.0; - - float ndotv = max( dot( normal, viewDir ),0.0); - for( int i = 0;i < NB_LIGHTS; i+=3){ - vec4 lightColor = g_LightData[i]; - vec4 lightData1 = g_LightData[i+1]; - vec4 lightDir; - vec3 lightVec; - lightComputeDir(wPosition, lightColor.w, lightData1, lightDir, lightVec); - - float fallOff = 1.0; - #if __VERSION__ >= 110 - // allow use of control flow - if(lightColor.w > 1.0){ - #endif - fallOff = computeSpotFalloff(g_LightData[i+2], lightVec); - #if __VERSION__ >= 110 - } - #endif - //point light attenuation - fallOff *= lightDir.w; - - lightDir.xyz = normalize(lightDir.xyz); - vec3 directDiffuse; - vec3 directSpecular; - - #ifdef SPECULAR_AA - float hdotv = PBR_ComputeDirectLightWithSpecularAA( - normal, lightDir.xyz, viewDir, - lightColor.rgb, fZero, Roughness, sigma, kappa, ndotv, - directDiffuse, directSpecular); - #else - float hdotv = PBR_ComputeDirectLight( - normal, lightDir.xyz, viewDir, - lightColor.rgb, fZero, Roughness, ndotv, - directDiffuse, directSpecular); - #endif - - vec3 directLighting = diffuseColor.rgb *directDiffuse + directSpecular; - - #if defined(USE_VERTEX_COLORS_AS_SUN_INTENSITY) || defined(STATIC_SUN_INTENSITY) - if(fallOff == 1.0){ - directLighting.rgb *= indoorSunLightExposure;// used to scale down how intense just the sun is indoors, and so the ambientLighting can be scaled back up indoors based on nearest pointlight intensity (ambient and direct light are 1.0 fallOff) - } - else{ - brightestPointLight = max(fallOff, brightestPointLight); - } - #endif - - finalLightingValue.rgb += directLighting * fallOff; - } - - float minVertLighting; - #ifdef BRIGHTEN_INDOOR_SHADOWS - minVertLighting = 0.0833; //enable this when using shadows, in order to brighten indoor areas (which are naturally covered from the DL shadows) so that indoor areas are not way too dark when using IndoorLighting with shadows compared to when shadows are off - #else - minVertLighting = 0.0533; - #endif - - finalLightingScale = max(finalLightingScale, brightestPointLight); - finalLightingScale = max(finalLightingScale, minVertLighting); //essentially just the vertColors.r (aka indoor light exposure) multiplied by the time of day scale. - - #if NB_PROBES >= 1 - vec3 color1 = vec3(0.0); - vec3 color2 = vec3(0.0); - vec3 color3 = vec3(0.0); - float weight1 = 1.0; - float weight2 = 0.0; - float weight3 = 0.0; - - float ndf = renderProbe(viewDir, wPosition, normal, norm, Roughness, diffuseColor, specularColor, ndotv, ao, g_LightProbeData, g_ShCoeffs, g_PrefEnvMap, color1); - #if NB_PROBES >= 2 - float ndf2 = renderProbe(viewDir, wPosition, normal, norm, Roughness, diffuseColor, specularColor, ndotv, ao, g_LightProbeData2, g_ShCoeffs2, g_PrefEnvMap2, color2); - #endif - #if NB_PROBES == 3 - float ndf3 = renderProbe(viewDir, wPosition, normal, norm, Roughness, diffuseColor, specularColor, ndotv, ao, g_LightProbeData3, g_ShCoeffs3, g_PrefEnvMap3, color3); - #endif - - #if NB_PROBES >= 2 - float invNdf = max(1.0 - ndf,0.0); - float invNdf2 = max(1.0 - ndf2,0.0); - float sumNdf = ndf + ndf2; - float sumInvNdf = invNdf + invNdf2; - #if NB_PROBES == 3 - float invNdf3 = max(1.0 - ndf3,0.0); - sumNdf += ndf3; - sumInvNdf += invNdf3; - weight3 = ((1.0 - (ndf3 / sumNdf)) / (NB_PROBES - 1)) * (invNdf3 / sumInvNdf); - #endif - - weight1 = ((1.0 - (ndf / sumNdf)) / (NB_PROBES - 1)) * (invNdf / sumInvNdf); - weight2 = ((1.0 - (ndf2 / sumNdf)) / (NB_PROBES - 1)) * (invNdf2 / sumInvNdf); - - float weightSum = weight1 + weight2 + weight3; - - weight1 /= weightSum; - weight2 /= weightSum; - weight3 /= weightSum; - #endif - - #ifdef USE_AMBIENT_LIGHT - color1.rgb *= g_AmbientLightColor.rgb; - color2.rgb *= g_AmbientLightColor.rgb; - color3.rgb *= g_AmbientLightColor.rgb; - #endif - - // multiply probes by the finalLightingScale, as determined by pixel's - // sunlightExposure and adjusted for nearby point/spot lights - color1.rgb *= finalLightingScale; - color2.rgb *= finalLightingScale; - color3.rgb *= finalLightingScale; - - finalLightingValue.rgb += color1 * clamp(weight1,0.0,1.0) + color2 * clamp(weight2,0.0,1.0) + color3 * clamp(weight3,0.0,1.0); - - #endif - - return finalLightingValue; -} diff --git a/jme3-core/src/main/resources/Common/ShaderLib/PBRLightingParamsReader.glsllib b/jme3-core/src/main/resources/Common/ShaderLib/PBRLightingParamsReader.glsllib deleted file mode 100644 index 6d78bd432b..0000000000 --- a/jme3-core/src/main/resources/Common/ShaderLib/PBRLightingParamsReader.glsllib +++ /dev/null @@ -1,205 +0,0 @@ -#import "Common/ShaderLib/Parallax.glsllib" - -varying vec4 Color; - -#ifdef BASECOLORMAP - uniform sampler2D m_BaseColorMap; -#endif - -#ifdef USE_PACKED_MR - uniform sampler2D m_MetallicRoughnessMap; -#else - #ifdef METALLICMAP - uniform sampler2D m_MetallicMap; - #endif - #ifdef ROUGHNESSMAP - uniform sampler2D m_RoughnessMap; - #endif -#endif - -#ifdef EMISSIVE - uniform vec4 m_Emissive; -#endif -#ifdef EMISSIVEMAP - uniform sampler2D m_EmissiveMap; -#endif -#if defined(EMISSIVE) || defined(EMISSIVEMAP) - uniform float m_EmissivePower; - uniform float m_EmissiveIntensity; -#endif - -uniform float m_Roughness; -uniform float m_Metallic; - -#ifdef SPECGLOSSPIPELINE - uniform vec4 m_Specular; - uniform float m_Glossiness; - #ifdef USE_PACKED_SG - uniform sampler2D m_SpecularGlossinessMap; - #else - uniform sampler2D m_SpecularMap; - uniform sampler2D m_GlossinessMap; - #endif -#endif - -#ifdef PARALLAXMAP - uniform sampler2D m_ParallaxMap; -#endif -#if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP))) - uniform float m_ParallaxHeight; -#endif - -#ifdef LIGHTMAP - uniform sampler2D m_LightMap; -#endif - -#ifdef AO_STRENGTH - uniform float m_AoStrength; -#endif - -#if defined(NORMALMAP) || defined(PARALLAXMAP) - uniform sampler2D m_NormalMap; -#endif -#ifdef NORMALSCALE - uniform float m_NormalScale; -#endif - -#if defined(USE_VERTEX_COLORS_AS_SUN_INTENSITY) - varying vec4 vertColors; -#endif -#ifdef STATIC_SUN_INTENSITY - uniform float m_StaticSunIntensity; -#endif - -void readMatParamsAndTextures(in mat3 tbnMat, in vec3 vViewDir, inout vec4 albedo, inout float Metallic, inout float Roughness, inout vec4 SpecularColor, inout float glossiness, inout vec3 lightMapColor, inout vec3 ao, inout float indoorSunLightExposure, inout vec3 normal, inout vec4 emissive, inout float alpha){ - #if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP))) - #ifdef STEEP_PARALLAX - #ifdef NORMALMAP_PARALLAX - //parallax map is stored in the alpha channel of the normal map - newTexCoord = steepParallaxOffset(m_NormalMap, vViewDir, texCoord, m_ParallaxHeight); - #else - //parallax map is a texture - newTexCoord = steepParallaxOffset(m_ParallaxMap, vViewDir, texCoord, m_ParallaxHeight); - #endif - #else - #ifdef NORMALMAP_PARALLAX - //parallax map is stored in the alpha channel of the normal map - newTexCoord = classicParallaxOffset(m_NormalMap, vViewDir, texCoord, m_ParallaxHeight); - #else - //parallax map is a texture - newTexCoord = classicParallaxOffset(m_ParallaxMap, vViewDir, texCoord, m_ParallaxHeight); - #endif - #endif - #else - newTexCoord = texCoord; - #endif - - #ifdef BASECOLORMAP - albedo = texture2D(m_BaseColorMap, newTexCoord) * Color; - #else - albedo = Color; - #endif - - alpha = albedo.a; - - #ifdef DISCARD_ALPHA - if(alpha < m_AlphaDiscardThreshold){ - discard; - } - #endif - - //ao in r channel, roughness in green channel, metallic in blue channel! - vec3 aoRoughnessMetallicValue = vec3(1.0, 1.0, 0.0); - #ifdef USE_PACKED_MR - aoRoughnessMetallicValue = texture2D(m_MetallicRoughnessMap, newTexCoord).rgb; - Roughness = aoRoughnessMetallicValue.g * max(m_Roughness, 1e-4); - Metallic = aoRoughnessMetallicValue.b * max(m_Metallic, 0.0); - #else - #ifdef ROUGHNESSMAP - Roughness = texture2D(m_RoughnessMap, newTexCoord).r * max(m_Roughness, 1e-4); - #else - Roughness = max(m_Roughness, 1e-4); - #endif - #ifdef METALLICMAP - Metallic = texture2D(m_MetallicMap, newTexCoord).r * max(m_Metallic, 0.0); - #else - Metallic = max(m_Metallic, 0.0); - #endif - #endif - - #if defined(NORMALMAP) - vec4 normalHeight = texture2D(m_NormalMap, newTexCoord); - // Note we invert directx style normal maps to opengl style - #ifdef NORMALSCALE - normal = normalize((normalHeight.xyz * vec3(2.0, NORMAL_TYPE * 2.0, 2.0) - vec3(1.0, NORMAL_TYPE * 1.0, 1.0)) * vec3(m_NormalScale, m_NormalScale, 1.0)); - #else - normal = normalize((normalHeight.xyz * vec3(2.0, NORMAL_TYPE * 2.0, 2.0) - vec3(1.0, NORMAL_TYPE * 1.0, 1.0))); - #endif - normal = normalize(tbnMat * normal); - //normal = normalize(normal * inverse(tbnMat)); - #endif - - //spec gloss tex reads: - - #ifdef SPECGLOSSPIPELINE - #ifdef USE_PACKED_SG - specularColor = texture2D(m_SpecularGlossinessMap, newTexCoord); - glossiness = specularColor.a * m_Glossiness; - specularColor *= m_Specular; - #else - #ifdef SPECULARMAP - specularColor = texture2D(m_SpecularMap, newTexCoord); - #else - specularColor = vec4(1.0); - #endif - #ifdef GLOSSINESSMAP - glossiness = texture2D(m_GlossinesMap, newTexCoord).r * m_Glossiness; - #else - glossiness = m_Glossiness; - #endif - specularColor *= m_Specular; - #endif - #endif - - - #ifdef LIGHTMAP - #ifdef SEPARATE_TEXCOORD - lightMapColor = texture2D(m_LightMap, texCoord2).rgb; - #else - lightMapColor = texture2D(m_LightMap, texCoord).rgb; - #endif - - #ifdef AO_MAP - lightMapColor.gb = lightMapColor.rr; - ao = lightMapColor; - #endif - #endif - - #if defined(AO_PACKED_IN_MR_MAP) && defined(USE_PACKED_MR) - ao = aoRoughnessMetallicValue.rrr; //note that this will override the AO value if it was previously read from a lightMap that is being used as AO_Map above. so don't try to use an AO map packed in metallic roughness while also using lightmap as ao map - #endif - - #ifdef AO_STRENGTH - ao = 1.0 + m_AoStrength * (ao - 1.0); - // sanity check - ao = clamp(ao, 0.0, 1.0); - #endif - - #if defined(EMISSIVE) || defined (EMISSIVEMAP) - #ifdef EMISSIVEMAP - emissive = texture2D(m_EmissiveMap, newTexCoord); - #ifdef EMISSIVE - emissive *= m_Emissive; - #endif - #endif - emissive = emissive * pow(emissive.a, m_EmissivePower) * m_EmissiveIntensity; - #endif - - #ifdef STATIC_SUN_INTENSITY - indoorSunLightExposure = m_StaticSunIntensity; //single float value to indicate percentage of sunlight hitting the model (only suitable for small models or models with equal sunlight exposure accross the entire model - #endif - #ifdef USE_VERTEX_COLORS_AS_SUN_INTENSITY - indoorSunLightExposure = vertColors.r * indoorSunLightExposure; // use red channel of vertexColors for non-uniform sunlighting accross a single model - #endif - -} From a606ac110edf75a404d012a3099e5e8c6fd45635 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Fri, 8 Mar 2024 14:30:41 +0100 Subject: [PATCH 21/22] fixes --- .../pbrlighting/PBRLightingUtils.glsllib | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) 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 5fb7f7a6f3..e987993fa1 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 @@ -20,25 +20,19 @@ // #define ENABLE_PBRLightingUtils_computeDirectLightContribution 1 // #define ENABLE_PBRLightingUtils_computeProbesContribution 1 -#if defined(ENABLE_PBRLightingUtils_readPBRSurface) || - defined(ENABLE_PBRLightingUtils_getWorldPosition) +#if defined(ENABLE_PBRLightingUtils_readPBRSurface)||defined(ENABLE_PBRLightingUtils_getWorldPosition) varying vec3 wPosition; #endif -#if defined(ENABLE_PBRLightingUtils_readPBRSurface) || - defined(ENABLE_PBRLightingUtils_getWorldNormal) +#if defined(ENABLE_PBRLightingUtils_readPBRSurface)||defined(ENABLE_PBRLightingUtils_getWorldNormal) varying vec3 wNormal; #endif -#if (defined(ENABLE_PBRLightingUtils_readPBRSurface) && - (defined(NORMALMAP) || defined(PARALLAXMAP)) - ) || - defined(ENABLE_PBRLightingUtils_getWorldTangent) - varying vec3 wTangent; +#if (defined(ENABLE_PBRLightingUtils_readPBRSurface)&&(defined(NORMALMAP)||defined(PARALLAXMAP)))||defined(ENABLE_PBRLightingUtils_getWorldTangent) + varying vec4 wTangent; #endif -#if defined(ENABLE_PBRLightingUtils_readPBRSurface) || - defined(ENABLE_PBRLightingUtils_getTexCoord) +#if defined(ENABLE_PBRLightingUtils_readPBRSurface)||defined(ENABLE_PBRLightingUtils_getTexCoord) varying vec2 texCoord; #ifdef SEPARATE_TEXCOORD varying vec2 texCoord2; @@ -48,9 +42,7 @@ #ifdef ENABLE_PBRLightingUtils_readPBRSurface - varying vec4 Color; - uniform vec4 g_AmbientLightColor; uniform float m_Roughness; From 585e1ec86040b9a7eeaa12c923fffc2fc6af58c4 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Fri, 8 Mar 2024 14:31:06 +0100 Subject: [PATCH 22/22] use modular pbr --- jme3-testdata/src/main/resources/Models/Tank/tank.j3m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jme3-testdata/src/main/resources/Models/Tank/tank.j3m b/jme3-testdata/src/main/resources/Models/Tank/tank.j3m index 3cd8ac4287..dd13f8a06f 100644 --- a/jme3-testdata/src/main/resources/Models/Tank/tank.j3m +++ b/jme3-testdata/src/main/resources/Models/Tank/tank.j3m @@ -1,4 +1,4 @@ -Material Tank : Common/MatDefs/Light/PBRLighting.j3md { +Material Tank : Common/MatDefs/Light/modular/PBRLighting.j3md { MaterialParameters { MetallicRoughnessMap : Flip Models/Tank/Tank_Occ_Rough_Metal.png