Sorted out the mix between eye space and world space vectors in translucent object shading

This commit is contained in:
Olivier Prat 2018-04-13 15:38:55 +02:00
parent 2adac241d0
commit 190e9313c7
14 changed files with 174 additions and 162 deletions

View file

@ -32,12 +32,13 @@
vec3 color = vec3(0.0);
<@endfunc@>
<@func prepareGlobalLight(isScattering)@>
<@func prepareGlobalLight(positionES, normalWS)@>
// prepareGlobalLight
// Transform directions to worldspace
vec3 fragNormal = vec3((normal));
vec3 fragEyeVector = vec3(invViewMat * vec4(-position, 0.0));
vec3 fragEyeDir = normalize(fragEyeVector);
vec3 fragNormalWS = vec3(<$normalWS$>);
vec3 fragPositionWS = vec3(invViewMat * vec4(<$positionES$>, 1.0));
vec3 fragEyeVectorWS = invViewMat[3].xyz - fragPositionWS;
vec3 fragEyeDirWS = normalize(fragEyeVectorWS);
<$fetchGlobalLight()$>
@ -46,7 +47,7 @@
<@func declareEvalAmbientGlobalColor()@>
vec3 evalAmbientGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, vec3 fresnel, float metallic, float roughness) {
<$prepareGlobalLight()$>
<$prepareGlobalLight(position, normal)$>
color += albedo * getLightColor(light) * obscurance * getLightAmbientIntensity(lightAmbient);
return color;
}
@ -67,14 +68,14 @@ vec3 albedo, vec3 fresnel, float metallic, float roughness
, float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature
<@endif@> ) {
<$prepareGlobalLight($supportScattering$)$>
<$prepareGlobalLight(position, normal)$>
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragEyeDirWS);
// Ambient
vec3 ambientDiffuse;
vec3 ambientSpecular;
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surfaceWS, metallic, fresnel, albedo, obscurance
<@if supportScattering@>
,scattering, midNormalCurvature, lowNormalCurvature
<@endif@> );
@ -85,7 +86,7 @@ vec3 albedo, vec3 fresnel, float metallic, float roughness
// Directional
vec3 directionalDiffuse;
vec3 directionalSpecular;
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surfaceWS, metallic, fresnel, albedo, shadowAttenuation
<@if supportScattering@>
,scattering, midNormalCurvature, lowNormalCurvature
<@endif@> );
@ -114,14 +115,14 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu
, float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature
<@endif@>
) {
<$prepareGlobalLight($supportScattering$)$>
<$prepareGlobalLight(position, normal)$>
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragEyeDirWS);
// Ambient
vec3 ambientDiffuse;
vec3 ambientSpecular;
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surfaceWS, metallic, fresnel, albedo, obscurance
<@if supportScattering@>
,scattering, midNormalCurvature, lowNormalCurvature
<@endif@>
@ -131,7 +132,7 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu
vec3 directionalDiffuse;
vec3 directionalSpecular;
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surfaceWS, metallic, fresnel, albedo, shadowAttenuation
<@if supportScattering@>
,scattering, midNormalCurvature, lowNormalCurvature
<@endif@>
@ -141,7 +142,7 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu
// Attenuate the light if haze effect selected
if ((hazeParams.hazeMode & HAZE_MODE_IS_KEYLIGHT_ATTENUATED) == HAZE_MODE_IS_KEYLIGHT_ATTENUATED) {
color = computeHazeColorKeyLightAttenuation(color, lightDirection, position);
color = computeHazeColorKeyLightAttenuation(color, lightDirection, fragPositionWS);
}
return color;
@ -180,9 +181,9 @@ vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, float obscur
<$declareLightingDirectional()$>
vec3 evalGlobalLightingAlphaBlended(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, float roughness, float opacity, vec3 prevLighting) {
<$prepareGlobalLight()$>
<$prepareGlobalLight(position, normal)$>
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragEyeDirWS);
color = prevLighting;
color += emissive * isEmissiveEnabled();
@ -190,14 +191,14 @@ vec3 evalGlobalLightingAlphaBlended(mat4 invViewMat, float shadowAttenuation, fl
// Ambient
vec3 ambientDiffuse;
vec3 ambientSpecular;
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance);
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surfaceWS, metallic, fresnel, albedo, obscurance);
color += ambientDiffuse;
color += ambientSpecular / opacity;
// Directional
vec3 directionalDiffuse;
vec3 directionalSpecular;
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation);
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surfaceWS, metallic, fresnel, albedo, shadowAttenuation);
color += directionalDiffuse;
color += directionalSpecular / opacity;
@ -211,26 +212,27 @@ vec3 evalGlobalLightingAlphaBlended(mat4 invViewMat, float shadowAttenuation, fl
<$declareLightingDirectional()$>
vec3 evalGlobalLightingAlphaBlendedWithHaze(
mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal,
mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 positionES, vec3 normalWS,
vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, float roughness, float opacity)
{
<$prepareGlobalLight()$>
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
<$prepareGlobalLight(positionES, normalWS)$>
SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragEyeDirWS);
color += emissive * isEmissiveEnabled();
// Ambient
vec3 ambientDiffuse;
vec3 ambientSpecular;
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance);
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surfaceWS, metallic, fresnel, albedo, obscurance);
color += ambientDiffuse;
color += ambientSpecular / opacity;
// Directional
vec3 directionalDiffuse;
vec3 directionalSpecular;
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation);
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surfaceWS, metallic, fresnel, albedo, shadowAttenuation);
color += directionalDiffuse;
color += directionalSpecular / opacity;
@ -238,8 +240,8 @@ vec3 evalGlobalLightingAlphaBlendedWithHaze(
if ((hazeParams.hazeMode & HAZE_MODE_IS_ACTIVE) == HAZE_MODE_IS_ACTIVE) {
vec4 colorV4 = computeHazeColor(
vec4(color, 1.0), // fragment original color
position, // fragment position in eye coordinates
fragEyeVector, // fragment position in world coordinates
positionES, // fragment position in eye coordinates
fragPositionWS, // fragment position in world coordinates
invViewMat[3].xyz, // eye position in world coordinates
lightDirection // keylight direction vector in world coordinates
);
@ -251,7 +253,7 @@ vec3 evalGlobalLightingAlphaBlendedWithHaze(
}
vec3 evalGlobalLightingAlphaBlendedWithHaze(
mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position,
mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 positionES, vec3 positionWS,
vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, SurfaceData surface, float opacity, vec3 prevLighting)
{
<$fetchGlobalLight()$>
@ -276,8 +278,8 @@ vec3 evalGlobalLightingAlphaBlendedWithHaze(
if ((hazeParams.hazeMode & HAZE_MODE_IS_ACTIVE) == HAZE_MODE_IS_ACTIVE) {
vec4 colorV4 = computeHazeColor(
vec4(color, 1.0), // fragment original color
position, // fragment position in eye coordinates
surface.eyeDir, // fragment eye vector in world coordinates
positionES, // fragment position in eye coordinates
positionWS, // fragment position in world coordinates
invViewMat[3].xyz, // eye position in world coordinates
lightDirection // keylight direction vector
);

View file

@ -21,12 +21,13 @@
<@include LightDirectional.slh@>
<@func prepareGlobalLight(isScattering)@>
<@func prepareGlobalLight(positionES, normalWS)@>
// prepareGlobalLight
// Transform directions to worldspace
vec3 fragNormal = vec3((normal));
vec3 fragEyeVector = vec3(invViewMat * vec4(-1.0*position, 0.0));
vec3 fragEyeDir = normalize(fragEyeVector);
vec3 fragNormalWS = vec3(<$normalWS$>);
vec3 fragPositionWS = vec3(invViewMat * vec4(<$positionES$>, 1.0));
vec3 fragEyeVectorWS = invViewMat[3].xyz - fragPositionWS;
vec3 fragEyeDirWS = normalize(fragEyeVectorWS);
// Get light
Light light = getKeyLight();
@ -42,7 +43,7 @@
<@func declareEvalAmbientGlobalColor()@>
vec3 evalAmbientGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, vec3 fresnel, float metallic, float roughness) {
<$prepareGlobalLight()$>
<$prepareGlobalLight(position, normal)$>
color += albedo * getLightColor(light) * obscurance * getLightAmbientIntensity(lightAmbient);
return color;
}
@ -63,14 +64,14 @@ vec3 albedo, vec3 fresnel, float metallic, float roughness
, float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature
<@endif@> ) {
<$prepareGlobalLight($supportScattering$)$>
<$prepareGlobalLight(position, normal)$>
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragEyeDirWS);
// Ambient
vec3 ambientDiffuse;
vec3 ambientSpecular;
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surfaceWS, metallic, fresnel, albedo, obscurance
<@if supportScattering@>
,scattering, midNormalCurvature, lowNormalCurvature
<@endif@> );
@ -81,7 +82,7 @@ vec3 albedo, vec3 fresnel, float metallic, float roughness
// Directional
vec3 directionalDiffuse;
vec3 directionalSpecular;
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surfaceWS, metallic, fresnel, albedo, shadowAttenuation
<@if supportScattering@>
,scattering, midNormalCurvature, lowNormalCurvature
<@endif@> );
@ -109,14 +110,14 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu
, float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature
<@endif@>
) {
<$prepareGlobalLight($supportScattering$)$>
<$prepareGlobalLight(position, normal)$>
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragEyeDirWS);
// Ambient
vec3 ambientDiffuse;
vec3 ambientSpecular;
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surfaceWS, metallic, fresnel, albedo, obscurance
<@if supportScattering@>
,scattering, midNormalCurvature, lowNormalCurvature
<@endif@>
@ -126,7 +127,7 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu
vec3 directionalDiffuse;
vec3 directionalSpecular;
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surfaceWS, metallic, fresnel, albedo, shadowAttenuation
<@if supportScattering@>
,scattering, midNormalCurvature, lowNormalCurvature
<@endif@>
@ -137,7 +138,7 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu
// FIXME - temporarily removed until we support it for forward...
// Attenuate the light if haze effect selected
// if ((hazeParams.hazeMode & HAZE_MODE_IS_KEYLIGHT_ATTENUATED) == HAZE_MODE_IS_KEYLIGHT_ATTENUATED) {
// color = computeHazeColorKeyLightAttenuation(color, lightDirection, position);
// color = computeHazeColorKeyLightAttenuation(color, lightDirection, fragPositionWS);
// }
return color;
@ -180,23 +181,23 @@ vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, float obscur
<$declareLightingDirectional()$>
vec3 evalGlobalLightingAlphaBlended(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, float roughness, float opacity) {
<$prepareGlobalLight()$>
<$prepareGlobalLight(position, normal)$>
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragEyeDirWS);
color += emissive * isEmissiveEnabled();
// Ambient
vec3 ambientDiffuse;
vec3 ambientSpecular;
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance);
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surfaceWS, metallic, fresnel, albedo, obscurance);
color += ambientDiffuse;
color += ambientSpecular / opacity;
// Directional
vec3 directionalDiffuse;
vec3 directionalSpecular;
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation);
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surfaceWS, metallic, fresnel, albedo, shadowAttenuation);
color += directionalDiffuse;
color += directionalSpecular / opacity;
@ -207,23 +208,23 @@ vec3 evalGlobalLightingAlphaBlendedWithHaze(
mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal,
vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, float roughness, float opacity)
{
<$prepareGlobalLight()$>
<$prepareGlobalLight(position, normal)$>
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragEyeDirWS);
color += emissive * isEmissiveEnabled();
// Ambient
vec3 ambientDiffuse;
vec3 ambientSpecular;
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance);
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surfaceWS, metallic, fresnel, albedo, obscurance);
color += ambientDiffuse;
color += ambientSpecular / opacity;
// Directional
vec3 directionalDiffuse;
vec3 directionalSpecular;
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation);
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surfaceWS, metallic, fresnel, albedo, shadowAttenuation);
color += directionalDiffuse;
color += directionalSpecular / opacity;
@ -232,8 +233,8 @@ vec3 evalGlobalLightingAlphaBlendedWithHaze(
/* if ((hazeParams.hazeMode & HAZE_MODE_IS_ACTIVE) == HAZE_MODE_IS_ACTIVE) {
vec4 colorV4 = computeHazeColor(
vec4(color, 1.0), // fragment original color
position, // fragment position in eye coordinates
fragEyeVector, // fragment position in world coordinates
positionES, // fragment position in eye coordinates
fragPositionWS, // fragment position in world coordinates
invViewMat[3].xyz, // eye position in world coordinates
lightDirection // keylight direction vector
);

View file

@ -47,14 +47,14 @@ void main(void) {
}
vec4 fragColor = texture(colorMap, varTexCoord0);
vec4 eyeFragPos = unpackPositionFromZeye(varTexCoord0);
vec4 fragPositionES = unpackPositionFromZeye(varTexCoord0);
mat4 viewInverse = getViewInverse();
vec4 worldFragPos = viewInverse * eyeFragPos;
vec4 worldEyePos = viewInverse[3];
vec4 fragPositionWS = viewInverse * fragPositionES;
vec4 eyePositionWS = viewInverse[3];
Light light = getKeyLight();
vec3 lightDirection = getLightDirection(light);
vec3 lightDirectionWS = getLightDirection(light);
outFragColor = computeHazeColor(fragColor, eyeFragPos.xyz, worldFragPos.xyz, worldEyePos.xyz, lightDirection);
outFragColor = computeHazeColor(fragColor, fragPositionES.xyz, fragPositionWS.xyz, eyePositionWS.xyz, lightDirectionWS);
}

View file

@ -43,14 +43,14 @@ layout(std140) uniform hazeBuffer {
// Input:
// color - fragment original color
// lightDirection - parameters of the keylight
// fragWorldPos - fragment position in world coordinates
// lightDirectionWS - parameters of the keylight
// fragPositionWS - fragment position in world coordinates
// Output:
// fragment colour after haze effect
//
// General algorithm taken from http://www.iquilezles.org/www/articles/fog/fog.htm, with permission
//
vec3 computeHazeColorKeyLightAttenuation(vec3 color, vec3 lightDirection, vec3 fragWorldPos) {
vec3 computeHazeColorKeyLightAttenuation(vec3 color, vec3 lightDirectionWS, vec3 fragPositionWS) {
// Directional light attenuation is simulated by assuming the light source is at a fixed height above the
// fragment. This height is where the haze density is reduced by 95% from the haze at the fragment's height
//
@ -65,7 +65,7 @@ vec3 computeHazeColorKeyLightAttenuation(vec3 color, vec3 lightDirection, vec3 f
}
// Note that we need the sine to be positive
float sin_pitch = abs(lightDirection.y);
float sin_pitch = abs(lightDirectionWS.y);
float distance;
const float minimumSinPitch = 0.001;
@ -79,7 +79,7 @@ vec3 computeHazeColorKeyLightAttenuation(vec3 color, vec3 lightDirection, vec3 f
// Note that the haze base reference affects only the haze density as function of altitude
float hazeDensityDistribution =
hazeParams.hazeKeyLightRangeFactor *
exp(-hazeParams.hazeKeyLightAltitudeFactor * (fragWorldPos.y - hazeParams.hazeBaseReference));
exp(-hazeParams.hazeKeyLightAltitudeFactor * (fragPositionWS.y - hazeParams.hazeBaseReference));
float hazeIntegral = hazeDensityDistribution * distance;
@ -92,27 +92,27 @@ vec3 computeHazeColorKeyLightAttenuation(vec3 color, vec3 lightDirection, vec3 f
}
// Input:
// fragColor - fragment original color
// fragEyePos - fragment position in eye coordinates
// fragWorldPos - fragment position in world coordinates
// eyeWorldPos - eye position in world coordinates
// fragColor - fragment original color
// fragPositionES - fragment position in eye coordinates
// fragPositionWS - fragment position in world coordinates
// eyePositionWS - eye position in world coordinates
// Output:
// fragment colour after haze effect
//
// General algorithm taken from http://www.iquilezles.org/www/articles/fog/fog.htm, with permission
//
vec4 computeHazeColor(vec4 fragColor, vec3 fragEyePos, vec3 fragWorldPos, vec3 eyeWorldPos, vec3 lightDirection) {
vec4 computeHazeColor(vec4 fragColor, vec3 fragPositionES, vec3 fragPositionWS, vec3 eyePositionWS, vec3 lightDirectionWS) {
// Distance to fragment
float distance = length(fragEyePos);
float eyeWorldHeight = eyeWorldPos.y;
float distance = length(fragPositionES);
float eyeWorldHeight = eyePositionWS.y;
// Convert haze colour from uniform into a vec4
vec4 hazeColor = vec4(hazeParams.hazeColor, 1.0);
// Directional light component is a function of the angle from the eye, between the fragment and the sun
vec3 fragToEyeWorldDir = normalize(fragWorldPos-eyeWorldPos);
vec3 fragToEyeDirWS = normalize(fragPositionWS - eyePositionWS);
float glareComponent = max(0.0, dot(fragToEyeWorldDir, -lightDirection));
float glareComponent = max(0.0, dot(fragToEyeDirWS, -lightDirectionWS));
float power = min(1.0, pow(glareComponent, hazeParams.hazeGlareBlend));
vec4 glareColor = vec4(hazeParams.hazeGlareColor, 1.0);
@ -140,7 +140,7 @@ vec4 computeHazeColor(vec4 fragColor, vec3 fragEyePos, vec3 fragWorldPos, vec3 e
vec3 hazeIntegral = hazeDensityDistribution * distance;
const float slopeThreshold = 0.01;
float deltaHeight = fragWorldPos.y - eyeWorldHeight;
float deltaHeight = fragPositionWS.y - eyeWorldHeight;
if (abs(deltaHeight) > slopeThreshold) {
float t = hazeParams.hazeHeightFactor * deltaHeight;
hazeIntegral *= (1.0 - exp (-t)) / t;
@ -168,7 +168,7 @@ vec4 computeHazeColor(vec4 fragColor, vec3 fragEyePos, vec3 fragWorldPos, vec3 e
float hazeIntegral = hazeDensityDistribution * distance;
const float slopeThreshold = 0.01;
float deltaHeight = fragWorldPos.y - eyeWorldHeight;
float deltaHeight = fragPositionWS.y - eyeWorldHeight;
if (abs(deltaHeight) > slopeThreshold) {
float t = hazeParams.hazeHeightFactor * deltaHeight;
// Protect from wild values

View file

@ -228,14 +228,14 @@ vec3 fetchLightmapMap(vec2 uv) {
}
<@endfunc@>
<@func evalMaterialNormalLOD(fragPos, fetchedNormal, interpolatedNormal, interpolatedTangent, normal)@>
<@func evalMaterialNormalLOD(fragPosES, fetchedNormal, interpolatedNormal, interpolatedTangent, normal)@>
{
vec3 normalizedNormal = normalize(<$interpolatedNormal$>.xyz);
vec3 normalizedTangent = normalize(<$interpolatedTangent$>.xyz);
vec3 normalizedBitangent = cross(normalizedNormal, normalizedTangent);
// attenuate the normal map divergence from the mesh normal based on distance
// The attenuation range [20,100] meters from the eye is arbitrary for now
vec3 localNormal = mix(<$fetchedNormal$>, vec3(0.0, 1.0, 0.0), smoothstep(20.0, 100.0, (-<$fragPos$>).z));
vec3 localNormal = mix(<$fetchedNormal$>, vec3(0.0, 1.0, 0.0), smoothstep(20.0, 100.0, (-<$fragPosES$>).z));
<$normal$> = vec3(normalizedBitangent * localNormal.x + normalizedNormal * localNormal.y + normalizedTangent * localNormal.z);
}
<@endfunc@>

View file

@ -23,11 +23,11 @@
<@include MaterialTextures.slh@>
<$declareMaterialTextures(ALBEDO, ROUGHNESS, NORMAL, METALLIC, EMISSIVE, OCCLUSION)$>
in vec4 _position;
in vec4 _positionES;
in vec2 _texCoord0;
in vec2 _texCoord1;
in vec3 _normal;
in vec3 _tangent;
in vec3 _normalWS;
in vec3 _tangentWS;
in vec3 _color;
layout(location = 0) out vec4 _fragColor0;
@ -56,9 +56,9 @@ void main(void) {
<$evalMaterialMetallic(metallicTex, metallic, matKey, metallic)$>;
vec3 fresnel = getFresnelF0(metallic, albedo);
vec3 fragPosition = _position.xyz;
vec3 fragPosition = _positionES.xyz;
vec3 fragNormal;
<$evalMaterialNormal(normalTex, _normal, _tangent, fragNormal)$>
<$evalMaterialNormal(normalTex, _normalWS, _tangentWS, fragNormal)$>
TransformCamera cam = getTransformCamera();

View file

@ -19,11 +19,11 @@
<@include MaterialTextures.slh@>
<$declareMaterialTextures(ALBEDO, ROUGHNESS, NORMAL, METALLIC, EMISSIVE, OCCLUSION, SCATTERING)$>
in vec4 _position;
in vec4 _positionES;
in vec2 _texCoord0;
in vec2 _texCoord1;
in vec3 _normal;
in vec3 _tangent;
in vec3 _normalWS;
in vec3 _tangentWS;
in vec3 _color;
void main(void) {
@ -46,8 +46,8 @@ void main(void) {
vec3 emissive = getMaterialEmissive(mat);
<$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>;
vec3 fragNormal;
<$evalMaterialNormalLOD(_position, normalTex, _normal, _tangent, fragNormal)$>
vec3 fragNormalWS;
<$evalMaterialNormalLOD(_positionES, normalTex, _normalWS, _tangentWS, fragNormalWS)$>
float metallic = getMaterialMetallic(mat);
<$evalMaterialMetallic(metallicTex, metallic, matKey, metallic)$>;
@ -56,7 +56,7 @@ void main(void) {
<$evalMaterialScattering(scatteringTex, scattering, matKey, scattering)$>;
packDeferredFragment(
normalize(fragNormal.xyz),
normalize(fragNormalWS.xyz),
opacity,
albedo,
roughness,

View file

@ -20,11 +20,11 @@
<@include MaterialTextures.slh@>
<$declareMaterialTexMapArrayBuffer()$>
out vec4 _position;
out vec4 _positionES;
out vec2 _texCoord0;
out vec2 _texCoord1;
out vec3 _normal;
out vec3 _tangent;
out vec3 _normalWS;
out vec3 _tangentWS;
out vec3 _color;
out float _alpha;
@ -40,7 +40,7 @@ void main(void) {
// standard transform
TransformCamera cam = getTransformCamera();
TransformObject obj = getTransformObject();
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _position, gl_Position)$>
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normal)$>
<$transformModelToWorldDir(cam, obj, inTangent.xyz, _tangent)$>
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _positionES, gl_Position)$>
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normalWS)$>
<$transformModelToWorldDir(cam, obj, inTangent.xyz, _tangentWS)$>
}

View file

@ -28,9 +28,9 @@
in vec2 _texCoord0;
in vec2 _texCoord1;
in vec4 _position;
in vec4 _worldPosition;
in vec3 _normal;
in vec4 _positionES;
in vec4 _positionWS;
in vec3 _normalWS;
in vec3 _color;
in float _alpha;
@ -58,20 +58,21 @@ void main(void) {
vec3 emissive = getMaterialEmissive(mat);
<$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>;
vec3 fragPosition = _position.xyz;
vec3 fragPositionES = _positionES.xyz;
vec3 fragPositionWS = _positionWS.xyz;
// Lighting is done in world space
vec3 fragNormal = normalize(_normal);
vec3 fragNormalWS = normalize(_normalWS);
TransformCamera cam = getTransformCamera();
vec3 fragEyeVector = vec3(cam._viewInverse * vec4(-fragPosition, 0.0));
vec3 fragEyeDir = normalize(fragEyeVector);
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
vec3 fragToEyeWS = fragPositionWS - cam._viewInverse[3].xyz;
vec3 fragToEyeDirWS = normalize(fragToEyeWS);
SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragToEyeDirWS);
vec4 localLighting = vec4(0.0);
<$fetchClusterInfo(_worldPosition)$>;
<$fetchClusterInfo(_positionWS)$>;
if (hasLocalLights(numLights, clusterPos, dims)) {
localLighting = evalLocalLighting(cluster, numLights, _worldPosition.xyz, surface,
localLighting = evalLocalLighting(cluster, numLights, fragPositionWS, surfaceWS,
metallic, fresnel, albedo, 0.0,
vec4(0), vec4(0), opacity);
}
@ -80,11 +81,12 @@ void main(void) {
cam._viewInverse,
1.0,
occlusionTex,
fragPosition,
fragPositionES,
fragPositionWS,
albedo,
fresnel,
metallic,
emissive,
surface, opacity, localLighting.rgb),
surfaceWS, opacity, localLighting.rgb),
opacity);
}

View file

@ -22,9 +22,9 @@
out float _alpha;
out vec2 _texCoord0;
out vec2 _texCoord1;
out vec4 _position;
out vec4 _worldPosition;
out vec3 _normal;
out vec4 _positionES;
out vec4 _positionWS;
out vec3 _normalWS;
out vec3 _color;
void main(void) {
@ -38,7 +38,7 @@ void main(void) {
// standard transform
TransformCamera cam = getTransformCamera();
TransformObject obj = getTransformObject();
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _position, gl_Position)$>
<$transformModelToWorldPos(obj, inPosition, _worldPosition)$>
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normal)$>
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _positionES, gl_Position)$>
<$transformModelToWorldPos(obj, inPosition, _positionWS)$>
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normalWS)$>
}

View file

@ -24,11 +24,11 @@
in vec2 _texCoord0;
in vec2 _texCoord1;
in vec4 _position;
in vec3 _normal;
in vec4 _positionES;
in vec4 _positionWS;
in vec3 _normalWS;
in vec3 _color;
in float _alpha;
in vec4 _worldPosition;
out vec4 _fragColor;
@ -37,7 +37,7 @@ void main(void) {
FadeObjectParams fadeParams;
<$fetchFadeObjectParams(fadeParams)$>
applyFade(fadeParams, _worldPosition.xyz, fadeEmissive);
applyFade(fadeParams, _positionWS.xyz, fadeEmissive);
Material mat = getMaterial();
BITFIELD matKey = getMaterialKey(mat);
@ -60,20 +60,21 @@ void main(void) {
vec3 emissive = getMaterialEmissive(mat);
<$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>;
vec3 fragPosition = _position.xyz;
vec3 fragPositionES = _positionES.xyz;
vec3 fragPositionWS = _positionWS.xyz;
// Lighting is done in world space
vec3 fragNormal = normalize(_normal);
vec3 fragNormalWS = normalize(_normalWS);
TransformCamera cam = getTransformCamera();
vec3 fragEyeVector = vec3(cam._viewInverse * vec4(-fragPosition, 0.0));
vec3 fragEyeDir = normalize(fragEyeVector);
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
vec3 fragToEyeWS = fragPositionWS - cam._viewInverse[3].xyz;
vec3 fragToEyeDirWS = normalize(fragToEyeWS);
SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragToEyeDirWS);
vec4 localLighting = vec4(0.0);
<$fetchClusterInfo(_worldPosition)$>;
<$fetchClusterInfo(_positionWS)$>;
if (hasLocalLights(numLights, clusterPos, dims)) {
localLighting = evalLocalLighting(cluster, numLights, _worldPosition.xyz, surface,
localLighting = evalLocalLighting(cluster, numLights, fragPositionWS, surfaceWS,
metallic, fresnel, albedo, 0.0,
vec4(0), vec4(0), opacity);
}
@ -82,11 +83,12 @@ void main(void) {
cam._viewInverse,
1.0,
occlusionTex,
fragPosition,
fragPositionES,
fragPositionWS,
albedo,
fresnel,
metallic,
emissive+fadeEmissive,
surface, opacity, localLighting.rgb),
emissive + fadeEmissive,
surfaceWS, opacity, localLighting.rgb),
opacity);
}

View file

@ -28,10 +28,10 @@
in vec2 _texCoord0;
in vec2 _texCoord1;
in vec4 _position;
in vec4 _worldPosition;
in vec3 _normal;
in vec3 _tangent;
in vec4 _positionES;
in vec4 _positionWS;
in vec3 _normalWS;
in vec3 _tangentWS;
in vec3 _color;
in float _alpha;
@ -59,20 +59,22 @@ void main(void) {
vec3 emissive = getMaterialEmissive(mat);
<$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>;
vec3 fragPosition = _position.xyz;
vec3 fragNormal;
<$evalMaterialNormalLOD(_position, normalTex, _normal, _tangent, fragNormal)$>
vec3 fragPositionES = _positionES.xyz;
vec3 fragPositionWS = _positionWS.xyz;
// Lighting is done in world space
vec3 fragNormalWS;
<$evalMaterialNormalLOD(_positionES, normalTex, _normalWS, _tangentWS, fragNormalWS)$>
TransformCamera cam = getTransformCamera();
vec3 fragEyeVector = vec3(cam._viewInverse * vec4(-fragPosition, 0.0));
vec3 fragEyeDir = normalize(fragEyeVector);
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
vec3 fragToEyeWS = fragPositionWS - cam._viewInverse[3].xyz;
vec3 fragToEyeDirWS = normalize(fragToEyeWS);
SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragToEyeDirWS);
vec4 localLighting = vec4(0.0);
<$fetchClusterInfo(_worldPosition)$>;
<$fetchClusterInfo(_positionWS)$>;
if (hasLocalLights(numLights, clusterPos, dims)) {
localLighting = evalLocalLighting(cluster, numLights, _worldPosition.xyz, surface,
localLighting = evalLocalLighting(cluster, numLights, fragPositionWS, surfaceWS,
metallic, fresnel, albedo, 0.0,
vec4(0), vec4(0), opacity);
}
@ -81,11 +83,12 @@ void main(void) {
cam._viewInverse,
1.0,
occlusionTex,
fragPosition,
fragPositionES,
fragPositionWS,
albedo,
fresnel,
metallic,
emissive,
surface, opacity, localLighting.rgb),
surfaceWS, opacity, localLighting.rgb),
opacity);
}

View file

@ -22,10 +22,10 @@
out float _alpha;
out vec2 _texCoord0;
out vec2 _texCoord1;
out vec4 _position;
out vec4 _worldPosition;
out vec3 _normal;
out vec3 _tangent;
out vec4 _positionES;
out vec4 _positionWS;
out vec3 _normalWS;
out vec3 _tangentWS;
out vec3 _color;
void main(void) {
@ -39,8 +39,8 @@ void main(void) {
// standard transform
TransformCamera cam = getTransformCamera();
TransformObject obj = getTransformObject();
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _position, gl_Position)$>
<$transformModelToWorldPos(obj, inPosition, _worldPosition)$>
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normal)$>
<$transformModelToWorldDir(cam, obj, inTangent.xyz, _tangent)$>
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _positionES, gl_Position)$>
<$transformModelToWorldPos(obj, inPosition, _positionWS)$>
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normalWS)$>
<$transformModelToWorldDir(cam, obj, inTangent.xyz, _tangentWS)$>
}

View file

@ -31,12 +31,12 @@
in vec2 _texCoord0;
in vec2 _texCoord1;
in vec4 _position;
in vec3 _normal;
in vec3 _tangent;
in vec4 _positionES;
in vec3 _normalWS;
in vec3 _tangentWS;
in vec3 _color;
in float _alpha;
in vec4 _worldPosition;
in vec4 _positionWS;
out vec4 _fragColor;
@ -45,7 +45,7 @@ void main(void) {
FadeObjectParams fadeParams;
<$fetchFadeObjectParams(fadeParams)$>
applyFade(fadeParams, _worldPosition.xyz, fadeEmissive);
applyFade(fadeParams, _positionWS.xyz, fadeEmissive);
Material mat = getMaterial();
int matKey = getMaterialKey(mat);
@ -68,21 +68,22 @@ void main(void) {
vec3 emissive = getMaterialEmissive(mat);
<$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>;
vec3 fragPosition = _position.xyz;
vec3 fragPositionES = _positionES.xyz;
vec3 fragPositionWS = _positionWS.xyz;
// Lighting is done in world space
vec3 fragNormal;
<$evalMaterialNormalLOD(_position, normalTex, _normal, _tangent, fragNormal)$>
vec3 fragNormalWS;
<$evalMaterialNormalLOD(_positionES, normalTex, _normalWS, _tangentWS, fragNormalWS)$>
TransformCamera cam = getTransformCamera();
vec3 fragEyeVector = vec3(cam._viewInverse * vec4(-fragPosition, 0.0));
vec3 fragEyeDir = normalize(fragEyeVector);
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
vec3 fragToEyeWS = fragPositionWS - cam._viewInverse[3].xyz;
vec3 fragToEyeDirWS = normalize(fragToEyeWS);
SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragToEyeDirWS);
vec4 localLighting = vec4(0.0);
<$fetchClusterInfo(_worldPosition)$>;
<$fetchClusterInfo(_positionWS)$>;
if (hasLocalLights(numLights, clusterPos, dims)) {
localLighting = evalLocalLighting(cluster, numLights, _worldPosition.xyz, surface,
localLighting = evalLocalLighting(cluster, numLights, fragPositionWS, surfaceWS,
metallic, fresnel, albedo, 0.0,
vec4(0), vec4(0), opacity);
}
@ -91,11 +92,12 @@ void main(void) {
cam._viewInverse,
1.0,
occlusionTex,
fragPosition,
fragPositionES,
fragPositionWS,
albedo,
fresnel,
metallic,
emissive+fadeEmissive,
surface, opacity, localLighting.rgb),
emissive + fadeEmissive,
surfaceWS, opacity, localLighting.rgb),
opacity);
}