// 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;\ float2 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;\ float2 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 _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