189 lines
7.0 KiB
HLSL
189 lines
7.0 KiB
HLSL
#ifndef UNITY_RAYTRACING_INTERSECTION_INCLUDED
|
|
#define UNITY_RAYTRACING_INTERSECTION_INCLUDED
|
|
|
|
// Engine includes
|
|
#include "UnityRayTracingMeshUtils.cginc"
|
|
|
|
// Raycone structure that defines the stateof the ray
|
|
struct RayCone
|
|
{
|
|
float width;
|
|
float spreadAngle;
|
|
};
|
|
|
|
// Structure that defines the current state of the intersection
|
|
struct RayIntersection
|
|
{
|
|
// Origin of the current ray -- FIXME: can be obtained by WorldRayPosition(), should we remove it?
|
|
float3 origin;
|
|
// Direction of the current ray -- FIXME: can be obtained by WorldRayDirection(), should we remove it?
|
|
float3 incidentDirection;
|
|
// Distance of the intersection
|
|
float t;
|
|
// Value that holds the color of the ray
|
|
float3 color;
|
|
// Cone representation of the ray
|
|
RayCone cone;
|
|
// The remaining available depth for the current Ray
|
|
uint remainingDepth;
|
|
// Current sample index
|
|
uint sampleIndex;
|
|
// Ray counter (used for multibounce)
|
|
uint rayCount;
|
|
// Pixel coordinate from which the initial ray was launched
|
|
uint2 pixelCoord;
|
|
// Velocity for the intersection point
|
|
float velocity;
|
|
};
|
|
|
|
struct AttributeData
|
|
{
|
|
// Barycentric value of the intersection
|
|
float2 barycentrics;
|
|
};
|
|
|
|
// Macro that interpolate any attribute using barycentric coordinates
|
|
#define INTERPOLATE_RAYTRACING_ATTRIBUTE(A0, A1, A2, BARYCENTRIC_COORDINATES) (A0 * BARYCENTRIC_COORDINATES.x + A1 * BARYCENTRIC_COORDINATES.y + A2 * BARYCENTRIC_COORDINATES.z)
|
|
|
|
// Structure to fill for intersections
|
|
struct IntersectionVertex
|
|
{
|
|
// Object space normal of the vertex
|
|
float3 normalOS;
|
|
// Object space tangent of the vertex
|
|
float4 tangentOS;
|
|
// UV coordinates
|
|
float4 texCoord0;
|
|
float4 texCoord1;
|
|
float4 texCoord2;
|
|
float4 texCoord3;
|
|
float4 color;
|
|
|
|
#ifdef USE_RAY_CONE_LOD
|
|
// Value used for LOD sampling
|
|
float triangleArea;
|
|
float texCoord0Area;
|
|
float texCoord1Area;
|
|
float texCoord2Area;
|
|
float texCoord3Area;
|
|
#endif
|
|
};
|
|
|
|
// Fetch the intersetion vertex data for the target vertex
|
|
void FetchIntersectionVertex(uint vertexIndex, out IntersectionVertex outVertex)
|
|
{
|
|
outVertex.normalOS = UnityRayTracingFetchVertexAttribute3(vertexIndex, kVertexAttributeNormal);
|
|
|
|
#ifdef ATTRIBUTES_NEED_TANGENT
|
|
outVertex.tangentOS = UnityRayTracingFetchVertexAttribute4(vertexIndex, kVertexAttributeTangent);
|
|
#else
|
|
outVertex.tangentOS = 0.0;
|
|
#endif
|
|
|
|
#ifdef ATTRIBUTES_NEED_TEXCOORD0
|
|
outVertex.texCoord0 = UnityRayTracingFetchVertexAttribute4(vertexIndex, kVertexAttributeTexCoord0);
|
|
#else
|
|
outVertex.texCoord0 = 0.0;
|
|
#endif
|
|
|
|
#ifdef ATTRIBUTES_NEED_TEXCOORD1
|
|
outVertex.texCoord1 = UnityRayTracingFetchVertexAttribute4(vertexIndex, kVertexAttributeTexCoord1);
|
|
#else
|
|
outVertex.texCoord1 = 0.0;
|
|
#endif
|
|
|
|
#ifdef ATTRIBUTES_NEED_TEXCOORD2
|
|
outVertex.texCoord2 = UnityRayTracingFetchVertexAttribute4(vertexIndex, kVertexAttributeTexCoord2);
|
|
#else
|
|
outVertex.texCoord2 = 0.0;
|
|
#endif
|
|
|
|
#ifdef ATTRIBUTES_NEED_TEXCOORD3
|
|
outVertex.texCoord3 = UnityRayTracingFetchVertexAttribute4(vertexIndex, kVertexAttributeTexCoord3);
|
|
#else
|
|
outVertex.texCoord3 = 0.0;
|
|
#endif
|
|
|
|
#ifdef ATTRIBUTES_NEED_COLOR
|
|
outVertex.color = UnityRayTracingFetchVertexAttribute4(vertexIndex, kVertexAttributeColor);
|
|
#else
|
|
outVertex.color = 0.0;
|
|
#endif
|
|
}
|
|
|
|
void GetCurrentIntersectionVertex(AttributeData attributeData, out IntersectionVertex outVertex)
|
|
{
|
|
// Fetch the indices of the currentr triangle
|
|
uint3 triangleIndices = UnityRayTracingFetchTriangleIndices(PrimitiveIndex());
|
|
|
|
// Fetch the 3 vertices
|
|
IntersectionVertex v0, v1, v2;
|
|
FetchIntersectionVertex(triangleIndices.x, v0);
|
|
FetchIntersectionVertex(triangleIndices.y, v1);
|
|
FetchIntersectionVertex(triangleIndices.z, v2);
|
|
|
|
// Compute the full barycentric coordinates
|
|
float3 barycentricCoordinates = float3(1.0 - attributeData.barycentrics.x - attributeData.barycentrics.y, attributeData.barycentrics.x, attributeData.barycentrics.y);
|
|
|
|
// Interpolate all the data
|
|
outVertex.normalOS = INTERPOLATE_RAYTRACING_ATTRIBUTE(v0.normalOS, v1.normalOS, v2.normalOS, barycentricCoordinates);
|
|
|
|
#ifdef ATTRIBUTES_NEED_TANGENT
|
|
outVertex.tangentOS = INTERPOLATE_RAYTRACING_ATTRIBUTE(v0.tangentOS, v1.tangentOS, v2.tangentOS, barycentricCoordinates);
|
|
#else
|
|
outVertex.tangentOS = 0.0;
|
|
#endif
|
|
|
|
#ifdef ATTRIBUTES_NEED_TEXCOORD0
|
|
outVertex.texCoord0 = INTERPOLATE_RAYTRACING_ATTRIBUTE(v0.texCoord0, v1.texCoord0, v2.texCoord0, barycentricCoordinates);
|
|
#else
|
|
outVertex.texCoord0 = 0.0;
|
|
#endif
|
|
|
|
#ifdef ATTRIBUTES_NEED_TEXCOORD1
|
|
outVertex.texCoord1 = INTERPOLATE_RAYTRACING_ATTRIBUTE(v0.texCoord1, v1.texCoord1, v2.texCoord1, barycentricCoordinates);
|
|
#else
|
|
outVertex.texCoord1 = 0.0;
|
|
#endif
|
|
|
|
#ifdef ATTRIBUTES_NEED_TEXCOORD2
|
|
outVertex.texCoord2 = INTERPOLATE_RAYTRACING_ATTRIBUTE(v0.texCoord2, v1.texCoord2, v2.texCoord2, barycentricCoordinates);
|
|
#else
|
|
outVertex.texCoord2 = 0.0;
|
|
#endif
|
|
|
|
#ifdef ATTRIBUTES_NEED_TEXCOORD3
|
|
outVertex.texCoord3 = INTERPOLATE_RAYTRACING_ATTRIBUTE(v0.texCoord3, v1.texCoord3, v2.texCoord3, barycentricCoordinates);
|
|
#else
|
|
outVertex.texCoord3 = 0.0;
|
|
#endif
|
|
|
|
#ifdef ATTRIBUTES_NEED_COLOR
|
|
outVertex.color = INTERPOLATE_RAYTRACING_ATTRIBUTE(v0.color, v1.color, v2.color, barycentricCoordinates);
|
|
#else
|
|
outVertex.color = 0.0;
|
|
#endif
|
|
|
|
#ifdef USE_RAY_CONE_LOD
|
|
// Compute the lambda value (area computed in object space)
|
|
outVertex.triangleArea = length(cross(v1.positionOS - v0.positionOS, v2.positionOS - v0.positionOS));
|
|
outVertex.texCoord0Area = abs((v1.texCoord0.x - v0.texCoord0.x) * (v2.texCoord0.y - v0.texCoord0.y) - (v2.texCoord0.x - v0.texCoord0.x) * (v1.texCoord0.y - v0.texCoord0.y));
|
|
outVertex.texCoord1Area = abs((v1.texCoord1.x - v0.texCoord1.x) * (v2.texCoord1.y - v0.texCoord1.y) - (v2.texCoord1.x - v0.texCoord1.x) * (v1.texCoord1.y - v0.texCoord1.y));
|
|
outVertex.texCoord2Area = abs((v1.texCoord2.x - v0.texCoord2.x) * (v2.texCoord2.y - v0.texCoord2.y) - (v2.texCoord2.x - v0.texCoord2.x) * (v1.texCoord2.y - v0.texCoord2.y));
|
|
outVertex.texCoord3Area = abs((v1.texCoord3.x - v0.texCoord3.x) * (v2.texCoord3.y - v0.texCoord3.y) - (v2.texCoord3.x - v0.texCoord3.x) * (v1.texCoord3.y - v0.texCoord3.y));
|
|
#endif
|
|
}
|
|
|
|
// Compute the proper world space geometric normal from the intersected triangle
|
|
void GetCurrentIntersectionGeometricNormal(AttributeData attributeData, out float3 geomNormalWS)
|
|
{
|
|
uint3 triangleIndices = UnityRayTracingFetchTriangleIndices(PrimitiveIndex());
|
|
float3 p0 = UnityRayTracingFetchVertexAttribute3(triangleIndices.x, kVertexAttributePosition);
|
|
float3 p1 = UnityRayTracingFetchVertexAttribute3(triangleIndices.y, kVertexAttributePosition);
|
|
float3 p2 = UnityRayTracingFetchVertexAttribute3(triangleIndices.z, kVertexAttributePosition);
|
|
|
|
geomNormalWS = normalize(mul(cross(p1 - p0, p2 - p0), (float3x3)WorldToObject3x4()));
|
|
}
|
|
|
|
#endif // UNITY_RAYTRACING_INTERSECTION_INCLUDED
|