Browse Source

[unity] Fixed Unity 2022.2 URP Forward+ renderer additional lights rendered (culled) incorrectly. Closes #2173.

Harald Csaszar 2 years ago
parent
commit
8b06294d76

+ 1 - 1
spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Include/Spine-DepthOnlyPass-URP.hlsl

@@ -36,7 +36,7 @@ half4 DepthOnlyFragment(VaryingsSpine input) : SV_TARGET
 {
 	fixed4 texureColor = tex2D(_MainTex, input.texcoordAndAlpha.xy);
 	clip(texureColor.a * input.texcoordAndAlpha.a - _Cutoff);
-	return 0;
+	return input.positionCS.z;
 }
 
 #endif

+ 42 - 14
spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Include/Spine-SkeletonLit-ForwardPass-URP.hlsl

@@ -29,6 +29,10 @@ struct VertexOutput {
 	float4 shadowCoord : TEXCOORD1;
 	half3 shadowedColor : TEXCOORD2;
 #endif
+#if defined(_ADDITIONAL_LIGHTS) && USE_FORWARD_PLUS
+	float3 positionWS : TEXCOORD3;
+	half3 normalWS : TEXCOORD4;
+#endif
 
 	UNITY_VERTEX_OUTPUT_STEREO
 };
@@ -45,7 +49,7 @@ half3 ProcessLight(float3 positionWS, half3 normalWS, uint meshRenderingLayers,
 	return LightingLambert(attenuatedLightColor, light.direction, normalWS);
 }
 
-half3 LightweightLightVertexSimplified(float3 positionWS, float3 positionCS, half3 normalWS, out half3 shadowedColor) {
+half3 LightweightLightVertexSimplified(float3 positionWS, half3 normalWS, out half3 shadowedColor) {
 	Light mainLight = GetMainLight();
 	half3 attenuatedLightColor = mainLight.color * (mainLight.distanceAttenuation * mainLight.shadowAttenuation);
 	half3 mainLightColor = LightingLambert(attenuatedLightColor, mainLight.direction, normalWS);
@@ -55,29 +59,41 @@ half3 LightweightLightVertexSimplified(float3 positionWS, float3 positionCS, hal
 #if defined(_ADDITIONAL_LIGHTS) || defined(_ADDITIONAL_LIGHTS_VERTEX)
 	uint meshRenderingLayers = GetMeshRenderingLayerBackwardsCompatible();
 #if USE_FORWARD_PLUS
-	for (uint lightIndex = 0; lightIndex < min(_AdditionalLightsDirectionalCount, MAX_VISIBLE_LIGHTS); lightIndex++)
+	for (uint lightIndex = 0; lightIndex < min(URP_FP_DIRECTIONAL_LIGHTS_COUNT, MAX_VISIBLE_LIGHTS); lightIndex++)
 	{
+		FORWARD_PLUS_SUBTRACTIVE_LIGHT_CHECK
 		additionalLightColor += ProcessLight(positionWS, normalWS, meshRenderingLayers, lightIndex);
 	}
-#endif
+#else // !USE_FORWARD_PLUS
 	int pixelLightCount = GetAdditionalLightsCount();
-	// fill out InputData struct
-	InputData inputData; // LIGHT_LOOP_BEGIN macro requires InputData struct in USE_FORWARD_PLUS branch
-	inputData.positionWS = positionWS;
-#if defined(_ADDITIONAL_LIGHTS) && USE_FORWARD_PLUS
-	inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(positionCS);
-#else
-	inputData.normalizedScreenSpaceUV = 0;
-#endif
-
 	LIGHT_LOOP_BEGIN_SPINE(pixelLightCount)
 		additionalLightColor += ProcessLight(positionWS, normalWS, meshRenderingLayers, lightIndex);
 	LIGHT_LOOP_END_SPINE
+#endif // USE_FORWARD_PLUS
 #endif
+
 	shadowedColor = additionalLightColor;
 	return mainLightColor + additionalLightColor;
 }
 
+#if defined(_ADDITIONAL_LIGHTS) && USE_FORWARD_PLUS
+half3 LightweightLightFragmentSimplified(float3 positionWS, float2 positionCS, half3 normalWS, out half3 shadowedColor) {
+	half3 additionalLightColor = half3(0, 0, 0);
+	shadowedColor = half3(0, 0, 0);
+
+	InputData inputData; // LIGHT_LOOP_BEGIN macro requires InputData struct in USE_FORWARD_PLUS branch
+	inputData.positionWS = positionWS;
+	inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(positionCS);
+	
+	uint meshRenderingLayers = GetMeshRenderingLayerBackwardsCompatible();
+	int pixelLightCount = GetAdditionalLightsCount();
+	LIGHT_LOOP_BEGIN_SPINE(pixelLightCount)
+		additionalLightColor += ProcessLight(positionWS, normalWS, meshRenderingLayers, lightIndex);
+	LIGHT_LOOP_END_SPINE
+	return additionalLightColor;
+}
+#endif
+
 VertexOutput vert(appdata v) {
 	VertexOutput o;
 	UNITY_SETUP_INSTANCE_ID(v);
@@ -89,7 +105,6 @@ VertexOutput vert(appdata v) {
 	half3 normalWS = normalize(mul((float3x3)unity_ObjectToWorld, fixedNormal));
 	o.uv0 = v.uv0;
 	o.pos = TransformWorldToHClip(positionWS);
-	float3 positionCS = o.pos;
 
 #ifdef _DOUBLE_SIDED_LIGHTING
 	// unfortunately we have to compute the sign here in the vertex shader
@@ -99,6 +114,11 @@ VertexOutput vert(appdata v) {
 	normalWS *= faceSign;
 #endif
 
+#if defined(_ADDITIONAL_LIGHTS) && USE_FORWARD_PLUS
+	o.positionWS = positionWS;
+	o.normalWS = normalWS;
+#endif
+
 	half3 shadowedColor;
 #if !defined(_LIGHT_AFFECTS_ADDITIVE)
 	if (color.a == 0) {
@@ -111,7 +131,7 @@ VertexOutput vert(appdata v) {
 	}
 #endif // !defined(_LIGHT_AFFECTS_ADDITIVE)
 
-	color.rgb *= LightweightLightVertexSimplified(positionWS, positionCS, normalWS, shadowedColor);
+	color.rgb *= LightweightLightVertexSimplified(positionWS, normalWS, shadowedColor);
 #if defined(SKELETONLIT_RECEIVE_SHADOWS)
 	o.shadowedColor = shadowedColor;
 #endif
@@ -145,6 +165,14 @@ half4 frag(VertexOutput i
 	if (i.color.a == 0)
 		return tex * i.color;
 
+#if defined(_ADDITIONAL_LIGHTS) && USE_FORWARD_PLUS
+	// USE_FORWARD_PLUS lights need to be processed in fragment shader,
+	// otherwise light culling by vertex will create a very bad lighting result.
+	half3 shadowedColor;
+	i.color.rgb += LightweightLightFragmentSimplified(i.positionWS, i.pos, i.normalWS, shadowedColor);
+	i.shadowedColor += shadowedColor;
+#endif
+
 #if defined(SKELETONLIT_RECEIVE_SHADOWS)
 	half shadowAttenuation = MainLightRealtimeShadow(i.shadowCoord);
 	i.color.rgb = lerp(i.shadowedColor, i.color.rgb, shadowAttenuation);

+ 1 - 1
spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Include/Spine-Sprite-DepthOnlyPass-URP.hlsl

@@ -36,7 +36,7 @@ half4 DepthOnlyFragmentSprite(VaryingsSprite input) : SV_TARGET
 {
 	fixed4 texureColor = calculateTexturePixel(input.texcoordAndAlpha.xy);
 	clip(texureColor.a * input.texcoordAndAlpha.a - _Cutoff);
-	return 0;
+	return input.positionCS.z;
 }
 
 #endif

+ 6 - 10
spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Include/Spine-Sprite-ForwardPass-URP.hlsl

@@ -38,9 +38,6 @@ struct VertexOutputLWRP
 #if defined(NEEDS_POSITION_WS)
 	float4 positionWS : TEXCOORD8;
 #endif
-#if defined(_ADDITIONAL_LIGHTS)
-	float4 positionCS : TEXCOORD9;
-#endif
 
 	UNITY_VERTEX_OUTPUT_STEREO
 };
@@ -142,8 +139,9 @@ half4 LightweightFragmentPBRSimplified(InputData inputData, half4 texAlbedoAlpha
 #endif
 
 #if USE_FORWARD_PLUS
-	for (uint lightIndex = 0; lightIndex < min(_AdditionalLightsDirectionalCount, MAX_VISIBLE_LIGHTS); lightIndex++)
+	for (uint lightIndex = 0; lightIndex < min(URP_FP_DIRECTIONAL_LIGHTS_COUNT, MAX_VISIBLE_LIGHTS); lightIndex++)
 	{
+		FORWARD_PLUS_SUBTRACTIVE_LIGHT_CHECK
 		finalColor += ProcessLightPBRSimplified(inputData, brdfData, shadowMask, meshRenderingLayers, lightIndex);
 	}
 #endif
@@ -217,8 +215,9 @@ half4 LightweightFragmentBlinnPhongSimplified(InputData inputData, half4 texDiff
 	half4 shadowMask = half4(1, 1, 1, 1);
 #endif
 #if USE_FORWARD_PLUS
-	for (uint lightIndex = 0; lightIndex < min(_AdditionalLightsDirectionalCount, MAX_VISIBLE_LIGHTS); lightIndex++)
+	for (uint lightIndex = 0; lightIndex < min(URP_FP_DIRECTIONAL_LIGHTS_COUNT, MAX_VISIBLE_LIGHTS); lightIndex++)
 	{
+		FORWARD_PLUS_SUBTRACTIVE_LIGHT_CHECK
 		diffuseLighting += ProcessLightLambert(inputData, shadowMask, meshRenderingLayers, lightIndex);
 	}
 #endif
@@ -259,9 +258,6 @@ VertexOutputLWRP ForwardPassVertexSprite(VertexInput input)
 #if defined(NEEDS_POSITION_WS)
 	output.positionWS = float4(positionWS, 1);
 #endif
-#if defined(_ADDITIONAL_LIGHTS)
-	output.positionCS = output.pos;
-#endif
 
 	half3 normalWS = calculateSpriteWorldNormal(input, -backFaceSign);
 	output.normalWorld.xyz = normalWS;
@@ -329,11 +325,11 @@ half4 ForwardPassFragmentSprite(VertexOutputLWRP input
 	inputData.positionWS = input.positionWS.rgb;
 #endif
 #if defined(_ADDITIONAL_LIGHTS) && USE_FORWARD_PLUS
-	inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.positionCS);
+	inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.pos);
 #else
 	inputData.normalizedScreenSpaceUV = 0;
 #endif
-
+	
 #if defined(SPECULAR)
 	half2 metallicGloss = getMetallicGloss(input.texcoord.xy);
 	half metallic = metallicGloss.x;

+ 2 - 1
spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Spine-Skeleton-URP.shader

@@ -66,6 +66,7 @@ Shader "Universal Render Pipeline/Spine/Skeleton" {
 			Tags{"LightMode" = "ShadowCaster"}
 
 			ZWrite On
+			ColorMask 0
 			ZTest LEqual
 			Cull Off
 
@@ -103,7 +104,7 @@ Shader "Universal Render Pipeline/Spine/Skeleton" {
 			Tags{"LightMode" = "DepthOnly"}
 
 			ZWrite On
-			ColorMask 0
+			ColorMask R
 			Cull Off
 
 			HLSLPROGRAM

+ 4 - 1
spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Spine-SkeletonLit-URP.shader

@@ -48,6 +48,7 @@
 			#pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE
 			#pragma multi_compile _ _LIGHT_AFFECTS_ADDITIVE
 			// Farward+ renderer keywords
+			#pragma multi_compile_fragment _ _LIGHT_LAYERS
 			#pragma multi_compile _ _FORWARD_PLUS
 			#pragma multi_compile_fragment _ _WRITE_RENDERING_LAYERS
 
@@ -58,6 +59,7 @@
 			//--------------------------------------
 			// GPU Instancing
 			#pragma multi_compile_instancing
+			#pragma instancing_options renderinglayer
 
 			//--------------------------------------
 			// Spine related keywords
@@ -84,6 +86,7 @@
 			Tags{"LightMode" = "ShadowCaster"}
 
 			ZWrite On
+			ColorMask 0
 			ZTest LEqual
 			Cull Off
 
@@ -122,7 +125,7 @@
 			Tags{"LightMode" = "DepthOnly"}
 
 			ZWrite On
-			ColorMask 0
+			ColorMask R
 			Cull Off
 
 			HLSLPROGRAM

+ 4 - 1
spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Spine-Sprite-URP.shader

@@ -108,6 +108,7 @@ Shader "Universal Render Pipeline/Spine/Sprite"
 			#pragma multi_compile _ _SHADOWS_SOFT
 			#pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE
 			// Farward+ renderer keywords
+			#pragma multi_compile_fragment _ _LIGHT_LAYERS
 			#pragma multi_compile _ _FORWARD_PLUS
 			#pragma multi_compile_fragment _ _WRITE_RENDERING_LAYERS
 
@@ -119,6 +120,7 @@ Shader "Universal Render Pipeline/Spine/Sprite"
 			//--------------------------------------
 			// GPU Instancing
 			#pragma multi_compile_instancing
+			#pragma instancing_options renderinglayer
 
 			//--------------------------------------
 			// Spine related keywords
@@ -141,6 +143,7 @@ Shader "Universal Render Pipeline/Spine/Sprite"
 			Tags{"LightMode" = "ShadowCaster"}
 
 			ZWrite On
+			ColorMask 0
 			ZTest LEqual
 			Cull Off
 
@@ -177,7 +180,7 @@ Shader "Universal Render Pipeline/Spine/Sprite"
 			Tags{"LightMode" = "DepthOnly"}
 
 			ZWrite On
-			ColorMask 0
+			ColorMask R
 			Cull Off
 
 			HLSLPROGRAM

+ 1 - 1
spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/package.json

@@ -2,7 +2,7 @@
   "name": "com.esotericsoftware.spine.urp-shaders",
   "displayName": "Spine Universal RP Shaders",
   "description": "This plugin provides universal render pipeline (URP) shaders for the spine-unity runtime.\n\nPrerequisites:\nIt requires a working installation of the spine-unity runtime, version 4.1.\n(See http://esotericsoftware.com/git/spine-runtimes/spine-unity)",
-  "version": "4.1.6",
+  "version": "4.1.7",
   "unity": "2019.3",
   "author": {
     "name": "Esoteric Software",