You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

200 lines
6.6 KiB

#define VFXComputePixelOutputToDBuffer(i,outDBuffer) \
{ \
DecalSurfaceData surfaceData; \
ZERO_INITIALIZE(DecalSurfaceData, surfaceData); \
VFXGetSurfaceDecalData(surfaceData,i); \
\
ENCODE_INTO_DBUFFER(surfaceData, outDBuffer); \
}
void VFXGetSurfaceDecalData(out DecalSurfaceData surfaceData, VFX_VARYING_PS_INPUTS i)
{
ZERO_INITIALIZE(DecalSurfaceData, surfaceData);
VFXTransformPSInputs(i);
${VFXLoadParameter:{enableDecalLayers}}
${VFXLoadParameter:{decalLayerMask}}
DecalPrepassData material;
ZERO_INITIALIZE(DecalPrepassData, material);
//Check light layer
if(_EnableDecalLayers)
{
// Clip the decal if it does not pass the decal layer mask of the receiving material.
// Decal layer of the decal
DecodeFromDecalPrepass(i.pos.xy, material);
if ((decalLayerMask & material.renderingLayerMask) == 0)
{
clip(-1);
}
}
float3 clipPos;
clipPos.xy = (i.pos.xy / _ScreenParams.xy) * 2.0f - 1.0f;
clipPos.z = VFXSampleDepth(i.pos);
clipPos.y *= _ProjectionParams.x;
float4 hpositionWS = mul(UNITY_MATRIX_I_VP, float4(clipPos,1.0f));
float4 worldPos = float4(hpositionWS.xyz / hpositionWS.w, 1.0f);
float4x4 worldToElement;
worldToElement[0] = i.worldToDecal0;
worldToElement[1] = i.worldToDecal1;
worldToElement[2] = -i.worldToDecal2; //Z points TOWARDS the surface, so we need to revert it
worldToElement[3] = float4(0,0,0,1);
float3 positionDS = mul(worldToElement, worldPos).xyz * 2.0f;
clip(1.0f - abs(positionDS));
float3x3 normalToWorld = transpose(float3x3(
VFXSafeNormalize(worldToElement[0].xyz),
VFXSafeNormalize(worldToElement[1].xyz),
VFXSafeNormalize(worldToElement[2].xyz)));
float2 uv = positionDS.xy * 0.5f + 0.5f;
VFXUVData uvData = GetUVData(i,uv);
float angleFadeFactor = 1.0f;
if(_EnableDecalLayers)
{
if (i.VFX_VARYING_ANGLEFADE.x > 0.0f) // if angle fade is enabled
{
float3 decalNormal = float3(normalToWorld[0].z, normalToWorld[1].z, normalToWorld[2].z);
float dotAngle = dot(material.geomNormalWS, decalNormal);
angleFadeFactor = DecodeAngleFade(dot(material.geomNormalWS, decalNormal), i.VFX_VARYING_ANGLEFADE);
}
}
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 HDRP_USE_BASE_COLOR
color *= VFXGetParticleColor(i);
#elif HDRP_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 HDRP_USE_BASE_COLOR_MAP
float4 colorMap = SampleTexture(VFX_SAMPLER(baseColorMap),uvData);
#if HDRP_USE_BASE_COLOR_MAP_COLOR
color.xyz *= colorMap.xyz;
#endif
#if HDRP_USE_BASE_COLOR_MAP_ALPHA
color.a *= colorMap.a;
#endif
#endif
color.a *= fadeFactor;
VFXClipFragmentColor(color.a,i);
#if SHADERPASS == SHADERPASS_VFX_DBUFFER_PROJECTOR
surfaceData.baseColor.rgb = saturate(color.rgb);
surfaceData.baseColor.a = color.a;
float albedoMapBlend = surfaceData.baseColor.a;
float maskMapBlend = fadeFactor;
#ifdef DECALS_4RT
float metallic = 0.0f;
float ao = 0.0f;
#ifdef VFX_VARYING_METALLIC
metallic = i.VFX_VARYING_METALLIC;
#endif
#ifdef VFX_VARYING_AMBIENT_OCCLUSION
ao = i.VFX_VARYING_AMBIENT_OCCLUSION;
#endif
#endif
float smoothness = 0.5f;
#ifdef VFX_VARYING_SMOOTHNESS
smoothness = i.VFX_VARYING_SMOOTHNESS;
#endif
#if HDRP_USE_MASK_MAP
surfaceData.mask = SampleTexture(VFX_SAMPLER(maskMap), uvData);
maskMapBlend = surfaceData.mask.z * fadeFactor;
#ifdef DECALS_4RT
surfaceData.mask.x = lerp(0, metallic, surfaceData.mask.x);
surfaceData.mask.y = lerp(0, ao, surfaceData.mask.y);
#endif
surfaceData.mask.z = lerp(0, smoothness, surfaceData.mask.w);
#else //HDRP_USE_MASK_MAP
#ifdef DECALS_4RT
surfaceData.mask.xy = float2(metallic, ao);
#endif
surfaceData.mask.z = smoothness;
#endif
#if VFX_MASK_BLEND_BASE_COLOR_ALPHA
surfaceData.mask.w = albedoMapBlend;
#elif VFX_MASK_BLEND_MASK_BLUE
surfaceData.mask.w = maskMapBlend;
#endif
float normalAlpha = 1.0f;
#ifdef DECAL_SURFACE_GRADIENT
float3x3 tangentToWorld = transpose(normalToWorld);
#if USE_NORMAL_MAP
float2 deriv = UnpackDerivativeNormalRGorAG(SampleTexture(VFX_SAMPLER(normalMap),uvData));
#else // USE_NORMAL_MAP
float2 deriv = float2(0.0f,0.0f);
#endif // USE_NORMAL_MAP
float3 normalWS = SurfaceGradientFromTBN(deriv, tangentToWorld[0], tangentToWorld[1]);
#else //DECAL_SURFACE_GRADIENT
#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);
#endif //DECAL_SURFACE_GRADIENT
#ifdef VFX_VARYING_NORMALALPHA
surfaceData.normalWS.w = i.VFX_VARYING_NORMALALPHA;
#else
surfaceData.normalWS.w = 0.0f;
#endif
surfaceData.normalWS.xyz = normalWS;
#if VFX_NORMAL_BLEND_BASE_COLOR_ALPHA
surfaceData.normalWS.w *= albedoMapBlend;
#elif VFX_NORMAL_BLEND_MASK_BLUE
surfaceData.normalWS.w *= maskMapBlend;
#endif
surfaceData.MAOSBlend.xy = float2(surfaceData.mask.w, surfaceData.mask.w);
#endif
#if SHADERPASS == SHADERPASS_VFX_DECAL_FORWARD_EMISSIVE
surfaceData.emissive = float3(1,1,1) * fadeFactor;
#if defined(VFX_VARYING_EMISSIVE) && (HDRP_USE_EMISSIVE_COLOR || HDRP_USE_ADDITIONAL_EMISSIVE_COLOR)
surfaceData.emissive *= i.VFX_VARYING_EMISSIVE;
#endif
#ifdef HDRP_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
// Inverse pre-expose using exposureWeight weight
float3 emissiveRcpExposure = surfaceData.emissive * GetInverseCurrentExposureMultiplier();
#ifdef VFX_VARYING_EXPOSUREWEIGHT
surfaceData.emissive = lerp(emissiveRcpExposure, surfaceData.emissive, i.VFX_VARYING_EXPOSUREWEIGHT);
#elif VFX_BYPASS_EXPOSURE
surfaceData.emissive = lerp(emissiveRcpExposure, surfaceData.emissive, 0.0f);
#else
surfaceData.emissive = lerp(emissiveRcpExposure, surfaceData.emissive, 1.0f);
#endif
surfaceData.emissive *= saturate(color.a);
#endif
}