diff --git a/8_ice_scene.frag b/8_ice_scene.frag index c6a2a6c..3065966 100644 --- a/8_ice_scene.frag +++ b/8_ice_scene.frag @@ -100,21 +100,27 @@ void main() { float solid = 0.45; // sheet 1 keeps its plasma, but its alpha becomes coverage if (layer > 0.5 && layer < 1.5) { vec3 ro = vec3(0.0, 0.0, 6.0); - vec3 rd = normalize(vec3((uv - 0.5) * 2.0 * vec2(u_res.x / u_res.y, 1.0), -1.0)); - float b = dot(ro, rd); - float disc = b * b - dot(ro, ro) + 2.4 * 2.4; - if (disc > 0.0) { - float near = max(-b - sqrt(disc), 0.0); - float t = near, d = 1.0; - for (int k = 0; k < 40; k++) { - d = sdShard(ro + rd * t, phase); - if (d < 0.003 || t > near + 5.0) break; - t += d; - } - if (d < 0.003) { - solid = 1.0; - vec3 pos = ro + rd * t; + vec3 lit = vec3(0.0); + float hits = 0.0; + // 3x3 supersample: pass 2 magnifies this sheet where the surface steepens at the + // cracks, and a one-pixel silhouette would show up there as big hard steps. + for (int sy = 0; sy < 3; sy++) { + for (int sx = 0; sx < 3; sx++) { + vec2 jitter = (vec2(float(sx), float(sy)) / 3.0 + 1.0 / 6.0 - 0.5) / u_res; + vec3 rd = normalize(vec3((uv + jitter - 0.5) * 2.0 * vec2(u_res.x / u_res.y, 1.0), -1.0)); + float b = dot(ro, rd); + float disc = b * b - dot(ro, ro) + 2.4 * 2.4; + if (disc <= 0.0) continue; + float near = max(-b - sqrt(disc), 0.0); + float t = near, d = 1.0; + for (int k = 0; k < 40; k++) { + d = sdShard(ro + rd * t, phase); + if (d < 0.003 || t > near + 5.0) break; + t += d; + } + if (d >= 0.003) continue; float e2 = 0.004; + vec3 pos = ro + rd * t; vec3 nrm = normalize(vec3( sdShard(pos + vec3(e2, 0.0, 0.0), phase) - sdShard(pos - vec3(e2, 0.0, 0.0), phase), sdShard(pos + vec3(0.0, e2, 0.0), phase) - sdShard(pos - vec3(0.0, e2, 0.0), phase), @@ -124,11 +130,16 @@ void main() { float key = max(dot(nrm, normalize(vec3(-0.45, 0.72, 0.52))), 0.0); float fill = max(dot(nrm, normalize(vec3(0.60, -0.20, -0.75))), 0.0); float rim = pow(1.0 - max(dot(nrm, -rd), 0.0), 4.0); - col = mix(vec3(0.004, 0.016, 0.026), vec3(0.060, 0.290, 0.340), key); - col += vec3(0.010, 0.060, 0.080) * fill; - col += vec3(0.20, 0.62, 0.72) * rim * 0.55; + vec3 c = mix(vec3(0.004, 0.016, 0.026), vec3(0.060, 0.290, 0.340), key); + c += vec3(0.010, 0.060, 0.080) * fill; + c += vec3(0.20, 0.62, 0.72) * rim * 0.55; + lit += c; + hits += 1.0; } } + float cov = hits / 9.0; + col = mix(col, lit / max(hits, 1.0), cov); + solid = mix(0.45, 1.0, cov); } float alpha = (layer > 0.5 && layer < 1.5) ? solid : (0.42 + layer * 0.26) / 2.6; gl_FragColor = vec4(col, alpha); diff --git a/ice_object.html b/ice_object.html index eafaaac..455bc40 100644 --- a/ice_object.html +++ b/ice_object.html @@ -16,7 +16,7 @@ canvas{display:block;width:100%;height:100%;touch-action:none}