#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); }