Skip to content

Commit

Permalink
Calculate absorption path length using refracted view ray
Browse files Browse the repository at this point in the history
  • Loading branch information
victorcoda committed Apr 20, 2021
1 parent 0902ee3 commit 905a12f
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 29 deletions.
11 changes: 4 additions & 7 deletions framework/shaders/common/absorption.h
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
// https://en.wikipedia.org/wiki/Beer%E2%80%93Lambert_law
// https://www.pvlighthouse.com.au/cms/lectures/altermatt/optics/the-lambert-beer-law
// https://www.rp-photonics.com/absorbance.html
// https://www.rp-photonics.com/absorption_length.html

vec3 absorb(vec3 a, float l)
vec3 absorb(vec3 rgb, float c, float x)
{
return exp(-a * l);
}

vec3 attenuationCoefficient(vec3 c, float d)
{
return -log(c) * d;
vec3 a = -log(rgb) * c;
return exp(-a * x);
}
4 changes: 2 additions & 2 deletions framework/shaders/common/ray.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// https://www.cs.princeton.edu/courses/archive/fall00/cs426/lectures/raycast/sld017.htm
float rayPlane(vec4 p, vec3 ro, vec3 rd)
float rayPlaneIntersection(vec4 p, vec3 o, vec3 d)
{
return -(dot(ro, p.xyz) + p.w)/dot(rd, p.xyz);
return -(dot(o, p.xyz) + p.w)/dot(d, p.xyz);
}
Binary file modified screenshots/seascape.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 22 additions & 20 deletions seascape/shaders/marine.frag
Original file line number Diff line number Diff line change
Expand Up @@ -38,31 +38,33 @@ void main()
// reconstruct normal from height map
const float strength = 10.;
vec3 normal = sobel(heightMap, texCoord, strength);
vec3 n = mat3(normalMatrix) * normal.xzy; // swap Y, Z

// view-space ray
const vec3 eye = vec3(0);
vec3 i = normalize(viewPos - eye);
// calculate indicent and refracted rays
vec3 i = normalize(viewPos);
vec3 r = refract(i, n, IOR_AIR/IOR_WATER);

// calculate absorption path length
float seabedDistance = rayPlane(seabed.viewPlane, eye, i);
float surfaceDistance = distance(eye, viewPos);
float absorptionLength = seabedDistance - surfaceDistance;

float absorptionLen = rayPlaneIntersection(seabed.viewPlane, viewPos, r);
// calculate refracted water color
vec3 sigma = attenuationCoefficient(surface.diffuse.rgb, 0.1);
vec3 refracted = absorb(sigma, absorptionLength);

vec3 l = light.viewDir.xyz;
vec3 n = mat3(normalMatrix) * normal.xzy; // swap Y, Z
vec3 r = reflect(-l, n);

// calcular specular
float RdV = max(dot(r, -i), 0.);
vec3 specular = surface.specular.rgb * pow(RdV, surface.shininess) * light.specular.rgb;
const float concentration = 0.1;
vec3 refracted = absorb(surface.diffuse.rgb, concentration, absorptionLen);

// lookup cubemap for reflected color
vec3 reflected = texture(envMap, reflect(i, n)).rgb * 1.2;

r = reflect(i, n);
vec3 reflected = texture(envMap, r).rgb * 1.2;

// calculate diffuse color
float coeff = fresnelSchlick(IOR_AIR, IOR_WATER, n, i);
oColor = mix(refracted, reflected, coeff) + specular;
vec3 diffuse = mix(refracted, reflected, coeff);

// calculate reflected ray
vec3 l = light.viewDir.xyz;
r = reflect(-l, n);
// calculate specular color
vec3 v = -i;
float RdV = max(dot(r, v), 0.);
vec3 specular = surface.specular.rgb * pow(RdV, surface.shininess) * light.specular.rgb;

oColor = diffuse + specular;
}

0 comments on commit 905a12f

Please sign in to comment.