evalLocalLighting function created in LightLocal.slh

This commit is contained in:
Olivier Prat 2018-01-15 12:02:29 +01:00
parent ca776fb9b4
commit 6af6b5fe41
2 changed files with 124 additions and 113 deletions

View file

@ -20,10 +20,10 @@
<@include LightClusterGrid.slh@>
<@func fetchClusterInfo(fragPos)@>
<@func fetchClusterInfo(fragWorldPos)@>
// From frag world pos find the cluster
vec4 clusterEyePos = frustumGrid_worldToEye(<$fragPos$>);
vec4 clusterEyePos = frustumGrid_worldToEye(<$fragWorldPos$>);
ivec3 clusterPos = frustumGrid_eyeToClusterPos(clusterEyePos.xyz);
ivec3 cluster = clusterGrid_getCluster(frustumGrid_clusterToIndex(clusterPos));
@ -31,7 +31,6 @@
if (numLights <= 0) {
discard;
}
int lightClusterOffset = cluster.z;
ivec3 dims = frustumGrid.dims.xyz;
if (clusterPos.x < 0 || clusterPos.x >= dims.x) {
@ -45,4 +44,120 @@
discard;
}
<@endfunc@>
<@endfunc@>
vec4 evalLocalLighting(ivec3 cluster, int numLights, vec3 fragWorldPos, vec3 fragNormal, vec3 fragEyeDir,
vec4 midNormalCurvature, vec4 lowNormalCurvature,
float fragRoughness, float fragScattering, float fragMetallic, vec3 fragFresnel, vec3 fragAlbedo) {
vec4 _fragColor = vec4(0.0);
int lightClusterOffset = cluster.z;
// Compute the rougness into gloss2 once:
float fragGloss2 = pow(fragRoughness + 0.001, 4.0);
bool withScattering = (fragScattering * isScatteringEnabled() > 0.0);
int numLightTouching = 0;
for (int i = 0; i < cluster.x; i++) {
// Need the light now
int theLightIndex = clusterGrid_getClusterLightId(i, lightClusterOffset);
Light light = getLight(theLightIndex);
// Clip againgst the light volume and Make the Light vector going from fragment to light center in world space
vec4 fragLightVecLen2;
vec4 fragLightDirLen;
if (!lightVolume_clipFragToLightVolumePoint(light.volume, fragWorldPos.xyz, fragLightVecLen2)) {
continue;
}
// Allright we re in the light sphere volume
fragLightDirLen.w = length(fragLightVecLen2.xyz);
fragLightDirLen.xyz = fragLightVecLen2.xyz / fragLightDirLen.w;
if (dot(fragNormal, fragLightDirLen.xyz) < 0.0) {
continue;
}
numLightTouching++;
vec3 diffuse = vec3(1.0);
vec3 specular = vec3(0.1);
// Allright we re valid in the volume
float fragLightDistance = fragLightDirLen.w;
vec3 fragLightDir = fragLightDirLen.xyz;
// Eval attenuation
float radialAttenuation = lightIrradiance_evalLightAttenuation(light.irradiance, fragLightDistance);
vec3 lightEnergy = radialAttenuation * getLightIrradiance(light);
// Eval shading
if (withScattering) {
evalFragShadingScattering(diffuse, specular, fragNormal, fragLightDir, fragEyeDir, fragMetallic, fragFresnel, fragRoughness, fragAlbedo
,fragScattering, midNormalCurvature, lowNormalCurvature );
} else {
evalFragShadingGloss(diffuse, specular, fragNormal, fragLightDir, fragEyeDir, fragMetallic, fragFresnel, fragGloss2, fragAlbedo);
}
diffuse *= lightEnergy * isDiffuseEnabled();
specular *= lightEnergy * isSpecularEnabled();
_fragColor.rgb += diffuse;
_fragColor.rgb += specular;
}
for (int i = cluster.x; i < numLights; i++) {
// Need the light now
int theLightIndex = clusterGrid_getClusterLightId(i, lightClusterOffset);
Light light = getLight(theLightIndex);
// Clip againgst the light volume and Make the Light vector going from fragment to light center in world space
vec4 fragLightVecLen2;
vec4 fragLightDirLen;
float cosSpotAngle;
if (!lightVolume_clipFragToLightVolumePoint(light.volume, fragWorldPos.xyz, fragLightVecLen2)) {
continue;
}
// Allright we re in the light sphere volume
fragLightDirLen.w = length(fragLightVecLen2.xyz);
fragLightDirLen.xyz = fragLightVecLen2.xyz / fragLightDirLen.w;
if (dot(fragNormal, fragLightDirLen.xyz) < 0.0) {
continue;
}
// Check spot
if (!lightVolume_clipFragToLightVolumeSpotSide(light.volume, fragLightDirLen, cosSpotAngle)) {
continue;
}
numLightTouching++;
vec3 diffuse = vec3(1.0);
vec3 specular = vec3(0.1);
// Allright we re valid in the volume
float fragLightDistance = fragLightDirLen.w;
vec3 fragLightDir = fragLightDirLen.xyz;
// Eval attenuation
float radialAttenuation = lightIrradiance_evalLightAttenuation(light.irradiance, fragLightDistance);
float angularAttenuation = lightIrradiance_evalLightSpotAttenuation(light.irradiance, cosSpotAngle);
vec3 lightEnergy = radialAttenuation * angularAttenuation * getLightIrradiance(light);
// Eval shading
if (withScattering) {
evalFragShadingScattering(diffuse, specular, fragNormal, fragLightDir, fragEyeDir, fragMetallic, fragFresnel, fragRoughness, fragAlbedo
,fragScattering, midNormalCurvature, lowNormalCurvature );
} else {
evalFragShadingGloss(diffuse, specular, fragNormal, fragLightDir, fragEyeDir, fragMetallic, fragFresnel, fragGloss2, fragAlbedo);
}
diffuse *= lightEnergy * isDiffuseEnabled();
specular *= lightEnergy * isSpecularEnabled();
_fragColor.rgb += diffuse;
_fragColor.rgb += specular;
}
return _fragColor;
}

View file

@ -38,9 +38,9 @@ void main(void) {
// Frag pos in world
mat4 invViewMat = getViewInverse();
vec4 fragPos = invViewMat * fragPosition;
vec4 fragWorldPos = invViewMat * fragPosition;
<$fetchClusterInfo(fragPos)$>;
<$fetchClusterInfo(fragWorldPos)$>;
vec4 midNormalCurvature;
vec4 lowNormalCurvature;
@ -53,113 +53,9 @@ void main(void) {
vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0);
vec3 fragEyeDir = normalize(fragEyeVector.xyz);
// Compute the rougness into gloss2 once:
float fragGloss2 = pow(frag.roughness + 0.001, 4.0);
bool withScattering = (frag.scattering * isScatteringEnabled() > 0.0);
int numLightTouching = 0;
for (int i = 0; i < cluster.x; i++) {
// Need the light now
int theLightIndex = clusterGrid_getClusterLightId(i, lightClusterOffset);
Light light = getLight(theLightIndex);
// Clip againgst the light volume and Make the Light vector going from fragment to light center in world space
vec4 fragLightVecLen2;
vec4 fragLightDirLen;
if (!lightVolume_clipFragToLightVolumePoint(light.volume, fragPos.xyz, fragLightVecLen2)) {
continue;
}
// Allright we re in the light sphere volume
fragLightDirLen.w = length(fragLightVecLen2.xyz);
fragLightDirLen.xyz = fragLightVecLen2.xyz / fragLightDirLen.w;
if (dot(frag.normal, fragLightDirLen.xyz) < 0.0) {
continue;
}
numLightTouching++;
vec3 diffuse = vec3(1.0);
vec3 specular = vec3(0.1);
// Allright we re valid in the volume
float fragLightDistance = fragLightDirLen.w;
vec3 fragLightDir = fragLightDirLen.xyz;
// Eval attenuation
float radialAttenuation = lightIrradiance_evalLightAttenuation(light.irradiance, fragLightDistance);
vec3 lightEnergy = radialAttenuation * getLightIrradiance(light);
// Eval shading
if (withScattering) {
evalFragShadingScattering(diffuse, specular, frag.normal, fragLightDir, fragEyeDir, frag.metallic, frag.fresnel, frag.roughness, frag.albedo
,frag.scattering, midNormalCurvature, lowNormalCurvature );
} else {
evalFragShadingGloss(diffuse, specular, frag.normal, fragLightDir, fragEyeDir, frag.metallic, frag.fresnel, fragGloss2, frag.albedo);
}
diffuse *= lightEnergy * isDiffuseEnabled();
specular *= lightEnergy * isSpecularEnabled();
_fragColor.rgb += diffuse;
_fragColor.rgb += specular;
}
for (int i = cluster.x; i < numLights; i++) {
// Need the light now
int theLightIndex = clusterGrid_getClusterLightId(i, lightClusterOffset);
Light light = getLight(theLightIndex);
// Clip againgst the light volume and Make the Light vector going from fragment to light center in world space
vec4 fragLightVecLen2;
vec4 fragLightDirLen;
float cosSpotAngle;
if (!lightVolume_clipFragToLightVolumePoint(light.volume, fragPos.xyz, fragLightVecLen2)) {
continue;
}
// Allright we re in the light sphere volume
fragLightDirLen.w = length(fragLightVecLen2.xyz);
fragLightDirLen.xyz = fragLightVecLen2.xyz / fragLightDirLen.w;
if (dot(frag.normal, fragLightDirLen.xyz) < 0.0) {
continue;
}
// Check spot
if (!lightVolume_clipFragToLightVolumeSpotSide(light.volume, fragLightDirLen, cosSpotAngle)) {
continue;
}
numLightTouching++;
vec3 diffuse = vec3(1.0);
vec3 specular = vec3(0.1);
// Allright we re valid in the volume
float fragLightDistance = fragLightDirLen.w;
vec3 fragLightDir = fragLightDirLen.xyz;
// Eval attenuation
float radialAttenuation = lightIrradiance_evalLightAttenuation(light.irradiance, fragLightDistance);
float angularAttenuation = lightIrradiance_evalLightSpotAttenuation(light.irradiance, cosSpotAngle);
vec3 lightEnergy = radialAttenuation * angularAttenuation * getLightIrradiance(light);
// Eval shading
if (withScattering) {
evalFragShadingScattering(diffuse, specular, frag.normal, fragLightDir, fragEyeDir, frag.metallic, frag.fresnel, frag.roughness, frag.albedo
,frag.scattering, midNormalCurvature, lowNormalCurvature );
} else {
evalFragShadingGloss(diffuse, specular, frag.normal, fragLightDir, fragEyeDir, frag.metallic, frag.fresnel, fragGloss2, frag.albedo);
}
diffuse *= lightEnergy * isDiffuseEnabled();
specular *= lightEnergy * isSpecularEnabled();
_fragColor.rgb += diffuse;
_fragColor.rgb += specular;
}
_fragColor = evalLocalLighting(cluster, numLights, fragWorldPos.xyz, frag.normal, fragEyeDir,
midNormalCurvature, lowNormalCurvature, frag.roughness, frag.scattering,
frag.metallic, frag.fresnel, frag.albedo);
}