UnityGame/Library/PackageCache/com.unity.render-pipelines.universal/Editor/VFXGraph/Shaders/VFXDecal.template
2024-10-27 10:53:47 +03:00

248 lines
9.0 KiB
Plaintext

#include "Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXLit.hlsl"
#if !defined(SHADERPASS)
#error SHADERPASS_is_not_define
#endif
#ifdef _DECAL_LAYERS
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareRenderingLayerTexture.hlsl"
#endif
#if defined(DECAL_LOAD_NORMAL)
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl"
#endif
#if defined(DECAL_PROJECTOR) || defined(DECAL_RECONSTRUCT_NORMAL)
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
#endif
void GetSurfaceDataFromSurfaceDecalData(DecalSurfaceData decalSurfaceData, inout SurfaceData surfaceData)
{
surfaceData.albedo = decalSurfaceData.baseColor.rgb;
surfaceData.metallic = saturate(decalSurfaceData.metallic);
surfaceData.specular = 0;
surfaceData.smoothness = saturate(decalSurfaceData.smoothness);
surfaceData.occlusion = decalSurfaceData.occlusion;
surfaceData.emission = decalSurfaceData.emissive;
surfaceData.alpha = saturate(decalSurfaceData.baseColor.w);
surfaceData.clearCoatMask = 0;
surfaceData.clearCoatSmoothness = 1;
}
void VFXGetSurfaceDecalData(out DecalSurfaceData surfaceData, out PositionInputs posInputs, out half3 receiverNormalWS, VFX_VARYING_PS_INPUTS i)
{
ZERO_INITIALIZE(DecalSurfaceData, surfaceData);
VFXTransformPSInputs(i);
float2 positionCS = i.pos.xy;
// Only screen space needs flip logic, other passes do not setup needed properties so we skip here
#if SHADERPASS == SHADERPASS_DECAL_SCREEN_SPACE_PROJECTOR
TransformScreenUV(positionCS, _ScreenSize.y);
#endif
//Check Rendering layer
#ifdef _DECAL_LAYERS
#ifdef _RENDER_PASS_ENABLED
uint surfaceRenderingLayer = DecodeMeshRenderingLayer(LOAD_FRAMEBUFFER_X_INPUT(GBUFFER4, positionCS.xy).r);
#else
uint surfaceRenderingLayer = LoadSceneRenderingLayer(positionCS.xy);
#endif
${VFXLoadParameter:{decalLayerMask}}
clip((surfaceRenderingLayer & decalLayerMask) - 0.1);
#endif
#if _RENDER_PASS_ENABLED && !defined(DECAL_RECONSTRUCT_NORMAL)
float depth = LOAD_FRAMEBUFFER_X_INPUT(GBUFFER3, positionCS.xy).x;
#else
float depth = LoadSceneDepth(positionCS.xy);
#endif
#if !UNITY_REVERSED_Z
depth = lerp(UNITY_NEAR_CLIP_VALUE, 1.0f, depth);
#endif
float2 positionSS = i.pos.xy * _ScreenSize.zw;
float3 positionWS = ComputeWorldSpacePosition(positionSS, depth, UNITY_MATRIX_I_VP);
posInputs = GetPositionInput(positionSS, _ScreenSize.zw, positionWS);
float4x4 worldToElement;
worldToElement[0] = i.worldToDecal[0];
worldToElement[1] = i.worldToDecal[1];
worldToElement[2] = -i.worldToDecal[2];
worldToElement[3] = float4(0,0,0,1);
float3 positionDS = mul(worldToElement, float4(positionWS,1.0f)).xyz;
clip(0.5f - abs(positionDS));
float3x3 normalToWorld = transpose(float3x3(
VFXSafeNormalize(worldToElement[0].xyz),
VFXSafeNormalize(worldToElement[1].xyz),
VFXSafeNormalize(worldToElement[2].xyz)));
float2 uv = positionDS.xy + float2(0.5, 0.5);
VFXUVData uvData = GetUVData(i,uv);
float angleFadeFactor = 1.0f;
receiverNormalWS = half3(0,1,0);
#if defined(DECAL_RECONSTRUCT_NORMAL)
#if defined(_DECAL_NORMAL_BLEND_HIGH)
receiverNormalWS = half3(ReconstructNormalTap9(i.pos.xy));
#elif defined(_DECAL_NORMAL_BLEND_MEDIUM)
receiverNormalWS = half3(ReconstructNormalTap5(i.pos.xy));
#else
receiverNormalWS = half3(ReconstructNormalDerivative(i.pos.xy));
#endif
#elif defined(DECAL_LOAD_NORMAL)
receiverNormalWS = half3(LoadSceneNormals(i.pos.xy));
#endif
#ifdef DECAL_ANGLE_FADE
if (i.VFX_VARYING_ANGLEFADE.y < 0.0f) // if angle fade is enabled
{
float3 decalNormal = float3(normalToWorld[0].z, normalToWorld[1].z, normalToWorld[2].z);
float dotAngle = dot(receiverNormalWS, decalNormal);
float2 angleFade = i.VFX_VARYING_ANGLEFADE;
angleFadeFactor = saturate(angleFade.x + angleFade.y * (dotAngle * (dotAngle - 2.0)));
}
#endif
float fadeFactor = i.VFX_VARYING_FADEFACTOR;
fadeFactor *= angleFadeFactor;
//Compute color even for emissive, to have the correct opacity
float4 color = float4(1,1,1,1);
#if URP_USE_BASE_COLOR
color *= VFXGetParticleColor(i);
#elif URP_USE_ADDITIONAL_BASE_COLOR
#if defined(VFX_VARYING_COLOR)
color.xyz *= i.VFX_VARYING_COLOR;
#endif
#if defined(VFX_VARYING_ALPHA)
color.a *= i.VFX_VARYING_ALPHA;
#endif
#endif
#if URP_USE_BASE_COLOR_MAP
float4 colorMap = SampleTexture(VFX_SAMPLER(baseColorMap),uvData);
#if URP_USE_BASE_COLOR_MAP_COLOR
color.xyz *= colorMap.xyz;
#endif
#if URP_USE_BASE_COLOR_MAP_ALPHA
color.a *= colorMap.a;
#endif
#endif
color.a *= fadeFactor;
VFXClipFragmentColor(color.a,i);
#if (SHADERPASS == SHADERPASS_DBUFFER_PROJECTOR) || (SHADERPASS == SHADERPASS_DECAL_SCREEN_SPACE_PROJECTOR) || (SHADERPASS == SHADERPASS_DECAL_GBUFFER_PROJECTOR)
surfaceData.baseColor.rgb = saturate(color.rgb);
surfaceData.baseColor.a = color.a;
float albedoMapBlend = surfaceData.baseColor.a;
float maskMapBlend = fadeFactor;
surfaceData.metallic = 0.0f;
surfaceData.occlusion = 1.0f;
#ifdef VFX_VARYING_METALLIC
surfaceData.metallic = i.VFX_VARYING_METALLIC;
#endif
#ifdef VFX_VARYING_AMBIENT_OCCLUSION
surfaceData.occlusion *= i.VFX_VARYING_AMBIENT_OCCLUSION;
#endif
surfaceData.smoothness = 0.5f;
#ifdef VFX_VARYING_SMOOTHNESS
surfaceData.smoothness = i.VFX_VARYING_SMOOTHNESS;
#endif
float4 metallicMapSample = (float4)1.0f;
float4 specularMapSample = (float4)1.0f;
#if URP_USE_METALLIC_MAP
metallicMapSample = SampleTexture(VFX_SAMPLER(metallicMap), uvData);
surfaceData.metallic *= metallicMapSample.r;
maskMapBlend *= metallicMapSample.b;
#endif
#if URP_USE_OCCLUSION_MAP
float4 mask = SampleTexture(VFX_SAMPLER(occlusionMap),uvData);
surfaceData.occlusion *= mask.g;
#endif
#if URP_USE_SMOOTHNESS_IN_ALBEDO
surfaceData.smoothness *= albedoMapBlend;
#elif URP_USE_SMOOTHNESS_IN_METALLIC
surfaceData.smoothness *= metallicMapSample.a;
#elif URP_USE_SMOOTHNESS_IN_SPECULAR
surfaceData.smoothness *= albedoMapBlend;//TODO: Not implemented yet;
#endif
#if VFX_MAOS_BLEND_BASE_COLOR_ALPHA
surfaceData.MAOSAlpha = albedoMapBlend;
#elif VFX_MAOS_BLEND_METALLIC_BLUE
surfaceData.MAOSAlpha = maskMapBlend;
#endif
float normalAlpha = 1.0f;
//No Decal Surface Gradient in URP implementation of Decals
#if USE_NORMAL_MAP
float3 normalTS = SampleNormalMap(VFX_SAMPLER(normalMap),uvData);
#else //USE_NORMAL_MAP
float3 normalTS = float3(0.0f,0.0f,1.0f);
#endif //USE_NORMAL_MAP
float3 normalWS = mul(normalToWorld, normalTS);
normalWS = normalize(normalWS);
surfaceData.normalWS.xyz = normalWS;
#ifdef VFX_VARYING_NORMALALPHA
surfaceData.normalWS.w = i.VFX_VARYING_NORMALALPHA;
#else
surfaceData.normalWS.w = 0.0f;
#endif
#if VFX_NORMAL_BLEND_BASE_COLOR_ALPHA
surfaceData.normalWS.w *= albedoMapBlend;
#elif VFX_NORMAL_BLEND_METALLIC_BLUE
surfaceData.normalWS.w *= maskMapBlend;
#endif
#endif
#if (SHADERPASS == SHADERPASS_FORWARD_EMISSIVE_PROJECTOR) || (SHADERPASS == SHADERPASS_DECAL_SCREEN_SPACE_PROJECTOR) || (SHADERPASS == SHADERPASS_DECAL_GBUFFER_PROJECTOR)
surfaceData.baseColor.a = color.a;
surfaceData.emissive = float3(1,1,1) * fadeFactor;
#if defined(VFX_VARYING_EMISSIVE) && (URP_USE_EMISSIVE_COLOR || URP_USE_ADDITIONAL_EMISSIVE_COLOR)
surfaceData.emissive *= i.VFX_VARYING_EMISSIVE;
#else
surfaceData.emissive = float3(0,0,0);
#endif
#ifdef URP_USE_EMISSIVE_MAP
float emissiveScale = 1.0f;
#ifdef VFX_VARYING_EMISSIVESCALE
emissiveScale = i.VFX_VARYING_EMISSIVESCALE;
#endif
surfaceData.emissive *= SampleTexture(VFX_SAMPLER(emissiveMap), uvData).rgb * emissiveScale;
#endif
#endif
}
void PrepareSurfaceAndInputData(VFX_VARYING_PS_INPUTS i, inout SurfaceData surfaceData, inout DecalSurfaceData decalSurfaceData, inout InputData inputData)
{
PositionInputs posInput;
ZERO_INITIALIZE(PositionInputs, posInput);
half3 receiverNormalWS;
VFXGetSurfaceDecalData(decalSurfaceData, posInput, receiverNormalWS, i);
GetSurfaceDataFromSurfaceDecalData(decalSurfaceData, surfaceData);
#if (SHADERPASS == SHADERPASS_DECAL_SCREEN_SPACE_PROJECTOR)
decalSurfaceData.normalWS.xyz = normalize(lerp(receiverNormalWS.xyz, decalSurfaceData.normalWS.xyz, decalSurfaceData.normalWS.w));
#endif
inputData = VFXGetInputData(i, posInput, decalSurfaceData.normalWS.xyz, true);
}