diff --git a/Compositor/ALS/als.xml b/Compositor/ALS/als.xml index 860627a89..84855f100 100644 --- a/Compositor/ALS/als.xml +++ b/Compositor/ALS/als.xml @@ -76,13 +76,13 @@ <name>forward</name> <type>scene</type> <effect-scheme>als-lighting</effect-scheme> - <!-- - <clustered-shading> - <tile-size>128</tile-size> - <num-threads>4</num-threads> - <depth-slices>16</depth-slices> - </clustered-shading> - --> + + <clustered-shading> + <tile-size>128</tile-size> + <num-threads>1</num-threads> + <depth-slices>1</depth-slices> + </clustered-shading> + <use-shadow-pass>csm0</use-shadow-pass> <use-shadow-pass>csm1</use-shadow-pass> <use-shadow-pass>csm2</use-shadow-pass> diff --git a/Compositor/Effects/model-default.eff b/Compositor/Effects/model-default.eff index aa3575b8b..72e1c2abc 100644 --- a/Compositor/Effects/model-default.eff +++ b/Compositor/Effects/model-default.eff @@ -481,6 +481,15 @@ <fragment-shader>Shaders/ALS/noise.frag</fragment-shader> <fragment-shader>Shaders/ALS/filters.frag</fragment-shader> <fragment-shader>Shaders/ALS/shadows-include.frag</fragment-shader> + <fragment-shader>Shaders/ALS/clustered-include.frag</fragment-shader> + <uniform-block-binding> + <name>PointLightBlock</name> + <index>5</index> + </uniform-block-binding> + <uniform-block-binding> + <name>SpotLightBlock</name> + <index>6</index> + </uniform-block-binding> </program> <uniform> <name>visibility</name> diff --git a/Compositor/Shaders/ALS/clustered-include.frag b/Compositor/Shaders/ALS/clustered-include.frag new file mode 100644 index 000000000..71f2f8c26 --- /dev/null +++ b/Compositor/Shaders/ALS/clustered-include.frag @@ -0,0 +1,133 @@ +#version 150 + +uniform usampler3D fg_ClusteredLightGrid; +uniform usamplerBuffer fg_ClusteredLightIndices; +uniform int fg_ClusteredTileSize; +uniform float fg_ClusteredSliceScale; +uniform float fg_ClusteredSliceBias; + +const bool debug = true; +const float shininess = 16.0; + +struct PointLight { + vec4 position; + vec4 ambient; + vec4 diffuse; + vec4 specular; + vec4 attenuation; +}; + +struct SpotLight { + vec4 position; + vec4 direction; + vec4 ambient; + vec4 diffuse; + vec4 specular; + vec4 attenuation; + float cos_cutoff; + float exponent; +}; + +layout (std140) uniform PointLightBlock { + PointLight pointLights[256]; +}; +layout (std140) uniform SpotLightBlock { + SpotLight spotLights[256]; +}; + + +vec3 addColors(vec3 a, vec3 b) +{ + return 0.14 * log(exp(a/0.14) + exp(b/0.14)); +} + +// @param p Fragment position in view space. +// @param n Fragment normal in view space. +vec3 addClusteredLightsContribution(vec3 inputColor, vec3 p, vec3 n) +{ + int slice = int(max(log2(-p.z) * fg_ClusteredSliceScale + + fg_ClusteredSliceBias, 0.0)); + ivec3 clusterCoord = ivec3(gl_FragCoord.xy / fg_ClusteredTileSize, slice); + uvec3 cluster = texelFetch(fg_ClusteredLightGrid, + clusterCoord, + 0).rgb; + uint startIndex = cluster.r; + uint pointCount = cluster.g; + uint spotCount = cluster.b; + + vec3 color = vec3(0.0); + + for (uint i = uint(0); i < pointCount; ++i) { + uint lightListIndex = texelFetch(fg_ClusteredLightIndices, + int(startIndex + i)).r; + PointLight light = pointLights[lightListIndex]; + + float range = light.attenuation.w; + vec3 toLight = light.position.xyz - p; + // Ignore fragments outside the light volume + if (dot(toLight, toLight) > (range * range)) + continue; + + //////////////////////////////////////////////////////////////////////// + // Actual lighting + + float d = length(toLight); + float att = 1.0 / (light.attenuation.x // constant + + light.attenuation.y * d // linear + + light.attenuation.z * d * d); // quadratic + vec3 lightDir = normalize(toLight); + float NdotL = max(dot(n, lightDir), 0.0); + + vec3 Iamb = light.ambient.rgb; + vec3 Idiff = light.diffuse.rgb * NdotL; + vec3 Ispec = vec3(0.0); + + if (NdotL > 0.0) { + vec3 halfVector = normalize(lightDir + normalize(-p)); + float NdotHV = max(dot(n, halfVector), 0.0); + Ispec = light.specular.rgb * att * pow(NdotHV, shininess); + } + + color += addColors(color, (Iamb + Idiff + Ispec) * att); + } + + for (uint i = uint(0); i < spotCount; ++i) { + uint lightListIndex = texelFetch(fg_ClusteredLightIndices, + int(startIndex + i)).r; + SpotLight light = spotLights[lightListIndex]; + + vec3 toLight = light.position.xyz - p; + + //////////////////////////////////////////////////////////////////////// + // Actual lighting + + float d = length(toLight); + float att = 1.0 / (light.attenuation.x // constant + + light.attenuation.y * d // linear + + light.attenuation.z * d * d); // quadratic + + vec3 lightDir = normalize(toLight); + + float spotDot = dot(-lightDir, light.direction.xyz); + if (spotDot < light.cos_cutoff) + continue; + + att *= pow(spotDot, light.exponent); + + float NdotL = max(dot(n, lightDir), 0.0); + + vec3 Iamb = light.ambient.rgb; + vec3 Idiff = light.diffuse.rgb * NdotL; + vec3 Ispec = vec3(0.0); + + if (NdotL > 0.0) { + vec3 halfVector = normalize(lightDir + normalize(-p)); + float NdotHV = max(dot(n, halfVector), 0.0); + Ispec = light.specular.rgb * att * pow(NdotHV, shininess); + } + + color += (Iamb + Idiff + Ispec) * att; + } + + return clamp(color + inputColor, 0.0, 1.0); +} diff --git a/Compositor/Shaders/ALS/generic-base.vert b/Compositor/Shaders/ALS/generic-base.vert index cd1150e29..6895e834b 100644 --- a/Compositor/Shaders/ALS/generic-base.vert +++ b/Compositor/Shaders/ALS/generic-base.vert @@ -22,6 +22,7 @@ varying vec4 diffuse_term; varying vec3 normal; varying vec3 relPos; +varying vec4 ecPosition; varying float yprime_alt; varying float mie_angle; @@ -75,7 +76,7 @@ void main() // this code is copied from default.vert - //vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex; + ecPosition = gl_ModelViewMatrix * gl_Vertex; gl_Position = ftransform(); gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; normal = gl_NormalMatrix * gl_Normal; diff --git a/Compositor/Shaders/ALS/model-base.frag b/Compositor/Shaders/ALS/model-base.frag index ecd756ff1..437b924fe 100644 --- a/Compositor/Shaders/ALS/model-base.frag +++ b/Compositor/Shaders/ALS/model-base.frag @@ -6,7 +6,7 @@ varying vec4 diffuse_term; varying vec3 normal; varying vec3 relPos; - +varying vec4 ecPosition; uniform sampler2D texture; @@ -57,6 +57,7 @@ vec3 landing_light(in float offset, in float offsetv); vec3 filter_combined (in vec3 color) ; float getShadowing(); +vec3 addClusteredLightsContribution(vec3 inputColor, vec3 v, vec3 N); float luminance(vec3 color) { @@ -318,6 +319,7 @@ fragColor.rgb = mix(hazeColor + secondary_light * fog_backscatter(mvisibility), } +fragColor.rgb = addClusteredLightsContribution(fragColor.rgb, ecPosition.xyz, normal); fragColor.rgb = filter_combined(fragColor.rgb); gl_FragColor = fragColor;