You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
82 lines
3.3 KiB
82 lines
3.3 KiB
#ifndef RAY_TRACING_SHADOW_UTILITIES_H_
|
|
#define RAY_TRACING_SHADOW_UTILITIES_H_
|
|
|
|
// Constant buffer that holds all scalar that we need
|
|
CBUFFER_START(RayTracingShadowUtilitiesConstantBuffer)
|
|
uint _RaytracingTargetLight;
|
|
float _RaytracingLightRadius;
|
|
float _RaytracingLightAngle;
|
|
float _RaytracingLightSizeX;
|
|
float _RaytracingLightSizeY;
|
|
int _RaytracingShadowSlot;
|
|
|
|
float4 _RaytracingChannelMask;
|
|
float4 _RaytracingChannelMask0;
|
|
float4 _RaytracingChannelMask1;
|
|
CBUFFER_END
|
|
|
|
// The various cases for shadow rays (spot and point)
|
|
#define POINT_VALID_DIR_PDF 1.0
|
|
#define POINT_WHITE_PDF -1.0
|
|
#define POINT_BLACK_PDF -2.0
|
|
#define POINT_BACK_FACE_PDF -3.0
|
|
|
|
float DistSqrToLight(LightData lightData, float3 positionWS)
|
|
{
|
|
// If the point is inside the spherical range, it will be visible
|
|
float3 dir = (lightData.positionRWS - positionWS);
|
|
return dot(dir, dir);
|
|
}
|
|
|
|
bool PositionInSpotRange(LightData lightData, float spotAngle, float3 positionWS, float dist2)
|
|
{
|
|
// Is the light inside the range of the light?
|
|
bool pointInsideRange = dist2 < (lightData.range * lightData.range);
|
|
|
|
// If the direction is going out of the cone, we invalidate this ray (to avoid casting useless rays)
|
|
// We need to use the direction towards the cone origin for culling, not the sampled point on the light
|
|
float3 relativePosition = positionWS - lightData.positionRWS;
|
|
float3 cullingDirection = normalize(relativePosition);
|
|
bool pointInsideCone = dot(cullingDirection, lightData.forward) > cos(0.5f * spotAngle);
|
|
|
|
return pointInsideRange && pointInsideCone;
|
|
}
|
|
|
|
bool PositionInPyramidRange(LightData lightData, float spotAngleX, float spotAngleY, float3 positionWS, float dist2)
|
|
{
|
|
// Is the light inside the range of the light?
|
|
bool pointInsideRange = dist2 < (lightData.range * lightData.range);
|
|
|
|
// If the direction is going out of the cone, we invalidate this ray (to avoid casting useless rays)
|
|
float3 relativePosition = positionWS - lightData.positionRWS;
|
|
|
|
float3 lightX = normalize(lightData.right);
|
|
float3 lightY = normalize(lightData.up);
|
|
float3 cullingDirectionX = normalize(relativePosition - dot(relativePosition, lightY) * lightY);
|
|
float3 cullingDirectionY = normalize(relativePosition - dot(relativePosition, lightX) * lightX);
|
|
|
|
bool pointInsidePyramid = dot(cullingDirectionX, lightData.forward) > cos(0.5f * spotAngleX) &&
|
|
dot(cullingDirectionY, lightData.forward) > cos(0.5f * spotAngleY);
|
|
|
|
return pointInsideRange && pointInsidePyramid;
|
|
}
|
|
|
|
bool PositionInBoxRange(LightData lightData, float sizeX, float sizeY, float3 positionWS, float dist2)
|
|
{
|
|
// Is the light inside the range of the light?
|
|
bool pointInsideRange = dist2 < (lightData.range * lightData.range);
|
|
|
|
// If the position is outside of the box light shaft, we invalidate this ray (to avoid casting useless rays)
|
|
float3 relativePosition = positionWS - lightData.positionRWS;
|
|
bool pointInsideBox = abs(dot(relativePosition, normalize(lightData.right))) < 0.5f * sizeX &&
|
|
abs(dot(relativePosition, normalize(lightData.up))) < 0.5f * sizeY;
|
|
|
|
return pointInsideRange && pointInsideBox;
|
|
}
|
|
|
|
bool PositionInPointRange(LightData lightData, float dist2)
|
|
{
|
|
return dist2 < (lightData.range * lightData.range);
|
|
}
|
|
|
|
#endif // RAY_TRACING_SHADOW_UTILITIES_H_
|