josemorval

Raymarching template

Jun 24th, 2016
324
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.21 KB | None | 0 0
  1. Shader "ShaderSandbox"
  2. {
  3.  
  4.     SubShader
  5.     {
  6.         Tags { "RenderType"="Opaque" }
  7.  
  8.         Pass
  9.         {
  10.             CGPROGRAM
  11.             #pragma vertex vert
  12.             #pragma fragment frag
  13.  
  14.             #include "UnityCG.cginc"
  15.             #include "Primitives.cginc"
  16.  
  17.             struct appdata
  18.             {
  19.                 float4 vertex : POSITION;
  20.                 float2 uv : TEXCOORD0;
  21.             };
  22.  
  23.             struct v2f
  24.             {
  25.                 float2 uv : TEXCOORD0;
  26.                 float4 vertex : SV_POSITION;
  27.             };
  28.            
  29.             v2f vert (appdata v)
  30.             {
  31.                 v2f o;
  32.                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
  33.                 o.uv = v.uv;
  34.                 return o;
  35.             }
  36.  
  37.             //////////////////////////////
  38.             //Primitives (distance fields)
  39.             //////////////////////////////
  40.  
  41.             float sdPlane( float3 p )
  42.             {
  43.                 return p.y;
  44.             }
  45.  
  46.             float sdSphere( float3 p, float s )
  47.             {
  48.                 return length(p)-s;
  49.             }
  50.  
  51.             float sdBox( float3 p, float3 b )
  52.             {
  53.                 float3 d = abs(p) - b;
  54.                 return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));
  55.             }
  56.             //////////////////////////////
  57.             //////////////////////////////
  58.  
  59.             //////////////////////////////
  60.             //Basic operations
  61.             //////////////////////////////
  62.  
  63.             float opS( float d1, float d2 )
  64.             {
  65.                 return max(-d2,d1);
  66.             }
  67.  
  68.             float2 opU( float2 d1, float2 d2 )
  69.             {
  70.                 return (d1.x<d2.x) ? d1 : d2;
  71.             }
  72.  
  73.             float3 opRep( float3 p, float3 c )
  74.             {
  75.                 return p%c-0.5*c;
  76.             }
  77.  
  78.             float3 opTwist( float3 p )
  79.             {
  80.                 float c = cos(3.0*p.y+10.0);
  81.                 float s = sin(3.0*p.y+10.0);
  82.                 float2x2 m = float2x2(c,-s,s,c);
  83.                 return float3(mul(p.xz,m),p.y);
  84.             }
  85.  
  86.             float smin( float a, float b)
  87.             {
  88.                 float k = 32.0;
  89.                 float res = exp( -k*a ) + exp( -k*b );
  90.                 return -log( res )/k;
  91.             }
  92.  
  93.             //////////////////////////////
  94.             //////////////////////////////
  95.  
  96.  
  97.             //////////////////////////////
  98.             //Great world-generator function
  99.             //////////////////////////////
  100.  
  101.             float2 map( float3 pos )
  102.             {
  103.                 float2 res = opU( float2( sdPlane(pos), 1.0 ),
  104.                                 float2(
  105.                                     smin(sdBox(opRep(pos-float3( 0.0,0.4*_Time.y, 0.0),float3(2.0,2.0,2.0)), float3(0.3,0.8,0.3) ),
  106.                                     sdSphere(opRep(pos-float3( sin(0.3*_Time.y+1.0*pos.x),0.4*_Time.y,0.0),float3(0.9,0.9,0.8)), 0.07 )),
  107.                                   46.9 ) );
  108.                 return res;
  109.             }  
  110.  
  111.             //////////////////////////////
  112.             //////////////////////////////  
  113.  
  114.             //////////////////////////////
  115.             //Raymarch evaluation
  116.             //////////////////////////////
  117.  
  118.             float2 castRay( float3 ro, float3 rd )
  119.             {
  120.                 float tmin = 0.01;
  121.                 float tmax = 20.0;
  122.                
  123.                 float precis = 0.002;
  124.                 float t = tmin;
  125.                 float m = -1.0;
  126.                 for( int i=0; i<50; i++ )
  127.                 {
  128.                     float2 res = map( ro+rd*t );
  129.                     if( res.x<precis || t>tmax ) break;
  130.                     t += res.x;
  131.                     m = res.y;
  132.                 }
  133.  
  134.                 if( t>tmax ) m=-1.0;
  135.                 return float2( t, m );
  136.             }
  137.  
  138.             //////////////////////////////
  139.             //////////////////////////////
  140.  
  141.             //////////////////////////////
  142.             //Shadows, normals and Ambient Occlusion by means of raymarch
  143.             //////////////////////////////
  144.  
  145.             float softshadow( float3 ro, float3 rd, float mint, float tmax )
  146.             {
  147.                 float res = 1.0;
  148.                 float t = mint;
  149.                 for( int i=0; i<16; i++ )
  150.                 {
  151.                     float h = map( ro + rd*t ).x;
  152.                     res = min( res, 8.0*h/t );
  153.                     t += clamp( h, 0.02, 0.10 );
  154.                     if( h<0.001 || t>tmax ) break;
  155.                 }
  156.                 return clamp( res, 0.0, 1.0 );
  157.  
  158.             }
  159.  
  160.             float3 calcNormal( float3 pos )
  161.             {
  162.                 float3 eps = float3( 0.001, 0.0, 0.0 );
  163.                 float3 nor = float3(
  164.                     map(pos+eps.xyy).x - map(pos-eps.xyy).x,
  165.                     map(pos+eps.yxy).x - map(pos-eps.yxy).x,
  166.                     map(pos+eps.yyx).x - map(pos-eps.yyx).x );
  167.                 return normalize(nor);
  168.             }
  169.  
  170.             float calcAO( float3 pos, float3 nor )
  171.             {
  172.                 float occ = 0.0;
  173.                 float sca = 1.0;
  174.                 for( int i=0; i<5; i++ )
  175.                 {
  176.                     float hr = 0.01 + 0.12*float(i)/4.0;
  177.                     float3 aopos =  nor * hr + pos;
  178.                     float dd = map( aopos ).x;
  179.                     occ += -(dd-hr)*sca;
  180.                     sca *= 0.95;
  181.                 }
  182.                 return clamp( 1.0 - 3.0*occ, 0.0, 1.0 );    
  183.             }
  184.  
  185.  
  186.             ////////////////////////////////
  187.             //THE RENDER step
  188.             ///////////////////////////////
  189.             float3 render( float3 ro, float3 rd )
  190.             {
  191.                 float3 col = float3(0.7, 0.9, 1.0) +rd.y*0.8;
  192.                 float2 res = castRay(ro,rd);
  193.                 float t = res.x;
  194.                 float m = res.y;
  195.                
  196.                 if( m>-0.5 )
  197.                 {
  198.                     float3 pos = ro + t*rd;
  199.                     float3 nor = calcNormal( pos );
  200.                     float3 ref = reflect( rd, nor );
  201.                    
  202.                     // material        
  203.                     col = 0.45 + 0.3*sin( float3(0.05,0.08,0.10)*(m-1.0) );
  204.                     col = 1.0/(1.0+0.1*t*t);
  205.  
  206.                     //Material
  207.                     if( m<1.5 )
  208.                     {
  209.                        
  210.                         float f =  ( floor(5.0*pos.z) + floor(5.0*pos.x))% 2.0;
  211.                         col = 0.4 + 0.1*f*float3(1.0);
  212.                     }
  213.  
  214.                     // lighitng        
  215.                     float occ = calcAO( pos, nor );
  216.                     float3 lig = normalize( float3(0.9, 0.9,0.9) );
  217.                     float amb = clamp( 0.5+0.5*nor.y, 0.0, 1.0 );
  218.                     float dif = clamp( dot( nor, lig ), 0.0, 1.0 );
  219.                     float bac = clamp( dot( nor, normalize(float3(-lig.x,0.0,-lig.z))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0);
  220.                     float dom = smoothstep( -0.1, 0.1, ref.y );
  221.                     float fre = pow( clamp(1.0+dot(nor,rd),0.0,1.0), 2.0 );
  222.                     float spe = pow(clamp( dot( ref, lig ), 0.0, 1.0 ),16.0);
  223.                    
  224.                     dif *= softshadow( pos, lig, 0.02, 2.5 );
  225.                     dom *= softshadow( pos, ref, 0.02, 2.5 );
  226.  
  227.                     float3 lin = float3(0.0);
  228.                     lin += 1.20*dif*float3(1.00,0.85,0.55);
  229.                     lin += 1.20*spe*float3(1.00,0.85,0.55)*dif;
  230.                     lin += 0.20*amb*float3(0.50,0.70,1.00)*occ;
  231.                     lin += 0.30*dom*float3(0.50,0.70,1.00)*occ;
  232.                     lin += 0.30*bac*float3(0.25,0.25,0.25)*occ;
  233.                     lin += 0.40*fre*float3(1.00,1.00,1.00)*occ;
  234.                     col = col*lin;
  235.  
  236.                     col = lerp( col, float3(0.8,0.9,1.0), 1.0-exp( -0.002*t*t ) );
  237.  
  238.                 }
  239.  
  240.                 return float3( clamp(col,0.0,1.0) );
  241.             }
  242.  
  243.             //////////////////////////////
  244.             //////////////////////////////
  245.  
  246.             //////////////////////////////
  247.             //Camera setup
  248.             ///////////////////////////////
  249.             float3x3 setCamera( float3 ro, float3 ta, float cr )
  250.             {
  251.                 float3 cw = normalize(ta-ro);
  252.                 float3 cp = float3(sin(cr), cos(cr),0.0);
  253.                 float3 cu = normalize( cross(cw,cp) );
  254.                 float3 cv = normalize( cross(cu,cw) );
  255.                 return float3x3( cu, cv, cw );
  256.             }
  257.  
  258.             //////////////////////////////
  259.             //////////////////////////////
  260.  
  261.             //////////////////////////////
  262.             //Fragment shader
  263.             ///////////////////////////////
  264.             float4 frag (v2f i) : SV_Target
  265.             {
  266.                 float2 q = i.uv.xy;
  267.                 float2 p = -1.0+2.0*q;
  268.                 p.x *= _ScreenParams.x/_ScreenParams.y;
  269.  
  270.                 float time = 15.0 + _Time.y;
  271.  
  272.                 float3 ro = float3( -0.5+5.0*cos(0.1*time), 2.0, 0.5 + 5.0*sin(0.1*time) );
  273.                 float3 ta = float3( -0.5, -0.4, 0.5 );
  274.                
  275.                 float3x3 ca = setCamera( ro, ta, 0.0 );
  276.                
  277.                 float3 rd =  mul(normalize(float3(p.xy,2.0)),ca);
  278.  
  279.                 float3 col = render( ro, rd );
  280.  
  281.                 col = pow( col, float3(0.4545) );
  282.  
  283.                 return float4( col, 1.0 );
  284.  
  285.             }
  286.  
  287.  
  288.             ENDCG
  289.         }
  290.     }
  291. }
Advertisement
Add Comment
Please, Sign In to add comment