436 lines
15 KiB
HLSL

#ifndef VERTEX_LIT_FORWARD_PASS_URP_INCLUDED
#define VERTEX_LIT_FORWARD_PASS_URP_INCLUDED
#include "Packages/com.esotericsoftware.spine.urp-shaders/Shaders/Include/Spine-Sprite-Common-URP.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#include "Packages/com.esotericsoftware.spine.urp-shaders/Shaders/Include/SpineCoreShaders/SpriteLighting.cginc"
#include "Packages/com.esotericsoftware.spine.urp-shaders/Shaders/Include/SpineCoreShaders/Spine-Common.cginc"
#include "Packages/com.esotericsoftware.spine.urp-shaders/Shaders/Include/Spine-Common-URP.hlsl"
#if defined(_ALPHAPREMULTIPLY_ON)
#undef _STRAIGHT_ALPHA_INPUT
#elif !defined(_STRAIGHT_ALPHA_INPUT)
#define _STRAIGHT_ALPHA_INPUT
#endif
#include "Packages/com.esotericsoftware.spine.urp-shaders/Shaders/Include/SpineCoreShaders/Spine-Skeleton-Tint-Common.cginc"
#if !defined(DYNAMICLIGHTMAP_ON) && !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) && defined(__PROBEVOLUME_HLSL__)
#define USE_ADAPTIVE_PROBE_VOLUMES
#endif
#if defined(_RIM_LIGHTING) || defined(_ADDITIONAL_LIGHTS) || defined(MAIN_LIGHT_CALCULATE_SHADOWS) || defined(USE_LIGHT_COOKIES) || defined(USE_ADAPTIVE_PROBE_VOLUMES)
#define NEEDS_POSITION_WS
#endif
////////////////////////////////////////
// Vertex output struct
//
struct VertexOutputLWRP
{
float4 pos : SV_POSITION;
fixed4 vertexColor : COLOR;
float3 texcoord : TEXCOORD0;
half4 fogFactorAndVertexLight : TEXCOORD1;
half3 viewDirectionWS : TEXCOORD2;
DECLARE_LIGHTMAP_OR_SH(lightmapUV, vertexSH, 3);
#if defined(_NORMALMAP)
half4 normalWorld : TEXCOORD4;
half4 tangentWorld : TEXCOORD5;
half4 binormalWorld : TEXCOORD6;
#else
half3 normalWorld : TEXCOORD4;
#endif
#if (defined(_MAIN_LIGHT_SHADOWS) || defined(MAIN_LIGHT_CALCULATE_SHADOWS)) && !defined(_RECEIVE_SHADOWS_OFF)
float4 shadowCoord : TEXCOORD7;
#endif
#if defined(NEEDS_POSITION_WS)
float4 positionWS : TEXCOORD8;
#endif
#if defined(_TINT_BLACK_ON)
float3 darkColor : TEXCOORD9;
#endif
#if defined(USE_ADAPTIVE_PROBE_VOLUMES)
float3 positionCS : TEXCOORD10;
#endif
UNITY_VERTEX_OUTPUT_STEREO
};
///////////////////////////////////////////////////////////////////////////////
// Vertex and Fragment functions //
///////////////////////////////////////////////////////////////////////////////
#if defined(_ADDITIONAL_LIGHT_SHADOWS) && !defined(_RECEIVE_SHADOWS_OFF)
half4 CalculateShadowMaskBackwardsCompatible(InputData inputData)
{
// To ensure backward compatibility we have to avoid using shadowMask input, as it is not present in older shaders
#if defined(SHADOWS_SHADOWMASK) && defined(LIGHTMAP_ON)
half4 shadowMask = inputData.shadowMask;
#elif !defined (LIGHTMAP_ON)
half4 shadowMask = unity_ProbesOcclusion;
#else
half4 shadowMask = half4(1, 1, 1, 1);
#endif
return shadowMask;
}
#endif
half3 LightweightLightVertexSimplified(float3 positionWS, half3 normalWS) {
#ifdef _MAIN_LIGHT_VERTEX
Light mainLight = GetMainLight();
half3 attenuatedLightColor = mainLight.color * (mainLight.distanceAttenuation * mainLight.shadowAttenuation);
half3 diffuseLightColor = LightingLambert(attenuatedLightColor, mainLight.direction, normalWS);
#else
half3 diffuseLightColor = half3(0, 0, 0);
#endif
#ifdef _ADDITIONAL_LIGHTS_VERTEX
int pixelLightCount = GetAdditionalLightsCount();
for (int i = 0; i < pixelLightCount; ++i)
{
Light light = GetAdditionalLight(i, positionWS);
half3 attenuatedLightColor = light.color * (light.distanceAttenuation * light.shadowAttenuation);
diffuseLightColor += LightingLambert(attenuatedLightColor, light.direction, normalWS);
}
#endif // _ADDITIONAL_LIGHTS_VERTEX
return diffuseLightColor;
}
#ifdef _DIFFUSE_RAMP
half3 LightingLambertRamped(half3 lightColor, float attenuation, half3 lightDir, half3 normal)
{
half angleDot = max(0, dot(lightDir, normal));
return calculateRampedDiffuse(lightColor, attenuation, angleDot);
}
#endif
#if defined(SPECULAR)
half3 ProcessLightPBRSimplified(InputData inputData, BRDFData brdfData, half4 shadowMask, uint meshRenderingLayers, int lightIndex)
{
#if defined(_ADDITIONAL_LIGHT_SHADOWS) && !defined(_RECEIVE_SHADOWS_OFF)
Light light = GetAdditionalLight(lightIndex, inputData.positionWS, shadowMask);
#else
Light light = GetAdditionalLight(lightIndex, inputData.positionWS);
#endif
#ifdef USE_LIGHT_LAYERS
if (!IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
return half3(0, 0, 0);
#endif
return LightingPhysicallyBased(brdfData, light, inputData.normalWS, inputData.viewDirectionWS);
}
half4 LightweightFragmentPBRSimplified(InputData inputData, half4 texAlbedoAlpha, half metallic, half3 specular,
half smoothness, half3 emission, half4 vertexColor)
{
#if !defined(_TINT_BLACK_ON)
half4 albedo = texAlbedoAlpha * vertexColor;
#else
half4 albedo = texAlbedoAlpha;
#endif
BRDFData brdfData;
half ignoredAlpha = 1; // ignore alpha, otherwise
InitializeBRDFData(albedo.rgb, metallic, specular, smoothness, ignoredAlpha, brdfData);
brdfData.specular *= albedo.a;
#ifndef _MAIN_LIGHT_VERTEX
#if (defined(_MAIN_LIGHT_SHADOWS) || defined(MAIN_LIGHT_CALCULATE_SHADOWS)) && !defined(_RECEIVE_SHADOWS_OFF)
Light mainLight = GetMainLight(inputData.shadowCoord);
#else
Light mainLight = GetMainLight();
#endif
#if defined(USE_LIGHT_COOKIES)
half3 cookieColor = SampleMainLightCookie(inputData.positionWS);
mainLight.color *= cookieColor;
#endif
half3 finalColor = inputData.bakedGI * albedo.rgb;
finalColor += LightingPhysicallyBased(brdfData, mainLight, inputData.normalWS, inputData.viewDirectionWS);
#else // _MAIN_LIGHT_VERTEX
half3 finalColor = inputData.bakedGI * albedo.rgb;
#endif // _MAIN_LIGHT_VERTEX
#ifdef _ADDITIONAL_LIGHTS
uint meshRenderingLayers = GetMeshRenderingLayerBackwardsCompatible();
#if defined(_ADDITIONAL_LIGHT_SHADOWS) && !defined(_RECEIVE_SHADOWS_OFF)
half4 shadowMask = CalculateShadowMaskBackwardsCompatible(inputData);
#else
half4 shadowMask = half4(1, 1, 1, 1);
#endif
#if USE_FORWARD_PLUS
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
uint pixelLightCount = GetAdditionalLightsCount();
LIGHT_LOOP_BEGIN_SPINE(pixelLightCount)
finalColor += ProcessLightPBRSimplified(inputData, brdfData, shadowMask, meshRenderingLayers, lightIndex);
LIGHT_LOOP_END_SPINE
#endif // _ADDITIONAL_LIGHTS
#ifdef _ADDITIONAL_LIGHTS_VERTEX
finalColor += inputData.vertexLighting * brdfData.diffuse;
#endif
finalColor += emission;
return prepareLitPixelForOutput(half4(finalColor, albedo.a), texAlbedoAlpha.a, vertexColor.a);
}
#else // !SPECULAR
half3 ProcessLightLambert(InputData inputData, half4 shadowMask, uint meshRenderingLayers, int lightIndex)
{
#if defined(_ADDITIONAL_LIGHT_SHADOWS) && !defined(_RECEIVE_SHADOWS_OFF)
Light light = GetAdditionalLight(lightIndex, inputData.positionWS, shadowMask);
#else
Light light = GetAdditionalLight(lightIndex, inputData.positionWS);
#endif
#ifdef USE_LIGHT_LAYERS
if (!IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
return half3(0, 0, 0);
#endif
half3 attenuation = (light.distanceAttenuation * light.shadowAttenuation);
half3 attenuatedLightColor = light.color * attenuation;
#ifndef _DIFFUSE_RAMP
return LightingLambert(attenuatedLightColor, light.direction, inputData.normalWS);
#else
return LightingLambertRamped(light.color, attenuation, light.direction, inputData.normalWS);
#endif
}
half4 LightweightFragmentBlinnPhongSimplified(InputData inputData, half4 texDiffuseAlpha, half3 emission, half4 vertexColor)
{
#if !defined(_TINT_BLACK_ON)
half4 diffuse = texDiffuseAlpha * vertexColor;
#else
half4 diffuse = texDiffuseAlpha;
#endif
#ifndef _MAIN_LIGHT_VERTEX
#if (defined(_MAIN_LIGHT_SHADOWS) || defined(MAIN_LIGHT_CALCULATE_SHADOWS)) && !defined(_RECEIVE_SHADOWS_OFF)
Light mainLight = GetMainLight(inputData.shadowCoord);
#else
Light mainLight = GetMainLight();
#endif
#if defined(USE_LIGHT_COOKIES)
half3 cookieColor = SampleMainLightCookie(inputData.positionWS);
mainLight.color *= cookieColor;
#endif
half3 diffuseLighting = inputData.bakedGI;
half3 attenuation = mainLight.distanceAttenuation* mainLight.shadowAttenuation;
half3 attenuatedLightColor = mainLight.color * attenuation;
#ifndef _DIFFUSE_RAMP
diffuseLighting += LightingLambert(attenuatedLightColor, mainLight.direction, inputData.normalWS);
#else
diffuseLighting += LightingLambertRamped(mainLight.color, attenuation, mainLight.direction, inputData.normalWS);
#endif
#else // _MAIN_LIGHT_VERTEX
half3 diffuseLighting = inputData.bakedGI;
#endif // _MAIN_LIGHT_VERTEX
#ifdef _ADDITIONAL_LIGHTS
uint meshRenderingLayers = GetMeshRenderingLayerBackwardsCompatible();
#if defined(_ADDITIONAL_LIGHT_SHADOWS) && !defined(_RECEIVE_SHADOWS_OFF)
half4 shadowMask = CalculateShadowMaskBackwardsCompatible(inputData);
#else
half4 shadowMask = half4(1, 1, 1, 1);
#endif
#if USE_FORWARD_PLUS
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
uint pixelLightCount = GetAdditionalLightsCount();
LIGHT_LOOP_BEGIN_SPINE(pixelLightCount)
diffuseLighting += ProcessLightLambert(inputData, shadowMask, meshRenderingLayers, lightIndex);
LIGHT_LOOP_END_SPINE
#endif
#ifdef _ADDITIONAL_LIGHTS_VERTEX
diffuseLighting += inputData.vertexLighting;
#endif
diffuseLighting += emission;
//half3 finalColor = diffuseLighting * diffuse + emission;
half3 finalColor = diffuseLighting * diffuse.rgb;
return prepareLitPixelForOutput(half4(finalColor, diffuse.a), texDiffuseAlpha.a, vertexColor.a);
}
#endif // SPECULAR
VertexOutputLWRP ForwardPassVertexSprite(VertexInput input)
{
VertexOutputLWRP output = (VertexOutputLWRP)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
output.pos = calculateLocalPos(input.vertex);
output.vertexColor = calculateVertexColor(input.color);
#if defined(_TINT_BLACK_ON)
output.darkColor = GammaToTargetSpace(
half3(input.tintBlackRG.r, input.tintBlackRG.g, input.tintBlackB.r)) + (_Black.rgb * input.color.a);
#endif
output.texcoord = float3(calculateTextureCoord(input.texcoord), 0);
float3 positionWS = TransformObjectToWorld(input.vertex.xyz);
float backFaceSign = 1;
#if defined(FIXED_NORMALS_BACKFACE_RENDERING)
backFaceSign = calculateBackfacingSign(positionWS.xyz);
#endif
output.viewDirectionWS = GetCameraPositionWS() - positionWS;
#if defined(NEEDS_POSITION_WS)
output.positionWS = float4(positionWS, 1);
#endif
half3 normalWS = calculateSpriteWorldNormal(input, -backFaceSign);
output.normalWorld.xyz = normalWS;
#if defined(_NORMALMAP)
output.tangentWorld.xyz = calculateWorldTangent(input.tangent);
output.binormalWorld.xyz = calculateSpriteWorldBinormal(input, output.normalWorld.xyz, output.tangentWorld.xyz, backFaceSign);
#endif
output.fogFactorAndVertexLight.yzw = LightweightLightVertexSimplified(positionWS, normalWS);
#if (defined(_MAIN_LIGHT_SHADOWS) || defined(MAIN_LIGHT_CALCULATE_SHADOWS)) && !defined(_RECEIVE_SHADOWS_OFF)
VertexPositionInputs vertexInput;
vertexInput.positionWS = positionWS;
vertexInput.positionCS = output.pos;
output.shadowCoord = GetShadowCoord(vertexInput);
#endif
#if defined(_FOG)
half fogFactor = ComputeFogFactor(output.pos.z);
output.fogFactorAndVertexLight.x = fogFactor;
#endif
#if IS_URP_15_OR_NEWER
#ifdef OUTPUT_SH4
#if IS_URP_17_OR_NEWER
float4 ignoredProbeOcclusion;
OUTPUT_SH4(positionWS, normalWS.xyz, GetWorldSpaceNormalizeViewDir(positionWS), output.vertexSH, ignoredProbeOcclusion);
#else // 15 or newer
OUTPUT_SH4(positionWS, normalWS.xyz, GetWorldSpaceNormalizeViewDir(positionWS), output.vertexSH);
#endif
#else
OUTPUT_SH(positionWS, normalWS.xyz, GetWorldSpaceNormalizeViewDir(positionWS), output.vertexSH);
#endif
#else
OUTPUT_SH(normalWS.xyz, output.vertexSH);
#endif
#if defined(USE_ADAPTIVE_PROBE_VOLUMES)
output.positionCS = output.pos;
#endif
return output;
}
half4 ForwardPassFragmentSprite(VertexOutputLWRP input
#ifdef USE_WRITE_RENDERING_LAYERS
, out float4 outRenderingLayers : SV_Target1
#endif
) : SV_Target0
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
fixed4 texureColor = calculateTexturePixel(input.texcoord.xy);
RETURN_UNLIT_IF_ADDITIVE_SLOT_TINT(texureColor, input.vertexColor, input.darkColor, _Color.a, _Black.a) // shall be called before ALPHA_CLIP
ALPHA_CLIP(texureColor, input.vertexColor)
#if defined(_TINT_BLACK_ON)
texureColor = fragTintedColor(texureColor, input.darkColor, input.vertexColor, _Color.a, _Black.a);
#endif
// fill out InputData struct
InputData inputData;
#if !defined(_RECEIVE_SHADOWS_OFF)
#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
inputData.shadowCoord = input.shadowCoord;
#elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)
inputData.shadowCoord = TransformWorldToShadowCoord(input.positionWS.xyz);
#elif defined(_MAIN_LIGHT_SHADOWS)
inputData.shadowCoord = input.shadowCoord;
#else
inputData.shadowCoord = float4(0, 0, 0, 0);
#endif
#endif
inputData.viewDirectionWS = input.viewDirectionWS;
inputData.vertexLighting = input.fogFactorAndVertexLight.yzw;
#if defined(PER_PIXEL_LIGHTING) && defined(_NORMALMAP)
half3 normalWS = calculateNormalFromBumpMap(input.texcoord.xy, input.tangentWorld.xyz, input.binormalWorld.xyz, input.normalWorld.xyz);
#else
half3 normalWS = input.normalWorld.xyz;
#endif
inputData.normalWS = normalWS;
#if defined(USE_ADAPTIVE_PROBE_VOLUMES)
half4 shadowMask = 1.0;
float4 ignoredProbeOcclusion;
inputData.bakedGI = SAMPLE_GI(input.vertexSH,
GetAbsolutePositionWS(input.positionWS),
inputData.normalWS.xyz,
GetWorldSpaceNormalizeViewDir(input.positionWS),
input.positionCS.xy,
ignoredProbeOcclusion,
shadowMask);
#else // USE_ADAPTIVE_PROBE_VOLUMES
inputData.bakedGI = SAMPLE_GI(input.lightmapUV, input.vertexSH, inputData.normalWS);
#endif
#if defined(_RIM_LIGHTING) || defined(_ADDITIONAL_LIGHTS) || defined(USE_LIGHT_COOKIES)
inputData.positionWS = input.positionWS.rgb;
#endif
#if defined(_ADDITIONAL_LIGHTS) && USE_FORWARD_PLUS
inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.pos);
// note: don't assign normalizedScreenSpaceUV otherwise since old URP versions are missing this member variable
#endif
#if defined(SPECULAR)
half2 metallicGloss = getMetallicGloss(input.texcoord.xy);
half metallic = metallicGloss.x;
half smoothness = metallicGloss.y; // this is 1 minus the square root of real roughness m.
half3 specular = half3(0, 0, 0);
half4 emission = half4(0, 0, 0, 1);
APPLY_EMISSION_SPECULAR(emission, input.texcoord.xy)
half4 pixel = LightweightFragmentPBRSimplified(inputData, texureColor, metallic, specular, smoothness, emission.rgb, input.vertexColor);
#else
half3 emission = half3(0, 0, 0);
APPLY_EMISSION(emission, input.texcoord.xy)
half4 pixel = LightweightFragmentBlinnPhongSimplified(inputData, texureColor, emission, input.vertexColor);
#endif
#if defined(_RIM_LIGHTING)
pixel.rgb = applyRimLighting(input.positionWS.xyz, normalWS, pixel);
#endif
COLORISE(pixel)
APPLY_FOG_LWRP(pixel, input.fogFactorAndVertexLight.x)
#ifdef USE_WRITE_RENDERING_LAYERS
uint renderingLayers = GetMeshRenderingLayerBackwardsCompatible();
outRenderingLayers = float4(EncodeMeshRenderingLayer(renderingLayers), 0, 0, 0);
#endif
return pixel;
}
#endif