Sharpen the ice: finer ridged grain, hairline seam sheen, more dispersion
Normals are now sampled at 0.008 so the creases resolve instead of being averaged away, and the seam sheen only lights the crack walls, which keeps the open water black. Fracture steps are trimmed so the sheets break at a seam instead of smearing into a pale ribbon.
This commit is contained in:
+14
-12
@@ -43,10 +43,10 @@ vec2 fracture(vec2 x) {
|
||||
// Static in world space; only the plasma behind it moves.
|
||||
float height(vec2 x) {
|
||||
vec2 fr = fracture(x);
|
||||
return 0.085 * (1.0 - abs(2.0 * fbm2(x * 1.9 + 2.0) - 1.0))
|
||||
+ 0.030 * (1.0 - abs(2.0 * fbm2(x * 4.6 - 5.0) - 1.0))
|
||||
+ 0.020 * clamp(fr.x * 60.0, -1.0, 1.0) // the slab sits at a different level
|
||||
+ 0.012 * clamp(fr.y * 60.0, -1.0, 1.0); // on each side of a crack
|
||||
return 0.090 * (1.0 - abs(2.0 * fbm2(x * 2.2 + 2.0) - 1.0))
|
||||
+ 0.055 * (1.0 - abs(2.0 * fbm2(x * 6.4 - 5.0) - 1.0))
|
||||
+ 0.014 * clamp(fr.x * 110.0, -1.0, 1.0) // the slab sits at a different level
|
||||
+ 0.009 * clamp(fr.y * 110.0, -1.0, 1.0); // on each side of a crack
|
||||
}
|
||||
void main() {
|
||||
vec2 screen = gl_FragCoord.xy / u_res;
|
||||
@@ -59,7 +59,7 @@ void main() {
|
||||
for (int i = 0; i < 2; i++) t = (FRONT + height(ray.xy * t)) / ray.z;
|
||||
vec3 hit = ray * t;
|
||||
|
||||
float e = 0.02;
|
||||
float e = 0.008;
|
||||
vec2 slope = vec2(height(hit.xy + vec2(e, 0.0)) - height(hit.xy - vec2(e, 0.0)),
|
||||
height(hit.xy + vec2(0.0, e)) - height(hit.xy - vec2(0.0, e))) / (2.0 * e);
|
||||
float bevel = smoothstep(0.14, 0.0, min(min(screen.x, 1.0 - screen.x), min(screen.y, 1.0 - screen.y)));
|
||||
@@ -70,9 +70,9 @@ void main() {
|
||||
// Refracted ray; red and blue bend a little differently, which is what makes ice ring.
|
||||
vec3 inside = refract(ray, normal, 1.0 / IOR);
|
||||
vec2 shearR = (refract(ray, normal, 1.0 / (IOR - 0.012)) - inside).xy;
|
||||
vec2 shearB = (refract(ray, normal, 1.0 / (IOR + 0.016)) - inside).xy;
|
||||
vec2 shearB = (refract(ray, normal, 1.0 / (IOR + 0.019)) - inside).xy;
|
||||
inside = normalize(inside);
|
||||
inside.z = min(inside.z, -0.50); // bound grazing rays at the crack steps
|
||||
inside.z = min(inside.z, -0.40); // bound grazing rays at the crack steps
|
||||
|
||||
// Recentre the parallax on the middle of the sheet stack: near and far sheets
|
||||
// then slide past each other at different rates as the pointer moves.
|
||||
@@ -106,12 +106,14 @@ void main() {
|
||||
col += sky * (fresnel * 1.2 + bevel * 0.03);
|
||||
// Steep faces of the crests catch a thin sheen: the edge of the frozen surface,
|
||||
// painted only where the ice actually tilts, so the open water stays black.
|
||||
float tilt = smoothstep(0.45, 0.95, length(slope));
|
||||
col += vec3(0.030, 0.085, 0.105) * tilt;
|
||||
// Only the crack walls are this steep, so this sheen outlines the seams alone
|
||||
// instead of washing the whole grain.
|
||||
float tilt = smoothstep(1.00, 2.60, length(slope));
|
||||
col += vec3(0.022, 0.062, 0.078) * tilt;
|
||||
vec2 fr = fracture(hit.xy);
|
||||
float crack = (1.0 - smoothstep(0.0, 0.006, abs(fr.x)))
|
||||
+ (1.0 - smoothstep(0.0, 0.006, abs(fr.y)));
|
||||
col += vec3(0.020, 0.055, 0.070) * crack * smoothstep(0.58, 0.80, fbm2(hit.xy * 0.30 + 21.0));
|
||||
float crack = (1.0 - smoothstep(0.0, 0.004, abs(fr.x)))
|
||||
+ (1.0 - smoothstep(0.0, 0.004, abs(fr.y)));
|
||||
col += vec3(0.020, 0.055, 0.068) * crack * smoothstep(0.58, 0.80, fbm2(hit.xy * 0.30 + 21.0));
|
||||
|
||||
gl_FragColor = vec4(pow(clamp(col, 0.0, 1.0), vec3(0.4545)), 1.0);
|
||||
}
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user