Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- float sdPlane(vec3 p)
- {
- return p.y;
- }
- float sdSphere(vec3 p, float s)
- {
- return length(p)-s;
- }
- vec2 opU( vec2 d1, vec2 d2 )
- {
- return (d1.x<d2.x) ? d1 : d2;
- }
- vec2 map(vec3 pos)
- {
- //En esta funcion se define la escena.
- //En este caso vamos a situar una esfera
- //de radio 1 en el origen de coordenas junto
- //con un plano situado a una unidad negativa
- //del eje Z.
- vec2 res = vec2(sdSphere(pos,1.0),2.0);
- //res = opU(res,vec2(sdSphere(pos+vec3(3.,-0.5,-3.),1.5),2.14));
- res = opU(res,vec2(sdPlane(pos-vec3(0.0,-1.0,0.0)),3.0));
- return res;
- }
- vec3 calcNormal(vec3 pos)
- {
- vec3 eps = vec3( 0.0005, 0.0, 0.0 );
- vec3 nor = vec3(
- map(pos+eps.xyy).x - map(pos-eps.xyy).x,
- map(pos+eps.yxy).x - map(pos-eps.yxy).x,
- map(pos+eps.yyx).x - map(pos-eps.yyx).x );
- return normalize(nor);
- }
- float castShadow(vec3 ro, vec3 rd)
- {
- float tmin = 1.0;
- float tmax = 20.0;
- float t = tmin;
- for( int i=0; i<64; i++ )
- {
- float precis = 0.0005*t;
- vec2 res = map(ro+rd*t);
- if( res.x<precis || t>tmax ) break;
- t += res.x;
- }
- if( t>tmax ) return 0.0;
- return 1.0;
- }
- vec2 castRay(vec3 ro, vec3 rd)
- {
- //Clipping planes de la camara
- float tmin = 1.0;
- float tmax = 20.0;
- float t = tmin;
- float m = -1.0;
- //Sphere tracing: se usa map para estimar la
- //distancia a la que estamos de la escena. Si
- //estamos a x unidades, todavía nos podemos mover
- //en la misma dirección x unidades, en caso contrario
- //paramos de movernos
- for( int i=0; i<64; i++ )
- {
- float precis = 0.0005*t;
- //Evaluamos la distancia a la escena
- vec2 res = map(ro+rd*t);
- if( res.x<precis || t>tmax ) break;
- t += res.x;
- m = res.y;
- }
- if( t>tmax ) m=-1.0;
- return vec2( t, m );
- }
- vec3 render(vec3 ro,vec3 rd)
- {
- vec3 col = vec3(1.0);
- //Lanzamos el rayo. Nos devuelve un vector
- //con la distancia t y un
- //indice asociado m al objecto
- vec2 res = castRay(ro,rd);
- float t = res.x;
- float m = res.y;
- if(m>-0.5){
- //Color en funcion del (indice del) objecto
- col = vec3(
- 0.3-0.3*cos(7.1*m),
- 0.7-0.5*cos(21.1*m+0.2),
- 0.7-0.2*cos(13.7*m-0.1)
- );
- vec3 lig = normalize(vec3(1.0,1.0,1.0));
- vec3 nor = calcNormal(ro+t*rd);
- vec3 ref = reflect(rd,nor);
- float shadow = castShadow(ro+t*rd,lig);
- float reflection = castShadow(ro+t*rd,ref);
- col*=(1.-0.3*shadow);
- col*=(1.-0.1*reflection);
- }
- return col;
- }
- mat3 setCamera(vec3 ro, vec3 ta, float cr)
- {
- vec3 cw = normalize(ta-ro);
- vec3 cp = vec3(sin(cr), cos(cr),0.0);
- vec3 cu = normalize( cross(cw,cp) );
- vec3 cv = normalize( cross(cu,cw) );
- return mat3( cu, cv, cw );
- }
- void main()
- {
- vec2 p = gl_FragCoord.xy/iResolution.xy-0.5;
- p.x*=iResolution.x/iResolution.y;
- //Poscion de la camara
- vec3 ro = vec3(10.*cos(0.5*iGlobalTime),3.0,10.*sin(0.5*iGlobalTime));
- //Posicion hacia la que miramos
- vec3 ta = vec3(0.0,0.0,0.0);
- //Matriz magica de la camara
- mat3 ca = setCamera( ro, ta, 0.0 );
- //Direccion del rayo desde el pixel actual
- vec3 rd = ca * normalize(vec3(p.xy,1.0));
- //Ray marching
- vec3 col = render( ro, rd );
- gl_FragColor = vec4(col,1.0);
- }
Advertisement
Add Comment
Please, Sign In to add comment