Compositor: Initial support for clustered shading under the ALS pipeline
This commit is contained in:
parent
1e7a0beb9a
commit
8c13cd13e1
5 changed files with 157 additions and 9 deletions
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
136
Compositor/Shaders/ALS/clustered-include.frag
Normal file
136
Compositor/Shaders/ALS/clustered-include.frag
Normal file
|
@ -0,0 +1,136 @@
|
|||
#version 120
|
||||
|
||||
#extension GL_ARB_uniform_buffer_object : enable
|
||||
#extension GL_EXT_gpu_shader4 : enable
|
||||
|
||||
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 = texelFetch3D(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 = texelFetchBuffer(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 = texelFetchBuffer(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);
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue