Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Shader "ShaderSandbox"
- {
- SubShader
- {
- Tags { "RenderType"="Opaque" }
- Pass
- {
- CGPROGRAM
- #pragma vertex vert
- #pragma fragment frag
- #include "UnityCG.cginc"
- #include "Primitives.cginc"
- struct appdata
- {
- float4 vertex : POSITION;
- float2 uv : TEXCOORD0;
- };
- struct v2f
- {
- float2 uv : TEXCOORD0;
- float4 vertex : SV_POSITION;
- };
- v2f vert (appdata v)
- {
- v2f o;
- o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
- o.uv = v.uv;
- return o;
- }
- //////////////////////////////
- //Primitives (distance fields)
- //////////////////////////////
- float sdPlane( float3 p )
- {
- return p.y;
- }
- float sdSphere( float3 p, float s )
- {
- return length(p)-s;
- }
- float sdBox( float3 p, float3 b )
- {
- float3 d = abs(p) - b;
- return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));
- }
- //////////////////////////////
- //////////////////////////////
- //////////////////////////////
- //Basic operations
- //////////////////////////////
- float opS( float d1, float d2 )
- {
- return max(-d2,d1);
- }
- float2 opU( float2 d1, float2 d2 )
- {
- return (d1.x<d2.x) ? d1 : d2;
- }
- float3 opRep( float3 p, float3 c )
- {
- return p%c-0.5*c;
- }
- float3 opTwist( float3 p )
- {
- float c = cos(3.0*p.y+10.0);
- float s = sin(3.0*p.y+10.0);
- float2x2 m = float2x2(c,-s,s,c);
- return float3(mul(p.xz,m),p.y);
- }
- float smin( float a, float b)
- {
- float k = 32.0;
- float res = exp( -k*a ) + exp( -k*b );
- return -log( res )/k;
- }
- //////////////////////////////
- //////////////////////////////
- //////////////////////////////
- //Great world-generator function
- //////////////////////////////
- float2 map( float3 pos )
- {
- float2 res = opU( float2( sdPlane(pos), 1.0 ),
- float2(
- 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) ),
- 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 )),
- 46.9 ) );
- return res;
- }
- //////////////////////////////
- //////////////////////////////
- //////////////////////////////
- //Raymarch evaluation
- //////////////////////////////
- float2 castRay( float3 ro, float3 rd )
- {
- float tmin = 0.01;
- float tmax = 20.0;
- float precis = 0.002;
- float t = tmin;
- float m = -1.0;
- for( int i=0; i<50; i++ )
- {
- float2 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 float2( t, m );
- }
- //////////////////////////////
- //////////////////////////////
- //////////////////////////////
- //Shadows, normals and Ambient Occlusion by means of raymarch
- //////////////////////////////
- float softshadow( float3 ro, float3 rd, float mint, float tmax )
- {
- float res = 1.0;
- float t = mint;
- for( int i=0; i<16; i++ )
- {
- float h = map( ro + rd*t ).x;
- res = min( res, 8.0*h/t );
- t += clamp( h, 0.02, 0.10 );
- if( h<0.001 || t>tmax ) break;
- }
- return clamp( res, 0.0, 1.0 );
- }
- float3 calcNormal( float3 pos )
- {
- float3 eps = float3( 0.001, 0.0, 0.0 );
- float3 nor = float3(
- 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 calcAO( float3 pos, float3 nor )
- {
- float occ = 0.0;
- float sca = 1.0;
- for( int i=0; i<5; i++ )
- {
- float hr = 0.01 + 0.12*float(i)/4.0;
- float3 aopos = nor * hr + pos;
- float dd = map( aopos ).x;
- occ += -(dd-hr)*sca;
- sca *= 0.95;
- }
- return clamp( 1.0 - 3.0*occ, 0.0, 1.0 );
- }
- ////////////////////////////////
- //THE RENDER step
- ///////////////////////////////
- float3 render( float3 ro, float3 rd )
- {
- float3 col = float3(0.7, 0.9, 1.0) +rd.y*0.8;
- float2 res = castRay(ro,rd);
- float t = res.x;
- float m = res.y;
- if( m>-0.5 )
- {
- float3 pos = ro + t*rd;
- float3 nor = calcNormal( pos );
- float3 ref = reflect( rd, nor );
- // material
- col = 0.45 + 0.3*sin( float3(0.05,0.08,0.10)*(m-1.0) );
- col = 1.0/(1.0+0.1*t*t);
- //Material
- if( m<1.5 )
- {
- float f = ( floor(5.0*pos.z) + floor(5.0*pos.x))% 2.0;
- col = 0.4 + 0.1*f*float3(1.0);
- }
- // lighitng
- float occ = calcAO( pos, nor );
- float3 lig = normalize( float3(0.9, 0.9,0.9) );
- float amb = clamp( 0.5+0.5*nor.y, 0.0, 1.0 );
- float dif = clamp( dot( nor, lig ), 0.0, 1.0 );
- 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);
- float dom = smoothstep( -0.1, 0.1, ref.y );
- float fre = pow( clamp(1.0+dot(nor,rd),0.0,1.0), 2.0 );
- float spe = pow(clamp( dot( ref, lig ), 0.0, 1.0 ),16.0);
- dif *= softshadow( pos, lig, 0.02, 2.5 );
- dom *= softshadow( pos, ref, 0.02, 2.5 );
- float3 lin = float3(0.0);
- lin += 1.20*dif*float3(1.00,0.85,0.55);
- lin += 1.20*spe*float3(1.00,0.85,0.55)*dif;
- lin += 0.20*amb*float3(0.50,0.70,1.00)*occ;
- lin += 0.30*dom*float3(0.50,0.70,1.00)*occ;
- lin += 0.30*bac*float3(0.25,0.25,0.25)*occ;
- lin += 0.40*fre*float3(1.00,1.00,1.00)*occ;
- col = col*lin;
- col = lerp( col, float3(0.8,0.9,1.0), 1.0-exp( -0.002*t*t ) );
- }
- return float3( clamp(col,0.0,1.0) );
- }
- //////////////////////////////
- //////////////////////////////
- //////////////////////////////
- //Camera setup
- ///////////////////////////////
- float3x3 setCamera( float3 ro, float3 ta, float cr )
- {
- float3 cw = normalize(ta-ro);
- float3 cp = float3(sin(cr), cos(cr),0.0);
- float3 cu = normalize( cross(cw,cp) );
- float3 cv = normalize( cross(cu,cw) );
- return float3x3( cu, cv, cw );
- }
- //////////////////////////////
- //////////////////////////////
- //////////////////////////////
- //Fragment shader
- ///////////////////////////////
- float4 frag (v2f i) : SV_Target
- {
- float2 q = i.uv.xy;
- float2 p = -1.0+2.0*q;
- p.x *= _ScreenParams.x/_ScreenParams.y;
- float time = 15.0 + _Time.y;
- float3 ro = float3( -0.5+5.0*cos(0.1*time), 2.0, 0.5 + 5.0*sin(0.1*time) );
- float3 ta = float3( -0.5, -0.4, 0.5 );
- float3x3 ca = setCamera( ro, ta, 0.0 );
- float3 rd = mul(normalize(float3(p.xy,2.0)),ca);
- float3 col = render( ro, rd );
- col = pow( col, float3(0.4545) );
- return float4( col, 1.0 );
- }
- ENDCG
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment