optimize
This commit is contained in:
parent
8706d510db
commit
a6a7e836cc
@ -1,16 +1,12 @@
|
||||
#version 300 es
|
||||
precision lowp float;
|
||||
uniform vec3 iResolution; // viewport resolution (in pixels)
|
||||
uniform float iTime; // shader playback time (in seconds)
|
||||
precision mediump float;
|
||||
uniform vec3 iResolution;
|
||||
uniform float iTime;
|
||||
uniform sampler2D iChannel1;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
const float pi = 3.1415927f;
|
||||
|
||||
float sdSphere(vec3 p, float s) {
|
||||
return length(p) - s;
|
||||
}
|
||||
const float PI = 3.1415927f;
|
||||
|
||||
float sdTorus(vec3 p, vec2 t) {
|
||||
vec2 q = vec2(length(p.xz) - t.x, p.y);
|
||||
@ -18,66 +14,87 @@ float sdTorus(vec3 p, vec2 t) {
|
||||
}
|
||||
|
||||
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
||||
vec2 pp = fragCoord.xy / iResolution.xy;
|
||||
pp = -1.0f + 2.0f * pp;
|
||||
pp.x *= iResolution.x / iResolution.y;
|
||||
vec2 uv = (fragCoord.xy / iResolution.xy) * 2.0f - 1.0f;
|
||||
uv.x *= iResolution.x / iResolution.y;
|
||||
|
||||
// camera
|
||||
vec3 lookAt = vec3(0.0f, -0.1f, 0.0f);
|
||||
|
||||
float eyer = 2.0f;
|
||||
float eyea = 0.0f;
|
||||
float eyea2 = (-0.24f) * pi * 2.0f;
|
||||
|
||||
vec3 ro = vec3(eyer * cos(eyea) * sin(eyea2), eyer * cos(eyea2), eyer * sin(eyea) * sin(eyea2)); //camera position
|
||||
float eyea2 = -0.24f * PI * 2.0f;
|
||||
vec3 ro = vec3(eyer * cos(eyea) * sin(eyea2), eyer * cos(eyea2), eyer * sin(eyea) * sin(eyea2));
|
||||
|
||||
vec3 front = normalize(lookAt - ro);
|
||||
vec3 left = normalize(cross(normalize(vec3(0.0f, 1, -0.1f)), front));
|
||||
vec3 left = normalize(cross(normalize(vec3(0.0f, 1.0f, -0.1f)), front));
|
||||
vec3 up = normalize(cross(front, left));
|
||||
vec3 rd = normalize(front * 1.5f + left * pp.x + up * pp.y); // rect vector
|
||||
vec3 rd = normalize(front * 1.5f + left * uv.x + up * uv.y);
|
||||
|
||||
vec3 bh = vec3(0.0f, 0.0f, 0.0f);
|
||||
float bhr = 0.1f;
|
||||
float bhmass = 5.0f;
|
||||
bhmass *= 0.001f; // premul G
|
||||
// black hole
|
||||
const vec3 bh = vec3(0.0f);
|
||||
const float bhr = 0.1f;
|
||||
float bhmass = 5.0f * 0.001f; // premul G
|
||||
|
||||
// integration
|
||||
vec3 p = ro;
|
||||
vec3 pv = rd;
|
||||
float dt = 0.02f;
|
||||
|
||||
const float dt = 0.02f;
|
||||
vec3 col = vec3(0.0f);
|
||||
|
||||
float noncaptured = 1.0f;
|
||||
|
||||
vec3 c1 = vec3(0.5f, 0.46f, 0.4f);
|
||||
vec3 c2 = vec3(1.0f, 0.8f, 0.6f);
|
||||
|
||||
for(float t = 0.0f; t < 1.0f; t += 0.005f) {
|
||||
p += pv * dt * noncaptured;
|
||||
// fixed iteration count, early-out when captured
|
||||
const int MAX_STEPS = 175; // original ~200 (1 / 0.005)
|
||||
for(int i = 0; i < MAX_STEPS; ++i) {
|
||||
if(noncaptured <= 0.0001f)
|
||||
break;
|
||||
|
||||
// gravity
|
||||
p += pv * (dt * noncaptured);
|
||||
|
||||
// gravity: compute bhv and reuse
|
||||
vec3 bhv = bh - p;
|
||||
float r = dot(bhv, bhv);
|
||||
pv += normalize(bhv) * ((bhmass) / r);
|
||||
float r2 = dot(bhv, bhv) + 1e-6f; // prevent div0
|
||||
float invLen = inversesqrt(r2);
|
||||
// normalize(bhv) = bhv * invLen
|
||||
// acceleration magnitude = bhmass / r2
|
||||
// combine: accel = normalize(bhv) * (bhmass / r2)
|
||||
pv += bhv * (invLen * (bhmass / r2));
|
||||
|
||||
noncaptured = smoothstep(0.0f, 0.666f, sdSphere(p - bh, bhr));
|
||||
// capture factor (reuse distance)
|
||||
float dist = sqrt(r2);
|
||||
noncaptured = smoothstep(0.0f, 0.666f, dist - bhr);
|
||||
|
||||
// Texture for the accretion disc
|
||||
// accretion disc texture
|
||||
float dr = length(bhv.xz);
|
||||
float da = atan(bhv.x, bhv.z);
|
||||
vec2 ra = vec2(dr, da * (0.01f + (dr - bhr) * 0.002f) + 2.0f * pi + iTime * 0.005f);
|
||||
ra *= vec2(10.0f, 20.0f);
|
||||
float da = atan(bhv.x, bhv.z); // keep same ordering as original
|
||||
// compact texture coordinate generation:
|
||||
float angleScale = 0.01f + (dr - bhr) * 0.002f;
|
||||
vec2 ra = vec2(dr * 10.0f, (da * angleScale + 2.0f * PI + iTime * 0.005f) * 20.0f);
|
||||
// sample lower frequency (reduce texture cost / cache pressure)
|
||||
float tx = texture(iChannel1, ra * vec2(0.1f, 0.5f)).r;
|
||||
float radial = max(0.0f, tx + 0.05f);
|
||||
float falloff = 4.0f / (0.001f + (dr - bhr) * 50.0f);
|
||||
|
||||
vec3 dcol = mix(c2, c1, pow(length(bhv) - bhr, 2.0f)) * max(0.0f, texture(iChannel1, ra * vec2(0.1f, 0.5f)).r + 0.05f) * (4.0f / ((0.001f + (length(bhv) - bhr) * 50.0f)));
|
||||
// color mix: avoid pow by squaring
|
||||
float sq = (dr - bhr);
|
||||
sq = sq * sq;
|
||||
vec3 dcol = mix(c2, c1, sq) * radial * falloff;
|
||||
|
||||
col += max(vec3(0.0f), dcol * smoothstep(0.0f, 1.0f, -sdTorus((p * vec3(1.0f, 25.0f, 1.0f)) - bh, vec2(0.8f, 0.99f))) * noncaptured);
|
||||
// torus SDF: scale p once
|
||||
vec3 ps = p * vec3(1.0f, 25.0f, 1.0f) - bh;
|
||||
float tor = sdTorus(ps, vec2(0.8f, 0.99f));
|
||||
float torMask = smoothstep(0.0f, 1.0f, -tor);
|
||||
|
||||
col += vec3(1.0f, 0.9f, 0.85f) * (1.0f / vec3(dot(bhv, bhv))) * 0.0033f * noncaptured;
|
||||
col += max(vec3(0.0f), dcol * torMask * noncaptured);
|
||||
|
||||
// simple brightening term (reuse r2)
|
||||
col += vec3(1.0f, 0.9f, 0.85f) * (1.0f / r2) * 0.0033f * noncaptured;
|
||||
}
|
||||
|
||||
fragColor = vec4(col, 1.0f);
|
||||
}
|
||||
|
||||
void main() {
|
||||
// gl_FragCoord.xy is pixel coordinates (1..width, 1..height)
|
||||
mainImage(FragColor, gl_FragCoord.xy);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user