#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); } void ray_march(inout 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 = _Ray_Marching_Min_Dist; const float kMaxDist = _Ray_Marching_Max_Dist; const uint kMaxIter = _Ray_Marching_Max_Iter; float d_cur; float d_acc = 0; for (uint ii = 0; ii < kMaxIter; ++ii) { float3 p = ro + rd * d_acc; d_cur = 1e9; #if defined(_RAY_MARCHING_BALL_GRID) float3 count = float3(_Ray_Marching_Ball_Grid_Count_X, _Ray_Marching_Ball_Grid_Count_Y, _Ray_Marching_Ball_Grid_Count_Z); d_cur = min(d_cur, map_ball_grid(p, count)); #endif #if defined(_RAY_MARCHING_OVERSTEP) d_cur *= _Ray_Marching_Overstepping_Factor; #endif d_acc += d_cur; if (abs(d_cur) < kMinDist) { break; } if (d_acc > kMaxDist) { break; } } if (abs(d_cur) > kMinDist) { discard; } // TODO clip / hit detection float3 lclPos = ro + rd * d_acc; float3 lclNorm; float3 lclTan; #if defined(_RAY_MARCHING_BALL_GRID) float3 count = float3(_Ray_Marching_Ball_Grid_Count_X, _Ray_Marching_Ball_Grid_Count_Y, _Ray_Marching_Ball_Grid_Count_Z); map_ball_grid_normal(count, lclPos, lclNorm, lclTan); #endif i.objPos = lclPos; i.normal = lclNorm; i.tangent.xyz = lclTan; } #endif // __RAY_MARCHING_INC