Skip to content

Commit

Permalink
Gloom: Refraction offset depends on volumetric distance
Browse files Browse the repository at this point in the history
The offset should be smaller near the surface.
  • Loading branch information
skyjake committed Sep 1, 2019
1 parent ee8353b commit 77047e8
Showing 1 changed file with 26 additions and 23 deletions.
Expand Up @@ -44,13 +44,13 @@ void main(void) {

mat3 tsToViewRotate = uWorldToViewRotate * Gloom_TangentMatrix(ts);
vec3 vsNormal = tsToViewRotate * normal;

vec4 diffuse = Gloom_FetchTexture(matIndex, Texture_Diffuse, texCoord);
float density = diffuse.a;
vec3 emissive = Gloom_FetchTexture(matIndex, Texture_Emissive, texCoord).rgb;
vec4 specGloss = Gloom_FetchTexture(matIndex, Texture_SpecularGloss, texCoord);
vec3 vsViewDir = -normalize(vVSPos.xyz);

vec3 vsPos = vVSPos.xyz / vVSPos.w;

// Write a displaced depth. // TODO: Add a routine for doing this.
Expand All @@ -63,43 +63,46 @@ void main(void) {
else {
gl_FragDepth = gl_FragCoord.z;
}

float viewDistance = length(vsPos);

float directVolDist = distance(vsPos, GBuffer_ViewSpacePos(vUV).xyz);

// Refraction. This is calculated in view space so the offset will be view-dependent.
vec4 refractedColor;
float reflectRatio;
vec3 refracted = refract(vsViewDir, vsNormal, 1.05);
if (refracted != vec3(0.0)) {
reflectRatio = max(0.0, dot(refracted, vsViewDir));
float refrFactor = 0.05 / max(1.0, viewDistance * 0.5);
vec2 fragPos = (gl_FragCoord.xy + refracted.xy * uViewportSize.y * refrFactor) / uViewportSize;
refractedColor = texture(uRefractedFrame, fragPos) * (1.0 - reflectRatio);
backPos = GBuffer_ViewSpacePos(fragPos).xyz;

// How far does light travel through the volume?
// if (backPos.z < vsPos.z) {
float volumetric = pow(density, 2.0) * 5.0 * log(distance(backPos, vsPos) + 1.0);
if (density > 0.0) {
refractedColor = mix(refractedColor, diffuse,
min(volumetric /* * density + pow(density, 2.0)*/, 1.0));
}
// }
// else {
// refractedColor = vec4(0.0);
// }
float refrFactor = 0.05 / max(1.0, viewDistance * 0.5) *
min(directVolDist * 4.0, 1.0);
vec2 fragPos = (gl_FragCoord.xy + refracted.xy * uViewportSize.y * refrFactor) / uViewportSize;
refractedColor = texture(uRefractedFrame, fragPos) * (1.0 - reflectRatio);
backPos = GBuffer_ViewSpacePos(fragPos).xyz;

// How far does light travel through the volume?
// if (backPos.z < vsPos.z) {
float volDist = distance(backPos, vsPos);
float volumetric = pow(density, 2.0) * 5.0 * log(volDist + 1.0);
if (density > 0.0) {
refractedColor = mix(refractedColor, diffuse,
min(volumetric /* * density + pow(density, 2.0)*/, 1.0));
}
// }
// else {
// refractedColor = vec4(0.0);
// }
}
else {
refractedColor = vec4(0.0);
reflectRatio = 1.0;
}

// Now we can apply lighting to the surface.
SurfacePoint sp = SurfacePoint(vsPos, vsNormal, diffuse.rgb * diffuse.a, specGloss);

out_FragColor = vec4(emissive, 0.0) + refractedColor;
out_FragColor.rgb +=
Gloom_DirectionalLighting(sp) +
out_FragColor.rgb +=
Gloom_DirectionalLighting(sp) +
Gloom_OmniLighting(sp) +
reflectRatio * Gloom_CubeReflection(uEnvMap, sp);
}

0 comments on commit 77047e8

Please sign in to comment.