diff --git a/leenkx/Shaders/bloom_pass/downsample_pass.frag.glsl b/leenkx/Shaders/bloom_pass/downsample_pass.frag.glsl index 925af66e..44932d2f 100644 --- a/leenkx/Shaders/bloom_pass/downsample_pass.frag.glsl +++ b/leenkx/Shaders/bloom_pass/downsample_pass.frag.glsl @@ -48,6 +48,10 @@ void main() { } if (currentMipLevel == 0) { + if (any(isnan(fragColor.rgb)) || any(isinf(fragColor.rgb))) { + fragColor.rgb = vec3(0.0); + } + // https://catlikecoding.com/unity/tutorials/advanced-rendering/bloom/#3.2 // https://catlikecoding.com/unity/tutorials/advanced-rendering/bloom/#3.4 diff --git a/leenkx/Shaders/compositor_pass/compositor_pass.frag.glsl b/leenkx/Shaders/compositor_pass/compositor_pass.frag.glsl index 8118432e..b7d9d7ba 100644 --- a/leenkx/Shaders/compositor_pass/compositor_pass.frag.glsl +++ b/leenkx/Shaders/compositor_pass/compositor_pass.frag.glsl @@ -69,6 +69,7 @@ uniform vec4 PPComp15; uniform vec4 PPComp16; uniform vec4 PPComp18; uniform vec4 PPComp19; +uniform vec4 PPComp20; #endif // #ifdef _CPos @@ -499,14 +500,15 @@ void main() { #ifdef _CExposure #ifdef _CPostprocess - fragColor.rgb+=fragColor.rgb*PPComp8.x; + fragColor.rgb *= pow(2.0, PPComp8.x); #else - fragColor.rgb+= fragColor.rgb*compoExposureStrength; + fragColor.rgb *= pow(2.0, compoExposureStrength); #endif #endif #ifdef _CPostprocess fragColor.rgb *= ComputeEV(0.0); + fragColor.rgb *= pow(2.0, PPComp20.x); // exposure and gamma #endif #ifdef _AutoExposure @@ -582,7 +584,9 @@ fragColor.rgb = min(fragColor.rgb, 65504 * 0.5); fragColor.rgb = tonemapAgXFull(fragColor.rgb); } //else { fragColor.rgb = vec3(0,1,0); //ERROR} #endif - +#ifdef _CGamma + fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / PPComp20.y)); +#endif #else #ifdef _CToneFilmic fragColor.rgb = tonemapFilmic(fragColor.rgb); // With gamma @@ -615,6 +619,10 @@ fragColor.rgb = min(fragColor.rgb, 65504 * 0.5); #endif #endif +#ifdef _CGamma + fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / compoGammaStrength)); +#endif + #ifdef _CBW // fragColor.rgb = vec3(clamp(dot(fragColor.rgb, fragColor.rgb), 0.0, 1.0)); fragColor.rgb = vec3((fragColor.r * 0.3 + fragColor.g * 0.59 + fragColor.b * 0.11) / 3.0) * 2.5; diff --git a/leenkx/Shaders/deferred_light/deferred_light.frag.glsl b/leenkx/Shaders/deferred_light/deferred_light.frag.glsl index ae4bba58..61f39501 100644 --- a/leenkx/Shaders/deferred_light/deferred_light.frag.glsl +++ b/leenkx/Shaders/deferred_light/deferred_light.frag.glsl @@ -907,26 +907,10 @@ tileBounds = vec4(0.0, 0.0, 1.0, 1.0); fragColor.rgb += cLightCol * sssStrengthCL * SSSSTransmittance(LWVPSpotArray[li], p, n, cLightDir, lightPlane.y, shadowMapAtlas, sssColorCL, sssRadiusCL, tileBoundsSpotArray[li]); #endif #else - if (li == 0) fragColor.rgb += cLightCol * sssStrengthCL * SSSSTransmittance(LWVPSpotArray[0], p, n, cLightDir, lightPlane.y, shadowMapSpot[0], sssColorCL, sssRadiusCL - #ifdef _ShadowMapAtlas - , vec4(0.0, 0.0, 1.0, 1.0) - #endif - ); - else if (li == 1) fragColor.rgb += cLightCol * sssStrengthCL * SSSSTransmittance(LWVPSpotArray[1], p, n, cLightDir, lightPlane.y, shadowMapSpot[1], sssColorCL, sssRadiusCL - #ifdef _ShadowMapAtlas - , vec4(0.0, 0.0, 1.0, 1.0) - #endif - ); - else if (li == 2) fragColor.rgb += cLightCol * sssStrengthCL * SSSSTransmittance(LWVPSpotArray[2], p, n, cLightDir, lightPlane.y, shadowMapSpot[2], sssColorCL, sssRadiusCL - #ifdef _ShadowMapAtlas - , vec4(0.0, 0.0, 1.0, 1.0) - #endif - ); - else if (li == 3) fragColor.rgb += cLightCol * sssStrengthCL * SSSSTransmittance(LWVPSpotArray[3], p, n, cLightDir, lightPlane.y, shadowMapSpot[3], sssColorCL, sssRadiusCL - #ifdef _ShadowMapAtlas - , vec4(0.0, 0.0, 1.0, 1.0) - #endif - ); + if (li == 0) fragColor.rgb += cLightCol * sssStrengthCL * SSSSTransmittance(LWVPSpotArray[0], p, n, cLightDir, lightPlane.y, shadowMapSpot[0], sssColorCL, sssRadiusCL); + else if (li == 1) fragColor.rgb += cLightCol * sssStrengthCL * SSSSTransmittance(LWVPSpotArray[1], p, n, cLightDir, lightPlane.y, shadowMapSpot[1], sssColorCL, sssRadiusCL); + else if (li == 2) fragColor.rgb += cLightCol * sssStrengthCL * SSSSTransmittance(LWVPSpotArray[2], p, n, cLightDir, lightPlane.y, shadowMapSpot[2], sssColorCL, sssRadiusCL); + else if (li == 3) fragColor.rgb += cLightCol * sssStrengthCL * SSSSTransmittance(LWVPSpotArray[3], p, n, cLightDir, lightPlane.y, shadowMapSpot[3], sssColorCL, sssRadiusCL); #endif } else { #ifdef _ShadowMapAtlas diff --git a/leenkx/Shaders/deferred_light_mobile/deferred_light.frag.glsl b/leenkx/Shaders/deferred_light_mobile/deferred_light.frag.glsl index 75512780..aa86595f 100644 --- a/leenkx/Shaders/deferred_light_mobile/deferred_light.frag.glsl +++ b/leenkx/Shaders/deferred_light_mobile/deferred_light.frag.glsl @@ -56,9 +56,15 @@ uniform vec2 cameraPlane; #ifdef _SinglePoint #ifdef _Spot //!uniform sampler2DShadow shadowMapSpot[1]; + #ifdef _ShadowMapTransparent + //!uniform sampler2D shadowMapSpotTransparent[1]; + #endif //!uniform mat4 LWVPSpotArray[1]; #else //!uniform samplerCubeShadow shadowMapPoint[1]; + #ifdef _ShadowMapTransparent + //!uniform samplerCube shadowMapPointTransparent[1]; + #endif //!uniform vec2 lightProj; #endif #endif @@ -66,26 +72,41 @@ uniform vec2 cameraPlane; #ifdef _ShadowMapAtlas #ifdef _SingleAtlas uniform sampler2DShadow shadowMapAtlas; + #ifdef _ShadowMapTransparent + uniform sampler2D shadowMapAtlasTransparent; + #endif #endif #endif #ifdef _ShadowMapAtlas #ifndef _SingleAtlas //!uniform sampler2DShadow shadowMapAtlasPoint; + #ifdef _ShadowMapTransparent + //!uniform sampler2D shadowMapAtlasPointTransparent; #endif - //!uniform vec4 pointLightDataArray[4]; + #endif + //!uniform vec4 pointLightDataArray[maxLightsCluster * 6]; #else //!uniform samplerCubeShadow shadowMapPoint[4]; + #ifdef _ShadowMapTransparent + //!uniform samplerCube shadowMapPointTransparent[4]; + #endif #endif //!uniform vec2 lightProj; #ifdef _Spot #ifdef _ShadowMapAtlas #ifndef _SingleAtlas //!uniform sampler2DShadow shadowMapAtlasSpot; + #ifdef _ShadowMapTransparent + //!uniform sampler2D shadowMapAtlasSpotTransparent; + #endif #endif #else - //!uniform sampler2DShadow shadowMapSpot[4]; + //!uniform sampler2DShadow shadowMapSpot[maxLightsCluster]; + #ifdef _ShadowMapTransparent + //!uniform sampler2D shadowMapSpotTransparent[maxLightsCluster]; #endif - //!uniform mat4 LWVPSpotArray[4]; + #endif + //!uniform mat4 LWVPSpotArray[maxLightsCluster]; #endif #endif #endif @@ -97,10 +118,16 @@ uniform vec3 sunCol; #ifdef _ShadowMapAtlas #ifndef _SingleAtlas uniform sampler2DShadow shadowMapAtlasSun; + #ifdef _ShadowMapTransparent + uniform sampler2D shadowMapAtlasSunTransparent; + #endif #endif //!uniform vec4 tileBoundsSunArray[maxLights * shadowmapCascades]; #else uniform sampler2DShadow shadowMap; + #ifdef _ShadowMapTransparent + uniform sampler2D shadowMapTransparent; + #endif #endif uniform float shadowsBias; #ifdef _CSM @@ -167,10 +194,11 @@ void main() { vec4 g1 = textureLod(gbuffer1, texCoord, 0.0); // Basecolor.rgb, spec/occ vec2 occspec = unpackFloat2(g1.a); - vec3 albedo = surfaceAlbedo(g1.rgb, metallic); // g1.rgb - basecolor - vec3 f0 = surfaceF0(g1.rgb, metallic); + vec3 basecolor = min(g1.rgb, vec3(2.0)); + vec3 albedo = surfaceAlbedo(basecolor, metallic); + vec3 f0 = surfaceF0(basecolor, metallic); #ifdef _ExtBRDF - f0 = mix(f0, min(g1.rgb, vec3(2.0)), vec3(matp6.y, matp6.z, matp6.w)); + f0 = mix(f0, basecolor, vec3(matp6.y, matp6.z, matp6.w)); #endif float depth = textureLod(gbufferD, texCoord, 0.0).r * 2.0 - 1.0; @@ -206,7 +234,7 @@ void main() { envl /= PI; #endif #else - vec3 envl = vec3(1.0); + vec3 envl = vec3(0.0); #endif #ifdef _Rad @@ -227,13 +255,23 @@ void main() { #endif #endif +#ifdef _Brdf + vec3 F = f0 * envBRDF.x + envBRDF.y; +#else + vec3 F = f0; +#endif + envl.rgb *= diffuseIBL(albedo, roughness, f0, dotNV); +#ifdef _Brdf + envl.rgb *= 1.0 - F; +#endif + #ifdef _Rad // Indirect specular - envl.rgb += prefilteredColor * (f0 * envBRDF.x + envBRDF.y) * 1.5 * occspec.y; + envl.rgb += prefilteredColor * F; #else #ifdef _EnvCol - envl.rgb += backgroundCol * surfaceF0(g1.rgb, metallic); // f0 + envl.rgb += backgroundCol * F; #endif #endif @@ -281,7 +319,12 @@ void main() { float transmittance = 1.0 - transF; #ifdef _Rad if (matp2.z > 0.0 && transmittance > 0.0) { - vec3 refrDir = transmissionIBLDirection(n, v, matp3.x); + vec3 refrDir; + if (matp3.y > 0.5) { + refrDir = reflect(-v, n); + } else { + refrDir = transmissionIBLDirection(n, v, matp3.x); + } float transLod = getMipFromRoughness(matp2.w, envmapNumMipmaps); vec3 transColor = textureLod(senvmapRadiance, envMapEquirect(refrDir), transLod).rgb; @@ -337,7 +380,7 @@ void main() { float sdotNH = max(0.0, dot(n, sh)); float sdotVH = max(0.0, dot(v, sh)); float sdotNL = max(0.0, dot(n, sunDir)); - float svisibility = 1.0; + vec3 svisibility = vec3(1.0); #ifdef _Anisotropy vec3 sdirect; if (abs(matp0.x) > 0.001 && dot(wTangent, wTangent) > 0.001) { @@ -385,29 +428,59 @@ void main() { #ifdef _CSM svisibility = shadowTestCascade( #ifdef _ShadowMapAtlas + #ifdef _ShadowMapTransparent + #ifndef _SingleAtlas + shadowMapAtlasSun, shadowMapAtlasSunTransparent + #else + shadowMapAtlas, shadowMapAtlasTransparent + #endif + #else #ifndef _SingleAtlas shadowMapAtlasSun #else shadowMapAtlas #endif + #endif #else - shadowMap + #ifdef _ShadowMapTransparent + shadowMap, shadowMapTransparent + #else + shadowMap + #endif + #endif + , eye, p + n * shadowsBias * 2, shadowsBias + #ifdef _ShadowMapTransparent + , false #endif - , eye, p + n * shadowsBias * 10, shadowsBias ); #else - vec4 lPos = LWVP * vec4(p + n * shadowsBias * 100, 1.0); + vec4 lPos = LWVP * vec4(p + n * shadowsBias * 2, 1.0); if (lPos.w > 0.0) svisibility = shadowTest( #ifdef _ShadowMapAtlas + #ifdef _ShadowMapTransparent + #ifndef _SingleAtlas + shadowMapAtlasSun, shadowMapAtlasSunTransparent + #else + shadowMapAtlas, shadowMapAtlasTransparent + #endif + #else #ifndef _SingleAtlas shadowMapAtlasSun #else shadowMapAtlas #endif + #endif #else - shadowMap + #ifdef _ShadowMapTransparent + shadowMap, shadowMapTransparent + #else + shadowMap + #endif #endif , lPos.xyz / lPos.w, shadowsBias + #ifdef _ShadowMapTransparent + , false + #endif ); #endif #endif @@ -415,11 +488,18 @@ void main() { fragColor.rgb += sdirect * svisibility * sunCol; #endif +#ifdef _ShadowMapAtlas +tileBounds = vec4(0.0, 0.0, 1.0, 1.0); +#endif + #ifdef _SinglePoint fragColor.rgb += sampleLight( p, n, v, dotNV, pointPos, pointCol, albedo, roughness, occspec.y, f0 #ifdef _ShadowMap , 0, pointBias, true + #ifdef _ShadowMapTransparent + , false + #endif #endif #ifdef _Spot , true, spotData.x, spotData.y, spotDir, spotData.zw, spotRight // TODO: Test! @@ -472,12 +552,15 @@ void main() { #ifdef _ShadowMap // light index, shadow bias, cast_shadows , li, lightsArray[li * 3 + 2].x, lightsArray[li * 3 + 2].z != 0.0 + #ifdef _ShadowMapTransparent + , false + #endif #endif #ifdef _Spot , lightsArray[li * 3 + 2].y != 0.0 , lightsArray[li * 3 + 2].y // spot size (cutoff) - , lightsArraySpot[li].w // spot blend (exponent) - , lightsArraySpot[li].xyz // spotDir + , lightsArraySpot[li * 2].w // spot blend (exponent) + , lightsArraySpot[li * 2].xyz // spotDir , vec2(lightsArray[li * 3].w, lightsArray[li * 3 + 1].w) // scale , lightsArraySpot[li * 2 + 1].xyz // right #endif diff --git a/leenkx/Shaders/deferred_light_mobile/deferred_light_mobile.json b/leenkx/Shaders/deferred_light_mobile/deferred_light_mobile.json index efa0f9ce..1c02511a 100644 --- a/leenkx/Shaders/deferred_light_mobile/deferred_light_mobile.json +++ b/leenkx/Shaders/deferred_light_mobile/deferred_light_mobile.json @@ -122,11 +122,6 @@ "link": "_inverseViewProjectionMatrixRight", "ifdef": ["_VRStereo"] }, - { - "name": "invVP", - "link": "_viewProjectionMatrix", - "ifdef": ["_SSRS"] - }, { "name": "smSizeUniform", "link": "_shadowMapSize", @@ -137,14 +132,6 @@ "link": "_lightPlane", "ifdef": ["_SSS"] }, - { - "name": "VP", - "link": "_viewProjectionMatrix", - "ifdef": ["_SSRS"] - }, - { - "ifdef": ["_SMSizeUniform"] - }, { "name": "lightProj", "link": "_lightPlaneProj", diff --git a/leenkx/Shaders/std/light_mobile.glsl b/leenkx/Shaders/std/light_mobile.glsl index 58878fd8..41aeacc3 100644 --- a/leenkx/Shaders/std/light_mobile.glsl +++ b/leenkx/Shaders/std/light_mobile.glsl @@ -14,15 +14,24 @@ #ifdef _SinglePoint #ifdef _Spot uniform sampler2DShadow shadowMapSpot[1]; + #ifdef _ShadowMapTransparent + uniform sampler2D shadowMapSpotTransparent[1]; + #endif uniform mat4 LWVPSpotArray[1]; #else uniform samplerCubeShadow shadowMapPoint[1]; + #ifdef _ShadowMapTransparent + uniform samplerCube shadowMapPointTransparent[1]; + #endif uniform vec2 lightProj; #endif #endif #ifdef _Clusters #ifdef _SingleAtlas //!uniform sampler2DShadow shadowMapAtlas; + #ifdef _ShadowMapTransparent + //!uniform sampler2D shadowMapAtlasTransparent; + #endif #endif #ifndef _SinglePoint uniform vec2 lightProj; @@ -30,17 +39,29 @@ #ifdef _ShadowMapAtlas #ifndef _SingleAtlas uniform sampler2DShadow shadowMapAtlasPoint; + #ifdef _ShadowMapTransparent + uniform sampler2D shadowMapAtlasPointTransparent; + #endif #endif #else uniform samplerCubeShadow shadowMapPoint[4]; + #ifdef _ShadowMapTransparent + uniform samplerCube shadowMapPointTransparent[4]; + #endif #endif #ifdef _Spot #ifdef _ShadowMapAtlas #ifndef _SingleAtlas uniform sampler2DShadow shadowMapAtlasSpot; + #ifdef _ShadowMapTransparent + uniform sampler2D shadowMapAtlasSpotTransparent; + #endif #endif #else uniform sampler2DShadow shadowMapSpot[maxLightsCluster]; + #ifdef _ShadowMapTransparent + uniform sampler2D shadowMapSpotTransparent[maxLightsCluster]; + #endif #endif uniform mat4 LWVPSpotArray[maxLightsCluster]; #endif @@ -51,6 +72,9 @@ vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, co const vec3 albedo, const float rough, const float spec, const vec3 f0 #ifdef _ShadowMap , int index, float bias, bool receiveShadow + #ifdef _ShadowMapTransparent + , bool transparent + #endif #endif #ifdef _Spot , bool isSpot, float spotSize, float spotBlend, vec3 spotDir, vec2 scale, vec3 right @@ -121,26 +145,77 @@ vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, co #ifdef _ShadowMap if (receiveShadow) { #ifdef _SinglePoint - vec4 lPos = LWVPSpotArray[0] * vec4(p + n * bias * 10, 1.0); - direct *= shadowTest(shadowMapSpot[0], lPos.xyz / lPos.w, bias); + vec4 lPos = LWVPSpotArray[0] * vec4(p + n * bias * 10, 1.0); + direct *= shadowTest(shadowMapSpot[0], + #ifdef _ShadowMapTransparent + shadowMapSpotTransparent[0], + #endif + lPos.xyz / lPos.w, bias + #ifdef _ShadowMapTransparent + , transparent + #endif + ); #endif #ifdef _Clusters vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0); #ifdef _ShadowMapAtlas - tileBounds = tileBoundsSpotArray[index]; - direct *= shadowTest( - #ifndef _SingleAtlas - shadowMapAtlasSpot - #else - shadowMapAtlas + tileBounds = tileBoundsSpotArray[index]; + direct *= shadowTest( + #ifdef _ShadowMapTransparent + #ifndef _SingleAtlas + shadowMapAtlasSpot, shadowMapAtlasSpotTransparent + #else + shadowMapAtlas, shadowMapAtlasTransparent + #endif + #else + #ifndef _SingleAtlas + shadowMapAtlasSpot + #else + shadowMapAtlas + #endif + #endif + , lPos.xyz / lPos.w, bias + #ifdef _ShadowMapTransparent + , transparent + #endif + ); + #else + if (index == 0) direct *= shadowTest(shadowMapSpot[0], + #ifdef _ShadowMapTransparent + shadowMapSpotTransparent[0], #endif - , lPos.xyz / lPos.w, bias - ); - #else - if (index == 0) direct *= shadowTest(shadowMapSpot[0], lPos.xyz / lPos.w, bias); - else if (index == 1) direct *= shadowTest(shadowMapSpot[1], lPos.xyz / lPos.w, bias); - else if (index == 2) direct *= shadowTest(shadowMapSpot[2], lPos.xyz / lPos.w, bias); - else if (index == 3) direct *= shadowTest(shadowMapSpot[3], lPos.xyz / lPos.w, bias); + lPos.xyz / lPos.w, bias + #ifdef _ShadowMapTransparent + , transparent + #endif + ); + else if (index == 1) direct *= shadowTest(shadowMapSpot[1], + #ifdef _ShadowMapTransparent + shadowMapSpotTransparent[1], + #endif + lPos.xyz / lPos.w, bias + #ifdef _ShadowMapTransparent + , transparent + #endif + ); + else if (index == 2) direct *= shadowTest(shadowMapSpot[2], + #ifdef _ShadowMapTransparent + shadowMapSpotTransparent[2], + #endif + lPos.xyz / lPos.w, bias + #ifdef _ShadowMapTransparent + , transparent + #endif + ); + else if (index == 3) direct *= shadowTest(shadowMapSpot[3], + #ifdef _ShadowMapTransparent + shadowMapSpotTransparent[3], + #endif + lPos.xyz / lPos.w, bias + #ifdef _ShadowMapTransparent + , transparent + #endif + ); #endif #endif } @@ -153,25 +228,76 @@ vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, co if (receiveShadow) { #ifdef _SinglePoint - #ifndef _Spot - direct *= PCFCube(shadowMapPoint[0], ld, -l, bias, lightProj, n); + #ifndef _Spot + direct *= PCFCube(shadowMapPoint[0], + #ifdef _ShadowMapTransparent + shadowMapPointTransparent[0], #endif + ld, -l, bias, lightProj, n + #ifdef _ShadowMapTransparent + , transparent #endif + ); + #endif + #endif #ifdef _Clusters #ifdef _ShadowMapAtlas - direct *= PCFFakeCube( - #ifndef _SingleAtlas - shadowMapAtlasPoint - #else - shadowMapAtlas - #endif - , ld, -l, bias, lightProj, n, index - ); + direct *= PCFFakeCube( + #ifdef _ShadowMapTransparent + #ifndef _SingleAtlas + shadowMapAtlasPoint, shadowMapAtlasPointTransparent #else - if (index == 0) direct *= PCFCube(shadowMapPoint[0], ld, -l, bias, lightProj, n); - else if (index == 1) direct *= PCFCube(shadowMapPoint[1], ld, -l, bias, lightProj, n); - else if (index == 2) direct *= PCFCube(shadowMapPoint[2], ld, -l, bias, lightProj, n); - else if (index == 3) direct *= PCFCube(shadowMapPoint[3], ld, -l, bias, lightProj, n); + shadowMapAtlas, shadowMapAtlasTransparent + #endif + #else + #ifndef _SingleAtlas + shadowMapAtlasPoint + #else + shadowMapAtlas + #endif + #endif + , ld, -l, bias, lightProj, n, index + #ifdef _ShadowMapTransparent + , transparent + #endif + ); + #else + if (index == 0) direct *= PCFCube(shadowMapPoint[0], + #ifdef _ShadowMapTransparent + shadowMapPointTransparent[0], + #endif + ld, -l, bias, lightProj, n + #ifdef _ShadowMapTransparent + , transparent + #endif + ); + else if (index == 1) direct *= PCFCube(shadowMapPoint[1], + #ifdef _ShadowMapTransparent + shadowMapPointTransparent[1], + #endif + ld, -l, bias, lightProj, n + #ifdef _ShadowMapTransparent + , transparent + #endif + ); + else if (index == 2) direct *= PCFCube(shadowMapPoint[2], + #ifdef _ShadowMapTransparent + shadowMapPointTransparent[2], + #endif + ld, -l, bias, lightProj, n + #ifdef _ShadowMapTransparent + , transparent + #endif + ); + else if (index == 3) direct *= PCFCube(shadowMapPoint[3], + #ifdef _ShadowMapTransparent + shadowMapPointTransparent[3], + #endif + ld, -l, bias, lightProj, n + #ifdef _ShadowMapTransparent + , transparent + #endif + ); #endif #endif } @@ -186,6 +312,9 @@ vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, co const vec3 albedo, const float rough, const float spec, const vec3 f0 #ifdef _ShadowMap , int index, float bias, bool receiveShadow + #ifdef _ShadowMapTransparent + , bool transparent + #endif #endif #ifdef _Spot , bool isSpot, float spotSize, float spotBlend, vec3 spotDir, vec2 scale, vec3 right @@ -194,6 +323,9 @@ vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, co return sampleLight(p, n, v, dotNV, lp, lightCol, albedo, rough, spec, f0 #ifdef _ShadowMap , index, bias, receiveShadow + #ifdef _ShadowMapTransparent + , transparent + #endif #endif #ifdef _Spot , isSpot, spotSize, spotBlend, spotDir, scale, right diff --git a/leenkx/Shaders/water_pass/water_pass.frag.glsl b/leenkx/Shaders/water_pass/water_pass.frag.glsl index 2c21f25c..bce540ca 100644 --- a/leenkx/Shaders/water_pass/water_pass.frag.glsl +++ b/leenkx/Shaders/water_pass/water_pass.frag.glsl @@ -151,6 +151,7 @@ void main() { } // Displace surface + float geomZ = p.z; // undisplaced depth for foam/fog tests p.z += (sin(p.x * 10.0 / waterDisplace + speed) * cos(p.y * 10.0 / waterDisplace + speed) + sin(p.x * 20.0 / waterDisplace + speed * 1.3) * cos(p.y * 20.0 / waterDisplace + speed * 1.3) * 0.5) / 50.0 * waterDisplace; @@ -227,15 +228,19 @@ void main() { // Blinn-Phong specular using half-vector, faded at horizon vec3 h = normalize(v + ld); float specAmount = pow(max(dot(n2, h), 0.0), 200.0) * (200.0 + 8.0) / (PI * 8.0); - fragColor.rgb += specAmount * (isSky ? 0.3 : 1.0) * horizonFactor; + fragColor.rgb += specAmount * (isSky ? 0.3 : 1.0); // Depth fog - blend toward waterColor with depth, faded at horizon - float depthFog = clamp(-(p.z - waterLevel) * waterDensity, 0.0, 0.9); + float depthFog = clamp(-(geomZ - waterLevel) * waterDensity, 0.0, 0.9); fragColor.rgb = mix(fragColor.rgb, waterColor, depthFog * horizonFactor); // Alpha fades smoothly at horizon instead of hard cut - fragColor.a = isSky ? horizonFactor : clamp(abs(p.z - waterLevel) * 5.0, 0.0, 1.0); + // Skydome sits 3.5 below the camera (_skydomeMatrix), so its horizon + // appears where the ray z reaches -3.5 / domeRadius + float farPlane = cameraProj.y / (1.0 - cameraProj.x); + float horizonFade = clamp((-3.5 / (farPlane * 0.95) - vray.z) * 20.0, 0.0, 1.0); + fragColor.a = isSky ? horizonFade : clamp(abs(geomZ - waterLevel) * 5.0, 0.0, 1.0); // Foam - based on actual geometry depth below water surface - float fd = isSky ? 1.0 : abs(p.z - waterLevel); + float fd = isSky ? 1.0 : abs(geomZ - waterLevel); if (fd < 0.1) { // Based on foam by Owen Deery // http://fire-face.com/personal/water diff --git a/leenkx/Shaders/water_pass/water_pass.json b/leenkx/Shaders/water_pass/water_pass.json index 7e884e05..07257b65 100644 --- a/leenkx/Shaders/water_pass/water_pass.json +++ b/leenkx/Shaders/water_pass/water_pass.json @@ -34,7 +34,7 @@ }, { "name": "ld", - "link": "_lightDirection" + "link": "_sunDirection" }, { "name": "invVP", diff --git a/leenkx/Sources/iron/object/LightObject.hx b/leenkx/Sources/iron/object/LightObject.hx index 3c25324d..da6a8d79 100644 --- a/leenkx/Sources/iron/object/LightObject.hx +++ b/leenkx/Sources/iron/object/LightObject.hx @@ -90,8 +90,16 @@ class LightObject extends Object { #if lnx_spot if (data.raw.type == "spot"){ - this.size = data.raw.spot_size; - this.blend = data.raw.spot_blend; + this.size = 0.0; + this.blend = 0.0; + if (data.raw.spot_size != null) { + var s: kha.FastFloat = data.raw.spot_size; + this.size = s; + } + if (data.raw.spot_blend != null) { + var b: kha.FastFloat = data.raw.spot_blend; + this.blend = b; + } } #end diff --git a/leenkx/Sources/leenkx/renderpath/Inc.hx b/leenkx/Sources/leenkx/renderpath/Inc.hx index b779b1cb..de585e18 100644 --- a/leenkx/Sources/leenkx/renderpath/Inc.hx +++ b/leenkx/Sources/leenkx/renderpath/Inc.hx @@ -669,8 +669,10 @@ class Inc { #end #if rp_ssrs + #if kha_opengl path.bindTarget("_main", "gbufferD"); #end + #end path.drawMeshes("translucent"); @@ -1314,7 +1316,11 @@ class ShadowMapAtlas { function new(light: LightObject, transparent: Bool) { + #if lnx_shadowmap_atlas_single_map + var maxTileSize = Std.int(Math.max(Inc.getCubeSize(), Inc.getCascadeSize())); + #else var maxTileSize = shadowMapAtlasSize(light); + #end this.target = shadowMapAtlasName(light.data.raw.type, transparent); this.sizew = this.sizeh = this.baseTileSizeConst = maxTileSize; this.depth = getSubdivisions(); @@ -1418,8 +1424,8 @@ class ShadowMapAtlas { public static inline function shadowMapAtlasName(type: String, transparent: Bool): String { #if lnx_shadowmap_atlas_single_map - return "shadowMapAtlas"; - #else + return transparent ? "shadowMapAtlasTransparent" : "shadowMapAtlas"; + #else switch (type) { case "point": return transparent ? "shadowMapAtlasPointTransparent" : "shadowMapAtlasPoint"; diff --git a/leenkx/Sources/leenkx/renderpath/Postprocess.hx b/leenkx/Sources/leenkx/renderpath/Postprocess.hx index 83fe4e91..b758490a 100644 --- a/leenkx/Sources/leenkx/renderpath/Postprocess.hx +++ b/leenkx/Sources/leenkx/renderpath/Postprocess.hx @@ -116,6 +116,11 @@ class Postprocess { 1 //0: Exposure ]; + public static var scene_color_uniforms = [ + 0.0, //0: Scene Exposure + 1.0 //1: Scene Gamma + ]; + public static var auto_exposure_uniforms = [ 1, //0: Auto Exposure Strength 1 //1: Auto Exposure Speed @@ -406,6 +411,10 @@ class Postprocess { v.x = auto_focus[0]; v.y = auto_focus[1]; v.z = auto_focus[2]; + case "_PPComp20": + v = iron.object.Uniforms.helpVec; + v.x = scene_color_uniforms[0]; // Scene Exposure + v.y = scene_color_uniforms[1]; // Scene Gamma } return v; diff --git a/leenkx/Sources/leenkx/renderpath/RenderPathDeferred.hx b/leenkx/Sources/leenkx/renderpath/RenderPathDeferred.hx index 948ae5e9..fa6a32de 100644 --- a/leenkx/Sources/leenkx/renderpath/RenderPathDeferred.hx +++ b/leenkx/Sources/leenkx/renderpath/RenderPathDeferred.hx @@ -560,6 +560,7 @@ class RenderPathDeferred { @:access(iron.RenderPath) public static function commands() { path.setTarget("gbuffer0"); // Only clear gbuffer0 + //path.setTarget("gbuffer0", ["gbuffer1"]); #if (rp_background == "Clear") { path.clearTarget(-1, 1.0); @@ -649,7 +650,11 @@ class RenderPathDeferred { { if (leenkx.data.Config.raw.rp_ssao != false) { path.setTarget("singlea"); + #if rp_ssao_half + path.bindTarget("half", "gbufferD"); + #else path.bindTarget("_main", "gbufferD"); + #end path.bindTarget("gbuffer0", "gbuffer0"); path.drawShader("shader_datas/ssao_pass/ssao_pass"); @@ -670,7 +675,11 @@ class RenderPathDeferred { { if (leenkx.data.Config.raw.rp_ssgi != false) { path.setTarget("ssgi_a"); + #if rp_ssgi_half + path.bindTarget("half", "gbufferD"); + #else path.bindTarget("_main", "gbufferD"); + #end path.bindTarget("gbuffer0", "gbuffer0"); path.bindTarget("gbuffer1", "gbuffer1"); #if rp_gbuffer_emission @@ -684,13 +693,21 @@ class RenderPathDeferred { path.setTarget("ssgi_b"); path.bindTarget("ssgi_a", "tex"); path.bindTarget("gbuffer0", "gbuffer0"); + #if rp_ssgi_half + path.bindTarget("half", "gbufferD"); + #else path.bindTarget("_main", "gbufferD"); + #end path.drawShader("shader_datas/ssgi_blur_pass/ssgi_blur_pass_x"); path.setTarget("ssgi_a"); path.bindTarget("ssgi_b", "tex"); path.bindTarget("gbuffer0", "gbuffer0"); + #if rp_ssgi_half + path.bindTarget("half", "gbufferD"); + #else path.bindTarget("_main", "gbufferD"); + #end path.drawShader("shader_datas/ssgi_blur_pass/ssgi_blur_pass_y"); } } diff --git a/leenkx/blender/lnx/make_renderpath.py b/leenkx/blender/lnx/make_renderpath.py index 6eee2aca..f8b5e31a 100644 --- a/leenkx/blender/lnx/make_renderpath.py +++ b/leenkx/blender/lnx/make_renderpath.py @@ -267,6 +267,8 @@ def build(): wrd.compo_defs += '_CSharpen' if lnx.utils.get_active_scene().view_settings.exposure != 0.0: wrd.compo_defs += '_CExposure' + if lnx.utils.get_active_scene().view_settings.gamma != 1.0: + wrd.compo_defs += '_CGamma' if rpdat.lnx_fog: wrd.compo_defs += '_CFog' compo_depth = True @@ -341,6 +343,7 @@ def build(): wrd.world_defs += '_FSR1_{0}'.format(rpdat.rp_fsr1) assets.add_shader_pass('fsr1_easu_pass') assets.add_shader_pass('fsr1_rcas_pass') + assets.add_shader_pass('copy_pass') if rpdat.rp_ssao: assets.add_khafile_def('rp_ssao') diff --git a/leenkx/blender/lnx/material/make_cluster.py b/leenkx/blender/lnx/material/make_cluster.py index d46148b1..88983950 100644 --- a/leenkx/blender/lnx/material/make_cluster.py +++ b/leenkx/blender/lnx/material/make_cluster.py @@ -46,9 +46,11 @@ def write(vert: shader.Shader, frag: shader.Shader): if is_transparent_shadows: frag.add_uniform('samplerCube shadowMapPointTransparent[4]', included=True) - if not '_VoxelAOvar' in wrd.world_defs and not '_VoxelGI' in wrd.world_defs or ((parse_opacity or '_VoxelShadow' in wrd.world_defs) and ('_VoxelAOvar' in wrd.world_defs or '_VoxelGI' in wrd.world_defs)): - vert.add_out('vec4 wvpposition') - vert.write('wvpposition = gl_Position;') + #if not '_VoxelAOvar' in wrd.world_defs and not '_VoxelGI' in wrd.world_defs or ((parse_opacity or '_VoxelShadow' in wrd.world_defs) and ('_VoxelAOvar' in wrd.world_defs or '_VoxelGI' in wrd.world_defs)): + #vert.add_out('vec4 wvpposition') + #vert.write('wvpposition = gl_Position;') + vert.add_out('vec4 wvpposition') + vert.write('wvpposition = gl_Position;') # wvpposition.z / wvpposition.w frag.write('float viewz = linearize(gl_FragCoord.z, cameraProj);') frag.write('int clusterI = getClusterI((wvpposition.xy / wvpposition.w) * 0.5 + 0.5, viewz, cameraPlane);') diff --git a/leenkx/blender/lnx/material/mat_utils.py b/leenkx/blender/lnx/material/mat_utils.py index 25f5ac8e..ca9c64a9 100644 --- a/leenkx/blender/lnx/material/mat_utils.py +++ b/leenkx/blender/lnx/material/mat_utils.py @@ -51,7 +51,7 @@ def get_rpasses(material): ar.append('translucent') elif is_transluc(material) and not material.lnx_discard and not material.lnx_blending and rpdat.rp_ss_refraction: ar.append('refraction') - if rpdat.rp_voxels != "Off" and has_voxels: + if rpdat.rp_voxels != "Off" and has_voxels and rpdat.lnx_material_model == 'Full': ar.append('voxel') if rpdat.rp_renderer == 'Forward' and rpdat.rp_depthprepass and not material.lnx_blending and not material.lnx_particle_flag: ar.append('depth') diff --git a/leenkx/blender/lnx/props_renderpath.py b/leenkx/blender/lnx/props_renderpath.py index c90080b3..45952d09 100644 --- a/leenkx/blender/lnx/props_renderpath.py +++ b/leenkx/blender/lnx/props_renderpath.py @@ -347,7 +347,7 @@ class LnxRPListItem(bpy.types.PropertyGroup): name="Max Lights Shadows", description="Max number of rendered shadow maps that can be visible in the screen. Always equal or lower than Max Lights", default='16') rp_shadowmap_atlas: BoolProperty(name="Shadow Map Atlasing", description="Group shadow maps of lights of the same type in the same texture", default=False, update=update_renderpath) rp_shadowmap_atlas_auto: BoolProperty(name="Automatic Atlasing", description="Automatically compute atlas sizes based on max lights and shadow map sizes", default=True, update=update_renderpath) - rp_shadowmap_atlas_single_map: BoolProperty(name="Shadow Map Atlas single map", description="Use a single texture for all different light types.", default=False, update=update_renderpath) + rp_shadowmap_atlas_single_map: BoolProperty(name="Shadow Map Atlas single map", description="Use a single texture for all different light types.", default=True, update=update_renderpath) rp_shadowmap_atlas_lod: BoolProperty(name="Shadow Map Atlas LOD (Experimental)", description="When enabled, the size of the shadow map will be determined on runtime based on the distance of the light to the camera", default=False, update=update_renderpath) rp_shadowmap_transparent: BoolProperty(name="Transparency", description="Enable shadows for transparent objects", default=True, update=update_renderpath) rp_shadowmap_atlas_lod_subdivisions: EnumProperty( diff --git a/leenkx/blender/lnx/write_data.py b/leenkx/blender/lnx/write_data.py index aadb4d95..8bccdbdf 100644 --- a/leenkx/blender/lnx/write_data.py +++ b/leenkx/blender/lnx/write_data.py @@ -1009,6 +1009,7 @@ const vec3 compoSharpenColor = vec3(""" + str(round(rpdat.lnx_sharpen_color[0] * if lnx.utils.get_active_scene().view_settings.exposure != 0.0: f.write( """const float compoExposureStrength = """ + str(round(lnx.utils.get_active_scene().view_settings.exposure * 100) / 100) + """; +const float compoGammaStrength = """ + str(round(lnx.utils.get_active_scene().view_settings.gamma * 100) / 100) + """; """) if rpdat.lnx_fog: