URL: http://glslsandbox.com/e#24403.1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
// Raymarched Liquid Sphere // By: Brandon Fogerty // bfogerty at gmail dot com // xdpixel.com #ifdef GL_ES precision mediump float; #endif uniform float time; uniform vec2 mouse; uniform vec2 resolution; #ifdef GL_ES precision mediump float; #endif const float EPS = 0.01; const int MAXI = 35; float hash( float x ) { return fract( sin( x ) * 43758.5453 ); } float noise( vec2 uv ) // Thanks Inigo Quilez { vec3 x = vec3( uv.xy, 0.0 ); vec3 p = floor( x ); vec3 f = fract( x ); f = f*f*(3.0 - 2.0*f); float offset = 57.0; float n = dot( p, vec3(1.0, offset, offset*2.0) ); return mix( mix( mix( hash( n + 0.0 ), hash( n + 1.0 ), f.x ), mix( hash( n + offset), hash( n + offset+1.0), f.x ), f.y ), mix( mix( hash( n + offset*2.0), hash( n + offset*2.0+1.0), f.x), mix( hash( n + offset*3.0), hash( n + offset*3.0+1.0), f.x), f.y), f.z); } float snoise( vec2 uv ) { return noise( uv ) * 2.0 - 1.0; } float fbm( vec2 uv, float lacunarity, float gain ) { float sum = 0.0; float amp = 0.3; for( int i = 0; i < 2; ++i ) { sum += ( snoise( uv ) ) * amp; amp *= gain; uv *= lacunarity; } return sum; } float sphere( vec3 ray, float r ) { float d = length(ray)-r; float t = time * 0.1; d += fbm( vec2( cos(ray.x+time)*ray.x+t, sin(ray.y+time)*ray.y+t ), 10.1, 0.1 ); return d; } float SceneDist( vec3 ray ) { float d = sphere( ray, 1.0 ); return d; } vec3 getNormal(vec3 pos) { vec2 eps = vec2(0.0, EPS); return normalize(vec3( SceneDist(pos + eps.yxx) - SceneDist(pos - eps.yxx), SceneDist(pos + eps.xyx) - SceneDist(pos - eps.xyx), SceneDist(pos + eps.xxy) - SceneDist(pos - eps.xxy))); } vec3 Lighting( vec3 camPos, vec3 pos, vec3 normal, vec3 diffuseColor ) { vec3 lightPos = vec3(0,0,10); vec3 lightDir = normalize( lightPos - pos ); vec3 viewDir = normalize( camPos - pos ); vec3 lightAmbientColor = vec3(0.1,0.1,0.1); vec3 lightSpecularColor = vec3(1,1,1); vec3 halfDir = normalize(viewDir + lightDir); float lightSpecularIntensity = pow( clamp(dot( normal, reflect(lightDir, normal )), 0.0, 1.0), 80.0 ); float lightDiffuseIntensity = clamp( dot( -normalize(pos), lightDir ), 0.00, 1.0); return lightAmbientColor + (lightDiffuseIntensity * diffuseColor) + (lightSpecularIntensity * lightSpecularColor); } vec3 RenderScene( vec2 uv ) { vec3 color = vec3(1,0,0); vec3 camPos = vec3(0,0,-3); vec3 camTarget = vec3(0.0, 0.0, 0.0); vec3 camUp = vec3(0,1.0,0); vec3 camFwd = normalize( camTarget - camPos ); vec3 camRight = normalize( cross( camUp, camFwd ) ); camUp = normalize( cross( camRight, camFwd ) ); float dist = SceneDist( camPos ); float total = dist; vec3 rayDir = vec3( normalize( camFwd + camRight * uv.x + camUp * uv.y ) ); for(int i=0; i < MAXI; ++i) { dist = SceneDist( camPos + rayDir * total ); total += dist; if( dist <= EPS ) { break; } } vec3 dest = camPos + rayDir * total; if( dist <= EPS ) { vec3 normal = getNormal( dest ); vec3 c0 = vec3(0.1,0.5,1.4)*0.3; vec3 c1 = vec3(0.1,1.4,0.2); vec3 diffuse = c0+normal.x + c1+normal.y; color = Lighting( camPos, dest, normal, diffuse ); } else { color = vec3(1.0) * length( uv ); } return color; } void main(void) { vec2 uv = ((gl_FragCoord.xy / resolution.xy) - 0.5) * vec2(2.0, 2.0 * resolution.y / resolution.x); vec3 color = RenderScene( uv ); // Scan line color -= mod(gl_FragCoord.y, 2.0) < 1.0 ? 0.5 : 0.0; gl_FragColor = vec4(color, 1.0); } |