1.Accumulate:
DistortionAccumulatePS.usf
void Main(
FVertexFactoryInterpolantsVSToPS Interpolants,
float4 PixelPosition : TEXCOORD6,
in float4 SvPosition : SV_Position
, in bool bIsFrontFace : SV_IsFrontFace ,
out float4 OutColor : SV_Target0
)
{
const uint EyeIndex = 0;
ResolvedView = ResolveView();
FMaterialPixelParameters MaterialParameters = GetMaterialPixelParameters(Interpolants, SvPosition);
FPixelMaterialInputs PixelMaterialInputs;
CalcMaterialParameters(MaterialParameters, PixelMaterialInputs, SvPosition, bIsFrontFace);
float3 Normal = GetMaterialNormal(MaterialParameters, PixelMaterialInputs);
float2 NDC = (MaterialParameters.ScreenPosition.xy / MaterialParameters.ScreenPosition.w);
float2 ScreenUV = NDC * ResolvedView.ScreenPositionScaleBias.xy + ResolvedView.ScreenPositionScaleBias.wz;
float2 Refraction = GetMaterialRefraction(PixelMaterialInputs);
float2 BufferUVDistortion = ComputeBufferUVDistortion(
MaterialParameters, PixelMaterialInputs, ResolvedView,
MaterialParameters.WorldNormal, DistortionPass_DistortionParams , ScreenUV, Refraction, true, EyeIndex);
float2 DistortBufferUV = ScreenUV + BufferUVDistortion;
float DistortSceneDepth = CalcSceneDepth(DistortBufferUV);
PostProcessUVDistortion(MaterialParameters, PixelMaterialInputs, DistortSceneDepth, BufferUVDistortion, Refraction);
float2 PosOffset = max(BufferUVDistortion,0);
float2 NegOffset = abs(min(BufferUVDistortion,0));
OutColor = float4(PosOffset.x,PosOffset.y,NegOffset.x,NegOffset.y);
}
void PostProcessUVDistortion(
in FMaterialPixelParameters MaterialParameters, in FPixelMaterialInputs PixelMaterialInputs,
in float DistortSceneDepth, inout float2 BufferUVDistortion, in float2 RefractionIORAndBias)
{
float Bias = -RefractionIORAndBias.y;
float Range = clamp(abs(Bias * 0.5f), 0, 50);
float Z = DistortSceneDepth;
float ZCompare = MaterialParameters.ScreenPosition.w;
float InvWidth = 1.0f / max(1.0f, Range);
BufferUVDistortion *= saturate((Z - ZCompare) * InvWidth + Bias);
static const float DistortionScaleBias = 4.0f;
BufferUVDistortion *= DistortionScaleBias;
}
float2 ComputeBufferUVDistortion(
in FMaterialPixelParameters MaterialParameters, in FPixelMaterialInputs PixelMaterialInputs, in ViewState ResolvedView,
in float3 WorldNormal, in float4 DistortionParameters, in float2 ScreenUV, in float2 RefractionIORAndBias, in bool TryToClip, in uint EyeIndex)
{
float3 ViewNormal = normalize(TransformWorldVectorToView(WorldNormal));
float AirIOR = 1.0f;
float2 ViewportUVDistortion = ViewNormal.xy * (RefractionIORAndBias.x - AirIOR);
float2 BufferUVDistortion = ViewportUVDistortion * ResolvedView.ViewSizeAndInvSize.xy * ResolvedView.BufferSizeAndInvSize.zw;
if (TryToClip)
{
clip(dot(BufferUVDistortion, BufferUVDistortion) - .00001);
}
float InvTanHalfFov = DistortionParameters.x;
float Ratio = DistortionParameters.y;
float2 FovFix = float2(InvTanHalfFov, Ratio*InvTanHalfFov);
const float OffsetFudgeFactor = 0.00023;
BufferUVDistortion *= DistortionParameters.zw * float2(OffsetFudgeFactor, -OffsetFudgeFactor) * FovFix;
return BufferUVDistortion;
}
2.Apply
DistortApplyScreenPS.usf
void Main(
in noperspective float4 TexCoord: TEXCOORD0,
out float4 OutColor : SV_Target0
)
{
float4 AccumDist = Texture2DSample(DistortionTexture,DistortionTextureSampler,TexCoord.xy);
float2 DistBufferUVOffset = (AccumDist.rg - AccumDist.ba);
DistBufferUVOffset *= InvDistortionScaleBias;
float2 NewBufferUV = TexCoord.xy + DistBufferUVOffset;
[flatten] if ( NewBufferUV.x < View_BufferBilinearUVMinMax.x || NewBufferUV.x > View_BufferBilinearUVMinMax.z ||
NewBufferUV.y < View_BufferBilinearUVMinMax.y || NewBufferUV.y > View_BufferBilinearUVMinMax.w )
{
NewBufferUV = TexCoord.xy;
}
OutColor = Texture2DSample(SceneColorTexture, SceneColorTextureSampler, NewBufferUV);
}
3.Merge
DistortApplyScreenPS.usf
void Merge(
in noperspective float4 TexCoord: TEXCOORD0,
out float4 OutColor : SV_Target0
)
{
OutColor = Texture2DSample(SceneColorTexture, SceneColorTextureSampler, TexCoord.xy);
}
4.ComposeTranslucencyToNewSceneColor
ComposeSeparateTranslucency.usf
void MainPS(
float4 SvPosition : SV_POSITION,
out float4 OutColor : SV_Target0)
{
float4 Debug = 0;
float2 SceneColorUV = ApplyScreenTransform(SvPosition.xy, ScreenPosToSceneColorUV);
float2 SeparateTranslucencyUV = ApplyScreenTransform(SvPosition.xy, ScreenPosToSeparateTranslucencyUV);
float4 SceneColorSample = SceneColorTexture.SampleLevel(SceneColorSampler, SceneColorUV, 0);
SeparateTranslucencyUV = clamp(SeparateTranslucencyUV, SeparateTranslucencyUVMin, SeparateTranslucencyUVMax);
float4 SeparateTranslucencySample = SeparateTranslucencyBilinearTexture.SampleLevel(SeparateTranslucencyBilinearSampler, SeparateTranslucencyUV, 0);
float4 SeparateModulationSample = SeparateModulationBilinearTexture.SampleLevel( SeparateModulationBilinearSampler, SeparateTranslucencyUV, 0);
OutColor.rgb = SceneColorSample.rgb * SeparateTranslucencySample.a * SeparateModulationSample.rgb + SeparateTranslucencySample.rgb;
float GreyScaleModulateColorBackgroundVisibility = dot(SeparateModulationSample.rgb, float3(1.0f / 3.0f, 1.0f / 3.0f, 1.0f / 3.0f));
OutColor.a = SceneColorSample.a * SeparateTranslucencySample.a * GreyScaleModulateColorBackgroundVisibility;
}