This commit is contained in:
Crizomb 2025-09-29 15:34:29 +02:00
commit 3fa75abfb2
42 changed files with 5634 additions and 0 deletions

View file

@ -0,0 +1,257 @@
// "Protoplanetary disk" by Duke
// https://www.shadertoy.com/view/MdtGRl
//-------------------------------------------------------------------------------------
// Based on "Dusty nebula 1" (https://www.shadertoy.com/view/4lSXD1)
// and Shane's "Cheap Cloud Flythrough" (https://www.shadertoy.com/view/Xsc3R4) shaders
// Some ideas came from other shaders from this wonderful site
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0
//-------------------------------------------------------------------------------------
#define BLACK_BLEND_THRESHOLD .4 // This is controls the dim of the screen
const float timeMultiplier = 0.1f;
//-------------------
#define pi 3.14159265
#define R(p, a) p=cos(a)*p+sin(a)*vec2(p.y, -p.x)
mat2 Spin(float angle)
{
return mat2(cos(angle), -sin(angle), sin(angle), cos(angle));
}
// iq's noise
float pn(in vec3 x)
{
vec3 p = floor(x);
vec3 f = fract(x);
f = f * f * (3.0 - 2.0 * f);
vec2 uv = (p.xy + vec2(37.0, 17.0) * p.z) + f.xy;
vec2 rg = textureLod(iChannel0, (uv + 0.5) / 256.0, 0.0).yx;
return -1.0 + 2.4 * mix(rg.x, rg.y, f.z);
}
float fpn(vec3 p)
{
return pn(p * .06125) * .5 + pn(p * .125) * .25 + pn(p * .25) * .125; // + pn(p*.5)*.625;
}
float rand(vec2 co)
{
return fract(sin(dot(co * 0.123, vec2(12.9898, 78.233))) * 43758.5453);
}
float Ring(vec3 p)
{
vec2 q = vec2(length(p.xy) - 2.3, p.z);
return length(q) - 0.01;
}
float length2(vec2 p)
{
return sqrt(p.x * p.x + p.y * p.y);
}
float length8(vec2 p)
{
p = p * p;
p = p * p;
p = p * p;
return pow(p.x + p.y, 1.0 / 8.0);
}
float Disk(vec3 p, vec3 t)
{
vec2 q = vec2(length2(p.xy) - t.x, p.z * 0.5);
return max(length8(q) - t.y, abs(p.z) - t.z);
}
float smin(float a, float b, float k)
{
float h = clamp(0.5 + 0.5 * (b - a) / k, 0.0, 1.0);
return mix(b, a, h) - k * h * (1.0 - h);
}
float map(vec3 p)
{
float t = 0.7 * iTime;
float d1 = Disk(p, vec3(2.0, 1., 0.05)) + fpn(vec3(Spin(t * 0.25 + p.z * .10) * p.xy * 20., p.z * 20. - t) * 5.0) * 0.545;
float d2 = Ring(p);
return smin(d1, d2, 1.0);
}
// assign color to the media
vec3 computeColor(float density, float radius)
{
// color based on density alone, gives impression of occlusion within
// the media
vec3 result = mix(1.1 * vec3(1.0, 0.9, 0.8), vec3(0.4, 0.15, 0.1), density);
// color added for disk
vec3 colCenter = 6. * vec3(0.8, 1.0, 1.0);
vec3 colEdge = 2. * vec3(0.48, 0.53, 0.5);
result *= mix(colCenter, colEdge, min((radius + .5) / 2.0, 1.15));
return result;
}
bool Raycylinderintersect(vec3 org, vec3 dir, out float near, out float far)
{
// quadratic x^2 + y^2 = 0.5^2 => (org.x + t*dir.x)^2 + (org.y + t*dir.y)^2 = 0.5
float a = dot(dir.xy, dir.xy);
float b = dot(org.xy, dir.xy);
float c = dot(org.xy, org.xy) - 12.;
float delta = b * b - a * c;
if (delta < 0.0)
return false;
// 2 roots
float deltasqrt = sqrt(delta);
float arcp = 1.0 / a;
near = (-b - deltasqrt) * arcp;
far = (-b + deltasqrt) * arcp;
// order roots
float temp = min(far, near);
far = max(far, near);
near = temp;
float znear = org.z + near * dir.z;
float zfar = org.z + far * dir.z;
// top, bottom
vec2 zcap = vec2(1.85, -1.85);
vec2 cap = (zcap - org.z) / dir.z;
if (znear < zcap.y)
near = cap.y;
else if (znear > zcap.x)
near = cap.x;
if (zfar < zcap.y)
far = cap.y;
else if (zfar > zcap.x)
far = cap.x;
return far > 0.0 && far > near;
}
void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
const float KEY_1 = 49.5 / 256.0;
const float KEY_2 = 50.5 / 256.0;
const float KEY_3 = 51.5 / 256.0;
float key = 0.0;
key += 0.7 * texture(iChannel1, vec2(KEY_1, 0.25)).x;
key += 0.7 * texture(iChannel1, vec2(KEY_2, 0.25)).x;
key += 0.7 * texture(iChannel1, vec2(KEY_3, 0.25)).x;
// ro: ray origin
// rd: direction of the ray
vec3 rd = normalize(vec3((gl_FragCoord.xy - 0.5 * iResolution.xy) / iResolution.y, 1.));
vec3 ro = vec3(0., 0., -6. + key * 1.6);
// ld, td: local, total density
// w: weighting factor
float ld = 0., td = 0., w = 0.;
// t: length of the ray
// d: distance function
float d = 1., t = 0.;
vec4 sum = vec4(0.0);
float min_dist = 0.0, max_dist = 0.0;
if (Raycylinderintersect(ro, rd, min_dist, max_dist))
{
t = min_dist * step(t, min_dist);
// raymarch loop
for (int i = 0; i < 56; i++)
{
vec3 pos = ro + t * rd;
float fld = 0.0;
// Loop break conditions.
if (td > (1. - 1. / 80.) || d < 0.008 * t || t > 10. || sum.a > 0.99 || t > max_dist) break;
// evaluate distance function
d = map(pos);
// direction to center
vec3 stardir = normalize(vec3(0.0) - pos);
// change this string to control density
d = max(d, 0.08);
if (d < 0.1)
{
// compute local density
ld = 0.1 - d;
// compute weighting factor
w = (1. - td) * ld;
// accumulate density
td += w + 1. / 200.;
float radiusFromCenter = length(pos - vec3(0.0));
vec4 col = vec4(computeColor(td, radiusFromCenter), td);
// uniform scale density
col.a *= 0.2;
// colour by alpha
col.rgb *= col.a / 0.8;
// alpha blend in contribution
sum = sum + col * (1.0 - sum.a);
}
td += 1. / 70.;
// point light calculations
vec3 ldst = vec3(0.0) - pos;
float lDist = max(length(ldst), 0.001);
// star in center
vec3 lightColor = vec3(1.0, 0.5, 0.25);
sum.rgb += lightColor / (lDist * lDist * lDist * 7.); //*10.); //add a bloom around the light
// using the light distance to perform some falloff
//float atten = 1./(1. + lDist*0.125 + lDist*lDist*0.4);
// accumulating the color
//sum += w*atten*fld;
// enforce minimum stepsize
d = max(d, 0.04);
t += max(d * 0.3, 0.02);
}
//scattering test
//sum *= 1. / exp( ld * 0.2 ) * 1.05;
sum = clamp(sum, 0.0, 1.0);
sum.xyz = sum.xyz * sum.xyz * (3.0 - 2.0 * sum.xyz);
}
// stars background
if (td < .8)
{
vec3 stars = vec3(pn(rd * 300.0) * 0.4 + 0.5);
vec3 starbg = vec3(0.0);
starbg = mix(starbg, vec3(0.8, 0.9, 1.0), smoothstep(0.99, 1.0, stars) * clamp(dot(vec3(0.0), rd) + 0.75, 0.0, 1.0));
starbg = clamp(starbg, 0.0, 1.0);
sum.xyz += starbg;
}
fragColor = vec4(sum.xyz, 1.0);
// vec2 termUV = fragCoord.xy / iResolution.xy;
// vec4 terminalColor = texture(iChannel0, termUV);
//
// float alpha = step(length(terminalColor.rgb), BLACK_BLEND_THRESHOLD);
// vec3 blendedColor = mix(terminalColor.rgb * 1.0, col.rgb * 0.3, alpha);
//
// fragColor = vec4(blendedColor, terminalColor.a);
}