简要介绍Unity URP的官方Demo在Android平台下的渲染流程。
阴影深度图(Shadow Map)生成
Color Buffer:无
Depth Buffer:_MainLightShadowmapTexture_1024x1024_Shadowmap D16_UNorm
Shader:Universal Render Pipeline/Lit
Pass: ShadowCaster (1)
顶点Shader:
float3 ApplyShadowBias ( float3 positionWS , float3 normalWS , float3 lightDirection )
{
float invNdotL = 1.0 - saturate ( dot ( lightDirection , normalWS ) ) ;
float scale = invNdotL * _ShadowBias . y ;
positionWS = lightDirection * _ShadowBias . xxx + positionWS ;
positionWS = normalWS * scale . xxx + positionWS ;
return positionWS ;
}
float4 GetShadowPositionHClip ( Attributes input )
{
float3 positionWS = TransformObjectToWorld ( input . positionOS . xyz ) ;
float3 normalWS = TransformObjectToWorldNormal ( input . normalOS ) ;
float3 lightDirectionWS = _LightDirection ;
float4 positionCS = TransformWorldToHClip ( ApplyShadowBias ( positionWS , normalWS , lightDirectionWS ) ) ;
positionCS . z = min ( positionCS . z , ( 1.0 ) ) ;
return positionCS ;
}
Varyings ShadowPassVertex ( Attributes input )
{
Varyings output ;
output . positionCS = GetShadowPositionHClip ( input ) ;
return output ;
}
颜色分级查找表(Color Grading LUT)生成
Color Buffer:_InternalGradingLut_1024x32_R8G8B8A8_UNorm_Tex2D R8G8B8A8_UNorm
Depth Buffer:无
Shader:Hidden/Universal Render Pipeline/LutBuilderLdr
Pass: LutBuilderLdr (0)
顶点Shader:
Varyings Vert ( Attributes input )
{
Varyings output ;
float4 pos = GetFullScreenTriangleVertexPosition ( input . vertexID ) ;
float2 uv = GetFullScreenTriangleTexCoord ( input . vertexID ) ;
output . positionCS = pos ;
output . texcoord = uv * _BlitScaleBias . xy + _BlitScaleBias . zw ;
return output ;
}
片元Shader:
min16float4 FragLutBuilderLdr ( Varyings input ) : SV_Target
{
float3 colorLinear = GetLutStripValue ( input . texcoord , _Lut_Params ) ;
float3 colorLMS = LinearToLMS ( colorLinear ) ;
colorLMS *= _ColorBalance . xyz ;
colorLinear = LMSToLinear ( colorLMS ) ;
float3 colorLog = LinearToLogC ( colorLinear ) ;
colorLog = ( colorLog - 0.4135884 ) * _HueSatCon . z + 0.4135884 ;
colorLinear = LogCToLinear ( colorLog ) ;
colorLinear *= _ColorFilter . xyz ;
colorLinear = max ( 0.0 , colorLinear ) ;
float balance = _SplitShadows . w ;
float3 colorGamma = PositivePow ( colorLinear , 1.0 / 2.2 ) ;
float luma = saturate ( GetLuminance ( saturate ( colorGamma ) ) + balance ) ;
float3 splitShadows = lerp ( ( 0.5 ) . xxx , _SplitShadows . xyz , 1.0 - luma ) ;
float3 splitHighlights = lerp ( ( 0.5 ) . xxx , _SplitHighlights . xyz , luma ) ;
colorGamma = SoftLight ( colorGamma , splitShadows ) ;
colorGamma = SoftLight ( colorGamma , splitHighlights ) ;
colorLinear = PositivePow ( colorGamma , 2.2 ) ;
colorLinear = float3 (
dot ( colorLinear , _ChannelMixerRed . xyz ) ,
dot ( colorLinear , _ChannelMixerGreen . xyz ) ,
dot ( colorLinear , _ChannelMixerBlue . xyz )
) ;
luma = GetLuminance ( colorLinear ) ;
float shadowsFactor = 1.0 - smoothstep ( _ShaHiLimits . x , _ShaHiLimits . y , luma ) ;
float highlightsFactor = smoothstep ( _ShaHiLimits . z , _ShaHiLimits . w , luma ) ;
float midtonesFactor = 1.0 - shadowsFactor - highlightsFactor ;
colorLinear = colorLinear * _Shadows . xyz * shadowsFactor
+ colorLinear * _Midtones . xyz * midtonesFactor
+ colorLinear * _Highlights . xyz * highlightsFactor ;
colorLinear = colorLinear * _Gain . xyz + _Lift . xyz ;
colorLinear = sign ( colorLinear ) * pow ( abs ( colorLinear ) , _Gamma . xyz ) ;
float satMult ;
float3 hsv = RgbToHsv ( colorLinear ) ;
{
satMult = EvaluateCurve ( _CurveHueVsSat , hsv . x ) * 2.0 ;
satMult *= EvaluateCurve ( _CurveSatVsSat , hsv . y ) * 2.0 ;
satMult *= EvaluateCurve ( _CurveLumVsSat , Luminance ( colorLinear ) ) * 2.0 ;
float hue = hsv . x + _HueSatCon . x ;
float offset = EvaluateCurve ( _CurveHueVsHue , hue ) - 0.5 ;
hue += offset ;
hsv . x = RotateHue ( hue , 0.0 , 1.0 ) ;
}
colorLinear = HsvToRgb ( hsv ) ;
luma = GetLuminance ( colorLinear ) ;
colorLinear = luma . xxx + ( _HueSatCon . yyy * satMult ) * ( colorLinear - luma . xxx ) ;
{
const float kHalfPixel = ( 1.0 / 128.0 ) / 2.0 ;
float3 c = colorLinear ;
c += kHalfPixel . xxx ;
float mr = EvaluateCurve ( _CurveMaster , c . r ) ;
float mg = EvaluateCurve ( _CurveMaster , c . g ) ;
float mb = EvaluateCurve ( _CurveMaster , c . b ) ;
c = float3 ( mr , mg , mb ) ;
c += kHalfPixel . xxx ;
float r = EvaluateCurve ( _CurveRed , c . r ) ;
float g = EvaluateCurve ( _CurveGreen , c . g ) ;
float b = EvaluateCurve ( _CurveBlue , c . b ) ;
colorLinear = float3 ( r , g , b ) ;
}
return min16float4 ( saturate ( colorLinear ) , 1.0 ) ;
}
不透明物体渲染
Color Buffer:
_CameraColorAttachmentA_1024x576_B10G11R11_UFloatPack32_Tex2D B10G11R11_UFLOATPack32
Depth Buffer:_CameraDepthAttachment_1024x576_Depth D32S8
Shader:Universal Render Pipeline/Lit
Pass: ForwardLit (0)
顶点Shader:
Varyings LitPassVertex ( Attributes input )
{
Varyings output = ( Varyings ) 0 ;
VertexPositionInputs vertexInput = GetVertexPositionInputs ( input . positionOS . xyz ) ;
VertexNormalInputs normalInput = GetVertexNormalInputs ( input . normalOS , input . tangentOS ) ;
output . uv = ( ( input . texcoord . xy ) * _BaseMap_ST . xy + _BaseMap_ST . zw ) ;
output . normalWS = normalInput . normalWS ;
min16float sign = input . tangentOS . w * GetOddNegativeScale ( ) ;
min16float4 tangentWS = min16float4 ( normalInput . tangentWS . xyz , sign ) ;
output . tangentWS = tangentWS ;
output . staticLightmapUV . xy = input . staticLightmapUV . xy * unity_LightmapST . xy + unity_LightmapST . zw ; ;
output . positionWS = vertexInput . positionWS ;
output . shadowCoord = GetShadowCoord ( vertexInput ) ;
output . positionCS = vertexInput . positionCS ;
return output ;
}
片元Shader:
ClusterIterator ClusterInit ( float2 normalizedScreenSpaceUV , float3 positionWS , int headerIndex )
{
ClusterIterator state = ( ClusterIterator ) 0 ;
uint2 tileId = uint2 ( normalizedScreenSpaceUV * ( ( float2 ) _FPParams1 . xy ) ) ;
state . tileOffset = tileId . y * ( ( uint ) _FPParams1 . z ) + tileId . x ;
state . tileOffset *= ( ( uint ) _FPParams1 . w ) ;
float viewZ = dot ( GetViewForwardDir ( ) , positionWS - GetCameraPositionWS ( ) ) ;
uint zBinBaseIndex = ( uint ) ( ( IsPerspectiveProjection ( ) ? log2 ( viewZ ) : viewZ ) * ( _FPParams0 . x ) + ( _FPParams0 . y ) ) ;
zBinBaseIndex = min ( 4 * 1024 - 1 , zBinBaseIndex ) * ( 2 + ( ( uint ) _FPParams1 . w ) ) ;
uint zBinHeaderIndex = zBinBaseIndex + headerIndex ;
state . zBinOffset = zBinBaseIndex + 2 ;
uint header = Select4 ( asuint ( URP_ZBins [ zBinHeaderIndex / 4 ] ) , zBinHeaderIndex % 4 ) ;
uint tileIndex = state . tileOffset ;
uint zBinIndex = state . zBinOffset ;
if ( ( ( uint ) _FPParams1 . w ) > 0 )
{
state . tileMask =
Select4 ( asuint ( urp_Tiles [ tileIndex / 4 ] ) , tileIndex % 4 ) &
Select4 ( asuint ( URP_ZBins [ zBinIndex / 4 ] ) , zBinIndex % 4 ) &
( 0xFFFFFFFFu << ( header & 0x1F ) ) & ( 0xFFFFFFFFu >> ( 31 - ( header >> 16 ) ) ) ;
}
return state ;
}
bool ClusterNext ( inout ClusterIterator it , out uint entityIndex )
{
bool hasNext = it . tileMask != 0 ;
uint bitIndex = URP_FirstBitLow ( it . tileMask ) ;
it . tileMask ^= ( 1 << bitIndex ) ;
entityIndex = bitIndex ;
return hasNext ;
}
min16float4 UniversalFragmentPBR ( InputData inputData , SurfaceData surfaceData )
{
bool specularHighlightsOff = false ;
BRDFData brdfData ;
InitializeBRDFData ( surfaceData , brdfData ) ;
BRDFData brdfDataClearCoat = CreateClearCoatBRDFData ( surfaceData , brdfData ) ;
min16float4 shadowMask = CalculateShadowMask ( inputData ) ;
AmbientOcclusionFactor aoFactor = CreateAmbientOcclusionFactor ( inputData , surfaceData ) ;
uint meshRenderingLayers = GetMeshRenderingLayer ( ) ;
Light mainLight = GetMainLight ( inputData , shadowMask , aoFactor ) ;
MixRealtimeAndBakedGI ( mainLight , inputData . normalWS , inputData . bakedGI ) ;
LightingData lightingData = CreateLightingData ( inputData , surfaceData ) ;
lightingData . giColor = GlobalIllumination ( brdfData , brdfDataClearCoat , surfaceData . clearCoatMask ,
inputData . bakedGI , aoFactor . indirectAmbientOcclusion , inputData . positionWS ,
inputData . normalWS , inputData . viewDirectionWS , inputData . normalizedScreenSpaceUV ) ;
if ( IsMatchingLightLayer ( mainLight . layerMask , meshRenderingLayers ) )
{
lightingData . mainLightColor = LightingPhysicallyBased ( brdfData , brdfDataClearCoat ,
mainLight ,
inputData . normalWS , inputData . viewDirectionWS ,
surfaceData . clearCoatMask , specularHighlightsOff ) ;
}
uint pixelLightCount = GetAdditionalLightsCount ( ) ;
for ( uint lightIndex = 0 ; lightIndex < min ( ( ( uint ) _FPParams0 . w ) , 32 ) ; lightIndex ++ )
{
if ( _AdditionalLightsColor [ lightIndex ] . a > 0.0h ) continue ;
Light light = GetAdditionalLight ( lightIndex , inputData , shadowMask , aoFactor ) ;
if ( IsMatchingLightLayer ( light . layerMask , meshRenderingLayers ) )
{
lightingData . additionalLightsColor += LightingPhysicallyBased ( brdfData , brdfDataClearCoat , light ,
inputData . normalWS , inputData . viewDirectionWS ,
surfaceData . clearCoatMask , specularHighlightsOff ) ;
}
}//for
{
uint lightIndex ; ClusterIterator _urp_internal_clusterIterator = ClusterInit ( inputData . normalizedScreenSpaceUV , inputData . positionWS , 0 ) ;
[ loop ] while ( ClusterNext ( _urp_internal_clusterIterator , lightIndex ) )
{
lightIndex += ( ( uint ) _FPParams0 . w ) ;
if ( _AdditionalLightsColor [ lightIndex ] . a > 0.0h ) continue ;
Light light = GetAdditionalLight ( lightIndex , inputData , shadowMask , aoFactor ) ;
if ( IsMatchingLightLayer ( light . layerMask , meshRenderingLayers ) )
{
lightingData . additionalLightsColor += LightingPhysicallyBased ( brdfData , brdfDataClearCoat , light ,
inputData . normalWS , inputData . viewDirectionWS ,
surfaceData . clearCoatMask , specularHighlightsOff ) ;
}
} //while
}
return min ( CalculateFinalColor ( lightingData , surfaceData . alpha ) , 65504.0 ) ;
}
void LitPassFragment (Varyings input, out min16float4 outColor : SV_Target0)
{
SurfaceData surfaceData ;
InitializeStandardLitSurfaceData ( input . uv , surfaceData ) ;
InputData inputData ;
InitializeInputData ( input , surfaceData . normalTS , inputData ) ;
min16float4 color = UniversalFragmentPBR ( inputData , surfaceData ) ;
color . rgb = MixFog ( color . rgb , inputData . fogCoord ) ;
color . a = OutputAlpha ( color . a , IsSurfaceTypeTransparent ( _Surface ) ) ;
outColor = color ;
}
天空盒渲染
Color Buffer:
_CameraColorAttachmentA_1024x576_B10G11R11_UFloatPack32_Tex2D B10G11R11_UFLOATPack32
Depth Buffer:_CameraDepthAttachment_1024x576_Depth D32S8
Shader:Skybox/Cubemap
Pass: <Unnamed> (0)
顶点Shader:
float3 RotateAroundYInDegrees (float3 vertex, float degrees)
{
float alpha = degrees * UNITY_PI / 180.0;
float sina, cosa;
sincos(alpha, sina, cosa);
float2x2 m = float2x2(cosa, -sina, sina, cosa);
return float3(mul(m, vertex.xz), vertex.y).xzy;
}
v2f vert (appdata_t v)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
float3 rotated = RotateAroundYInDegrees(v.vertex.xyz, _Rotation);
o.vertex = UnityObjectToClipPos(rotated);
o.texcoord = v.vertex.xyz;
return o;
}
片元Shader:
fixed4 frag (v2f i) : SV_Target
{
half4 tex = texCUBE (_Tex, i.texcoord);
half3 c = DecodeHDR (tex, _Tex_HDR);
c = c * _Tint.rgb * unity_ColorSpaceDouble.rgb;
c *= _Exposure;
return half4(c, 1);
}
深度图拷贝
Color Buffer:
_CameraDepthTexture_1024x576_R32_SFloat_Tex2D R32_SFloat
Depth Buffer:无
Shader:Hidden/Universal Render Pipeline/CopyDepth
Pass: CopyDepth (0)
顶点Shader:
Varyings Vert ( Attributes input )
{
Varyings output ;
;
;
//#line 53
float4 pos = GetFullScreenTriangleVertexPosition ( input . vertexID ) ;
float2 uv = GetFullScreenTriangleTexCoord ( input . vertexID ) ;
//#line 57
output . positionCS = pos ;
output . texcoord = uv * _BlitScaleBias . xy + _BlitScaleBias . zw ;
return output ;
}
片元Shader:
float SampleDepth ( float2 uv )
{
return _CameraDepthAttachment . SampleBias ( sampler_CameraDepthAttachment , uv , _GlobalMipBias . x ) . r ;
}
float frag ( Varyings input ) : SV_Target
{
return SampleDepth ( input . texcoord ) ;
}
贴花渲染
Color Buffer:
_CameraColorAttachmentA_1024x576_B10G11R11_UFloatPack32_Tex2D B10G11R11_UFLOATPack32
Depth Buffer:_CameraDepthAttachment_1024x576_Depth D32S8
Shader:Shader Graphs/GrungeDecal_Graph
Pass: DecalScreenSpaceProjector (1)
顶点Shader:
片元Shader:
颜色图拷贝
Color Buffer:
_CameraColorAttachmentA_1024x576_B10G11R11_UFloatPack32_Tex2D B10G11R11_UFLOATPack32
Depth Buffer:无
Shader:Hidden/Universal/CoreBlit
Pass: <Unnamed> (0)
顶点Shader:
Varyings Vert ( Attributes input )
{
Varyings output ;
float4 pos = GetFullScreenTriangleVertexPosition ( input . vertexID ) ;
float2 uv = GetFullScreenTriangleTexCoord ( input . vertexID ) ;
output . positionCS = pos ;
output . texcoord = uv * _BlitScaleBias . xy + _BlitScaleBias . zw ;
return output ;
}
片元Shader:
float4 FragBlit ( Varyings input , SamplerState s )
{
return _BlitTexture . SampleLevel ( s , input . texcoord . xy , _BlitMipLevel ) ;
}
float4 FragNearest ( Varyings input ) : SV_Target
{
return FragBlit ( input , sampler_PointClamp ) ;
}
半透明物体渲染
Color Buffer:
_CameraColorAttachmentA_1024x576_B10G11R11_UFloatPack32_Tex2D B10G11R11_UFLOATPack32
Depth Buffer:_CameraDepthAttachment_1024x576_Depth D32S8
Shader:Shader Graphs/Water
Pass: Universal Forward(0)
顶点Shader:
片元Shader:
雾效渲染
Color Buffer:
_CameraColorAttachmentA_1024x576_B10G11R11_UFloatPack32_Tex2D B10G11R11_UFLOATPack32
Depth Buffer:_CameraDepthAttachment_1024x576_Depth D32S8
Shader:Shader Graphs/HeightFog
Pass: DrawProcedural (0)
顶点Shader:
片元Shader:
运动矢量渲染
Color Buffer:
_MotionVectorTexture_1024x576_R16G16_SFloat_Tex2D R16G16_SFloat
Depth Buffer:_MotionVectorDepthTexture_1024x576_Depth D32S8
Shader:Hidden/Universal Render Pipeline/CameraMotionVectors
Pass: Camera Motion Vectors (0)
顶点Shader:
Varyings vert ( Attributes input )
{
Varyings output ;
output . position = GetFullScreenTriangleVertexPosition ( input . vertexID ) ;
return output ;
}
片元Shader:
min16float4 frag ( Varyings input , out float outDepth : SV_Depth ) : SV_Target
{
float2 uv = input . position . xy / _ScaledScreenParams . xy ;
float depth = SampleSceneDepth ( uv ) . x ;
outDepth = depth ;
float3 posWS = ComputeWorldSpacePosition ( uv , depth , unity_MatrixInvVP ) ;
float4 posCS = mul ( _NonJitteredViewProjMatrix , float4 ( posWS . xyz , 1.0 ) ) ;
float4 prevPosCS = mul ( _PrevViewProjMatrix , float4 ( posWS . xyz , 1.0 ) ) ;
min16float2 posNDC = posCS . xy * rcp ( posCS . w ) ;
min16float2 prevPosNDC = prevPosCS . xy * rcp ( prevPosCS . w ) ;
min16float2 velocity = ( posNDC - prevPosNDC ) ;
velocity . y = - velocity . y ;
velocity . xy *= 0.5 ;
return min16float4 ( velocity , 0 , 0 ) ;
}
时间反走样
累计缓存更新
Color Buffer:
_CameraColorAttachmentA_1024x576_B10G11R11_UFloatPack32_Tex2D B10G11R11_UFLOATPack32
Depth Buffer:无
Shader:Hidden/Universal Render Pipeline/TemporalAA
Pass: TemporalAA - Accumulate - Quality Medium (2)
顶点Shader:
Varyings Vert ( Attributes input )
{
Varyings output ;
float4 pos = GetFullScreenTriangleVertexPosition ( input . vertexID ) ;
float2 uv = GetFullScreenTriangleTexCoord ( input . vertexID ) ;
output . positionCS = pos ;
output . texcoord = uv * _BlitScaleBias . xy + _BlitScaleBias . zw ;
return output ;
}
片元Shader:
min16float4 DoTemporalAA ( Varyings input , int clampQuality , int motionQuality , int historyQuality , int centralFiltering )
{
float2 uv = input . texcoord ;
min16float3 colorCenter ;
if ( centralFiltering >= 1 )
colorCenter = FilterColor ( uv , _TaaFilterWeights ) ;
else
colorCenter = SceneToWorkingSpace ( SampleColorPoint ( uv , float2 ( 0 , 0 ) ) . xyz ) ;
min16float3 boxMax = colorCenter ;
min16float3 boxMin = colorCenter ;
min16float3 moment1 = colorCenter ;
min16float3 moment2 = colorCenter * colorCenter ;
AdjustColorBox ( boxMin , boxMax , moment1 , moment2 , uv , 0.0f , - 1.0f ) ;
AdjustColorBox ( boxMin , boxMax , moment1 , moment2 , uv , - 1.0f , 0.0f ) ;
AdjustColorBox ( boxMin , boxMax , moment1 , moment2 , uv , 1.0f , 0.0f ) ;
AdjustColorBox ( boxMin , boxMax , moment1 , moment2 , uv , 0.0f , 1.0f ) ;
if ( clampQuality >= 1 )
{
AdjustColorBox ( boxMin , boxMax , moment1 , moment2 , uv , - 1.0f , - 1.0f ) ;
AdjustColorBox ( boxMin , boxMax , moment1 , moment2 , uv , 1.0f , - 1.0f ) ;
AdjustColorBox ( boxMin , boxMax , moment1 , moment2 , uv , - 1.0f , 1.0f ) ;
AdjustColorBox ( boxMin , boxMax , moment1 , moment2 , uv , 1.0f , 1.0f ) ;
}
if ( clampQuality >= 2 )
{
min16float perSample = 1 / min16float ( 9 ) ;
min16float3 mean = moment1 * perSample ;
min16float3 stdDev = sqrt ( abs ( moment2 * perSample - mean * mean ) ) ;
min16float devScale = _TaaVarianceClampScale ;
min16float3 devMin = mean - devScale * stdDev ;
min16float3 devMax = mean + devScale * stdDev ;
boxMin = max ( boxMin , devMin ) ;
boxMax = min ( boxMax , devMax ) ;
}
min16float bestOffsetX = 0.0f ;
min16float bestOffsetY = 0.0f ;
min16float bestDepth = 1.0f ;
if ( motionQuality >= 1 )
{
AdjustBestDepthOffset ( bestDepth , bestOffsetX , bestOffsetY , uv , 0.0f , 0.0f ) ;
AdjustBestDepthOffset ( bestDepth , bestOffsetX , bestOffsetY , uv , 1.0f , 0.0f ) ;
AdjustBestDepthOffset ( bestDepth , bestOffsetX , bestOffsetY , uv , 0.0f , - 1.0f ) ;
AdjustBestDepthOffset ( bestDepth , bestOffsetX , bestOffsetY , uv , - 1.0f , 0.0f ) ;
AdjustBestDepthOffset ( bestDepth , bestOffsetX , bestOffsetY , uv , 0.0f , 1.0f ) ;
}
if ( motionQuality >= 2 )
{
AdjustBestDepthOffset ( bestDepth , bestOffsetX , bestOffsetY , uv , - 1.0f , - 1.0f ) ;
AdjustBestDepthOffset ( bestDepth , bestOffsetX , bestOffsetY , uv , 1.0f , - 1.0f ) ;
AdjustBestDepthOffset ( bestDepth , bestOffsetX , bestOffsetY , uv , - 1.0f , 1.0f ) ;
AdjustBestDepthOffset ( bestDepth , bestOffsetX , bestOffsetY , uv , 1.0f , 1.0f ) ;
}
min16float2 depthOffsetUv = min16float2 ( bestOffsetX , bestOffsetY ) ;
min16float2 velocity = GetVelocityWithOffset ( uv , depthOffsetUv ) ;
float2 historyUv = uv + velocity * float2 ( 1 , 1 ) ;
min16float3 accum = ( historyQuality >= 2 ) ?
SampleBicubic5TapHalf ( _TaaAccumulationTex , historyUv , _TaaAccumulationTex_TexelSize . xyzw ) :
SceneToWorkingSpace ( _TaaAccumulationTex . SampleBias ( sampler_LinearClamp , historyUv , _GlobalMipBias . x ) . xyz ) ;
min16float3 clampAccum = ( clampQuality >= 3 ) ? ClipToAABBCenter ( accum , boxMin , boxMax ) : clamp ( accum , boxMin , boxMax ) ;
min16float frameInfluence = ( ( historyQuality >= 1 ) && any ( abs ( uv - 0.5 + velocity ) > 0.5 ) ) ? 1 : _TaaFrameInfluence ;
min16float3 workingColor = ApplyHistoryColorLerp ( clampAccum , colorCenter , frameInfluence ) ;
min16float3 dstSceneColor = WorkingSpaceToScene ( workingColor ) ;
return min16float4 ( max ( dstSceneColor , 0.0 ) , 1.0 ) ;
}
min16float4 TaaFrag ( Varyings input ) : SV_Target
{
return DoTemporalAA ( input , 2 , 2 , 1 , 0 ) ;
}
颜色历史拷贝
Color Buffer:
_TaaAccumulationTex_1024x576_B10G11R11_UFloatPack32_Tex2D B10G11R11_UFLOATPack32
Depth Buffer:无
Shader:Hidden/Universal Render Pipeline/TemporalAA
Pass: TemporalAA - Copy History (5)
顶点Shader:
Varyings Vert ( Attributes input )
{
Varyings output ;
float4 pos = GetFullScreenTriangleVertexPosition ( input . vertexID ) ;
float2 uv = GetFullScreenTriangleTexCoord ( input . vertexID ) ;
output . positionCS = pos ;
output . texcoord = uv * _BlitScaleBias . xy + _BlitScaleBias . zw ;
return output ;
}
片元Shader:
min16float4 DoCopy ( Varyings input )
{
float2 uv = input . texcoord . xy ;
min16float3 color = _BlitTexture . SampleBias ( sampler_PointClamp , uv , _GlobalMipBias . x ) . xyz ;
return min16float4 ( color , 1.0f ) ;
}
min16float4 TaaFrag ( Varyings input ) : SV_Target
{
return DoCopy ( input ) ;
}
光晕图生成
预滤波
Color Buffer:
_BloomMipDown0_256x144_B10G11R11_UFloatPack32_Tex2D B10G11R11_UFLOATPack32
Depth Buffer:无
Shader:Hidden/Universal Render Pipeline/Bloom
Pass: Bloom Prefilter (0)
顶点Shader:
Varyings Vert ( Attributes input )
{
Varyings output ;
float4 pos = GetFullScreenTriangleVertexPosition ( input . vertexID ) ;
float2 uv = GetFullScreenTriangleTexCoord ( input . vertexID ) ;
output . positionCS = pos ;
output . texcoord = uv * _BlitScaleBias . xy + _BlitScaleBias . zw ;
return output ;
}
片元Shader:
min16float4 EncodeHDR ( min16float3 color )
{
min16float4 outColor = min16float4 ( color , 1.0 ) ;
return outColor ;
}
min16float4 FragPrefilter ( Varyings input ) : SV_Target
{
float2 uv = input . texcoord ;
min16float3 color = _BlitTexture . SampleBias ( sampler_LinearClamp , uv , _GlobalMipBias . x ) . xyz ;
color = min ( _Params . y , color ) ;
min16float brightness = Max3 ( color . r , color . g , color . b ) ;
min16float softness = clamp ( brightness - _Params . z + _Params . w , 0.0 , 2.0 * _Params . w ) ;
softness = ( softness * softness ) / ( 4.0 * _Params . w + 1e-4 ) ;
min16float multiplier = max ( brightness - _Params . z , softness ) / max ( brightness , 1e-4 ) ;
color *= multiplier ;
color = max ( color , 0 ) ;
return EncodeHDR ( color ) ;
}
第一次水平模糊
Color Buffer:
_BloomMipUp1_128x72_B10G11R11_UFloatPack32_Tex2D B10G11R11_UFLOATPack32
Depth Buffer:无
Shader:Hidden/Universal Render Pipeline/Bloom
Pass: Bloom Blur Horizontal (1)
顶点Shader:
Varyings Vert ( Attributes input )
{
Varyings output ;
float4 pos = GetFullScreenTriangleVertexPosition ( input . vertexID ) ;
float2 uv = GetFullScreenTriangleTexCoord ( input . vertexID ) ;
output . positionCS = pos ;
output . texcoord = uv * _BlitScaleBias . xy + _BlitScaleBias . zw ;
return output ;
}
片元Shader:
min16float4 EncodeHDR ( min16float3 color )
{
min16float4 outColor = min16float4 ( color , 1.0 ) ;
return outColor ;
}
min16float4 FragBlurH ( Varyings input ) : SV_Target
{
float texelSize = _BlitTexture_TexelSize . x * 2.0 ;
float2 uv = input . texcoord ;
min16float3 c0 = DecodeHDR ( _BlitTexture . SampleBias ( sampler_LinearClamp , uv - float2 ( texelSize * 4.0 , 0.0 ) , _GlobalMipBias . x ) ) ;
min16float3 c1 = DecodeHDR ( _BlitTexture . SampleBias ( sampler_LinearClamp , uv - float2 ( texelSize * 3.0 , 0.0 ) , _GlobalMipBias . x ) ) ;
min16float3 c2 = DecodeHDR ( _BlitTexture . SampleBias ( sampler_LinearClamp , uv - float2 ( texelSize * 2.0 , 0.0 ) , _GlobalMipBias . x ) ) ;
min16float3 c3 = DecodeHDR ( _BlitTexture . SampleBias ( sampler_LinearClamp , uv - float2 ( texelSize * 1.0 , 0.0 ) , _GlobalMipBias . x ) ) ;
min16float3 c4 = DecodeHDR ( _BlitTexture . SampleBias ( sampler_LinearClamp , uv , _GlobalMipBias . x ) ) ;
min16float3 c5 = DecodeHDR ( _BlitTexture . SampleBias ( sampler_LinearClamp , uv + float2 ( texelSize * 1.0 , 0.0 ) , _GlobalMipBias . x ) ) ;
min16float3 c6 = DecodeHDR ( _BlitTexture . SampleBias ( sampler_LinearClamp , uv + float2 ( texelSize * 2.0 , 0.0 ) , _GlobalMipBias . x ) ) ;
min16float3 c7 = DecodeHDR ( _BlitTexture . SampleBias ( sampler_LinearClamp , uv + float2 ( texelSize * 3.0 , 0.0 ) , _GlobalMipBias . x ) ) ;
min16float3 c8 = DecodeHDR ( _BlitTexture . SampleBias ( sampler_LinearClamp , uv + float2 ( texelSize * 4.0 , 0.0 ) , _GlobalMipBias . x ) ) ;
min16float3 color = c0 * 0.01621622 + c1 * 0.05405405 + c2 * 0.12162162 + c3 * 0.19459459
+ c4 * 0.22702703
+ c5 * 0.19459459 + c6 * 0.12162162 + c7 * 0.05405405 + c8 * 0.01621622 ;
return EncodeHDR ( color ) ;
}
第一次垂直模糊
Color Buffer:
_BloomMipDown1_128x72_B10G11R11_UFloatPack32_Tex2D B10G11R11_UFLOATPack32
Depth Buffer:无
Shader:Hidden/Universal Render Pipeline/Bloom
Pass: Bloom Blur Vertical (2)
顶点Shader:
Varyings Vert ( Attributes input )
{
Varyings output ;
float4 pos = GetFullScreenTriangleVertexPosition ( input . vertexID ) ;
float2 uv = GetFullScreenTriangleTexCoord ( input . vertexID ) ;
output . positionCS = pos ;
output . texcoord = uv * _BlitScaleBias . xy + _BlitScaleBias . zw ;
return output ;
}
片元Shader:
min16float4 EncodeHDR ( min16float3 color )
{
min16float4 outColor = min16float4 ( color , 1.0 ) ;
return outColor ;
}
min16float4 FragBlurV ( Varyings input ) : SV_Target
{
;
float texelSize = _BlitTexture_TexelSize . y ;
float2 uv = input . texcoord ;
//#line 139
min16float3 c0 = DecodeHDR ( _BlitTexture . SampleBias ( sampler_LinearClamp , uv - float2 ( 0.0 , texelSize * 3.23076923 ) , _GlobalMipBias . x ) ) ;
min16float3 c1 = DecodeHDR ( _BlitTexture . SampleBias ( sampler_LinearClamp , uv - float2 ( 0.0 , texelSize * 1.38461538 ) , _GlobalMipBias . x ) ) ;
min16float3 c2 = DecodeHDR ( _BlitTexture . SampleBias ( sampler_LinearClamp , uv , _GlobalMipBias . x ) ) ;
min16float3 c3 = DecodeHDR ( _BlitTexture . SampleBias ( sampler_LinearClamp , uv + float2 ( 0.0 , texelSize * 1.38461538 ) , _GlobalMipBias . x ) ) ;
min16float3 c4 = DecodeHDR ( _BlitTexture . SampleBias ( sampler_LinearClamp , uv + float2 ( 0.0 , texelSize * 3.23076923 ) , _GlobalMipBias . x ) ) ;
min16float3 color = c0 * 0.07027027 + c1 * 0.31621622
+ c2 * 0.22702703
+ c3 * 0.31621622 + c4 * 0.07027027 ;
return EncodeHDR ( color ) ;
}
第二次水平模糊
Color Buffer:
_BloomMipUp2_64x36_B10G11R11_UFloatPack32_Tex2D B10G11R11_UFLOATPack32
Depth Buffer:无
Shader:Hidden/Universal Render Pipeline/Bloom
Pass: Bloom Blur Horizontal (1)
第二次垂直模糊
Color Buffer:
_BloomMipDown2_64x36_B10G11R11_UFloatPack32_Tex2D B10G11R11_UFLOATPack32
Depth Buffer:无
Shader:Hidden/Universal Render Pipeline/Bloom
Pass: Bloom Blur Vertical (2)
第三次水平模糊
Color Buffer:
_BloomMipUp3_32x18_B10G11R11_UFloatPack32_Tex2D B10G11R11_UFLOATPack32
Depth Buffer:无
Shader:Hidden/Universal Render Pipeline/Bloom
Pass: Bloom Blur Horizontal (1)
第三次垂直模糊
Color Buffer:
_BloomMipDown3_32x18_B10G11R11_UFloatPack32_Tex2D B10G11R11_UFLOATPack32
Depth Buffer:无
Shader:Hidden/Universal Render Pipeline/Bloom
Pass: Bloom Blur Vertical (2)
第一次上采样
Color Buffer:
_BloomMipUp2_64x36_B10G11R11_UFloatPack32_Tex2D B10G11R11_UFLOATPack32
Depth Buffer:无
Shader:Hidden/Universal Render Pipeline/Bloom
Pass: Bloom Upsample (3)
顶点Shader:
Varyings Vert ( Attributes input )
{
Varyings output ;
float4 pos = GetFullScreenTriangleVertexPosition ( input . vertexID ) ;
float2 uv = GetFullScreenTriangleTexCoord ( input . vertexID ) ;
output . positionCS = pos ;
output . texcoord = uv * _BlitScaleBias . xy + _BlitScaleBias . zw ;
return output ;
}
片元Shader:
min16float4 EncodeHDR ( min16float3 color )
{
min16float4 outColor = min16float4 ( color , 1.0 ) ;
return outColor ;
}
min16float3 DecodeHDR ( min16float4 color )
{
return color . xyz ;
}
min16float3 Upsample ( float2 uv )
{
min16float3 highMip = DecodeHDR ( _BlitTexture . SampleBias ( sampler_LinearClamp , uv , _GlobalMipBias . x ) ) ;
min16float3 lowMip = DecodeHDR ( _SourceTexLowMip . SampleBias ( sampler_LinearClamp , uv , _GlobalMipBias . x ) ) ;
return lerp ( highMip , lowMip , _Params . x ) ;
}
min16float4 FragUpsample ( Varyings input ) : SV_Target
{
min16float3 color = Upsample ( input . texcoord ) ;
return EncodeHDR ( color ) ;
}
第二次上采样
Color Buffer:
_BloomMipUp1_128x72_B10G11R11_UFloatPack32_Tex2D B10G11R11_UFLOATPack32
Depth Buffer:无
Shader:Hidden/Universal Render Pipeline/Bloom
Pass: Bloom Upsample (3)
第三次上采样
Color Buffer:
_BloomMipUp0_256x144_B10G11R11_UFloatPack32_Tex2D B10G11R11_UFLOATPack32
Depth Buffer:无
Shader:Hidden/Universal Render Pipeline/Bloom
Pass: Bloom Upsample (3)
后处理效果合成
Color Buffer:
_CameraColorAttachmentA_1024x576_B10G11R11_UFloatPack32_Tex2D B10G11R11_UFLOATPack32
Depth Buffer:无
Shader:Hidden/Universal Render Pipeline/UberPost
Pass: UberPost (0)
顶点Shader:
Varyings Vert ( Attributes input )
{
Varyings output ;
float4 pos = GetFullScreenTriangleVertexPosition ( input . vertexID ) ;
float2 uv = GetFullScreenTriangleTexCoord ( input . vertexID ) ;
output . positionCS = pos ;
output . texcoord = uv * _BlitScaleBias . xy + _BlitScaleBias . zw ;
return output ;
}
片元Shader:
float2 DistortUV ( float2 uv )
{
return uv ;
}
min16float3 DecodeRGBM ( min16float4 rgbm )
{
return rgbm . xyz * rgbm . w * kRGBMRange ;
}
min16float3 ApplyVignette ( min16float3 input , float2 uv , float2 center , float intensity , float roundness , float smoothness , min16float3 color )
{
center = center ;
float2 dist = abs ( uv - center ) * intensity ;
dist . x *= roundness ;
float vfactor = pow ( saturate ( 1.0 - dot ( dist , dist ) ) , smoothness ) ;
return input * lerp ( color , ( 1.0 ) . xxx , vfactor ) ;
}
float3 NeutralCurve ( float3 x , min16float a , min16float b , min16float c , min16float d , min16float e , min16float f )
{
return ( ( x * ( a * x + c * b ) + d * e ) / ( x * ( a * x + b ) + d * f ) ) - e / f ;
}
min16float3 NeutralTonemap ( min16float3 x )
{
const min16float a = 0.2 ;
const min16float b = 0.29 ;
const min16float c = 0.24 ;
const min16float d = 0.272 ;
const min16float e = 0.02 ;
const min16float f = 0.3 ;
const min16float whiteLevel = 5.3 ;
const min16float whiteClip = 1.0 ;
x = min ( x , 435.18712 ) ;
min16float3 whiteScale = ( 1.0 ) . xxx / NeutralCurve ( whiteLevel , a , b , c , d , e , f ) ;
x = NeutralCurve ( x * whiteScale , a , b , c , d , e , f ) ;
x *= whiteScale ;
x /= whiteClip . xxx ;
return x ;
}
min16float3 ApplyTonemap ( min16float3 input )
{
input = NeutralTonemap ( input ) ;
return saturate ( input ) ;
}
min16float3 FastLinearToSRGB ( min16float3 c )
{
return saturate ( 1.055 * PositivePow ( c , 0.416666667 ) - 0.055 ) ;
}
min16float3 GetLinearToSRGB ( min16float3 c )
{
return FastLinearToSRGB ( c ) ;
}
min16float3 GetSRGBToLinear ( min16float3 c )
{
return FastSRGBToLinear ( c ) ;
}
min16float3 FastSRGBToLinear ( min16float3 c )
{
return c * ( c * ( c * 0.305306011 + 0.682171111 ) + 0.012522878 ) ;
}
min16float3 ApplyLut2D ( Texture2D tex , SamplerState samplerTex , float3 uvw , float3 scaleOffset )
{
uvw . z *= scaleOffset . z ;
float shift = floor ( uvw . z ) ;
uvw . xy = uvw . xy * scaleOffset . z * scaleOffset . xy + scaleOffset . xy * 0.5 ;
uvw . x += shift * scaleOffset . y ;
uvw . xyz = lerp (
tex . SampleLevel ( samplerTex , uvw . xy , 0.0 ) . rgb ,
tex . SampleLevel ( samplerTex , uvw . xy + float2 ( scaleOffset . y , 0.0 ) , 0.0 ) . rgb ,
uvw . z - shift
) ;
return uvw ;
}
min16float3 ApplyColorGrading ( min16float3 input , float postExposure , Texture2D lutTex , SamplerState lutSampler , float3 lutParams , Texture2D userLutTex , SamplerState userLutSampler , float3 userLutParams , float userLutContrib )
{
input *= postExposure ;
{
input = ApplyTonemap ( input ) ;
[ branch ]
if ( userLutContrib > 0.0 )
{
input . rgb = GetLinearToSRGB ( input . rgb ) ;
min16float3 outLut = ApplyLut2D ( userLutTex , userLutSampler , input , userLutParams ) ;
input = lerp ( input , outLut , userLutContrib ) ;
input . rgb = GetSRGBToLinear ( input . rgb ) ;
}
input = ApplyLut2D ( lutTex , lutSampler , input , lutParams ) ;
}
return input ;
}
min16float4 FragUberPost ( Varyings input ) : SV_Target
{
float2 uv = input . texcoord ;
float2 uvDistorted = DistortUV ( uv ) ;
min16float3 color = ( 0.0 ) . xxx ;
{
color = _BlitTexture . SampleBias ( sampler_LinearClamp , uvDistorted , _GlobalMipBias . x ) . xyz ;
}
{
float2 uvBloom = uvDistorted ;
min16float4 bloom = _Bloom_Texture . SampleBias ( sampler_LinearClamp , uvBloom , _GlobalMipBias . x ) ;
[ branch ]
if ( _Bloom_RGBM . x > 0 )
{
bloom . xyz = DecodeRGBM ( bloom ) ;
}
bloom . xyz *= _Bloom_Params . x ;
color += bloom . xyz * _Bloom_Params . yzw ;
}
[ branch ]
if ( _Vignette_Params2 . z > 0 )
{
color = ApplyVignette ( color , uvDistorted , _Vignette_Params2 . xy , _Vignette_Params2 . z , _Vignette_Params1 . w , _Vignette_Params2 . w , _Vignette_Params1 . xyz ) ;
}
{
color = ApplyColorGrading ( color , _Lut_Params . w , _InternalLut , sampler_LinearClamp , _Lut_Params . xyz , _UserLut , sampler_LinearClamp , _UserLut_Params . xyz , _UserLut_Params . w ) ;
}
return min16float4 ( color , 1.0 ) ;
}
最终画面生成
缩放设置
Color Buffer:
_ScalingSetupTexture_1024x576_A2B10G10R10_UNormPack32_Tex2D A2B10G10R10_UNormPack32
Depth Buffer:无
Shader:Hidden/Universal Render Pipeline/Scaling Setup
Pass: ScalingSetup (0)
顶点Shader:
Varyings Vert ( Attributes input )
{
Varyings output ;
float4 pos = GetFullScreenTriangleVertexPosition ( input . vertexID ) ;
float2 uv = GetFullScreenTriangleTexCoord ( input . vertexID ) ;
output . positionCS = pos ;
output . texcoord = uv * _BlitScaleBias . xy + _BlitScaleBias . zw ;
return output ;
}
片元Shader:
min16float4 FragScalingSetup ( Varyings input ) : SV_Target
{
float2 uv = input . texcoord ;
float2 positionNDC = uv ;
int2 positionSS = uv * _SourceSize . xy ;
min16float3 color = _BlitTexture . SampleBias ( sampler_PointClamp , uv , _GlobalMipBias . x ) . xyz ;
return min16float4 ( color , 1.0 ) ;
}
边缘自适应空间上采样
Color Buffer:
_UpScaledTexture_1280x720_A2B10G10R10_UNormPack32_Tex2D A2B10G10R10_UNormPack32
Depth Buffer:无
Shader:Hidden/Universal Render Pipeline/Edge Adaptive Spatial Upsampling
Pass: EASU (0)
顶点Shader:
Varyings Vert ( Attributes input )
{
Varyings output ;
float4 pos = GetFullScreenTriangleVertexPosition ( input . vertexID ) ;
float2 uv = GetFullScreenTriangleTexCoord ( input . vertexID ) ;
output . positionCS = pos ;
output . texcoord = uv * _BlitScaleBias . xy + _BlitScaleBias . zw ;
return output ;
}
片元Shader:
void FsrEasuF (
out float3 pix ,
uint2 ip ,
uint4 con0 ,
uint4 con1 ,
uint4 con2 ,
uint4 con3 ) {
//#line 325
float2 pp = float2 ( ip ) * asfloat ( uint2 ( con0 . xy ) ) + asfloat ( uint2 ( con0 . zw ) ) ;
float2 fp = floor ( pp ) ;
pp -= fp ;
//#line 345
float2 p0 = fp * asfloat ( uint2 ( con1 . xy ) ) + asfloat ( uint2 ( con1 . zw ) ) ;
float2 p1 = p0 + asfloat ( uint2 ( con2 . xy ) ) ;
float2 p2 = p0 + asfloat ( uint2 ( con2 . zw ) ) ;
float2 p3 = p0 + asfloat ( uint2 ( con3 . xy ) ) ;
float4 bczzR = FsrEasuRF ( p0 ) ;
float4 bczzG = FsrEasuGF ( p0 ) ;
float4 bczzB = FsrEasuBF ( p0 ) ;
FsrEasuProcessInput ( bczzR , bczzG , bczzB ) ;
float4 ijfeR = FsrEasuRF ( p1 ) ;
float4 ijfeG = FsrEasuGF ( p1 ) ;
float4 ijfeB = FsrEasuBF ( p1 ) ;
FsrEasuProcessInput ( ijfeR , ijfeG , ijfeB ) ;
float4 klhgR = FsrEasuRF ( p2 ) ;
float4 klhgG = FsrEasuGF ( p2 ) ;
float4 klhgB = FsrEasuBF ( p2 ) ;
FsrEasuProcessInput ( klhgR , klhgG , klhgB ) ;
float4 zzonR = FsrEasuRF ( p3 ) ;
float4 zzonG = FsrEasuGF ( p3 ) ;
float4 zzonB = FsrEasuBF ( p3 ) ;
FsrEasuProcessInput ( zzonR , zzonG , zzonB ) ;
//#line 368
float4 bczzL = bczzB * AF4_x ( float ( 0.5 ) ) + ( bczzR * AF4_x ( float ( 0.5 ) ) + bczzG ) ;
float4 ijfeL = ijfeB * AF4_x ( float ( 0.5 ) ) + ( ijfeR * AF4_x ( float ( 0.5 ) ) + ijfeG ) ;
float4 klhgL = klhgB * AF4_x ( float ( 0.5 ) ) + ( klhgR * AF4_x ( float ( 0.5 ) ) + klhgG ) ;
float4 zzonL = zzonB * AF4_x ( float ( 0.5 ) ) + ( zzonR * AF4_x ( float ( 0.5 ) ) + zzonG ) ;
float bL = bczzL . x ;
float cL = bczzL . y ;
float iL = ijfeL . x ;
float jL = ijfeL . y ;
float fL = ijfeL . z ;
float eL = ijfeL . w ;
float kL = klhgL . x ;
float lL = klhgL . y ;
float hL = klhgL . z ;
float gL = klhgL . w ;
float oL = zzonL . z ;
float nL = zzonL . w ;
float2 dir = AF2_x ( float ( 0.0 ) ) ;
float len = AF1_x ( float ( 0.0 ) ) ;
FsrEasuSetF ( dir , len , pp , true , false , false , false , bL , eL , fL , gL , jL ) ;
FsrEasuSetF ( dir , len , pp , false , true , false , false , cL , fL , gL , hL , kL ) ;
FsrEasuSetF ( dir , len , pp , false , false , true , false , fL , iL , jL , kL , nL ) ;
FsrEasuSetF ( dir , len , pp , false , false , false , true , gL , jL , kL , lL , oL ) ;
//#line 394
float2 dir2 = dir * dir ;
float dirR = dir2 . x + dir2 . y ;
bool zro = dirR < AF1_x ( float ( 1.0 / 32768.0 ) ) ;
dirR = APrxLoRsqF1 ( dirR ) ;
dirR = zro ? AF1_x ( float ( 1.0 ) ) : dirR ;
dir . x = zro ? AF1_x ( float ( 1.0 ) ) : dir . x ;
dir *= AF2_x ( float ( dirR ) ) ;
len = len * AF1_x ( float ( 0.5 ) ) ;
len *= len ;
float stretch = ( dir . x * dir . x + dir . y * dir . y ) * APrxLoRcpF1 ( max ( abs ( dir . x ) , abs ( dir . y ) ) ) ;
//#line 409
float2 len2 = float2 ( AF1_x ( float ( 1.0 ) ) + ( stretch - AF1_x ( float ( 1.0 ) ) ) * len , AF1_x ( float ( 1.0 ) ) + AF1_x ( float ( - 0.5 ) ) * len ) ;
//#line 412
float lob = AF1_x ( float ( 0.5 ) ) + AF1_x ( float ( ( 1.0 / 4.0 - 0.04 ) - 0.5 ) ) * len ;
float clp = APrxLoRcpF1 ( lob ) ;
//#line 421
float3 min4 = min ( AMin3F3 ( float3 ( ijfeR . z , ijfeG . z , ijfeB . z ) , float3 ( klhgR . w , klhgG . w , klhgB . w ) , float3 ( ijfeR . y , ijfeG . y , ijfeB . y ) ) ,
float3 ( klhgR . x , klhgG . x , klhgB . x ) ) ;
float3 max4 = max ( AMax3F3 ( float3 ( ijfeR . z , ijfeG . z , ijfeB . z ) , float3 ( klhgR . w , klhgG . w , klhgB . w ) , float3 ( ijfeR . y , ijfeG . y , ijfeB . y ) ) ,
float3 ( klhgR . x , klhgG . x , klhgB . x ) ) ;
float3 aC = AF3_x ( float ( 0.0 ) ) ;
float aW = AF1_x ( float ( 0.0 ) ) ;
FsrEasuTapF ( aC , aW , float2 ( 0.0 , - 1.0 ) - pp , dir , len2 , lob , clp , float3 ( bczzR . x , bczzG . x , bczzB . x ) ) ;
FsrEasuTapF ( aC , aW , float2 ( 1.0 , - 1.0 ) - pp , dir , len2 , lob , clp , float3 ( bczzR . y , bczzG . y , bczzB . y ) ) ;
FsrEasuTapF ( aC , aW , float2 ( - 1.0 , 1.0 ) - pp , dir , len2 , lob , clp , float3 ( ijfeR . x , ijfeG . x , ijfeB . x ) ) ;
FsrEasuTapF ( aC , aW , float2 ( 0.0 , 1.0 ) - pp , dir , len2 , lob , clp , float3 ( ijfeR . y , ijfeG . y , ijfeB . y ) ) ;
FsrEasuTapF ( aC , aW , float2 ( 0.0 , 0.0 ) - pp , dir , len2 , lob , clp , float3 ( ijfeR . z , ijfeG . z , ijfeB . z ) ) ;
FsrEasuTapF ( aC , aW , float2 ( - 1.0 , 0.0 ) - pp , dir , len2 , lob , clp , float3 ( ijfeR . w , ijfeG . w , ijfeB . w ) ) ;
FsrEasuTapF ( aC , aW , float2 ( 1.0 , 1.0 ) - pp , dir , len2 , lob , clp , float3 ( klhgR . x , klhgG . x , klhgB . x ) ) ;
FsrEasuTapF ( aC , aW , float2 ( 2.0 , 1.0 ) - pp , dir , len2 , lob , clp , float3 ( klhgR . y , klhgG . y , klhgB . y ) ) ;
FsrEasuTapF ( aC , aW , float2 ( 2.0 , 0.0 ) - pp , dir , len2 , lob , clp , float3 ( klhgR . z , klhgG . z , klhgB . z ) ) ;
FsrEasuTapF ( aC , aW , float2 ( 1.0 , 0.0 ) - pp , dir , len2 , lob , clp , float3 ( klhgR . w , klhgG . w , klhgB . w ) ) ;
FsrEasuTapF ( aC , aW , float2 ( 1.0 , 2.0 ) - pp , dir , len2 , lob , clp , float3 ( zzonR . z , zzonG . z , zzonB . z ) ) ;
FsrEasuTapF ( aC , aW , float2 ( 0.0 , 2.0 ) - pp , dir , len2 , lob , clp , float3 ( zzonR . w , zzonG . w , zzonB . w ) ) ;
pix = min ( max4 , max ( min4 , aC * AF3_x ( float ( ARcpF1 ( aW ) ) ) ) ) ;
}
min16float3 ApplyEASU ( uint2 positionSS )
{
float3 color ;
FsrEasuF (
color , positionSS , asuint ( _FsrEasuConstants0 ) , asuint ( _FsrEasuConstants1 ) , asuint ( _FsrEasuConstants2 ) , asuint ( _FsrEasuConstants3 )
) ;
return color ;
}
min16float4 FragEASU ( Varyings input ) : SV_Target
{
float2 uv = input . texcoord ;
uint2 integerUv = uv * _ScreenParams . xy ;
min16float3 color = ApplyEASU ( integerUv ) ;
color = Gamma20ToLinear ( color ) ;
return min16float4 ( color , 1.0 ) ;
}
最终后处理
Color Buffer:
GameView RT R8G8B8A8_SRGB
Depth Buffer:无
Shader:Hidden/Universal Render Pipeline/FinalPost
Pass: FinalPost (0)
顶点Shader:
Varyings Vert ( Attributes input )
{
Varyings output ;
float4 pos = GetFullScreenTriangleVertexPosition ( input . vertexID ) ;
float2 uv = GetFullScreenTriangleTexCoord ( input . vertexID ) ;
output . positionCS = pos ;
output . texcoord = uv * _BlitScaleBias . xy + _BlitScaleBias . zw ;
return output ;
}
片元Shader:
void FsrRcasF (
out float pixR ,
out float pixG ,
out float pixB ,
uint2 ip ,
uint4 con ) {
int2 sp = int2 ( ip ) ;
float3 b = FsrRcasLoadF ( sp + int2 ( 0 , - 1 ) ) . rgb ;
float3 d = FsrRcasLoadF ( sp + int2 ( - 1 , 0 ) ) . rgb ;
float3 e = FsrRcasLoadF ( sp ) . rgb ;
float3 f = FsrRcasLoadF ( sp + int2 ( 1 , 0 ) ) . rgb ;
float3 h = FsrRcasLoadF ( sp + int2 ( 0 , 1 ) ) . rgb ;
float bR = b . r ;
float bG = b . g ;
float bB = b . b ;
float dR = d . r ;
float dG = d . g ;
float dB = d . b ;
float eR = e . r ;
float eG = e . g ;
float eB = e . b ;
float fR = f . r ;
float fG = f . g ;
float fB = f . b ;
float hR = h . r ;
float hG = h . g ;
float hB = h . b ;
FsrRcasInputF ( bR , bG , bB ) ;
FsrRcasInputF ( dR , dG , dB ) ;
FsrRcasInputF ( eR , eG , eB ) ;
FsrRcasInputF ( fR , fG , fB ) ;
FsrRcasInputF ( hR , hG , hB ) ;
float bL = bB * AF1_x ( float ( 0.5 ) ) + ( bR * AF1_x ( float ( 0.5 ) ) + bG ) ;
float dL = dB * AF1_x ( float ( 0.5 ) ) + ( dR * AF1_x ( float ( 0.5 ) ) + dG ) ;
float eL = eB * AF1_x ( float ( 0.5 ) ) + ( eR * AF1_x ( float ( 0.5 ) ) + eG ) ;
float fL = fB * AF1_x ( float ( 0.5 ) ) + ( fR * AF1_x ( float ( 0.5 ) ) + fG ) ;
float hL = hB * AF1_x ( float ( 0.5 ) ) + ( hR * AF1_x ( float ( 0.5 ) ) + hG ) ;
float nz = AF1_x ( float ( 0.25 ) ) * bL + AF1_x ( float ( 0.25 ) ) * dL + AF1_x ( float ( 0.25 ) ) * fL + AF1_x ( float ( 0.25 ) ) * hL - eL ;
nz = ASatF1 ( abs ( nz ) * APrxMedRcpF1 ( AMax3F1 ( AMax3F1 ( bL , dL , eL ) , fL , hL ) - AMin3F1 ( AMin3F1 ( bL , dL , eL ) , fL , hL ) ) ) ;
nz = AF1_x ( float ( - 0.5 ) ) * nz + AF1_x ( float ( 1.0 ) ) ;
float mn4R = min ( AMin3F1 ( bR , dR , fR ) , hR ) ;
float mn4G = min ( AMin3F1 ( bG , dG , fG ) , hG ) ;
float mn4B = min ( AMin3F1 ( bB , dB , fB ) , hB ) ;
float mx4R = max ( AMax3F1 ( bR , dR , fR ) , hR ) ;
float mx4G = max ( AMax3F1 ( bG , dG , fG ) , hG ) ;
float mx4B = max ( AMax3F1 ( bB , dB , fB ) , hB ) ;
float2 peakC = float2 ( 1.0 , - 1.0 * 4.0 ) ;
float hitMinR = min ( mn4R , eR ) * ARcpF1 ( AF1_x ( float ( 4.0 ) ) * mx4R ) ;
float hitMinG = min ( mn4G , eG ) * ARcpF1 ( AF1_x ( float ( 4.0 ) ) * mx4G ) ;
float hitMinB = min ( mn4B , eB ) * ARcpF1 ( AF1_x ( float ( 4.0 ) ) * mx4B ) ;
float hitMaxR = ( peakC . x - max ( mx4R , eR ) ) * ARcpF1 ( AF1_x ( float ( 4.0 ) ) * mn4R + peakC . y ) ;
float hitMaxG = ( peakC . x - max ( mx4G , eG ) ) * ARcpF1 ( AF1_x ( float ( 4.0 ) ) * mn4G + peakC . y ) ;
float hitMaxB = ( peakC . x - max ( mx4B , eB ) ) * ARcpF1 ( AF1_x ( float ( 4.0 ) ) * mn4B + peakC . y ) ;
float lobeR = max ( - hitMinR , hitMaxR ) ;
float lobeG = max ( - hitMinG , hitMaxG ) ;
float lobeB = max ( - hitMinB , hitMaxB ) ;
float lobe = max ( AF1_x ( float ( - ( 0.25 - ( 1.0 / 16.0 ) ) ) ) , min ( AMax3F1 ( lobeR , lobeG , lobeB ) , AF1_x ( float ( 0.0 ) ) ) ) * asfloat ( uint ( con . x ) ) ;
float rcpL = APrxMedRcpF1 ( AF1_x ( float ( 4.0 ) ) * lobe + AF1_x ( float ( 1.0 ) ) ) ;
pixR = ( lobe * bR + lobe * dR + lobe * hR + lobe * fR + eR ) * rcpL ;
pixG = ( lobe * bG + lobe * dG + lobe * hG + lobe * fG + eG ) * rcpL ;
pixB = ( lobe * bB + lobe * dB + lobe * hB + lobe * fB + eB ) * rcpL ;
return ; }
min16float3 ApplyRCAS ( uint2 positionSS )
{
float3 color ;
FsrRcasF (
color . r ,
color . g ,
color . b ,
positionSS ,
asuint ( _FsrRcasConstants )
) ;
return color ;
}
float CopySign ( float x , float s , bool ignoreNegZero = true )
{
if ( ignoreNegZero )
{
return ( s >= 0 ) ? abs ( x ) : - abs ( x ) ;
}
else
{
uint negZero = 0x80000000u ;
uint signBit = negZero & asuint ( s ) ;
return asfloat ( BitFieldInsert ( negZero , signBit , asuint ( x ) ) ) ;
}
}
float FastSign ( float s , bool ignoreNegZero = true )
{
return CopySign ( 1.0 , s , ignoreNegZero ) ;
}
min16float3 PositivePow ( min16float3 base , min16float3 power )
{
return pow ( abs ( base ) , power ) ;
}
min16float3 LinearToSRGB ( min16float3 c )
{
min16float3 sRGBLo = c * 12.92 ;
min16float3 sRGBHi = ( PositivePow ( c , min16float3 ( 1.0 / 2.4 , 1.0 / 2.4 , 1.0 / 2.4 ) ) * 1.055 ) - 0.055 ;
min16float3 sRGB = ( c <= 0.0031308 ) ? sRGBLo : sRGBHi ;
return sRGB ;
}
min16float3 GetLinearToSRGB ( min16float3 c )
{
return LinearToSRGB ( c ) ;
}
min16float3 SRGBToLinear ( min16float3 c )
{
min16float3 linearRGBLo = c / 12.92 ;
min16float3 linearRGBHi = PositivePow ( ( c + 0.055 ) / 1.055 , min16float3 ( 2.4 , 2.4 , 2.4 ) ) ;
min16float3 linearRGB = ( c <= 0.04045 ) ? linearRGBLo : linearRGBHi ;
return linearRGB ;
}
min16float3 GetSRGBToLinear ( min16float3 c )
{
return SRGBToLinear ( c ) ;
}
min16float3 ApplyDithering ( min16float3 input , float2 uv , Texture2D BlueNoiseTexture , SamplerState BlueNoiseSampler , float2 scale , float2 offset , float paperWhite , float oneOverPaperWhite )
{
float noise = BlueNoiseTexture . SampleBias ( BlueNoiseSampler , uv * scale + offset , _GlobalMipBias . x ) . a * 2.0 - 1.0 ;
noise = FastSign ( noise ) * ( 1.0 - sqrt ( 1.0 - abs ( noise ) ) ) ;
//#line 166
input = GetSRGBToLinear ( GetLinearToSRGB ( input ) + noise / 255.0 ) ;
//#line 169
return input ;
}
min16float4 FragFinalPost ( Varyings input ) : SV_Target
{
float2 uv = input . texcoord ;
float2 positionNDC = uv ;
int2 positionSS = uv * _SourceSize . xy ;
min16float3 color = ApplyRCAS ( positionSS ) ;
{
color = ApplyDithering ( color , positionNDC , _BlueNoise_Texture , sampler_PointRepeat , _Dithering_Params . xy , _Dithering_Params . zw , _HDROutputLuminanceParams . z , _HDROutputLuminanceParams . w ) ;
}
min16float4 finalColor = min16float4 ( color , 1 ) ;
return finalColor ;
}