josemorval

Simple Raymarch

Oct 5th, 2017
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.32 KB | None | 0 0
  1. float sdPlane(vec3 p)
  2. {
  3.   return p.y;
  4. }
  5.  
  6. float sdSphere(vec3 p, float s)
  7. {
  8.   return length(p)-s;
  9. }
  10.  
  11. vec2 opU( vec2 d1, vec2 d2 )
  12. {
  13.   return (d1.x<d2.x) ? d1 : d2;
  14. }
  15.  
  16. vec2 map(vec3 pos)
  17. {
  18.   //En esta funcion se define la escena.
  19.   //En este caso vamos a situar una esfera
  20.   //de radio 1 en el origen de coordenas junto
  21.   //con un plano situado a una unidad negativa
  22.   //del eje Z.
  23.   vec2 res = vec2(sdSphere(pos,1.0),2.0);
  24.   //res = opU(res,vec2(sdSphere(pos+vec3(3.,-0.5,-3.),1.5),2.14));
  25.   res = opU(res,vec2(sdPlane(pos-vec3(0.0,-1.0,0.0)),3.0));
  26.   return res;
  27. }
  28.  
  29. vec3 calcNormal(vec3 pos)
  30. {
  31.   vec3 eps = vec3( 0.0005, 0.0, 0.0 );
  32.     vec3 nor = vec3(
  33.         map(pos+eps.xyy).x - map(pos-eps.xyy).x,
  34.         map(pos+eps.yxy).x - map(pos-eps.yxy).x,
  35.         map(pos+eps.yyx).x - map(pos-eps.yyx).x );
  36.     return normalize(nor);
  37. }
  38.  
  39. float castShadow(vec3 ro, vec3 rd)
  40. {
  41.     float tmin = 1.0;
  42.     float tmax = 20.0;
  43.  
  44.     float t = tmin;
  45.     for( int i=0; i<64; i++ )
  46.     {
  47.         float precis = 0.0005*t;
  48.  
  49.         vec2 res = map(ro+rd*t);
  50.       if( res.x<precis || t>tmax ) break;
  51.       t += res.x;
  52.     }
  53.  
  54.     if( t>tmax ) return 0.0;
  55.     return 1.0;
  56. }
  57.  
  58. vec2 castRay(vec3 ro, vec3 rd)
  59. {
  60.     //Clipping planes de la camara
  61.     float tmin = 1.0;
  62.     float tmax = 20.0;
  63.  
  64.     float t = tmin;
  65.     float m = -1.0;
  66.  
  67.     //Sphere tracing: se usa map para estimar la
  68.     //distancia a la que estamos de la escena. Si
  69.     //estamos a x unidades, todavía nos podemos mover
  70.     //en la misma dirección x unidades, en caso contrario
  71.     //paramos de movernos
  72.     for( int i=0; i<64; i++ )
  73.     {
  74.         float precis = 0.0005*t;
  75.  
  76.       //Evaluamos la distancia a la escena
  77.         vec2 res = map(ro+rd*t);
  78.       if( res.x<precis || t>tmax ) break;
  79.       t += res.x;
  80.         m = res.y;
  81.     }
  82.  
  83.     if( t>tmax ) m=-1.0;
  84.     return vec2( t, m );
  85. }
  86.  
  87. vec3 render(vec3 ro,vec3 rd)
  88. {
  89.   vec3 col = vec3(1.0);
  90.  
  91.   //Lanzamos el rayo. Nos devuelve un vector
  92.   //con la distancia t y un
  93.   //indice asociado m al objecto
  94.   vec2 res = castRay(ro,rd);
  95.   float t = res.x;
  96.   float m = res.y;
  97.  
  98.   if(m>-0.5){
  99.       //Color en funcion del (indice del) objecto
  100.       col = vec3(
  101.         0.3-0.3*cos(7.1*m),
  102.         0.7-0.5*cos(21.1*m+0.2),
  103.         0.7-0.2*cos(13.7*m-0.1)
  104.       );
  105.  
  106.       vec3 lig = normalize(vec3(1.0,1.0,1.0));
  107.       vec3 nor = calcNormal(ro+t*rd);
  108.       vec3 ref = reflect(rd,nor);
  109.       float shadow = castShadow(ro+t*rd,lig);
  110.       float reflection = castShadow(ro+t*rd,ref);
  111.      
  112.       col*=(1.-0.3*shadow);
  113.       col*=(1.-0.1*reflection);
  114.   }
  115.  
  116.   return col;
  117. }
  118.  
  119. mat3 setCamera(vec3 ro, vec3 ta, float cr)
  120. {
  121.     vec3 cw = normalize(ta-ro);
  122.     vec3 cp = vec3(sin(cr), cos(cr),0.0);
  123.     vec3 cu = normalize( cross(cw,cp) );
  124.     vec3 cv = normalize( cross(cu,cw) );
  125.   return mat3( cu, cv, cw );
  126. }
  127.  
  128. void main()
  129. {
  130.   vec2 p = gl_FragCoord.xy/iResolution.xy-0.5;
  131.   p.x*=iResolution.x/iResolution.y;
  132.  
  133.   //Poscion de la camara
  134.   vec3 ro = vec3(10.*cos(0.5*iGlobalTime),3.0,10.*sin(0.5*iGlobalTime));
  135.  
  136.   //Posicion hacia la que miramos
  137.   vec3 ta = vec3(0.0,0.0,0.0);
  138.  
  139.   //Matriz magica de la camara
  140.   mat3 ca = setCamera( ro, ta, 0.0 );
  141.  
  142.   //Direccion del rayo desde el pixel actual
  143.   vec3 rd = ca * normalize(vec3(p.xy,1.0));
  144.  
  145.   //Ray marching
  146.   vec3 col = render( ro, rd );
  147.  
  148.   gl_FragColor = vec4(col,1.0);
  149. }
Advertisement
Add Comment
Please, Sign In to add comment