1// Compatibility #ifdefs needed for parameters 2#ifdef GL_ES 3#define COMPAT_PRECISION mediump 4#else 5#define COMPAT_PRECISION 6#endif 7 8// Parameter lines go here: 9#pragma parameter RETRO_PIXEL_SIZE "Retro Pixel Size" 0.84 0.0 1.0 0.01 10#ifdef PARAMETER_UNIFORM 11// All parameter floats need to have COMPAT_PRECISION in front of them 12uniform COMPAT_PRECISION float RETRO_PIXEL_SIZE; 13#else 14#define RETRO_PIXEL_SIZE 0.84 15#endif 16 17#if defined(VERTEX) 18 19#if __VERSION__ >= 130 20#define COMPAT_VARYING out 21#define COMPAT_ATTRIBUTE in 22#define COMPAT_TEXTURE texture 23#else 24#define COMPAT_VARYING varying 25#define COMPAT_ATTRIBUTE attribute 26#define COMPAT_TEXTURE texture2D 27#endif 28 29#ifdef GL_ES 30#define COMPAT_PRECISION mediump 31#else 32#define COMPAT_PRECISION 33#endif 34 35COMPAT_ATTRIBUTE vec4 VertexCoord; 36COMPAT_ATTRIBUTE vec4 COLOR; 37COMPAT_ATTRIBUTE vec4 TexCoord; 38COMPAT_VARYING vec4 COL0; 39COMPAT_VARYING vec4 TEX0; 40// out variables go here as COMPAT_VARYING whatever 41 42vec4 _oPosition1; 43uniform mat4 MVPMatrix; 44uniform COMPAT_PRECISION int FrameDirection; 45uniform COMPAT_PRECISION int FrameCount; 46uniform COMPAT_PRECISION vec2 OutputSize; 47uniform COMPAT_PRECISION vec2 TextureSize; 48uniform COMPAT_PRECISION vec2 InputSize; 49 50// compatibility #defines 51#define vTexCoord TEX0.xy 52#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize 53#define OutSize vec4(OutputSize, 1.0 / OutputSize) 54 55void main() 56{ 57 gl_Position = MVPMatrix * VertexCoord; 58 TEX0.xy = VertexCoord.xy; 59// Paste vertex contents here: 60} 61 62#elif defined(FRAGMENT) 63 64#if __VERSION__ >= 130 65#define COMPAT_VARYING in 66#define COMPAT_TEXTURE texture 67out vec4 FragColor; 68#else 69#define COMPAT_VARYING varying 70#define FragColor gl_FragColor 71#define COMPAT_TEXTURE texture2D 72#endif 73 74#ifdef GL_ES 75#ifdef GL_FRAGMENT_PRECISION_HIGH 76precision highp float; 77#else 78precision mediump float; 79#endif 80#define COMPAT_PRECISION mediump 81#else 82#define COMPAT_PRECISION 83#endif 84 85uniform COMPAT_PRECISION int FrameDirection; 86uniform COMPAT_PRECISION int FrameCount; 87uniform COMPAT_PRECISION vec2 OutputSize; 88uniform COMPAT_PRECISION vec2 TextureSize; 89uniform COMPAT_PRECISION vec2 InputSize; 90uniform sampler2D Texture; 91COMPAT_VARYING vec4 TEX0; 92// in variables go here as COMPAT_VARYING whatever 93 94// compatibility #defines 95#define Source Texture 96#define vTexCoord TEX0.xy 97 98#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize 99#define OutSize vec4(OutputSize, 1.0 / OutputSize) 100 101// delete all 'params.' or 'registers.' or whatever in the fragment 102float iGlobalTime = float(FrameCount)*0.025; 103vec2 iResolution = OutputSize.xy; 104 105// A basic raytracer with help from inigo's article: http://www.iquilezles.org/www/articles/simplegpurt/simplegpurt.htm 106 107const int iterations = 5; 108const float maxDist = 1000.0; 109const vec3 amb = vec3(1.0); 110const float eps = 1e-3; 111 112struct Camera 113{ 114 vec3 up, right, forward; 115 vec3 position; 116}; 117 118Camera cam; 119vec4 spheres[10]; 120vec4 colors[10]; 121vec2 materials[10]; 122 123void init() 124{ 125 // X Y Z Radius 126 spheres[0] = vec4( 0, 0, -1.5, 0.1); 127 spheres[1] = vec4( 0, 0.25, -1.5, 0.1); 128 spheres[2] = vec4( 0, -0.7, -1.5, 0.3); 129 spheres[3] = vec4( 0, -0.1, -1.5, 0.3); 130 spheres[4] = vec4( 0, -0.1, -1.5, 0.15); 131 spheres[5] = vec4( 1001.0, 0, 0, 1000.0); 132 spheres[6] = vec4(-1001.0, 0, 0, 1000.0); 133 spheres[7] = vec4( 0, 1001.0, 0, 1000.0); 134 spheres[8] = vec4( 0, -1001.0, 0, 1000.0); 135 spheres[9] = vec4( 0, 0, -1002.0, 1000.0); 136 137 //R G B Diffuse 138 colors[0] = vec4(1.0, 0.8, 0.0,-1.0); 139 colors[1] = vec4(0.0, 0.0, 1.0,-1.0); 140 colors[2] = vec4(1.0, 1.0, 1.0, 1.0); 141 colors[3] = vec4(1.0, 1.0, 1.0, 1.0); 142 colors[4] = vec4(1.0, 0.0, 0.0, 1.0); 143 colors[5] = vec4(0.0, 1.0, 0.0, 0.7); 144 colors[6] = vec4(1.0, 0.0, 0.0, 0.7); 145 colors[7] = vec4(1.0, 1.0, 1.0, 0.7); 146 colors[8] = vec4(1.0, 1.0, 1.0, 0.7); 147 colors[9] = vec4(1.0, 1.0, 1.0, 0.7); 148 149 //Reflection Coeff, Refraction index 150 materials[0] = vec2 (0.0, 0.0); 151 materials[1] = vec2 (0.0, 0.0); 152 materials[2] = vec2 (1.0, 0.0); 153 materials[3] = vec2 (0.1, 0.8); 154 materials[4] = vec2 (0.1, 0.8); 155 materials[5] = vec2 (0.0, 0.0); 156 materials[6] = vec2 (0.0, 0.0); 157 materials[7] = vec2 (0.1, 0.0); 158 materials[8] = vec2 (0.1, 0.0); 159 materials[9] = vec2 (0.1, 0.0); 160 161 cam.up = vec3(0.0, 1.0, 0.0); 162 cam.right = vec3(1.0, 0.0, 0.0); 163 cam.forward = vec3(0.0, 0.0,-1.0); 164 cam.position = vec3(0.0, 0.0,-0.2); 165} 166 167vec3 getRayDir(vec2 fragCoord) 168{ 169 vec2 uv = (fragCoord.xy / iResolution.xy )*2.0 - 1.0; 170 uv.x *= iResolution.x/iResolution.y; 171 return normalize(uv.x * cam.right + uv.y * cam.up + cam.forward); 172} 173 174 175// The Intersection funtions and shading funcs are taken from inigo's article: 176// http://www.iquilezles.org/www/articles/simplegpurt/simplegpurt.htm 177 178bool intersectSphere(vec3 ro, vec3 rd, vec4 sp, float tm, out float t) 179{ 180 bool r = false; 181 vec3 v = ro - sp.xyz; 182 float b = dot(v,rd); 183 float c = dot(v,v) - sp.w*sp.w; 184 t = b*b-c; 185 if( t > 0.0 ) 186 { 187 t = -b-sqrt(t); 188 r = (t > 0.0) && (t < tm); 189 } 190 return r; 191} 192 193float calcInter(vec3 ro, vec3 rd, out vec4 ob, out vec4 col,out vec2 mat) 194{ 195 float tm = maxDist; 196 float t; 197 198 if(intersectSphere(ro,rd,spheres[0],tm,t)) { ob = spheres[0]; col = colors[0]; tm = t; mat = materials[0]; } 199 if(intersectSphere(ro,rd,spheres[1],tm,t)) { ob = spheres[1]; col = colors[1]; tm = t; mat = materials[1]; } 200 if(intersectSphere(ro,rd,spheres[2],tm,t)) { ob = spheres[2]; col = colors[2]; tm = t; mat = materials[2]; } 201 if(intersectSphere(ro,rd,spheres[3],tm,t)) { ob = spheres[3]; col = colors[3]; tm = t; mat = materials[3]; } 202 if(intersectSphere(ro,rd,spheres[4],tm,t)) { ob = spheres[4]; col = colors[4]; tm = t; mat = materials[4]; } 203 if(intersectSphere(ro,rd,spheres[5],tm,t)) { ob = spheres[5]; col = colors[5]; tm = t; mat = materials[5]; } 204 if(intersectSphere(ro,rd,spheres[6],tm,t)) { ob = spheres[6]; col = colors[6]; tm = t; mat = materials[6]; } 205 if(intersectSphere(ro,rd,spheres[7],tm,t)) { ob = spheres[7]; col = colors[7]; tm = t; mat = materials[7]; } 206 if(intersectSphere(ro,rd,spheres[8],tm,t)) { ob = spheres[8]; col = colors[8]; tm = t; mat = materials[8]; } 207 if(intersectSphere(ro,rd,spheres[9],tm,t)) { ob = spheres[9]; col = colors[9]; tm = t; mat = materials[9]; } 208 209 return tm; 210} 211 212bool inShadow(vec3 ro,vec3 rd,float d) 213{ 214 float t; 215 bool ret = false; 216 217 if(intersectSphere(ro,rd,spheres[2],d,t)){ ret = true; } 218 if(intersectSphere(ro,rd,spheres[3],d,t)){ ret = true; } 219 if(intersectSphere(ro,rd,spheres[4],d,t)){ ret = true; } 220 if(intersectSphere(ro,rd,spheres[5],d,t)){ ret = true; } 221 if(intersectSphere(ro,rd,spheres[6],d,t)){ ret = true; } 222 if(intersectSphere(ro,rd,spheres[7],d,t)){ ret = true; } 223 if(intersectSphere(ro,rd,spheres[8],d,t)){ ret = true; } 224 225 return ret; 226} 227 228vec3 calcShade(vec3 pt, vec4 ob, vec4 col,vec2 mat,vec3 n) 229{ 230 231 float dist,diff; 232 vec3 lcol,l; 233 234 vec3 color = vec3(0.0); 235 vec3 ambcol = amb * (1.0-col.w) * col.rgb; 236 vec3 scol = col.w * col.rgb; 237 238 if(col.w > 0.0) //If its not a light 239 { 240 l = spheres[0].xyz - pt; 241 dist = length(l); 242 l = normalize(l); 243 lcol = colors[0].rgb; 244 diff = clamp(dot(n,l),0.0,1.0); 245 color += (ambcol * lcol + lcol * diff * scol) / (1.0+dist*dist); 246 if(inShadow(pt,l,dist)) 247 color *= 0.7; 248 249 l = spheres[1].xyz - pt; 250 dist = length(l); 251 l = normalize(l); 252 vec3 lcol = colors[1].rgb; 253 diff = clamp(dot(n,l),0.0,1.0); 254 color += (ambcol * lcol + lcol * diff * scol) / (1.0+dist*dist); 255 256 if(inShadow(pt,l,dist)) 257 color *= 0.7; 258 } 259 else 260 color = col.rgb; 261 262 return color; 263} 264 265float getFresnel(vec3 n,vec3 rd,float r0) 266{ 267 float ndotv = clamp(dot(n, -rd), 0.0, 1.0); 268 return r0 + (1.0 - r0) * pow(1.0 - ndotv, 5.0); 269} 270 271vec3 getReflection(vec3 ro,vec3 rd) 272{ 273 vec3 color = vec3(0); 274 vec4 ob,col; 275 vec2 mat; 276 float tm = calcInter(ro,rd,ob,col,mat); 277 if(tm < maxDist) 278 { 279 vec3 pt = ro + rd*tm; 280 vec3 n = normalize(pt - ob.xyz); 281 color = calcShade(pt,ob,col,mat,n); 282 } 283 return color; 284} 285 286void rotObjects() 287{ 288 spheres[0].x += sin(iGlobalTime) * 0.4; 289 spheres[0].z += cos(iGlobalTime) * 0.4; 290 291 spheres[1].x += sin(iGlobalTime) * -0.3; 292 spheres[1].z += cos(iGlobalTime) * -0.3; 293} 294 295 296void mainImage( out vec4 fragColor, in vec2 fragCoord ) 297{ 298 init(); 299 float fresnel,tm; 300 vec4 ob,col; 301 vec2 mat; 302 vec3 pt,refCol,n,refl; 303 304 vec3 mask = vec3(1.0); 305 vec3 color = vec3(0.0); 306 vec3 ro = cam.position; 307 vec3 rd = getRayDir(fragCoord); 308 309 rotObjects(); 310 311 for(int i = 0; i < iterations; i++) 312 { 313 tm = calcInter(ro,rd,ob,col,mat); 314 if(tm < maxDist) 315 { 316 pt = ro + rd*tm; 317 n = normalize(pt - ob.xyz); 318 fresnel = getFresnel(n,rd,mat.x); 319 mask *= fresnel; 320 321 if(mat.y > 0.0) // Refractive 322 { 323 ro = pt - n*eps; 324 refl = reflect(rd,n); 325 refCol = getReflection(ro, refl); 326 color += refCol * mask; 327 mask = col.rgb * (1.0 - fresnel) * (mask / fresnel); 328 rd = refract(rd, n, mat.y); 329 } 330 else if(mat.x > 0.0) // Reflective 331 { 332 color += calcShade(pt,ob,col,mat,n) * (1.0 - fresnel) * mask / fresnel; 333 ro = pt + n*eps; 334 rd = reflect(rd, n); 335 } 336 else // Diffuse 337 { 338 color += calcShade(pt,ob,col,mat,n) * mask/fresnel; 339 break; 340 } 341 } 342 } 343 fragColor = vec4(color,1.0); 344} 345 346 void main(void) 347{ 348 //just some shit to wrap shadertoy's stuff 349 vec2 FragCoord = vTexCoord.xy*OutputSize.xy; 350 mainImage(FragColor,FragCoord); 351} 352#endif 353