Created
April 16, 2013 04:24
-
-
Save DavidSouther/5393329 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// based on https://www.shadertoy.com/view/4dXGR4 by flight404, itself | |
// based on https://www.shadertoy.com/view/lsf3RH by trisomie21 | |
float snoise(vec3 uv, float res) { | |
const vec3 s = vec3(1e0, 1e2, 1e4); | |
uv *= res; | |
vec3 uv0 = floor(mod(uv, res))*s; | |
vec3 uv1 = floor(mod(uv+vec3(1.), res))*s; | |
vec3 f = fract(uv); f = f*f*(3.0-2.0*f); | |
vec4 v = vec4(uv0.x+uv0.y+uv0.z, uv1.x+uv0.y+uv0.z, | |
uv0.x+uv1.y+uv0.z, uv1.x+uv1.y+uv0.z); | |
vec4 r = fract(sin(v*1e-3)*1e5); | |
float r0 = mix(mix(r.x, r.y, f.x), mix(r.z, r.w, f.x), f.y); | |
r = fract(sin((v + uv1.z - uv0.z)*1e-3)*1e5); | |
float r1 = mix(mix(r.x, r.y, f.x), mix(r.z, r.w, f.x), f.y); | |
return mix(r0, r1, f.z)*2.-1.; | |
} | |
float freqs[4]; | |
void Randomness(sampler2D texture){ | |
freqs[0] = texture2D( texture, vec2( 0.01, 0.25 ) ).x; | |
freqs[1] = texture2D( texture, vec2( 0.07, 0.25 ) ).x; | |
freqs[2] = texture2D( texture, vec2( 0.15, 0.25 ) ).x; | |
freqs[3] = texture2D( texture, vec2( 0.30, 0.25 ) ).x; | |
} | |
/** | |
* Calculate the brightness given a texture. The texture should | |
* vary over time, ideally using an audio channel. | |
*/ | |
float Brightness(){ | |
float brightness = freqs[1] * 0.25 + freqs[2] * 0.25; | |
return brightness; | |
} | |
// Sphere vector | |
vec2 Sphere(vec2 uv, float aspect, float radius){ | |
vec2 sp = -1.0 + 2.0 * uv; | |
sp.x *= aspect; // Behave as a circle | |
// Tied inversely to radius | |
// Regression for radius = {0.2, 0.3, 0.4}. Other values work less well. | |
float scale = 5.35 - 18.25 * radius + 20.0 * radius * radius; | |
// Project as a circle? | |
sp *= scale; | |
return sp; | |
} | |
/** | |
* Edge intensity | |
*/ | |
float F(vec2 sp, float radius){ | |
float r = dot(sp,sp); | |
float f = (1.0-sqrt(abs(1.0-r)))/(r);// + brightness * 0.5; | |
return f; | |
} | |
/** | |
* The base of the star is the main disk, providing the base color for the star, | |
* a sharp edge around the star, and a bit of static glow. | |
*/ | |
vec3 Base(float f, vec3 color){ | |
//vec3 base = vec3( f * ( 0.75 + brightness * 0.3 ) * color ); | |
vec3 base = vec3( f * color ); | |
return base; | |
} | |
/** | |
* The starSphere is the tumultuous base texture of the star. | |
*/ | |
vec3 StarSphere(vec2 sp, float f, float brightness, float dist, float radius, float time, sampler2D texture){ | |
vec3 starSphere = vec3( 0.0 ); | |
if( dist < radius ){ //Inside the sphere | |
vec2 newUv; | |
newUv.x = sp.x*f; | |
newUv.y = sp.y*f; | |
newUv += vec2( time, 0.0 ); // Rotate the star | |
vec3 texSample = texture2D( texture, newUv ).rgb; | |
// This does a random lookup for parts of the star... | |
// Gets the underspin + topflow effect | |
float uOff = ( texSample.g * brightness * 2.0 + time ); | |
vec2 starUv = newUv + vec2( uOff, 0.0 ); | |
starSphere = texture2D( texture, starUv ).rgb; // Get a piece of the star | |
} | |
return starSphere; | |
} | |
/** | |
* Helper to get noise for the corona. | |
*/ | |
float fVal(vec3 coord, float fade, float time, float brightness, vec3 noise){ | |
float fVal = 1.0 - fade; | |
float newTime = abs( snoise( coord + vec3( 0.0, -time * ( noise.x + brightness * 0.001 ), time * 0.015 ), noise.y ) ); | |
for( int i=1; i<=7; i++ ){ | |
float power = pow( 2.0, float(i + 1) ); | |
fVal += ( 0.5 / power ) * snoise( coord + vec3( 0.0, -time, time * 0.2 ), ( 4.0 * ( noise.z ) * ( newTime + 1.0 ) ) ); | |
} | |
fVal = pow( fVal * max( 1.1 - fade, 0.0 ), 2.0 ) * 50.0; | |
return fVal; | |
} | |
/** | |
* The Corona is the part of the star that extends out past its | |
* radius, with the pretty loops and whatnot. | |
*/ | |
vec3 Corona(vec2 p, float time, float dist, float radius, float brightness, vec3 color){ | |
// First number controls outer radius (inversely), second controls inner radius. | |
float fade = pow( length( 1.75 * p ), 0.50 ); | |
float angle = atan( p.x, p.y )/6.2832; | |
vec3 coord = vec3( angle, dist, time * 0.1 ); | |
float corona = 0.0; | |
// For last vec, first number is speed flowing out | |
// second number is amount of loopiness (larger is smaller loops | |
// third number is graininess | |
corona += fVal(coord, fade, time, brightness, vec3(0.35, 15.0, 10.0)); | |
corona += fVal(coord, fade, time, brightness, vec3(0.15, 45.0, 25.0)); | |
if( dist < radius ) // Inside the disk, quickly drop off in scale. Mostly occluded by the disk. | |
corona *= pow( dist * (1.0 / radius), 24.0 ); | |
return corona * color; | |
} | |
/** | |
* The glow is the overall light emanating from the star into the surrounding space. | |
*/ | |
vec3 StarGlow(float dist, float brightness, vec3 color){ | |
float starGlow = 1.0 - dist * ( 1.0 - brightness ); | |
starGlow = clamp(starGlow, 0.0, 1.0); | |
return starGlow * color; | |
} | |
void main(void) | |
{ | |
//float radius = 0.24 + brightness * 0.2; | |
// Radius of the star, ~ in % of window width. | |
float radius = 0.3 ; | |
float time = iGlobalTime * 0.1; | |
float aspect = iResolution.x/iResolution.y; | |
Randomness(iChannel1); | |
float brightness = Brightness(); | |
// Good colors: | |
// Main Sequence G | |
vec3 color = vec3( 0.8, 0.65, 0.3 ); | |
// O | |
//vec3 color = vec3( 0.25, 0.65, 1.0 ); | |
// F | |
//vec3 color = vec3( 1.0, 1.0, 0.8 ); | |
// M | |
// vec3 color = vec3( 0.95, 0.2, 0.1 ); | |
// Position of this pixel on the canvas | |
vec2 uv = gl_FragCoord.xy / iResolution.xy; | |
// Position of this pixel relative to center of star | |
vec2 p = (-0.5 + uv) * vec2(aspect, 1.0); | |
vec2 sp = Sphere(uv, aspect, radius); | |
float f = F(sp, radius); | |
float dist = length(p); | |
vec3 starSphere = StarSphere(sp, f, brightness, dist, radius, time, iChannel0); | |
vec3 base = Base(f, color); | |
vec3 corona = Corona(p, time, dist, radius, brightness, color); | |
//vec3 starGlow = StarGlow(dist, brightness, glow); | |
//gl_FragColor.rgb = base + starSphere + corona + starGlow ; | |
//gl_FragColor.rgb = base + starSphere + corona; | |
gl_FragColor.rgb = base + starSphere + corona; | |
gl_FragColor.a = 1.0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment