602 lines
19 KiB
HLSL
602 lines
19 KiB
HLSL
#ifndef BADDOG_AREA_SPINE_LIT_PASSES_INCLUDED
|
|
#define BADDOG_AREA_SPINE_LIT_PASSES_INCLUDED
|
|
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
|
|
|
|
#undef LIGHTMAP_ON
|
|
|
|
CBUFFER_START(UnityPerMaterial)
|
|
float4 _MainTex_ST;
|
|
half _Cutoff;
|
|
half4 _Color;
|
|
half4 _Black;
|
|
CBUFFER_END
|
|
|
|
sampler2D _MainTex;
|
|
|
|
inline half3 BGSpine_GammaToTargetSpace(half3 gammaColor)
|
|
{
|
|
#if UNITY_COLORSPACE_GAMMA
|
|
return gammaColor;
|
|
#else
|
|
return SRGBToLinear(gammaColor);
|
|
#endif
|
|
}
|
|
|
|
inline half4 BGSpine_PMAGammaToTargetSpace(half4 gammaPMAColor)
|
|
{
|
|
#if UNITY_COLORSPACE_GAMMA
|
|
return gammaPMAColor;
|
|
#else
|
|
return gammaPMAColor.a == 0
|
|
? half4(SRGBToLinear(gammaPMAColor.rgb), gammaPMAColor.a)
|
|
: half4(SRGBToLinear(gammaPMAColor.rgb / gammaPMAColor.a) * gammaPMAColor.a, gammaPMAColor.a);
|
|
#endif
|
|
}
|
|
|
|
float4 BGSpine_fragTintedColor(float4 texColor, float3 darkTintColor, float4 lightTintColorPMA, float lightColorAlpha, float darkColorAlpha)
|
|
{
|
|
float a = texColor.a * lightTintColorPMA.a;
|
|
|
|
#if !defined(_STRAIGHT_ALPHA_INPUT)
|
|
float3 texDarkColor = texColor.a - texColor.rgb;
|
|
#else
|
|
float3 texDarkColor = (1 - texColor.rgb);
|
|
#endif
|
|
float3 darkColor = texDarkColor * darkTintColor.rgb * lightColorAlpha;
|
|
float3 lightColor = texColor.rgb * lightTintColorPMA.rgb;
|
|
|
|
float4 fragColor = float4(darkColor + lightColor, a);
|
|
#if defined(_STRAIGHT_ALPHA_INPUT)
|
|
fragColor.rgb *= texColor.a;
|
|
#endif
|
|
|
|
#if defined(_DARK_COLOR_ALPHA_ADDITIVE)
|
|
fragColor.a = a * (1 - darkColorAlpha);
|
|
#endif
|
|
return fragColor;
|
|
}
|
|
|
|
#if defined(_WRITE_RENDERING_LAYERS) || defined(_LIGHT_LAYERS)
|
|
uint BGSpine_GetMeshRenderingLayerBackwardsCompatible()
|
|
{
|
|
// URP 14+ exposes GetMeshRenderingLayer(). Older: GetMeshRenderingLightLayer().
|
|
// We prefer the 14+ API when present.
|
|
#if defined(SHADER_API_GLES) || defined(SHADER_API_GLES3)
|
|
// No reliable version macro on all targets; best-effort fallback.
|
|
return 0;
|
|
#else
|
|
#if defined(UNIVERSAL_REALTIME_LIGHTS_INCLUDED)
|
|
// In URP 17 this exists.
|
|
return GetMeshRenderingLayer();
|
|
#else
|
|
return 0;
|
|
#endif
|
|
#endif
|
|
}
|
|
#else
|
|
uint BGSpine_GetMeshRenderingLayerBackwardsCompatible()
|
|
{
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// ShadowCaster pass (names kept to match existing shader pragmas)
|
|
// -----------------------------------------------------------------------------
|
|
#if defined(BGAREA_SPINE_PASS_SHADOWCASTER)
|
|
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl"
|
|
|
|
float3 _LightDirection;
|
|
|
|
struct AttributesSpine
|
|
{
|
|
float4 positionOS : POSITION;
|
|
float3 normalOS : NORMAL;
|
|
float4 vertexColor : COLOR;
|
|
float2 texcoord : TEXCOORD0;
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
};
|
|
|
|
struct VaryingsSpine
|
|
{
|
|
float4 positionCS : SV_POSITION;
|
|
float4 texcoordAndAlpha : TEXCOORD0;
|
|
};
|
|
|
|
float4 GetShadowPositionHClip(float3 positionOS, half3 normalWS)
|
|
{
|
|
float3 positionWS = TransformObjectToWorld(positionOS);
|
|
float4 positionCS = TransformWorldToHClip(ApplyShadowBias(positionWS, normalWS, _LightDirection));
|
|
|
|
#if UNITY_REVERSED_Z
|
|
positionCS.z = min(positionCS.z, positionCS.w * UNITY_NEAR_CLIP_VALUE);
|
|
#else
|
|
positionCS.z = max(positionCS.z, positionCS.w * UNITY_NEAR_CLIP_VALUE);
|
|
#endif
|
|
|
|
return positionCS;
|
|
}
|
|
|
|
VaryingsSpine ShadowPassVertexSkeletonLit(AttributesSpine input)
|
|
{
|
|
VaryingsSpine output;
|
|
UNITY_SETUP_INSTANCE_ID(input);
|
|
|
|
output.texcoordAndAlpha.xyz = float3(TRANSFORM_TEX(input.texcoord, _MainTex).xy, 0);
|
|
|
|
half3 fixedNormalOS = half3(0, 0, -1);
|
|
half3 normalWS = normalize(TransformObjectToWorldNormal(fixedNormalOS));
|
|
#ifdef _DOUBLE_SIDED_LIGHTING
|
|
half3 viewDirWS = UNITY_MATRIX_V[2].xyz;
|
|
half faceSign = sign(dot(viewDirWS, normalWS));
|
|
normalWS *= faceSign;
|
|
#endif
|
|
|
|
output.positionCS = GetShadowPositionHClip(input.positionOS.xyz, normalWS);
|
|
output.texcoordAndAlpha.a = input.vertexColor.a;
|
|
return output;
|
|
}
|
|
|
|
half4 ShadowPassFragmentSkeletonLit(VaryingsSpine input) : SV_TARGET
|
|
{
|
|
fixed4 texureColor = tex2D(_MainTex, input.texcoordAndAlpha.xy);
|
|
clip(texureColor.a * input.texcoordAndAlpha.a - _Cutoff);
|
|
return 0;
|
|
}
|
|
|
|
#endif // BGAREA_SPINE_PASS_SHADOWCASTER
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// DepthOnly pass
|
|
// -----------------------------------------------------------------------------
|
|
#if defined(BGAREA_SPINE_PASS_DEPTHONLY)
|
|
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
|
|
|
struct AttributesSpine
|
|
{
|
|
float4 positionOS : POSITION;
|
|
float3 normalOS : NORMAL;
|
|
float4 vertexColor : COLOR;
|
|
float2 texcoord : TEXCOORD0;
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
};
|
|
|
|
struct VaryingsSpine
|
|
{
|
|
float4 positionCS : SV_POSITION;
|
|
float4 texcoordAndAlpha : TEXCOORD0;
|
|
UNITY_VERTEX_OUTPUT_STEREO
|
|
};
|
|
|
|
VaryingsSpine DepthOnlyVertex(AttributesSpine input)
|
|
{
|
|
VaryingsSpine output = (VaryingsSpine)0;
|
|
UNITY_SETUP_INSTANCE_ID(input);
|
|
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
|
|
|
|
output.texcoordAndAlpha.xyz = float3(TRANSFORM_TEX(input.texcoord, _MainTex).xy, 0);
|
|
output.texcoordAndAlpha.a = input.vertexColor.a;
|
|
output.positionCS = TransformObjectToHClip(input.positionOS.xyz);
|
|
return output;
|
|
}
|
|
|
|
half4 DepthOnlyFragment(VaryingsSpine input) : SV_TARGET
|
|
{
|
|
fixed4 texureColor = tex2D(_MainTex, input.texcoordAndAlpha.xy);
|
|
clip(texureColor.a * input.texcoordAndAlpha.a - _Cutoff);
|
|
return input.positionCS.z;
|
|
}
|
|
|
|
#endif // BGAREA_SPINE_PASS_DEPTHONLY
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// DepthNormals pass
|
|
// -----------------------------------------------------------------------------
|
|
#if defined(BGAREA_SPINE_PASS_DEPTHNORMALS)
|
|
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
|
|
|
struct AttributesSpine
|
|
{
|
|
float4 positionOS : POSITION;
|
|
float3 normalOS : NORMAL;
|
|
float4 vertexColor : COLOR;
|
|
float2 texcoord : TEXCOORD0;
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
};
|
|
|
|
struct VaryingsSpine
|
|
{
|
|
float3 normalWS : NORMAL;
|
|
float4 positionCS : SV_POSITION;
|
|
float4 texcoordAndAlpha : TEXCOORD0;
|
|
UNITY_VERTEX_OUTPUT_STEREO
|
|
};
|
|
|
|
VaryingsSpine DepthNormalsVertex(AttributesSpine input)
|
|
{
|
|
VaryingsSpine output = (VaryingsSpine)0;
|
|
UNITY_SETUP_INSTANCE_ID(input);
|
|
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
|
|
|
|
half3 fixedNormal = half3(0, 0, -1);
|
|
half3 normalWS = normalize(mul((float3x3)unity_ObjectToWorld, fixedNormal));
|
|
|
|
#ifdef _DOUBLE_SIDED_LIGHTING
|
|
half3 viewDirWS = UNITY_MATRIX_V[2].xyz;
|
|
half faceSign = sign(dot(viewDirWS, normalWS));
|
|
normalWS *= faceSign;
|
|
#endif
|
|
output.normalWS = normalWS;
|
|
|
|
output.texcoordAndAlpha.xyz = float3(TRANSFORM_TEX(input.texcoord, _MainTex).xy, 0);
|
|
output.texcoordAndAlpha.a = input.vertexColor.a;
|
|
output.positionCS = TransformObjectToHClip(input.positionOS.xyz);
|
|
return output;
|
|
}
|
|
|
|
void DepthNormalsFragment(
|
|
VaryingsSpine input,
|
|
out half4 outNormalWS : SV_Target0
|
|
#ifdef _WRITE_RENDERING_LAYERS
|
|
, out float4 outRenderingLayers : SV_Target1
|
|
#endif
|
|
)
|
|
{
|
|
fixed4 texureColor = tex2D(_MainTex, input.texcoordAndAlpha.xy);
|
|
clip(texureColor.a * input.texcoordAndAlpha.a - _Cutoff);
|
|
|
|
float3 normalWS = input.normalWS;
|
|
#if defined(_GBUFFER_NORMALS_OCT)
|
|
float2 octNormalWS = PackNormalOctQuadEncode(normalWS);
|
|
float2 remappedOctNormalWS = saturate(octNormalWS * 0.5 + 0.5);
|
|
half3 packedNormalWS = PackFloat2To888(remappedOctNormalWS);
|
|
outNormalWS = half4(packedNormalWS, 0.0);
|
|
#else
|
|
outNormalWS = half4(normalWS, 0.0);
|
|
#endif
|
|
|
|
#ifdef _WRITE_RENDERING_LAYERS
|
|
uint renderingLayers = BGSpine_GetMeshRenderingLayerBackwardsCompatible();
|
|
outRenderingLayers = float4(EncodeMeshRenderingLayer(renderingLayers), 0, 0, 0);
|
|
#endif
|
|
}
|
|
|
|
#endif // BGAREA_SPINE_PASS_DEPTHNORMALS
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// ForwardLit pass
|
|
// -----------------------------------------------------------------------------
|
|
#if defined(BGAREA_SPINE_PASS_FORWARDLIT)
|
|
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl"
|
|
|
|
// Unity 6 / URP 17: _FORWARD_PLUS keywords/macros were deprecated in favor of _CLUSTER_LIGHT_LOOP.
|
|
// Keep the existing Spine-derived code path compiling by mapping the deprecated macro to the new one.
|
|
#if USE_CLUSTER_LIGHT_LOOP && !defined(FORWARD_PLUS_SUBTRACTIVE_LIGHT_CHECK)
|
|
#define FORWARD_PLUS_SUBTRACTIVE_LIGHT_CHECK CLUSTER_LIGHT_LOOP_SUBTRACTIVE_LIGHT_CHECK
|
|
#endif
|
|
|
|
// Area light include (arealight package)
|
|
#include "Packages/com.baddog.rendering.arealight/Shaders/Include/BGAreaLighting.hlsl"
|
|
|
|
// Receive shadows for main light when requested
|
|
#if (defined(_MAIN_LIGHT_SHADOWS) || defined(MAIN_LIGHT_CALCULATE_SHADOWS)) && !defined(_RECEIVE_SHADOWS_OFF)
|
|
#define BGAREA_SPINE_RECEIVE_SHADOWS
|
|
#endif
|
|
|
|
// Fog keyword guard (mirrors your modified file)
|
|
#if !(defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2))
|
|
#undef _FOG
|
|
#endif
|
|
|
|
// Adaptive Probe Volumes (keep behavior close to Spine)
|
|
#if !defined(DYNAMICLIGHTMAP_ON) && !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) && defined(__PROBEVOLUME_HLSL__)
|
|
#define BGAREA_SPINE_USE_ADAPTIVE_PROBE_VOLUMES
|
|
#endif
|
|
|
|
struct appdata
|
|
{
|
|
float3 pos : POSITION;
|
|
float3 normal : NORMAL;
|
|
half4 color : COLOR;
|
|
float2 uv0 : TEXCOORD0;
|
|
#if defined(_TINT_BLACK_ON)
|
|
float2 tintBlackRG : TEXCOORD1;
|
|
float2 tintBlackB : TEXCOORD2;
|
|
#endif
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
};
|
|
|
|
struct VertexOutput
|
|
{
|
|
half4 color : COLOR0;
|
|
|
|
#if defined(_FOG)
|
|
float3 uv0AndFog : TEXCOORD0;
|
|
#else
|
|
float2 uv0 : TEXCOORD0;
|
|
#endif
|
|
float4 pos : SV_POSITION;
|
|
|
|
#if defined(BGAREA_SPINE_RECEIVE_SHADOWS)
|
|
float4 shadowCoord : TEXCOORD1;
|
|
half3 shadowedColor : TEXCOORD2;
|
|
#endif
|
|
|
|
// Always provide position/normal for per-pixel area light and (optional) Forward+/APV.
|
|
float3 positionWS : TEXCOORD3;
|
|
half3 normalWS : TEXCOORD4;
|
|
|
|
#if defined(_TINT_BLACK_ON)
|
|
float3 darkColor : TEXCOORD5;
|
|
#endif
|
|
|
|
#if defined(BGAREA_SPINE_USE_ADAPTIVE_PROBE_VOLUMES) && defined(_ADAPTIVE_PROBE_VOLUMES_PER_PIXEL)
|
|
float3 positionCS : TEXCOORD6;
|
|
#endif
|
|
|
|
UNITY_VERTEX_OUTPUT_STEREO
|
|
};
|
|
|
|
#if defined(_FOG)
|
|
#define BGSpine_PackedUV0(i) (i.uv0AndFog.xy)
|
|
#define BGSpine_PackedFog(i) (i.uv0AndFog.z)
|
|
#else
|
|
#define BGSpine_PackedUV0(i) (i.uv0.xy)
|
|
#endif
|
|
|
|
half3 BGSpine_ProcessLight(float3 positionWS, half3 normalWS, uint meshRenderingLayers, int lightIndex)
|
|
{
|
|
Light light = GetAdditionalLight(lightIndex, positionWS);
|
|
#ifdef USE_LIGHT_LAYERS
|
|
if (!IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
|
|
return half3(0, 0, 0);
|
|
#endif
|
|
|
|
half3 attenuatedLightColor = light.color * (light.distanceAttenuation * light.shadowAttenuation);
|
|
return LightingLambert(attenuatedLightColor, light.direction, normalWS);
|
|
}
|
|
|
|
half3 BGSpine_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);
|
|
|
|
half3 additionalLightColor = half3(0, 0, 0);
|
|
// Note: we don't add any lighting in the fragment shader in non-Forward+ case.
|
|
#if defined(_ADDITIONAL_LIGHTS) || defined(_ADDITIONAL_LIGHTS_VERTEX)
|
|
uint meshRenderingLayers = BGSpine_GetMeshRenderingLayerBackwardsCompatible();
|
|
#if USE_FORWARD_PLUS || USE_CLUSTER_LIGHT_LOOP
|
|
for (uint lightIndex = 0; lightIndex < min(URP_FP_DIRECTIONAL_LIGHTS_COUNT, MAX_VISIBLE_LIGHTS); lightIndex++)
|
|
{
|
|
FORWARD_PLUS_SUBTRACTIVE_LIGHT_CHECK
|
|
additionalLightColor += BGSpine_ProcessLight(positionWS, normalWS, meshRenderingLayers, (int)lightIndex);
|
|
}
|
|
#else
|
|
uint pixelLightCount = GetAdditionalLightsCount();
|
|
for (uint lightIndex = 0u; lightIndex < pixelLightCount; ++lightIndex)
|
|
{
|
|
additionalLightColor += BGSpine_ProcessLight(positionWS, normalWS, meshRenderingLayers, (int)lightIndex);
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
shadowedColor = additionalLightColor;
|
|
return mainLightColor + additionalLightColor;
|
|
}
|
|
|
|
#if defined(_ADDITIONAL_LIGHTS) && (USE_FORWARD_PLUS || USE_CLUSTER_LIGHT_LOOP)
|
|
half3 BGSpine_LightweightLightFragmentSimplified(float3 positionWS, float2 positionCS, half3 normalWS, out half3 shadowedColor)
|
|
{
|
|
half3 additionalLightColor = half3(0, 0, 0);
|
|
shadowedColor = half3(0, 0, 0);
|
|
|
|
// LIGHT_LOOP_BEGIN needs these fields.
|
|
InputData inputData;
|
|
inputData.positionWS = positionWS;
|
|
inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(positionCS);
|
|
|
|
uint meshRenderingLayers = BGSpine_GetMeshRenderingLayerBackwardsCompatible();
|
|
uint pixelLightCount = GetAdditionalLightsCount();
|
|
|
|
LIGHT_LOOP_BEGIN(pixelLightCount)
|
|
additionalLightColor += BGSpine_ProcessLight(positionWS, normalWS, meshRenderingLayers, (int)lightIndex);
|
|
LIGHT_LOOP_END
|
|
|
|
return additionalLightColor;
|
|
}
|
|
#endif
|
|
|
|
VertexOutput vert(appdata v)
|
|
{
|
|
VertexOutput o;
|
|
UNITY_SETUP_INSTANCE_ID(v);
|
|
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
|
|
|
|
half4 color = BGSpine_PMAGammaToTargetSpace(v.color);
|
|
float3 positionWS = TransformObjectToWorld(v.pos);
|
|
half3 fixedNormal = half3(0, 0, -1);
|
|
half3 normalWS = normalize(mul((float3x3)unity_ObjectToWorld, fixedNormal));
|
|
|
|
o.pos = TransformWorldToHClip(positionWS);
|
|
#if defined(_FOG)
|
|
half fogFactor = ComputeFogFactor(o.pos.z);
|
|
BGSpine_PackedFog(o) = fogFactor;
|
|
#endif
|
|
BGSpine_PackedUV0(o) = v.uv0;
|
|
|
|
#ifdef _DOUBLE_SIDED_LIGHTING
|
|
// Match Spine behavior: flip normal based on view direction.
|
|
half3 viewDirWS = UNITY_MATRIX_V[2].xyz;
|
|
half faceSign = sign(dot(viewDirWS, normalWS));
|
|
normalWS *= faceSign;
|
|
#endif
|
|
|
|
o.positionWS = positionWS;
|
|
o.normalWS = normalWS;
|
|
|
|
#if defined(_TINT_BLACK_ON)
|
|
color *= _Color;
|
|
o.darkColor = BGSpine_GammaToTargetSpace(half3(v.tintBlackRG.r, v.tintBlackRG.g, v.tintBlackB.r)) + (_Black.rgb * v.color.a);
|
|
#endif
|
|
|
|
half3 shadowedColor;
|
|
#if !defined(_LIGHT_AFFECTS_ADDITIVE)
|
|
if (color.a == 0)
|
|
{
|
|
o.color = color;
|
|
#if defined(BGAREA_SPINE_RECEIVE_SHADOWS)
|
|
o.shadowedColor = color.rgb;
|
|
o.shadowCoord = float4(0, 0, 0, 0);
|
|
#endif
|
|
return o;
|
|
}
|
|
#endif
|
|
|
|
color.rgb *= BGSpine_LightweightLightVertexSimplified(positionWS, normalWS, shadowedColor);
|
|
|
|
// Ambient light via SH / APV / Lightmap macro (mirrors Spine; safe even if v.lightmapUV doesn't exist).
|
|
half3 vertexSH;
|
|
float4 ignoredProbeOcclusion;
|
|
#if defined(OUTPUT_SH4)
|
|
OUTPUT_SH4(positionWS, normalWS.xyz, GetWorldSpaceNormalizeViewDir(positionWS), vertexSH, ignoredProbeOcclusion);
|
|
#else
|
|
OUTPUT_SH(normalWS.xyz, vertexSH);
|
|
#endif
|
|
|
|
#if defined(BGAREA_SPINE_USE_ADAPTIVE_PROBE_VOLUMES)
|
|
#if !defined(_ADAPTIVE_PROBE_VOLUMES_PER_PIXEL)
|
|
half4 shadowMask = 1.0;
|
|
half3 bakedGI = SAMPLE_GI(vertexSH,
|
|
GetAbsolutePositionWS(positionWS),
|
|
normalWS.xyz,
|
|
GetWorldSpaceNormalizeViewDir(positionWS),
|
|
o.pos.xy,
|
|
ignoredProbeOcclusion,
|
|
shadowMask) * v.color.a;
|
|
#else
|
|
half3 bakedGI = half3(0.0, 0.0, 0.0);
|
|
o.positionCS = o.pos;
|
|
#endif
|
|
#else
|
|
half3 bakedGI = SAMPLE_GI(v.lightmapUV, vertexSH, normalWS) * v.color.a;
|
|
#endif
|
|
color.rgb += bakedGI;
|
|
o.color = color;
|
|
|
|
#if defined(BGAREA_SPINE_RECEIVE_SHADOWS)
|
|
shadowedColor += bakedGI;
|
|
o.shadowedColor = shadowedColor;
|
|
|
|
VertexPositionInputs vertexInput;
|
|
vertexInput.positionWS = positionWS;
|
|
vertexInput.positionCS = o.pos;
|
|
o.shadowCoord = GetShadowCoord(vertexInput);
|
|
#endif
|
|
return o;
|
|
}
|
|
|
|
half4 frag(VertexOutput i
|
|
#ifdef USE_WRITE_RENDERING_LAYERS
|
|
, out float4 outRenderingLayers : SV_Target1
|
|
#endif
|
|
) : SV_Target0
|
|
{
|
|
half4 tex = tex2D(_MainTex, BGSpine_PackedUV0(i));
|
|
#if !defined(_TINT_BLACK_ON) && defined(_STRAIGHT_ALPHA_INPUT)
|
|
tex.rgb *= tex.a;
|
|
#endif
|
|
|
|
// Optional per-pixel APV contribution (mirrors Spine pattern).
|
|
#if defined(BGAREA_SPINE_USE_ADAPTIVE_PROBE_VOLUMES) && defined(_ADAPTIVE_PROBE_VOLUMES_PER_PIXEL)
|
|
half3 vertexSH;
|
|
float4 ignoredProbeOcclusion;
|
|
OUTPUT_SH4(i.positionWS, i.normalWS.xyz, GetWorldSpaceNormalizeViewDir(i.positionWS), vertexSH, ignoredProbeOcclusion);
|
|
half4 shadowMask = 1.0;
|
|
half3 bakedGI = SAMPLE_GI(vertexSH,
|
|
GetAbsolutePositionWS(i.positionWS),
|
|
i.normalWS.xyz,
|
|
GetWorldSpaceNormalizeViewDir(i.positionWS),
|
|
i.positionCS.xy,
|
|
ignoredProbeOcclusion,
|
|
shadowMask) * i.color.a;
|
|
i.color.rgb += bakedGI;
|
|
#endif
|
|
|
|
if (i.color.a == 0)
|
|
{
|
|
#if defined(_TINT_BLACK_ON)
|
|
return BGSpine_fragTintedColor(tex, i.darkColor, i.color, _Color.a, _Black.a);
|
|
#else
|
|
return tex * i.color;
|
|
#endif
|
|
}
|
|
|
|
// Forward+/Cluster additional lights are processed in fragment.
|
|
#if defined(_ADDITIONAL_LIGHTS) && (USE_FORWARD_PLUS || USE_CLUSTER_LIGHT_LOOP)
|
|
half3 shadowedColor;
|
|
i.color.rgb += BGSpine_LightweightLightFragmentSimplified(i.positionWS, i.pos.xy, i.normalWS, shadowedColor);
|
|
#if defined(BGAREA_SPINE_RECEIVE_SHADOWS)
|
|
i.shadowedColor += shadowedColor;
|
|
#endif
|
|
#endif
|
|
|
|
// Area light contribution (matches BadDog arealight design: independent loop over compact area buffer).
|
|
#if defined(_ENABLE_BG_AREA_LIGHTING)
|
|
half3 viewDirWS = GetWorldSpaceNormalizeViewDir(i.positionWS);
|
|
half3 areaRadiance = EvaluateAreaLight(
|
|
i.positionWS,
|
|
i.normalWS,
|
|
viewDirWS,
|
|
half3(1.0, 1.0, 1.0), // brdfDiffuse: treat as radiance term, will be multiplied by tex later.
|
|
half3(0.0, 0.0, 0.0), // brdfSpecular: Spine lit is diffuse-only by default.
|
|
1.0, // perceptualRoughness
|
|
float3(0.0, 0.0, 0.0), // fresnel0
|
|
true // specularHighlightsOff
|
|
);
|
|
i.color.rgb += areaRadiance;
|
|
#if defined(BGAREA_SPINE_RECEIVE_SHADOWS)
|
|
i.shadowedColor += areaRadiance;
|
|
#endif
|
|
#endif
|
|
|
|
#if defined(BGAREA_SPINE_RECEIVE_SHADOWS)
|
|
half shadowAttenuation = MainLightRealtimeShadow(i.shadowCoord);
|
|
i.color.rgb = lerp(i.shadowedColor, i.color.rgb, shadowAttenuation);
|
|
#endif
|
|
|
|
#ifdef USE_WRITE_RENDERING_LAYERS
|
|
uint renderingLayers = BGSpine_GetMeshRenderingLayerBackwardsCompatible();
|
|
outRenderingLayers = float4(EncodeMeshRenderingLayer(renderingLayers), 0, 0, 0);
|
|
#endif
|
|
|
|
#if defined(_TINT_BLACK_ON)
|
|
half4 pixel = BGSpine_fragTintedColor(tex, i.darkColor, i.color, _Color.a, _Black.a);
|
|
#else
|
|
half4 pixel = tex * i.color;
|
|
#endif
|
|
|
|
#if defined(_FOG)
|
|
pixel.rgb = MixFogColor(pixel.rgb, unity_FogColor.rgb * pixel.a, BGSpine_PackedFog(i));
|
|
#endif
|
|
return pixel;
|
|
}
|
|
|
|
#endif // BGAREA_SPINE_PASS_FORWARDLIT
|
|
|
|
#endif // BADDOG_AREA_SPINE_LIT_PASSES_INCLUDED
|
|
|