diff --git a/framework/shaders/common/absorption.h b/framework/shaders/common/absorption.h index 154b857..894e613 100644 --- a/framework/shaders/common/absorption.h +++ b/framework/shaders/common/absorption.h @@ -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); } diff --git a/framework/shaders/common/ray.h b/framework/shaders/common/ray.h index c74cdde..99087d7 100644 --- a/framework/shaders/common/ray.h +++ b/framework/shaders/common/ray.h @@ -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); } diff --git a/screenshots/seascape.jpg b/screenshots/seascape.jpg index a13117a..01c1952 100644 Binary files a/screenshots/seascape.jpg and b/screenshots/seascape.jpg differ diff --git a/seascape/shaders/marine.frag b/seascape/shaders/marine.frag index 9da8488..82c7fdd 100644 --- a/seascape/shaders/marine.frag +++ b/seascape/shaders/marine.frag @@ -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; }