BlueRoseNote/03-UnrealEngine/Rendering/Shader/Effect/Ue4 PostProcess 效果大小错误解决方法.md
2023-06-29 11:55:02 +08:00

57 lines
3.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

早几年学习后处理Shader的时候遇到编辑器视口中的渲染结果与视口大小不匹配的问题
![](https://cdn.jsdelivr.net/gh/blueroseslol/ImageBag@latest/ImageBag/Images/PostProcessMaterialError.png)
PS.该问题不会在使用SceneTexture节点制作的后处理效果材质中发生。但它不易于维护与修改。所以我花了些时间来解决这个问题。
## 问题成因与解决方法
可以看得出这个问题是因为ViewSize与BufferSize不一造成的。经过一系列测试使用ViewportUVToBufferUV()对UV坐标进行转换就可以解决问题该函数位于Common.h。
```c#
float2 ViewportUVToBufferUV(float2 ViewportUV)
{
float2 PixelPos = ViewportUV * View.ViewSizeAndInvSize.xy;
return (PixelPos + View.ViewRectMin.xy) * View.BufferSizeAndInvSize.zw;
}
```
ScreenUV使用GetViewportUV(Parameters)来获取Step为ResolvedView.ViewSizeAndInvSize.zw用法大致如下
```c#
float GetDepthTestWeight(float2 ScreenUV,float Stepx, float Stepy, float3x3 KernelX, float3x3 KernelY,float DepthTestThreshold)
{
float3x3 image;
float CurrentPixelDepth=GetScreenSpaceData(ViewportUVToBufferUV(ScreenUV)).GBuffer.Depth;
image = float3x3(
length(GetScreenSpaceData(ViewportUVToBufferUV(ScreenUV + float2(-Stepx,Stepy))).GBuffer.Depth-CurrentPixelDepth),
length(GetScreenSpaceData(ViewportUVToBufferUV(ScreenUV + float2(0,Stepy))).GBuffer.Depth-CurrentPixelDepth),
length(GetScreenSpaceData(ViewportUVToBufferUV(ScreenUV + float2(Stepx,Stepy))).GBuffer.Depth-CurrentPixelDepth),
length(GetScreenSpaceData(ViewportUVToBufferUV(ScreenUV + float2(-Stepx,0))).GBuffer.Depth-CurrentPixelDepth),
0,
length(GetScreenSpaceData(ViewportUVToBufferUV(ScreenUV + float2(Stepx,0))).GBuffer.Depth-CurrentPixelDepth),
length(GetScreenSpaceData(ViewportUVToBufferUV(ScreenUV + float2(-Stepx,-Stepy))).GBuffer.Depth-CurrentPixelDepth),
length(GetScreenSpaceData(ViewportUVToBufferUV(ScreenUV + float2(0,-Stepy))).GBuffer.Depth-CurrentPixelDepth),
length(GetScreenSpaceData(ViewportUVToBufferUV(ScreenUV + float2(Stepx,-Stepy))).GBuffer.Depth-CurrentPixelDepth)
);
UNROLL
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
// image[i][j] = image[i][j] > CurrentPixelDepth * DepthTestThreshold ? 1 : 0;
image[i][j] = saturate(image[i][j] / (CurrentPixelDepth * DepthTestThreshold));
}
}
float2 StrokeWeight;
StrokeWeight.x = convolve(KernelX, image);
StrokeWeight.y = convolve(KernelY, image);
return length(StrokeWeight);
}
```
当然如果是直接在渲染管线里添加渲染Pass的方式来实现后处理效果那也不会出现这个问题因为每帧都会按照View大小创建新的buffer所以不会出现这个问题。
## 材质编辑器的相关大小节点。
- ScreenPosition代码为GetViewportUV(FMaterialVertexParameters Parameters)。
- ViewSize可视视口的大小。代码为View.ViewSizeAndInvSize.xyzw为倒数值。
- MF_ScreenResolution具体有VisibleResolution(就是ViewSize节点输出结果) 与BufferResolution(ViewProperty的RenderTargetSize)
- SceneTexelSize场景纹素大小这是一个float2的值对应着UVuvuv均为正数。
- MF_ScreenAlignedPixelToPixelUVsRenderTargetSize / TextureSize。 其中TextureSize可以是ViewSize。可以用来实现一些修改View大小后后处理尺寸不变得效果。
- 后处理节点的SizeClampSceneTextureUV(ViewportUVToSceneTextureUVSceneTextureId)