Shader "CrispyPin/Raymarch1" { Properties { [Header(Raymarcher Properties)] _MaxSteps ("Max steps", Int) = 256 _MaxDist ("Max distance", Float) = 100 _SurfDist ("Surface distance threshold", Range(0.00001, 0.05)) = 0.001 } SubShader { Tags { "RenderType"="Opaque" } Cull Off LOD 100 /* Pass{ CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; }; struct v2f { float4 vertex : SV_POSITION; float3 ro : TEXCOORD1; float3 hitPos : TEXCOORD2; }; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); //object space o.ro = mul(unity_WorldToObject, float4(_WorldSpaceCameraPos, 1)); o.hitPos = v.vertex; //world space //o.ro = _WorldSpaceCameraPos; //o.hitPos = mul(unity_ObjectToWorld, v.vertex); return o; } fixed4 frag (v2f i) : SV_Target { discard; return fixed4(0,0,0,0); } ENDCG } */ Pass { Name "AddPass" Tags { "LightMode" = "ForwardAdd"} CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; }; struct v2f { float4 vertex : SV_POSITION; float3 ro : TEXCOORD1; float3 hitPos : TEXCOORD2; }; int _MaxSteps; float _MaxDist; float _SurfDist; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); //object space o.ro = mul(unity_WorldToObject, float4(_WorldSpaceCameraPos, 1)); o.hitPos = v.vertex; //world space //o.ro = _WorldSpaceCameraPos; //o.hitPos = mul(unity_ObjectToWorld, v.vertex); return o; } float smoothMin(float a, float b, float k) { return min(a, b) - pow(max(k - abs(a-b), 0), 3)/(6*k*k); } float sdSphere(float3 p, float3 o, float r) { return length(p - o) - r; } float sdBox(float3 p, float3 dim) { return length(float3( max(abs(p.x) - dim.x/2.0, 0), max(abs(p.y) - dim.y/2.0, 0), max(abs(p.z) - dim.z/2.0, 0))); } float3 repDomain(float3 p, float3 r) { return fmod(abs(p + r/2.0), r) - r/2.0; } float GetDist(float3 p) { /* float d = 0; float s = sin(100*_Time + p.x*10) * 0.02 + 0.028; float s2 = cos(105*_Time + p.x*10) * 0.02 + 0.028; //s += sin(p.x/10)*0.03; float3 rep = repDomain(p, float3(0.026, 0.15, 0.2));// fmod(abs(p + 0.05), 0.1)-0.05; d = sdBox(rep, float3(0.02, s2, s)) - 0.004; d = smoothMin(d, sdBox(rep, float3(0.01, s*1.0, s2*1.5)) - 0.004, 0.01); */ float d = sdSphere(p, 0, 0.1f); // float3 second = ObjSpaceLightDir(0); // float3 second = _WorldSpaceLightPos0; float3 second = mul(unity_WorldToObject, _WorldSpaceLightPos0); d = smoothMin(d, sdBox(p-second, 0.3f), 0.2); //d = smoothMin(d, sdSphere(p, float3(0,0,0), 5), .3); return d; } //marches a ray through the scene float Raymarch(float3 ro, float3 rd) { float rayLen = 0;// total distance marched / distance from origin float dist; // distance from the raymarched scene for ( int i = 0; i < _MaxSteps; i++) { //position = origin + distance * direction float3 p = ro + rayLen * rd; dist = GetDist(p); rayLen += dist;// move forward if (dist < _SurfDist || rayLen > _MaxDist) { break; } } return rayLen; } float3 GetNormal(float3 p) { float2 e = float2(0.001, 0); float3 n = GetDist(p) - float3( GetDist(p-e.xyy), GetDist(p-e.yxy), GetDist(p-e.yyx)); return normalize(n); } fixed4 frag (v2f i) : SV_Target { float3 ro = i.ro; float3 rd = normalize(i.hitPos - ro); float d = Raymarch(ro, rd); fixed4 col = 1; if (d >= _MaxDist) { discard; } float3 p = ro + rd * d; float3 n = GetNormal(p); col.rgb = dot(n, normalize(float3(1,0.5,1))); col *= float4(d, 1, 1, 1); return col; } ENDCG } } }