Rasagar/Library/PackageCache/com.unity.render-pipelines.universal/ShaderLibrary/LightCookie/LightCookie.hlsl
2024-08-26 23:07:20 +03:00

118 lines
4.3 KiB
HLSL

#ifndef UNIVERSAL_LIGHT_COOKIE_INCLUDED
#define UNIVERSAL_LIGHT_COOKIE_INCLUDED
// Includes
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LightCookie/LightCookieInput.hlsl"
#if defined(_LIGHT_COOKIES)
#ifndef REQUIRES_WORLD_SPACE_POS_INTERPOLATOR
#define REQUIRES_WORLD_SPACE_POS_INTERPOLATOR 1
#endif
#endif
float2 ComputeLightCookieUVDirectional(float4x4 worldToLight, float3 samplePositionWS, float4 atlasUVRect, uint2 uvWrap)
{
// Translate and rotate 'positionWS' into the light space.
// Project point to light "view" plane, i.e. discard Z.
float2 positionLS = mul(worldToLight, float4(samplePositionWS, 1)).xy;
// Remap [-1, 1] to [0, 1]
// (implies the transform has ortho projection mapping world space box to [-1, 1])
float2 positionUV = positionLS * 0.5 + 0.5;
// Tile texture for cookie in repeat mode
positionUV.x = (uvWrap.x == URP_TEXTURE_WRAP_MODE_REPEAT) ? frac(positionUV.x) : positionUV.x;
positionUV.y = (uvWrap.y == URP_TEXTURE_WRAP_MODE_REPEAT) ? frac(positionUV.y) : positionUV.y;
positionUV.x = (uvWrap.x == URP_TEXTURE_WRAP_MODE_CLAMP) ? saturate(positionUV.x) : positionUV.x;
positionUV.y = (uvWrap.y == URP_TEXTURE_WRAP_MODE_CLAMP) ? saturate(positionUV.y) : positionUV.y;
// Remap to atlas texture
float2 positionAtlasUV = atlasUVRect.xy * float2(positionUV) + atlasUVRect.zw;
return positionAtlasUV;
}
float2 ComputeLightCookieUVSpot(float4x4 worldToLightPerspective, float3 samplePositionWS, float4 atlasUVRect)
{
// Translate, rotate and project 'positionWS' into the light clip space.
float4 positionCS = mul(worldToLightPerspective, float4(samplePositionWS, 1));
float2 positionNDC = positionCS.xy / positionCS.w;
// Remap NDC to the texture coordinates, from NDC [-1, 1]^2 to [0, 1]^2.
float2 positionUV = saturate(positionNDC * 0.5 + 0.5);
// Remap into rect in the atlas texture
float2 positionAtlasUV = atlasUVRect.xy * float2(positionUV) + atlasUVRect.zw;
return positionAtlasUV;
}
float2 ComputeLightCookieUVPoint(float4x4 worldToLight, float3 samplePositionWS, float4 atlasUVRect)
{
// Translate and rotate 'positionWS' into the light space.
float4 positionLS = mul(worldToLight, float4(samplePositionWS, 1));
float3 sampleDirLS = normalize(positionLS.xyz / positionLS.w);
// Project direction to Octahederal quad UV.
float2 positionUV = saturate(PackNormalOctQuadEncode(sampleDirLS) * 0.5 + 0.5);
// Remap to atlas texture
float2 positionAtlasUV = atlasUVRect.xy * float2(positionUV) + atlasUVRect.zw;
return positionAtlasUV;
}
real3 SampleMainLightCookie(float3 samplePositionWS)
{
if(!IsMainLightCookieEnabled())
return real3(1,1,1);
float2 uv = ComputeLightCookieUVDirectional(_MainLightWorldToLight, samplePositionWS, float4(1, 1, 0, 0), URP_TEXTURE_WRAP_MODE_NONE);
real4 color = SampleMainLightCookieTexture(uv);
return IsMainLightCookieTextureRGBFormat() ? color.rgb
: IsMainLightCookieTextureAlphaFormat() ? color.aaa
: color.rrr;
}
real3 SampleAdditionalLightCookie(int perObjectLightIndex, float3 samplePositionWS)
{
if(!IsLightCookieEnabled(perObjectLightIndex))
return real3(1,1,1);
int lightType = GetLightCookieLightType(perObjectLightIndex);
int isSpot = lightType == URP_LIGHT_TYPE_SPOT;
int isDirectional = lightType == URP_LIGHT_TYPE_DIRECTIONAL;
float4x4 worldToLight = GetLightCookieWorldToLightMatrix(perObjectLightIndex);
float4 uvRect = GetLightCookieAtlasUVRect(perObjectLightIndex);
float2 uv;
if(isSpot)
{
uv = ComputeLightCookieUVSpot(worldToLight, samplePositionWS, uvRect);
}
else if(isDirectional)
{
uv = ComputeLightCookieUVDirectional(worldToLight, samplePositionWS, uvRect, URP_TEXTURE_WRAP_MODE_REPEAT);
}
else
{
uv = ComputeLightCookieUVPoint(worldToLight, samplePositionWS, uvRect);
}
real4 color = SampleAdditionalLightsCookieAtlasTexture(uv);
return IsAdditionalLightsCookieAtlasTextureRGBFormat() ? color.rgb
: IsAdditionalLightsCookieAtlasTextureAlphaFormat() ? color.aaa
: color.rrr;
}
#endif //UNIVERSAL_LIGHT_COOKIE_INCLUDED