unity PostProcess 屏幕后处理

使用流程

  1. 首先项目需要使用URP,这里导入URP管线,创建URP pipline资源
  2. 修改项目的渲染管线为新创建的pipline
  3. 修改 URP_Renderer 参数,使支持后处理![[Pasted image 20220717204145.png]]
  4. camera 勾选上postprocessing选项
  5. 场景中创建Volume, 创建新的profile
  6. 添加Bloom

官方文档

Post-processing in the High Definition Render Pipeline | High Definition RP | 14.0.3 (unity3d.com)

部分后处理介绍

bloom 泛光

泛光 - LearnOpenGL CN (learnopengl-cn.github.io)
Bloom | High Definition RP | 14.0.3 (unity3d.com)
简介:

  1. 通过亮度阈值过滤出高亮的部分
  2. 将这个超过一定亮度阈限的纹理进行模糊
  3. 最终的被模糊化的纹理就是我们用来获得发出光晕效果的东西。这个已模糊的纹理要添加到原来的HDR场景纹理之上。因为模糊过滤器的应用明亮区域发出光晕,所以明亮区域在长和宽上都有所扩展。

    在这里插入图片描述

Color Curves

和PS的曲线一样,支持全局和RGB单个通道的设置,根据曲线的值,将原值映射到新的值

Film Grain

薄膜颗粒效应模拟了胶片的随机光学结构,通常是由物理薄膜上存在的小颗粒引起的。
在这里插入图片描述

Lens Distortion

镜头失真效果扭曲最终渲染的图片,以模拟真实世界的照相机镜头的形状。
可以实现凸透镜和凹透镜的效果
在这里插入图片描述

自定义屏幕后处理

Custom Post Processing in Unity URP | Febucci
目前(URP 12.1.5,2022 年 5 月)没有简单的方法可以在 Unity 的 URP 中使用卷来自定义后期处理效果。URP 路线图说它“正在进行中”,但即使这种情况已经有一段时间了,我们确实有一些功能可以帮助我们手动实现相同的结果(类似于之前的后期处理堆栈 V2)

unity的URP package里面有内置的几种效果,且代码是开源的,可以在Packages -> Universal RP -> Runtime -> Passes中看到。
简单的反色效果:
在这里插入图片描述
在这里插入图片描述

流程

  1. 创建volume,控制变量和效果是否激活
  2. 创建renderer feature, 添加到URP渲染管线的后处理中
  3. 实现custom pass ,执行画面处理

创建custom volume

[Serializable, VolumeComponentMenuForRenderPipeline("MySelf/test", typeof(UniversalRenderPipeline))]
public class MySelfVolume : VolumeComponent, IPostProcessComponent
{
    
    
    public MinFloatParameter intensity = new MinFloatParameter(0f, 0f);

    public bool IsActive() => intensity.value > 0f;

    public bool IsTileCompatible() => false;
}

VolumeComponent 的Parameter类型,可以让参数跟随权重变化,它们可以在Global或local中应用(其中权重也受相机与音量边界的距离的影响)。

现在,就可以在volume的add override中选择新加的volume了

Custom Renderer Feature

代码比较简单:

public class MySelfPostFeature : ScriptableRendererFeature
{
    
    
    MySelfRenderPass renderPass;
    Material mMat;
    public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
    {
    
    
        renderer.EnqueuePass(renderPass);
    }

    public override void Create()
    {
    
    
        var shader = Shader.Find("Hidden/MySelfShader");
        mMat = new Material(shader);
        renderPass = new MySelfRenderPass("PostEffectRender", RenderPassEvent.AfterRenderingTransparents, mMat, 0);
    }
}

Custom Pass

主要的渲染逻辑,需要在OnCameraSetup中,拿到cameraColorTarget,同时创建一个RT进行绘制。

public class MySelfRenderPass : ScriptableRenderPass
{
    
    

    // Used to render from camera to post processings
    // back and forth, until we render the final image to
    // the camera
    RenderTargetIdentifier source;
    RenderTargetIdentifier destinationA;

    readonly int temporaryRTIdA = Shader.PropertyToID("_TempRT");

    public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
    {
    
    
        // Grab the camera target descriptor. We will use this when creating a temporary render texture.
        RenderTextureDescriptor descriptor = renderingData.cameraData.cameraTargetDescriptor;
        descriptor.depthBufferBits = 0;

        var renderer = renderingData.cameraData.renderer;
        source = renderer.cameraColorTarget;

        // Create a temporary render texture using the descriptor from above.
        cmd.GetTemporaryRT(temporaryRTIdA, descriptor, FilterMode.Bilinear);
        destinationA = new RenderTargetIdentifier(temporaryRTIdA);
    }

    // The actual execution of the pass. This is where custom rendering occurs.
    public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
    {
    
    
        // Skipping post processing rendering inside the scene View
        if (renderingData.cameraData.isSceneViewCamera)
            return;

        CommandBuffer cmd = CommandBufferPool.Get("Custom Post Processing");
        cmd.Clear();
        var stack = VolumeManager.instance.stack;
        var customEffect = stack.GetComponent<MySelfVolume>();
        if (customEffect.IsActive())
        {
    
    
            Blit(cmd, source, destinationA);
            Blit(cmd, destinationA, source, mMat);
        }
        context.ExecuteCommandBuffer(cmd);
        CommandBufferPool.Release(cmd);
    }

    //Cleans the temporary RTs when we don't need them anymore
    public override void OnCameraCleanup(CommandBuffer cmd)
    {
    
    
        cmd.ReleaseTemporaryRT(temporaryRTIdA);
    }

    Material mMat;
    public MySelfRenderPass(string passname, RenderPassEvent _event, Material _mat, float contrast)
    {
    
    
        this.renderPassEvent = _event;
        mMat = _mat;
    }
}

Material

使用包含_MainTex的shader即可,这里使用的是unity创建shader时的默认模版,反色效果

Shader "Hidden/MySelfShader"
{
    
    
    Properties
    {
    
    
        _MainTex ("Texture", 2D) = "white" {
    
    }
    }
    SubShader
    {
    
    
        // No culling or depth
        Cull Off ZWrite Off ZTest Always

        Pass
        {
    
    
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
    
    
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
    
    
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            v2f vert (appdata v)
            {
    
    
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }

            sampler2D _MainTex;

            fixed4 frag (v2f i) : SV_Target
            {
    
    
                fixed4 col = tex2D(_MainTex, i.uv);
                // just invert the colors
                col.rgb = 1 - col.rgb;
                col.a = 0.1;
                return col;
            }
            ENDCG
        }
    }
}

猜你喜欢

转载自blog.csdn.net/fztfztfzt/article/details/125909181