Skip to content

Instantly share code, notes, and snippets.

@DavidSouther
Created April 16, 2013 04:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DavidSouther/5393329 to your computer and use it in GitHub Desktop.
Save DavidSouther/5393329 to your computer and use it in GitHub Desktop.
// 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