#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_orig; } 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; undeform_normal(tmp, rd_perp, rd_tan); rd = normalize(rd_perp + rd_tan); #endif const float kMinDist = 1e-4; // TODO dial this in & parameterize const float kMaxDist = 10; // TODO parameterize const uint kMaxIter = 30; float d_acc = 0; for (uint ii = 0; ii < kMaxIter; ++ii) { float3 p = ro + rd * d_acc; float d_cur = 1e9; #if defined(_RAY_MARCHING_BALL_GRID) float3 count = _Ray_Marching_Ball_Grid_Count; d_cur = min(d_cur, map_ball_grid(p, count)); #endif 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; #if defined(_RAY_MARCHING_BALL_GRID) float3 count = _Ray_Marching_Ball_Grid_Count; map_ball_grid_normal(count, lclPos, lclNorm, lclTan); #endif RayMarchResult res; res.objPos = lclPos; res.objNorm = lclNorm; res.objTan = lclTan; return res; } #endif // __RAY_MARCHING_INC