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
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
|
|
}
|
|
|