radiance: margin inside the glass rim; haloed corona sparks and glints (oversized soft-falloff points)
This commit is contained in:
@ -98,7 +98,8 @@ float lifeAlpha(float x) {
|
||||
float layerR(uint idx) {
|
||||
float k = h01(idx * 8u + 5u);
|
||||
float u = h01(idx * 8u + 4u);
|
||||
return k < 0.5 ? mix(0.94, 1.0, u) : mix(0.4, 0.94, u);
|
||||
// both stay clear of the glass at r = 1, leaving a margin around the rim
|
||||
return k < 0.5 ? mix(0.86, 0.925, u) : mix(0.4, 0.85, u);
|
||||
}
|
||||
// A drifting ridge field: density peaks along thin curved sheets, which cut the sphere as ribbons.
|
||||
float density(vec3 dir, float t) {
|
||||
@ -372,7 +373,7 @@ void main() {
|
||||
}
|
||||
float r = length(pos);
|
||||
vec3 n = pos / max(r, 1e-4);
|
||||
float surf = step(0.9, rt);
|
||||
float surf = step(0.855, rt);
|
||||
|
||||
// the cursor: the 2D fluid under the particle's screen position, pushed into 3D
|
||||
vec3 bp = bodyToView(pos);
|
||||
@ -403,7 +404,7 @@ void main() {
|
||||
n = pos / max(r, 1e-4);
|
||||
vel -= n * max(dot(vel, n), 0.0) * smoothstep(rt - 0.05, rt + 0.01, r);
|
||||
r = mix(r, rt, 1.0 - exp(-uDt * 1.6));
|
||||
pos = n * min(r, 0.985);
|
||||
pos = n * min(r, 0.93);
|
||||
|
||||
stir = max(stir * exp(-uDt * 1.2), clamp(fm * front * 1.5, 0.0, 1.5));
|
||||
oPos = vec4(pos, stir);
|
||||
@ -425,6 +426,7 @@ uniform float uR; // css px
|
||||
uniform float uDpr;
|
||||
out vec4 vColor;
|
||||
out float vGlow;
|
||||
out float vCore;
|
||||
|
||||
void main() {
|
||||
uint idx = uint(gl_VertexID);
|
||||
@ -458,17 +460,17 @@ void main() {
|
||||
size = mix(1.5 + r.y * 1.5 + n * 1.3, 2.8 + r.w * 2.4, spark);
|
||||
float tw = 0.5 + 0.5 * sin(t * (1.2 + r.x * 2.5) + r.w * 40.0);
|
||||
col.a *= mix(1.0, mix(0.4, 1.0, tw), spark);
|
||||
vGlow = spark;
|
||||
vGlow = spark * 0.5;
|
||||
// the far side reads dimmer through the glass, and so do particles hanging deep in the volume
|
||||
// (it also thins the crowd that edge-on particles would form along the limb)
|
||||
col.a *= mix(0.2, 1.0, smoothstep(-0.2, 0.6, bp.z));
|
||||
col.a *= mix(0.65, 1.0, step(0.9, rt));
|
||||
col.a *= mix(0.65, 1.0, step(0.855, rt));
|
||||
col.a *= lifeAlpha(lt);
|
||||
// stirred particles heat up: brighter, hotter, a little bigger
|
||||
col.rgb = mix(col.rgb, vec3(1.0, 0.8, 0.55), clamp(stir * 0.3, 0.0, 0.4));
|
||||
col.a = min(1.0, col.a * (1.0 + stir * 0.5));
|
||||
size *= 1.0 + stir * 0.8;
|
||||
vGlow = max(vGlow, clamp(stir * 0.8, 0.0, 1.0));
|
||||
size *= 1.0 + stir * 0.5;
|
||||
vGlow = max(vGlow, clamp(stir * 0.2, 0.0, 0.25));
|
||||
} else {
|
||||
P p = corona(idx);
|
||||
vec2 disp = s0.xy;
|
||||
@ -491,7 +493,10 @@ void main() {
|
||||
|
||||
vec2 px = uCenter + vec2(vp.x, -vp.y) * uR;
|
||||
gl_Position = vec4(px.x / uView.x * 2.0 - 1.0, 1.0 - px.y / uView.y * 2.0, 0.0, 1.0);
|
||||
gl_PointSize = size * sc * uDpr * persp;
|
||||
// glowing points are drawn larger so the halo has room around the core
|
||||
float glowScale = 1.0 + vGlow * 2.4;
|
||||
gl_PointSize = size * sc * uDpr * persp * glowScale;
|
||||
vCore = 1.0 / glowScale;
|
||||
vColor = col;
|
||||
}
|
||||
`;
|
||||
@ -499,12 +504,12 @@ void main() {
|
||||
const FRAG_PARTICLES = `${HEAD}
|
||||
in vec4 vColor;
|
||||
in float vGlow;
|
||||
in float vCore; // the core's share of the point's width; the rest is room for the halo
|
||||
out vec4 o;
|
||||
void main() {
|
||||
vec2 c = gl_PointCoord - 0.5;
|
||||
float r = length(c);
|
||||
float core = smoothstep(0.5, 0.18, r);
|
||||
float halo = vGlow * smoothstep(0.5, 0.0, r) * 0.55;
|
||||
float rr = length(gl_PointCoord - 0.5) * 2.0; // 0 at the centre, 1 at the edge of the point
|
||||
float core = 1.0 - smoothstep(0.36 * vCore, vCore, rr);
|
||||
float halo = vGlow * pow(max(1.0 - rr, 0.0), 2.2) * 0.55;
|
||||
float a = vColor.a * clamp(core + halo, 0.0, 1.0);
|
||||
if (a < 0.01) discard;
|
||||
o = vec4(vColor.rgb * a, a);
|
||||
|
||||
Reference in New Issue
Block a user