93 lines
3.0 KiB
HLSL
93 lines
3.0 KiB
HLSL
#ifndef XRA_RAYMARCH_TEX3D
|
|
#define XRA_RAYMARCH_TEX3D
|
|
|
|
SamplerState sdfr_sampler_linear_clamp;
|
|
SamplerState sdfr_sampler_trilinear_clamp;
|
|
|
|
struct SDFrVolumeData
|
|
{
|
|
float4x4 WorldToLocal;
|
|
float3 Extents;
|
|
};
|
|
|
|
|
|
|
|
|
|
inline float2 LineAABBIntersect(float3 ro, float3 re, float3 aabbMin, float3 aabbMax)
|
|
{
|
|
float3 invRd = 1.0 / (re - ro);
|
|
float3 mini = invRd * (aabbMin - ro);
|
|
float3 maxi = invRd * (aabbMax - ro);
|
|
float3 closest = min(mini, maxi);
|
|
float3 furthest = max(mini, maxi);
|
|
|
|
float2 intersections;
|
|
//furthest near intersection
|
|
intersections.x = max(closest.x, max(closest.y, closest.z));
|
|
//closest far intersection
|
|
intersections.y = min(furthest.x, min(furthest.y, furthest.z));
|
|
//map 0 ray origin, 1 ray end
|
|
return saturate(intersections);
|
|
}
|
|
|
|
//incoming ray is world space
|
|
inline float DistanceFunctionTex3D( in float3 rayPosWS, in float3 rayOrigin, in float3 rayEnd, in SDFrVolumeData data, in Texture3D tex )
|
|
{
|
|
float4x4 w2l = data.WorldToLocal;
|
|
float3 extents = data.Extents;
|
|
|
|
//take ray to local space of bounds (now the bounds is axis-aligned relative to the ray)
|
|
float3 originLocal = mul(w2l,float4(rayOrigin,1)).xyz;
|
|
float3 endLocal = mul(w2l,float4(rayEnd,1)).xyz;
|
|
|
|
float2 intersection = LineAABBIntersect(originLocal, endLocal, -extents, extents);
|
|
|
|
//if the ray intersects
|
|
if ( intersection.x < intersection.y && intersection.x < 1 )
|
|
{
|
|
float3 rayPosLocal = mul(w2l,float4(rayPosWS,1)).xyz;
|
|
rayPosLocal /= extents.xyz*2;
|
|
rayPosLocal += 0.5; //texture space
|
|
//values are -1 to 1
|
|
float sample = tex.SampleLevel( sdfr_sampler_linear_clamp, rayPosLocal, 0 ).r;
|
|
sample *= length(extents); //scale by magnitude of bound extent -- NC: Should this by times 2 as extents is halfsize?
|
|
return sample;
|
|
}
|
|
//TODO not really consistent
|
|
return distance(rayOrigin,rayEnd);
|
|
}
|
|
|
|
inline float DistanceFunctionTex3DFast(in float3 rayPosWS, in SDFrVolumeData data, in Texture3D tex)
|
|
{
|
|
float4x4 w2l = data.WorldToLocal;
|
|
float3 extents = data.Extents;
|
|
|
|
float3 rayPosLocal = mul(w2l, float4(rayPosWS, 1)).xyz;
|
|
rayPosLocal /= extents.xyz * 2;
|
|
rayPosLocal += 0.5; //texture space
|
|
//values are -1 to 1
|
|
float sample = tex.SampleLevel(sdfr_sampler_linear_clamp, rayPosLocal, 0).r;
|
|
sample *= length(extents); //scale by magnitude of bound extent
|
|
return sample;
|
|
}
|
|
|
|
|
|
// Find the min distance to AABB
|
|
inline float DistanceToAABB(in float3 rayOrigin, in float3 rayEnd, in SDFrVolumeData data)
|
|
{
|
|
float4x4 w2l = data.WorldToLocal;
|
|
float3 extents = data.Extents;
|
|
|
|
//take ray to local space of bounds (now the bounds is axis-aligned relative to the ray)
|
|
float3 originLocal = mul(w2l, float4(rayOrigin, 1)).xyz;
|
|
float3 endLocal = mul(w2l, float4(rayEnd, 1)).xyz;
|
|
|
|
float2 intersection = LineAABBIntersect(originLocal, endLocal, -extents, extents);
|
|
|
|
if (intersection.x < intersection.y && intersection.x < 1)
|
|
{
|
|
return intersection.x * distance(rayOrigin, rayEnd);
|
|
}
|
|
return distance(rayOrigin, rayEnd);
|
|
}
|
|
#endif |