diff --git a/features/Dynamic Cubemaps/Shaders/DynamicCubemaps/DynamicCubemaps.hlsli b/features/Dynamic Cubemaps/Shaders/DynamicCubemaps/DynamicCubemaps.hlsli index 7db9c0671..bc0ee7fd2 100644 --- a/features/Dynamic Cubemaps/Shaders/DynamicCubemaps/DynamicCubemaps.hlsli +++ b/features/Dynamic Cubemaps/Shaders/DynamicCubemaps/DynamicCubemaps.hlsli @@ -1,79 +1,82 @@ TextureCube specularTexture : register(t64); -// https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile -half2 EnvBRDFApprox(half Roughness, half NoV) +namespace DynamicCubemaps { - const half4 c0 = { -1, -0.0275, -0.572, 0.022 }; - const half4 c1 = { 1, 0.0425, 1.04, -0.04 }; - half4 r = Roughness * c0 + c1; - half a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y; - half2 AB = half2(-1.04, 1.04) * a004 + r.zw; - return AB; -} + // https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile + half2 EnvBRDFApprox(half Roughness, half NoV) + { + const half4 c0 = { -1, -0.0275, -0.572, 0.022 }; + const half4 c1 = { 1, 0.0425, 1.04, -0.04 }; + half4 r = Roughness * c0 + c1; + half a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y; + half2 AB = half2(-1.04, 1.04) * a004 + r.zw; + return AB; + } #if !defined(WATER) -float3 GetDynamicCubemapSpecularIrradiance(float2 uv, float3 N, float3 VN, float3 V, float roughness, float distance) -{ - float3 R = reflect(-V, N); - float level = roughness * 9.0; + float3 GetDynamicCubemapSpecularIrradiance(float2 uv, float3 N, float3 VN, float3 V, float roughness, float distance) + { + float3 R = reflect(-V, N); + float level = roughness * 9.0; - // Horizon specular occlusion - // https://marmosetco.tumblr.com/post/81245981087 - float horizon = min(1.0 + dot(R, VN), 1.0); - horizon *= horizon * horizon; + // Horizon specular occlusion + // https://marmosetco.tumblr.com/post/81245981087 + float horizon = min(1.0 + dot(R, VN), 1.0); + horizon *= horizon * horizon; - float3 specularIrradiance = specularTexture.SampleLevel(SampColorSampler, R, level).xyz; - specularIrradiance *= horizon; - specularIrradiance = sRGB2Lin(specularIrradiance); + float3 specularIrradiance = specularTexture.SampleLevel(SampColorSampler, R, level).xyz; + specularIrradiance *= horizon; + specularIrradiance = sRGB2Lin(specularIrradiance); - return specularIrradiance; -} + return specularIrradiance; + } -float3 GetDynamicCubemap(float2 uv, float3 N, float3 VN, float3 V, float roughness, float3 F0, float3 diffuseColor, float distance) -{ - float3 R = reflect(-V, N); - float NoV = saturate(dot(N, V)); + float3 GetDynamicCubemap(float2 uv, float3 N, float3 VN, float3 V, float roughness, float3 F0, float3 diffuseColor, float distance) + { + float3 R = reflect(-V, N); + float NoV = saturate(dot(N, V)); - float level = roughness * 7.0; + float level = roughness * 7.0; - float2 specularBRDF = EnvBRDFApprox(roughness, NoV); + float2 specularBRDF = EnvBRDFApprox(roughness, NoV); - // Horizon specular occlusion - // https://marmosetco.tumblr.com/post/81245981087 - float horizon = min(1.0 + dot(R, VN), 1.0); - horizon *= horizon * horizon; + // Horizon specular occlusion + // https://marmosetco.tumblr.com/post/81245981087 + float horizon = min(1.0 + dot(R, VN), 1.0); + horizon *= horizon * horizon; - // Roughness dependent fresnel - // https://www.jcgt.org/published/0008/01/03/paper.pdf - float3 Fr = max(1.0.xxx - roughness.xxx, F0) - F0; - float3 S = Fr * pow(1.0 - NoV, 5.0); + // Roughness dependent fresnel + // https://www.jcgt.org/published/0008/01/03/paper.pdf + float3 Fr = max(1.0.xxx - roughness.xxx, F0) - F0; + float3 S = Fr * pow(1.0 - NoV, 5.0); # if defined(DEFERRED) - return horizon * ((F0 + S) * specularBRDF.x + specularBRDF.y); + return horizon * ((F0 + S) * specularBRDF.x + specularBRDF.y); # else - float3 specularIrradiance = specularTexture.SampleLevel(SampColorSampler, R, level).xyz; - specularIrradiance = sRGB2Lin(specularIrradiance); - - return specularIrradiance * ((F0 + S) * specularBRDF.x + specularBRDF.y); -# endif -} - -float3 GetDynamicCubemapFresnel(float2 uv, float3 N, float3 VN, float3 V, float roughness, float level, float3 diffuseColor, float distance) -{ - float NoV = saturate(dot(N, V)); - float2 specularBRDF = EnvBRDFApprox(roughness, NoV); - if (specularBRDF.y > 0.001) { - float3 R = reflect(-V, N); float3 specularIrradiance = specularTexture.SampleLevel(SampColorSampler, R, level).xyz; + specularIrradiance = sRGB2Lin(specularIrradiance); - // Horizon specular occlusion - // https://marmosetco.tumblr.com/post/81245981087 - float horizon = min(1.0 + dot(R, VN), 1.0); - specularIrradiance *= horizon * horizon; + return specularIrradiance * ((F0 + S) * specularBRDF.x + specularBRDF.y); +# endif + } - return specularIrradiance * specularBRDF.y; + float3 GetDynamicCubemapFresnel(float2 uv, float3 N, float3 VN, float3 V, float roughness, float level, float3 diffuseColor, float distance) + { + float NoV = saturate(dot(N, V)); + float2 specularBRDF = EnvBRDFApprox(roughness, NoV); + if (specularBRDF.y > 0.001) { + float3 R = reflect(-V, N); + float3 specularIrradiance = specularTexture.SampleLevel(SampColorSampler, R, level).xyz; + + // Horizon specular occlusion + // https://marmosetco.tumblr.com/post/81245981087 + float horizon = min(1.0 + dot(R, VN), 1.0); + specularIrradiance *= horizon * horizon; + + return specularIrradiance * specularBRDF.y; + } + return 0.0; } - return 0.0; +#endif // !WATER } -#endif diff --git a/package/Shaders/Lighting.hlsl b/package/Shaders/Lighting.hlsl index 07baab6b9..355baf95a 100644 --- a/package/Shaders/Lighting.hlsl +++ b/package/Shaders/Lighting.hlsl @@ -2324,7 +2324,7 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace F0 = lerp(F0, sRGB2Lin(complexSpecular), (float)complexMaterial); # endif - envColor = GetDynamicCubemap(screenUV, worldSpaceNormal, worldSpaceVertexNormal, worldSpaceViewDirection, envRoughness, F0, diffuseColor, viewPosition.z) * envMask; + envColor = DynamicCubemaps::GetDynamicCubemap(screenUV, worldSpaceNormal, worldSpaceVertexNormal, worldSpaceViewDirection, envRoughness, F0, diffuseColor, viewPosition.z) * envMask; } # endif # endif // defined (ENVMAP) || defined (MULTI_LAYER_PARALLAX) || defined(EYE) @@ -2393,7 +2393,7 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace # if !defined(DEFERRED) # if defined(DYNAMIC_CUBEMAPS) - specularColorPBR += indirectSpecularLobeWeight * GetDynamicCubemapSpecularIrradiance(screenUV, worldSpaceNormal, worldSpaceVertexNormal, worldSpaceViewDirection, pbrSurfaceProperties.Roughness, viewPosition.z); + specularColorPBR += indirectSpecularLobeWeight * DynamicCubemaps::GetDynamicCubemapSpecularIrradiance(screenUV, worldSpaceNormal, worldSpaceVertexNormal, worldSpaceViewDirection, pbrSurfaceProperties.Roughness, viewPosition.z); # endif # else indirectDiffuseLobeWeight *= vertexColor;