【Unity】RenderFeature笔记

本文详细介绍了Unity中的RenderFeature在UniversalRenderPipeline(URP)中的应用,涉及后处理效果、使用CommandBuffer进行Blit操作、创建网格、渲染到纹理以及与VolumeComponent的交互,展示了如何利用这些功能定制渲染流程。

低功耗蓝牙项目,需要一块懂省电的板

思澈 SF32LB52 芯片,BLE 协议栈深度优化,上手即开发

【Unity】RenderFeature笔记

RenderFeature是在urp中添加的额外渲染pass,并可以将这个pass插入到渲染列队中的任意位置。内置渲染管线中Graphics 的功能需要在RenderFeature里实现,常见的如DrawMesh和Blit

​ 可以实现的效果包括但不限于

  1. 后处理,可以编写shader对整个渲染画面进行修改。比如一些全局特效包括:场景描边,地形扫描;

  2. 创建网格,通过DrawMesh绘制定义的网格;

  3. 渲染画面,将场景渲染到纹理;

一、RanderFeature简介

1. 创建RanderFeature

在project中Create→Rendering→URPRenderFeature

2.RanderFeature结构
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

public class CustomRenderPassFeatureTest : ScriptableRendererFeature
{
    class CustomRenderPass : ScriptableRenderPass
    {
        // 在执行渲染通道之前调用
        // 创建临时渲染目标纹理。
        //为Execute提前准备需要的RenderTexture或者其它变量
        public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData){}
        //核心方法,实现这个renderPass的逻辑
        public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData){}
        //释放在OnCameraSetup里,声明的变量如TemporaryRenderTexture
        public override void OnCameraCleanup(CommandBuffer cmd) {}
    }
    CustomRenderPass m_ScriptablePass;

    /// <inheritdoc/>
    public override void Create()
    {
        m_ScriptablePass = new CustomRenderPass();
        //定义渲染的位置
        m_ScriptablePass.renderPassEvent = RenderPassEvent.AfterRenderingOpaques;
    }

    // 这里你可以在渲染器中注入一个或多个渲染通道。
    //每一帧都执行
    public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
    {
        //把实例化的CustomRenderPass插入渲染管线
        renderer.EnqueuePass(m_ScriptablePass);
    }
}
3.RenderFeatrue使用

在Universal Render Pipeline Asset_Renderer直接Add RenderFeatrue

二、后处理效果

关键词
1、CommandBuffer.Blit

Blit是很常用的后期效果方法,在Build_in中常常是在OnRenderImage里被调用,与urp不同的是,在build_in里是通过Graphics.Blit调用。

Graphics.Blit

常用的接口: Blit(RenderTexturesource, RenderTexture dest, Material mat);

即使用着色器将源纹理复制到目标渲染纹理。

CommandBuffer.Blit

常用的接口:public void Blit (Rendering.RenderTargetIdentifier source, Rendering.RenderTargetIdentifier dest, Material mat);

这与 Graphics.Blit相似 - 主要用于从一个(渲染)纹理复制到其他纹理,可能使用自定义着色器;

源纹理或渲染目标将作为“_MainTex”属性传递给材质。

在shader中,_MainTex对应的是source,最后retrun对应的是dest

2、RenderTargetIdentifier

渲染目标标识符,标识 CommandBuffer的 RenderTexture;

使用 CommandBuffer.GetTemporaryRT 创建的具有名称的临时渲染纹理;

ScriptableRenderPass中有colorAttachment和depthAttachment是可以直接使用;

RenderTargetHandle.CameraTarget.Identifier()可以得到当前的渲染标识符

renderingData.cameraData.renderer.cameraColorTarget 也可以得到当前的渲染标识符

简单实现

实现脚本

using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

public class CustomRenderPassFeatureTest : ScriptableRendererFeature
{
    //结构说明
    class CustomRenderPass : ScriptableRenderPass
    {
        // 在执行渲染通道之前调用
        // 创建临时渲染目标纹理。
        //为Execute提前准备需要的RenderTexture或者其它变量

        public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData) {}
      
        //核心方法,实现这个renderPass的逻辑
        public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData){}

        //释放在OnCameraSetup里,声明的变量如TemporaryRenderTexture
        public override void OnCameraCleanup(CommandBuffer cmd){}
    }
    //后处理效果
    class CustomRenderShaderPostPass : ScriptableRenderPass
    {  
        //定义渲染材质,通过Create方法赋值
        public Material _Material;
        public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
        {
            //创建一个CommandBuffer
            CommandBuffer cmd = CommandBufferPool.Get("ShowShader");
            //这里有一个疑问,渲染标识符不管怎么传都不影响结果
            cmd.Blit(colorAttachment, RenderTargetHandle.CameraTarget.Identifier(), _Material);
            //执行CommandBuffer
            context.ExecuteCommandBuffer(cmd);
            //回收CommandBuffer
            CommandBufferPool.Release(cmd);
        }
    }

    CustomRenderShaderPostPass m_ScriptablePassPost;
    public Shader shader;
    /// <inheritdoc/>
    public override void Create()
    {
        m_ScriptablePassPost = new CustomRenderShaderPostPass();
        //通过创建一个渲染材质
        m_ScriptablePassPost._Material = new Material(shader);
        //定义渲染的位置
        m_ScriptablePassPost.renderPassEvent = RenderPassEvent.AfterRenderingOpaques;
    }
    // 这里你可以在渲染器中注入一个或多个渲染通道。
    //每一帧都执行
    public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
    {
        //把实例化的CustomRenderPass插入渲染管线
        renderer.EnqueuePass(m_ScriptablePassPost);
    }
}
1.实现饱和度和对比度调整

用shaderGraph实现

用shader实现

Shader "Unlit/SaturationContrastShader"
{
   
   
    SubShader
    {
   
   
        Pass
        {
   
   
           ZTest Always ZWrite Off
            CGPROGRAM

            #pragma vertex vert_img  // 使用内置的vert_img顶点着色器
            #pragma fragment frag

            #include "UnityCG.cginc"

            sampler2D _CameraColorTexture; 
            

低功耗蓝牙项目,需要一块懂省电的板

思澈 SF32LB52 芯片,BLE 协议栈深度优化,上手即开发

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小生云木

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值