Rasagar/Library/PackageCache/com.unity.render-pipelines.universal/Shaders/2D/Include/LightingUtility.hlsl
2024-08-26 23:07:20 +03:00

205 lines
8.5 KiB
HLSL

// Must match: LightBatch.isBatchingSupported
#define USE_STRUCTURED_BUFFER_FOR_LIGHT2D_DATA 0
#if USE_NORMAL_MAP
#if LIGHT_QUALITY_FAST
#define NORMALS_LIGHTING_COORDS(TEXCOORDA, TEXCOORDB) \
half4 lightDirection : TEXCOORDA;\
half2 screenUV : TEXCOORDB;
#define TRANSFER_NORMALS_LIGHTING(output, worldSpacePos, lightPosition, lightZDistance)\
output.screenUV = ComputeNormalizedDeviceCoordinates(output.positionCS.xyz / output.positionCS.w);\
half3 planeNormal = -GetViewForwardDir();\
half3 projLightPos = lightPosition.xyz - (dot(lightPosition.xyz - worldSpacePos.xyz, planeNormal) - lightZDistance) * planeNormal;\
output.lightDirection.xyz = projLightPos - worldSpacePos.xyz;\
output.lightDirection.w = 0;
#define APPLY_NORMALS_LIGHTING(input, lightColor, lightPosition, lightZDistance)\
half4 normal = SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, input.screenUV);\
half3 normalUnpacked = UnpackNormalRGBNoScale(normal);\
half3 dirToLight = normalize(input.lightDirection.xyz);\
lightColor = lightColor * saturate(dot(dirToLight, normalUnpacked));
#else
#define NORMALS_LIGHTING_COORDS(TEXCOORDA, TEXCOORDB) \
half4 positionWS : TEXCOORDA;\
half2 screenUV : TEXCOORDB;
#define TRANSFER_NORMALS_LIGHTING(output, worldSpacePos, lightPosition, lightZDistance) \
output.screenUV = ComputeNormalizedDeviceCoordinates(output.positionCS.xyz / output.positionCS.w); \
output.positionWS = worldSpacePos;
#define APPLY_NORMALS_LIGHTING(input, lightColor, lightPosition, lightZDistance)\
half4 normal = SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, input.screenUV);\
half3 normalUnpacked = UnpackNormalRGBNoScale(normal);\
half3 planeNormal = -GetViewForwardDir();\
half3 projLightPos = lightPosition.xyz - (dot(lightPosition.xyz - input.positionWS.xyz, planeNormal) - lightZDistance) * planeNormal;\
half3 dirToLight = normalize(projLightPos - input.positionWS.xyz);\
lightColor = lightColor * saturate(dot(dirToLight, normalUnpacked));
#endif
#define NORMALS_LIGHTING_VARIABLES \
TEXTURE2D(_NormalMap); \
SAMPLER(sampler_NormalMap);
#else
#define NORMALS_LIGHTING_COORDS(TEXCOORDA, TEXCOORDB)
#define NORMALS_LIGHTING_VARIABLES
#define TRANSFER_NORMALS_LIGHTING(output, worldSpacePos, lightPosition, lightZDistance)
#define APPLY_NORMALS_LIGHTING(input, lightColor, lightPosition, lightZDistance)
#endif
#define SHADOW_COORDS(TEXCOORDA)\
float2 shadowUV : TEXCOORDA;
#define SHADOW_VARIABLES\
TEXTURE2D(_ShadowTex);\
SAMPLER(sampler_ShadowTex);
// Need to look at shadow caster to remove issue with shadows
#define APPLY_SHADOWS(input, color, intensity)\
if(intensity < 1)\
{\
half4 shadowTex = SAMPLE_TEXTURE2D(_ShadowTex, sampler_ShadowTex, input.shadowUV); \
half shadowFinalValue = dot(half4(1,0,0,0), shadowTex.rgba);\
half unshadowValue = dot(half4(0,1,0,0), shadowTex.rgba);\
half unshadowGTEOne = unshadowValue > 1;\
half spriteAlpha = dot(half4(0,0,1,0), shadowTex.rgba);\
half unshadowFinalValue = unshadowGTEOne * (unshadowValue - (1-spriteAlpha)) + (1-unshadowGTEOne) * (unshadowValue * spriteAlpha);\
half shadowIntensity = 1-saturate(shadowFinalValue - unshadowFinalValue); \
color.rgb = (color.rgb * shadowIntensity) + (color.rgb * intensity*(1 - shadowIntensity));\
}
#define TRANSFER_SHADOWS(output)\
output.shadowUV = ComputeNormalizedDeviceCoordinates(output.positionCS.xyz / output.positionCS.w);
#define SHAPE_LIGHT(index)\
TEXTURE2D(_ShapeLightTexture##index);\
SAMPLER(sampler_ShapeLightTexture##index);\
half2 _ShapeLightBlendFactors##index;\
half4 _ShapeLightMaskFilter##index;\
half4 _ShapeLightInvertedFilter##index;
#if !defined(USE_SHAPE_LIGHT_TYPE_0) && !defined(USE_SHAPE_LIGHT_TYPE_1) && !defined(USE_SHAPE_LIGHT_TYPE_2) && !defined(USE_SHAPE_LIGHT_TYPE_3)
#define USE_DEFAULT_LIGHT_TYPE 1
#endif
struct FragmentOutput
{
#if USE_SHAPE_LIGHT_TYPE_0 || USE_DEFAULT_LIGHT_TYPE
half4 GLightBuffer0 : SV_Target0;
#endif
#if USE_SHAPE_LIGHT_TYPE_1
half4 GLightBuffer1 : SV_Target1;
#endif
#if USE_SHAPE_LIGHT_TYPE_2
half4 GLightBuffer2 : SV_Target2;
#endif
#if USE_SHAPE_LIGHT_TYPE_3
half4 GLightBuffer3 : SV_Target3;
#endif
};
FragmentOutput ToFragmentOutput(half4 finalColor)
{
FragmentOutput output;
#if USE_SHAPE_LIGHT_TYPE_0 || USE_DEFAULT_LIGHT_TYPE
output.GLightBuffer0 = finalColor;
#endif
#if USE_SHAPE_LIGHT_TYPE_1
output.GLightBuffer1 = finalColor;
#endif
#if USE_SHAPE_LIGHT_TYPE_2
output.GLightBuffer2 = finalColor;
#endif
#if USE_SHAPE_LIGHT_TYPE_3
output.GLightBuffer3 = finalColor;
#endif
return output;
}
#define LIGHT_OFFSET(TEXCOORD)\
float4 lightOffset : TEXCOORD;
// Light-Batcher mapping for Reference.
// OuterAngle; // 1-0 where 1 is the value at 0 degrees and 1 is the value at 180 degrees
// InnerAngle; // 1-0 where 1 is the value at 0 degrees and 1 is the value at 180 degrees
// InnerRadiusMult; // 1-0 where 1 is the value at the center and 0 is the value at the outer radius
// Note: IsFullSpotlight // Is no longer fed but deduced within the shader. Value basically is test for InnerAngle = 1.0f
// Likewise InnerAngleMult is also deduced and is basically 1 / (Outer - Inner)
// Position.xyz => _LightPosition
// Position.w => _LightZDistance
// ShadowIntensity => In case of Volumetric Lighting this represents ShadowVolumeIntensity
struct PerLight2D
{
float4x4 InvMatrix;
float4 Color;
float4 Position;
float FalloffIntensity;
float FalloffDistance;
float OuterAngle;
float InnerAngle;
float InnerRadiusMult;
float VolumeOpacity;
float ShadowIntensity;
int LightType;
};
#if USE_STRUCTURED_BUFFER_FOR_LIGHT2D_DATA
#define UNITY_LIGHT2D_DATA \
\
uniform StructuredBuffer<PerLight2D> _Light2DBuffer; \
\
int _BatchBufferOffset; \
\
PerLight2D GetPerLight2D(float4 color) \
{ \
int idx = (int)(color.b * 64) + _BatchBufferOffset; \
return _Light2DBuffer[idx]; \
}
#define _L2D_INVMATRIX light.InvMatrix
#define _L2D_COLOR light.Color
#define _L2D_POSITION light.Position
#define _L2D_FALLOFF_INTENSITY light.FalloffIntensity
#define _L2D_FALLOFF_DISTANCE light.FalloffDistance
#define _L2D_OUTER_ANGLE light.OuterAngle
#define _L2D_INNER_ANGLE light.InnerAngle
#define _L2D_INNER_RADIUS_MULT light.InnerRadiusMult
#define _L2D_VOLUME_OPACITY light.VolumeOpacity
#define _L2D_SHADOW_INTENSITY light.ShadowIntensity
#define _L2D_LIGHT_TYPE light.LightType
#else
#define UNITY_LIGHT2D_DATA \
\
float4x4 L2DInvMatrix; \
float4 L2DColor; \
float4 L2DPosition; \
float L2DFalloffIntensity; \
float L2DFalloffDistance; \
float L2DOuterAngle; \
float L2DInnerAngle; \
float L2DInnerRadiusMult; \
float L2DVolumeOpacity; \
float L2DShadowIntensity; \
int L2DLightType; \
#define _L2D_INVMATRIX L2DInvMatrix
#define _L2D_COLOR L2DColor
#define _L2D_POSITION L2DPosition
#define _L2D_FALLOFF_INTENSITY L2DFalloffIntensity
#define _L2D_FALLOFF_DISTANCE L2DFalloffDistance
#define _L2D_OUTER_ANGLE L2DOuterAngle
#define _L2D_INNER_ANGLE L2DInnerAngle
#define _L2D_INNER_RADIUS_MULT L2DInnerRadiusMult
#define _L2D_VOLUME_OPACITY L2DVolumeOpacity
#define _L2D_SHADOW_INTENSITY L2DShadowIntensity
#define _L2D_LIGHT_TYPE L2DLightType
#endif