Unity SRP 可编程渲染管线的基本用法

news2024/9/25 7:20:35

可编程渲染管线使用教程
SRP 可以处理Canvas为Screen Space - Overlay的渲染

安装插件

首先进入package manager,下载Core RP Lib组件
在这里插入图片描述

创建渲染管线

编写渲染管线逻辑脚本

新建脚本取名为MPipeLine,该脚本用于实现渲染管线的处理逻辑

using UnityEngine;
using UnityEngine.Rendering;

public class MPipeLine : RenderPipeline
{
    public MPipeLine() { }

    protected override void Render(ScriptableRenderContext context, Camera[] cameras)
    {
        // 创建渲染指令,默认填充白色
        var cmd = new CommandBuffer();
        cmd.ClearRenderTarget(true, true, Color.white);
        context.ExecuteCommandBuffer(cmd);
        cmd.Release();

        // 提交渲染指令
        context.Submit();
    }
}

编写渲染管线与编辑器关联

创建脚本MPipelineAsset,用于与unity编辑器建立关联,允许将工程与自定义渲染管线进行绑定

using UnityEngine;
using UnityEngine.Rendering;

[CreateAssetMenu(menuName = "Rendering/MPipelineAsset")]
public class MPipelineAsset : RenderPipelineAsset
{
    protected override RenderPipeline CreatePipeline()
    {
    	// 渲染逻辑脚本
        return new MPipeLine();
    }
}

创建并配置PipeLine Asset

首先创建Asset文件
在这里插入图片描述
在这里插入图片描述
点击Edit > projectsettings > graphics,设置asset为我们刚才新建的那个管线资源
在这里插入图片描述
在这里插入图片描述

编辑渲染管线逻辑

渲染逻辑有两种写法,一种是直接创建指令

    //var cmd = new CommandBuffer() { name = "clear" };
    //cmd.ClearRenderTarget(true, true, Color.white);
    //context.ExecuteCommandBuffer(cmd);
    //cmd.Release();
    //context.Submit();

另一种是调用渲染api来实现,所有的逻辑要包在Begin、end之间

    RenderPipeline.BeginFrameRendering(context, cameras);
    // 要渲染的相机
    Camera camera = cameras[0];
    // 相机渲染   不透明
    RenderCamera(context, camera, "shader1", SortingCriteria.CommonOpaque, RenderQueueRange.opaque);
    RenderCamera(context, camera, "shader2", SortingCriteria.CommonTransparent, RenderQueueRange.transparent);

    // 结束帧渲染你
    RenderPipeline.EndFrameRendering(context, cameras);

我们这里使用后者来分别创建透明、不透明、及天空盒的渲染逻辑

  protected override void Render(ScriptableRenderContext context, Camera[] cameras)
  {
      // 开始帧渲染
      RenderPipeline.BeginFrameRendering(context, cameras);
      // 要渲染的相机
      Camera camera = cameras[0];
      // 相机渲染   不透明, shader1是自建shader,代码在后面
      RenderCamera(context, camera, "shader1", SortingCriteria.CommonOpaque, RenderQueueRange.opaque);
      // 相机渲染   不透明, shader2是自建shader,代码在后面
      RenderCamera(context, camera, "shader2", SortingCriteria.CommonTransparent, RenderQueueRange.transparent);

      // 结束帧渲染
      RenderPipeline.EndFrameRendering(context, cameras);
  }
  
  private void RenderCamera(ScriptableRenderContext context, Camera camera, string TagId, SortingCriteria criteria, RenderQueueRange queue)
  {
      // 开始渲染摄像机
      RenderPipeline.BeginCameraRendering(context, camera);

      // Camera 区域剔除
      ScriptableCullingParameters cullingParameters = new ScriptableCullingParameters();
      cullingParameters.cullingOptions |= CullingOptions.OcclusionCull;
      // 剔除除了default layer之外的layer
      cullingParameters.cullingMask = 1 << 0;
      camera.TryGetCullingParameters(out cullingParameters);
      var cullingResults = context.Cull(ref cullingParameters);

      // 更新当前摄像机内置着色器变量值
      context.SetupCameraProperties(camera);

      // DrawingSettings用来描述可见物体的排序方式,以及绘制使用的Shader Pass
      ShaderTagId shaderTagId = new ShaderTagId(TagId);
      var sortingSettings = new SortingSettings(camera) {
          criteria = criteria 
      };
      DrawingSettings drawingSettings = new DrawingSettings(
          shaderTagId, 
          sortingSettings
      );

     // 过滤  FilteringSettings用来描述渲染时如何过滤可见物体
      FilteringSettings filteringSettings = new FilteringSettings(queue);

      // 绘制图形
      context.DrawRenderers(cullingResults, ref drawingSettings, ref filteringSettings);

      // 绘制天空盒
      if (camera.clearFlags == CameraClearFlags.Skybox && RenderSettings.skybox != null && queue != RenderQueueRange.transparent)
      {
          context.DrawSkybox(camera);
      }

      // 提交渲染按 
      context.Submit();

      // 结束渲染摄像机
      RenderPipeline.EndCameraRendering(context, camera);
  }

创建着色器

分别创建shader1.shader, shader2.shader两个着色器资源,并将下列代码填入
shader1:

Shader "Custom/mShader1"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
     Blend One OneMinusSrcAlpha
        Pass
        {
            Tags { "LightMode"="shader1" }
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

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

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

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

            fixed4 frag (v2f i) : SV_Target
            {
                // sample the texture
                fixed4 col = tex2D(_MainTex, i.uv);
                // apply fog
                UNITY_APPLY_FOG(i.fogCoord, col);
                return col;
            }
            ENDCG
        }
    }
}

shader2:

Shader "Custom/mShader2"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "#A84242" {}
        _MainColor("color", Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags{
            "Queue" = "Transparent"
            "RenderType"="Transparent"
            "PreviewType"="Plane"
        }
        Cull Off
        //Lighting On 
        //ZWrite On
        Blend One OneMinusSrcAlpha
        Pass
        {
            Tags { "LightMode"="shader2" }
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

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

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            fixed4 _MainColor;
            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o,o.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // sample the texture
                fixed4 col = tex2D(_MainTex, i.uv) * _MainColor;
                // apply fog
                //UNITY_APPLY_FOG(i.fogCoord, col);
                col.a = _MainColor.a;
                return col;
            }
            ENDCG
        }
    }
}

测试效果

然后创建材质mat1.materil、mat2.materil。 mat1关联shader1,mat2关联shader2,将mat2的color透明度调到100
在这里插入图片描述

在场景中创建cube1和cube2两个方形物体,这时我们是什么都看不到的。
在这里插入图片描述

拖动cube2,一部分挡在cube1前面,并将mat1赋给cube1,mat2赋给cube2。此时我们就能看到自定义渲染管线生效了
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2121516.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python计算机视觉 第7章-图像搜索

Python计算机视觉 第7章-图像搜索 7.1 基于内容的图像检索 在大型图像数据库上&#xff0c;CBIR&#xff08;Content-Based Image Retrieval&#xff0c;基于内容的图像检索&#xff09;技术用于检索在视觉上具相似性的图像。这样返回的图像可以是颜色相似、纹理相似、图像中…

优秀一点点

在职场中&#xff0c;想要获得晋升&#xff0c;重要的是比其他同事优秀一点点。这就好比百米短跑比赛&#xff0c;第一名比第二名可能之快了0.01秒&#xff0c;这个0.01秒&#xff0c;和跑一百米所花的10秒钟比起来&#xff0c;可能只有千分之一。也就是说&#xff0c;第一名比…

麦汁煮沸工艺

麦汁煮沸是啤酒酿造中至关重要的工艺环节之一&#xff0c;直接影响啤酒的风味。今天&#xff0c;天泰邀您一起深入探讨这一关键的酿造技术。 煮沸麦汁 在煮沸麦汁时&#xff0c;时间和温度控制至关重要。通常&#xff0c;麦汁煮沸持续 40 到 50 分钟&#xff0c;具体时间取决于…

OpenAI Embeddings API: How embeddings work?

题意&#xff1a;OpenAI 嵌入 API&#xff1a;嵌入是如何工作的&#xff1f; 问题背景&#xff1a; There are quite a few tutorials on embeddings in OpenAI. I cant understand how they work. 在OpenAI中有很多关于嵌入的教程&#xff0c;但我无法理解它们是如何工作的。…

轻松实现游戏串流,内网穿透

一、部署Gemini Gemini使用教程 二、部署Moonlight 过程大概说一下&#xff0c;网上有太多太多moonlight的东西了 需要运行游戏的机器上安装GFE&#xff08;GeForce Experience&#xff09;&#xff0c;登录并开启GAMESTREAM&#xff08;游戏串流&#xff09;功能 注&…

什么是 Flash Attention

Flash Attention 是 由 Tri Dao 和 Dan Fu 等人在2022年的论文 FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness 中 提出的&#xff0c; 论文可以从 https://arxiv.org/abs/2205.14135 页面下载&#xff0c;点击 View PDF 就可以下载。 下面我…

Php数组函数中的那些什么sort排序函数是不是很乱? 可以这样看。以及php搜索给定的值在数组中最后一次出现的位置的实现思考

一、Php数组函数中的那些什么sort排序函数是不是很乱? 可以这样看 PHP的数组函数真不少&#xff0c;甚至对一个程序员来说&#xff0c;在其整个程序生涯中有些方法他永远也不会用上。不过每一个方法都有其价值、或者在出现的时候有其价值。所以偶尔有空时还是可以去看看。在这…

并发编程:线程池(下)

一、线程池常用的阻塞队列有哪些&#xff1f; 新任务来的时候会先判断当前运行的线程数量是否达到核心线程数&#xff0c;如果达到的话&#xff0c;新任务就会被存放在队列中。 不同的线程池会选用不同的阻塞队列&#xff0c;我们可以结合内置线程池来分析。 容量为 Integer…

UE5 半透明阴影 快速解决方案

Step 1&#xff1a; 打开该选项 Step 2&#xff1a; 将半透明材质给到模型后&#xff0c;设置光照的Shadow Resolution Scale&#xff0c;越大&#xff0c;阴影的效果越好 Step 3&#xff1a; 用这种方式去做&#xff0c;阴影会因为半透明的程度&#xff0c;降低阴影的浓度 要…

Spring security 动态权限管理(基于数据库)

一、简介 如果对该篇文章不了解&#xff0c;请移步上一篇文章&#xff1a;spring security 中的授权使用-CSDN博客 当我们配置的 URL 拦截规则请求 URL 所需要的权限都是通过代码来配置的&#xff0c;这样就比较死板&#xff0c;如果想要调整访问某一个 URL 所需要的权限&…

【专项刷题】— 队列

1、N 叉树的层序遍历 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 每次遍历一层节点的时候就把当前节点的值添加到列表中再将当前层的节点的子节点添加到队列中每次遍历完一层之后就添加到总表中代码&#xff1a; public List<List<Integer>> levelO…

如何远程实时监控员工的电脑屏幕?远程桌面监控的五个可实现方法分享

想象一下&#xff0c;你在办公室喝着咖啡&#xff0c;员工的电脑屏幕却在数百公里之外实时呈现在你的眼前。你可以看到他们在干什么&#xff0c;是埋头工作还是悄悄摸鱼&#xff1f;远程桌面监控让这一切变得触手可及&#xff0c;简直像给了管理者一双“千里眼”&#xff01; 如…

RedisTemplate操作String的API

文章目录 1 String 介绍2 命令3 对应 RedisTemplate API❄️❄️ 3.1 添加缓存❄️❄️ 3.2 设置过期时间(单独设置)❄️❄️ 3.3 获取缓存值❄️❄️ 3.4 删除key❄️❄️ 3.5 顺序递增❄️❄️ 3.6 顺序递减 ⛄4 以下是一些常用的API⛄5 应用场景 1 String 介绍 String 类型…

9.10-AutoAWQ代码解析

1、首先要去官网下载源码。https://github.com/casper-hansen/AutoAWQ.githttps://github.com/casper-hansen/AutoAWQ.git 2、git clone后&#xff0c;下载AutoAWQ所需环境。 pip install -e . 3、查看quantize.py代码&#xff0c;修改model_path部分&#xff0c;修改为想要量…

系统架构师考试学习笔记第四篇——架构设计实践知识(19)嵌入式系统架构设计理论与实践

本章考点&#xff1a; 第19课时主要学习嵌入式系统架构设计的理论和工作中的实践。根据新版考试大纲&#xff0c;本课时知识点会涉及案例分析题&#xff08;25分&#xff09;。在历年考试中&#xff0c;案例题对该部分内容都有固定考查&#xff0c;综合知识选择题目中有固定分值…

您与该网站的连接不是私密连接,存在安全隐患

您与该网站的连接不是私密连接&#xff0c;存在安全隐患。 攻击者可能会试图窃取您的信息&#xff08;例如&#xff1a;密码、通讯内容或信用卡信息&#xff09;。为避免您的信息失窃&#xff0c;建议您停止访问该页面。了解详情 解决办法如下&#xff1a; 1、查看电脑时间&…

使用FastJson2将对象转成JSON字符串时,小数位“0”开头时转换出错

maven坐标&#xff1a; <dependency> <groupId>com.alibaba.fastjson2</groupId> <artifactId>fastjson2</artifactId> <version>2.0.40</version> </dependency> 问题现象&#xff1a; 问题原因&#xff1a; I…

IP路由选择

文章目录 1. 基本概念2. RIP(路由选择信息协议)3. OSPF 1. 基本概念 路由选择协议 路由选择协议让路由器能够动态地发现互联网络&#xff0c;并确保所有路由器的路由选择表都相同。路由选择协议还用于找出最佳路径&#xff0c;让分组穿越互联网络前往目的地的效率最高。RIP、R…

领夹麦克风哪个品牌好?无线领夹麦克风品牌大全,麦克风推荐

在这个全民直播、Vlog盛行的时代&#xff0c;一款轻便高效的无线领夹麦克风成了不少内容创作者的必备神器。但市面上产品五花八门&#xff0c;有的打着“超远传输、无损音质”的旗号&#xff0c;实则性能平平&#xff0c;甚至存在信号干扰、噪音大等问题&#xff0c;让人直呼交…

SpringBoot集成MyBatis-PlusDruid

目录 MyBatis-Plus简介 实例演示 创建Springboot项目 初始化Springboot项目 添加关键依赖 application.properties添加相关配置 启动类 编写实体类 编写mapper接口 条件构造器 分页插件 自定义 SQL 映射 MyBatis-Plus简介 MyBatis-Plus简介‌MyBatis-Plus‌&…