#ifndef __RAY_MARCHING_INC #define __RAY_MARCHING_INC #include "math.cginc" #include "ray_marching_maps.hlsl" #include "texture_utils.cginc" #include "vertex.cginc" struct RayMarchResult { float3 objPos; float3 objNorm; float3 objTan; }; float3 getObjPos(v2f i) { return i.objPos; } void GetRoRd(v2f i, out float3 ro, out float3 rd) { ro = getObjPos(i); float3 objCamPos = mul(unity_WorldToObject, float4(_WorldSpaceCameraPos, 1)); float3 obj_space_camera_pos = mul(unity_WorldToObject, float4(_WorldSpaceCameraPos, 1.0)); rd = normalize(getObjPos(i) - obj_space_camera_pos); } RayMarchResult ray_march(v2f i) { float3 ro, rd; GetRoRd(i, ro, rd); #if defined(_VERTEX_DEFORMATION) float3 rd_perp = i.normal * dot(i.normal, rd); float3 rd_tan = rd - rd_perp; float3 tmp = ro; deform_normal(tmp, rd_perp, rd_tan); rd = rd_perp + rd_tan; #endif const float kMinDist = 1e-3; // TODO dial this in & parameterize const float kMaxDist = 10; // TODO parameterize const uint kMaxIter = 10; float d_acc = 0; for (uint ii = 0; ii < kMaxIter; ++ii) { float3 p = ro + rd * d_acc; float d_cur = map(p); d_acc += d_cur; if (d_cur < kMinDist) { break; } if (d_acc > kMaxDist) { break; } } // TODO clip / hit detection float3 lclPos = ro + rd * d_acc; float3 lclNorm; float3 lclTan; map_normal(lclPos, lclNorm, lclTan); RayMarchResult res; res.objPos = lclPos; res.objNorm = lclNorm; res.objTan = lclTan; return res; } #endif // __RAY_MARCHING_INC