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.
117 lines
4.3 KiB
117 lines
4.3 KiB
#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
|
|
|