Unity SRP 即 Unity Scriptable Rendering Pipeline(可编程渲染管线),是Unity 2018的新功能,使开发者可以通过脚本按需构建自己的渲染过程。在学习和参考:

吉祥的游戏编程笔记

中关于Unity SRP的相关内容后,这里做一个简单的学习记录,如有错误之处,希望可以多多交流。
SRP中的内容可以用一张图说明: SRP的创建过程分为3个部分:

  • Custom Render Pipeline
  • Custom Render Pipeline Asset
  • Shader

Custom Render Pipeline

该部分是自定义渲染管线的起点,也是核心部分,继承自RenderPipeline类。在该类中的Render()方法中,定义自己的渲染流程中的规则及进行参数设置。一般来说,渲染的过程是将摄像机视野中3D或2D的场景对象进过一系列的处理最后转换成一张2D的图片输出到屏幕上。因此在Render()方法中,处理起点是从编辑场景里的每一个输出相机开始,经过如下过程:

  • 设置渲染目标
  • 绘制天空盒
  • 执行裁剪过程
  • 执行过滤过程
  • 绘制场景准备
  • 执行管线

在这一系列的过程中,需要将相关的指令和设置提交,通过 CommandBuffer和ScriptableRenderContext对象实现。 CommandBuffer对象作为指令缓存集,记录部分指令然后集中提交。ScriptableRenderContext对象可以理解成渲染过程中的一个管理器,CommandBuffer对象的指令提交需要通过ScriptableRenderContext对象完成,同时ScriptableRenderContext对象还可以管理如天空球的绘制、下达执行管线渲染等操作。
Custom Render Pipeline 完整代码:

using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Rendering;namespace Kata03 {
public class CustomRenderPipeline : RenderPipeline
{CommandBuffer _cb;//该函数在管线销毁时调用public override void Dispose(){base.Dispose();if (_cb != null) {_cb.Clear();_cb = null;}}//该函数在管线渲染时调用public override void Render(ScriptableRenderContext renderContext, Camera[] cameras){base.Render(renderContext, cameras);if (_cb == null) {_cb = new CommandBuffer();}//设置Shader中要使用的光源变量名var _LightDir = Shader.PropertyToID("_LightDir");var _LightColor = Shader.PropertyToID("_LightColor");var _CameraPos = Shader.PropertyToID("_CameraPos");//对于每个相机执行的操作foreach (var camera in cameras){//设置渲染上下文相机属性renderContext.SetupCameraProperties(camera);_cb.name = "Setup";//显式设置渲染目标为相机BackBuffer(如果相机没有指定渲染纹理,则直接绘制到屏幕)_cb.SetRenderTarget(BuiltinRenderTextureType.CameraTarget);//设置渲染目标颜色为相机背景色_cb.ClearRenderTarget(true, true, camera.backgroundColor);//设置相机的着色器全局变量Vector4 CameraPosition = new Vector4(camera.transform.localPosition.x, camera.transform.localPosition.y, camera.transform.localPosition.z, 1.0f);_cb.SetGlobalVector(_CameraPos, camera.transform.localToWorldMatrix * CameraPosition);renderContext.ExecuteCommandBuffer(_cb);_cb.Clear();//天空盒绘制renderContext.DrawSkybox(camera);//执行裁剪var culled = new CullResults();CullResults.Cull(camera, renderContext, out culled);/*裁剪结果包括:可见的物体列表:visibleRenderers可见灯光列表:visibleLights可见反射探针(CubeMap):visibleReflectionProbes裁剪结果并未排序*///获取所有灯光var lights = culled.visibleLights;_cb.name = "RenderLights";foreach (var light in lights){//挑选出平行光处理if (light.lightType != LightType.Directional) continue;//获取光源方向Vector4 pos = light.localToWorld.GetColumn(0);Vector4 lightDir = new Vector4(pos.x,pos.y,pos.z,0);//获取光源颜色Color lightColor = light.finalColor;//构建shader常量缓存_cb.SetGlobalVector(_LightDir,lightDir);_cb.SetGlobalColor(_LightColor,lightColor);renderContext.ExecuteCommandBuffer(_cb);_cb.Clear();var rs = new FilterRenderersSettings(true);//只渲染固体范围rs.renderQueueRange = RenderQueueRange.opaque;//包括所有层rs.layerMask = ~0;//渲染设置,使用Shader中LightMode为"BaseLit"的Passvar ds = new DrawRendererSettings(camera,new ShaderPassName("BaseLit"));//物体绘制renderContext.DrawRenderers(culled.visibleRenderers,ref ds,rs);break;}//开始执行管线renderContext.Submit();}}}
}

Custom Render Pipeline Asset

Custom Render Pipeline Asset 继承自 Render Pipeline Asset,用来在项目中生成自定义渲染管线资源,主要实现 IRenderPipelineAsset接口方法, InternalCreatePipeline(),生成自定义的 Custom RenderPipeline 对象,完整代码:

using UnityEngine.Experimental.Rendering;#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.ProjectWindowCallback;
#endifnamespace Kata03 {public class CustomRenderPipelineAsset : RenderPipelineAsset
{
#if UNITY_EDITOR[MenuItem("Assets/Create/Render Pipeline/Kata03/Pipeline Asset")]static void CreateKata03Pipeline() {ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0,CreateInstance<CreateKata03PipelineAsset>(),"Kata03 Pipeline.asset",null,null);}class CreateKata03PipelineAsset : EndNameEditAction{public override void Action(int instanceId, string pathName, string resourceFile){var instance = CreateInstance<CustomRenderPipelineAsset>();AssetDatabase.CreateAsset(instance,pathName);}}#endifprotected override IRenderPipeline InternalCreatePipeline(){return new CustomRenderPipeline();}}
}

有了 Custom Render Pipeline Asset 后,在Projects中通过 Create->RdnerPipeline->Kata03->Pipeline 即可创建对应的自定义渲染管线资源,然后替换原有的管线,在Edit->Project->Settings->Graphics中的Scriptable Render PipelineLine Settings中完成替换。

Shader

Shader是配合当前的自定义管线,完成场景内的物体着色,这和之前使用Unity内置管线没有区别。只是这里有一点需要注意的是:
在CustomRenderPipeline的渲染设置中,

var ds = new DrawRendererSettings(camera,new ShaderPassName("BaseLit"));

这里在构建ShaderPassName对象时,传递的参数为使用的Shader的Pass中"LightMode"对应的名称,因为在自定义渲染管线中,场景内物体光照着色的区分是通过Shader内的Pass里的"LightMode"进行的。包含光照计算的Shader代码:

Shader "Custom/BaseDirLit"
{
Properties
{_Color("Tint", Color) = (0.5,0.5,0.5,1)_DiffuseFactor("Diffuse Factor", Range(0,1)) = 1_SpecularColor("Specular Color",Color)=(1,1,1,1)_SpecularFactor("Specular Factor", Range(0,1)) = 1_SpecularPower("Specular Power",Float) = 100
}HLSLINCLUDE#include "UnityCG.cginc"
#define PI 3.14159265359uniform float4 _LightDir;
uniform float4 _LightColor;
uniform float4 _CameraPos;
uniform float4 _Color;
uniform float _DiffuseFactor;
uniform float _SpecularFactor;
uniform float _SpecularColor;
uniform float _SpecularPower;struct a2v
{float4 vertex : POSITION;float4 normal : NORMAL;
};struct v2f
{float4 pos : SV_POSITION;float4 normalWorld : TEXCOORD1;float4 worldPos : TEXCOORD2;
};v2f vert(a2v v)
{v2f o;UNITY_INITIALIZE_OUTPUT(v2f,o);o.pos = UnityObjectToClipPos(v.vertex);o.normalWorld = float4(normalize(mul(normalize(v.normal.xyz), (float3x3)unity_WorldToObject)),v.normal.w);o.worldPos = mul(unity_ObjectToWorld,v.vertex);return o;
}half4 frag(v2f i) : SV_Target
{fixed4 diffuse=_DiffuseFactor*max(0.0,dot(_LightDir.xyz,normalize(i.normalWorld.xyz)))*_Color*_LightColor;fixed3 viewDir=normalize(_CameraPos.xyz-i.worldPos.xyz);fixed3 halfDir=normalize(_LightDir.xyz+viewDir);fixed4 specular= _LightColor*_SpecularFactor*pow(max(0,dot(normalize(i.normalWorld.xyz),halfDir)),_SpecularPower)*max(0,saturate(dot(normalize(i.normalWorld.xyz),_LightDir.xyz)))*(_SpecularPower+8)/(8+PI);return diffuse+specular;
}ENDHLSLSubShader
{Tags{ "Queue" = "Geometry" }LOD 100Pass{Tags {"LightMode" = "BaseLit"}HLSLPROGRAM#pragma vertex vert#pragma fragment fragENDHLSL}}
}

在场景中使用该Shader的材质,得到的对应效果:

初识Unity SRP相关推荐

  1. 初识Unity Shader 流光闪烁效果

    初识Unity Shader 流光闪烁效果 // An highlighted block Shader "Custom/mistake" {Properties {_node_1 ...

  2. Unity SRP初识之URP

    URP是Unity基于SRP提供的兼顾表现与性能的渲染管线.URP前身命名为LWRP(轻量级渲染管线),后更名为URP. URP已包含在新建工程的工程模板中 URP使用简化的基于物理的照明和材质来实现 ...

  3. unity两个项目合并 同名_从实际项目升级中关于 Unity SRP 的一些评测

    Untiy 推出SRP 已经接近一年了,其中官方宣称 LWRP 在2018年年底时已经处于 production ready 既随时可以做产品了,于是改名为URP, 不过 HDRP 还需要2019.4 ...

  4. Unity SRP自定义渲染管线 -- 2.Custom Shaders

    本章将接着上一篇文章,在初步实现一个渲染管线后来创建自定义的shader.上一篇文章的链接 https://blog.csdn.net/yinfourever/article/details/9051 ...

  5. Unity SRP自定义渲染管线 -- 1.Custom Pipeline

    该篇是对Catlike Coding这篇文章的概要总结,本人能力有限,如果有不正确的地方欢迎指正  https://catlikecoding.com/unity/tutorials/scriptab ...

  6. Unity SRP系列——DrawCalls

    实例原文 Unity通用渲染管线(URP)系列(二)--Draw Calls(Shaders&Batches) - 知乎 (zhihu.com) Draw Calls (catlikecodi ...

  7. Unity SRP URP HDRP 的区别

    https://blog.csdn.net/weixin_41622043/article/details/107623694 1.Build-In Render 内置渲染器(默认)兼容太多,反而不能 ...

  8. Unity SRP自定义渲染管线学习2.2: 合批(Batching) SRP Batcher

    接下来我们要来学习下自定义渲染管线中的合批,这一节主要学习SRP Batcher 每一次的Draw Call都需要CPU和GPU之间的通信,如果有大量的数据需要从CPU发送到GPU中,那GPU就可能因 ...

  9. Unity SRP世界空间重建

    世界空间重建解决的是:当我们在不透明物体渲染完成,想要知道深度缓存中保存当前渲染的物体的世界空间位置.这个功能还是比较常用的,一些后处理效果比如雾效,ScreenSpace效果都基于此. 重建世界空间 ...

  10. Unity SRP Batcher 合批 BUG?- SRP: Node use different shader keyword

    文章目录 环境 问题 论坛发现同问 发问者解答 环境 Unity : 2019.4.30f1 URP : 7.7.1 问题 合批失败的原因显示:SRP: Node use different shad ...

最新文章

  1. 彻底疯了,要给雷锋开博客?
  2. 关于epoll中的read函数说明
  3. jOOQ,H2和Maven入门
  4. Oracle存储过程(转)
  5. TensorFlow 2.0 - tf.saved_model.save 模型导出
  6. python模块matplotlib.pyplot用法_Python中Matplotlib模块的简单使用
  7. GB28181之H264打包PS
  8. easyexcel 在 设置标题_EasyExcel 自定义单元格式的问题。
  9. 查看linux中某个端口(port)是否被占用***
  10. Vegas2020注册机
  11. JAVA后台实现文件批量下载
  12. java 打印心_在Java中打印输出心形图案!
  13. linux 软链接 相对路径,Linux入门之ln命令创建软链接的绝对路径和相对路径详解(Ubuntu)...
  14. Micheal Collins nlp课程笔记(二)Tagging Problems and Hidden Markov Models
  15. 金戒指用计算机怎么算,大姐拿来一个金戒指,先卖后当有蹊跷,鉴定后发现有问题,假的...
  16. flutter 图片加载
  17. 风险管理中的风险预测、风险评估、风险控制
  18. 行式 Excel 文件拆分
  19. P13、14-Windows与网络基础-NTFS之文件、文件夹权限
  20. 详细使用git打tag,删除tag,切换到某个tag时期,删除/查看分支

热门文章

  1. 【Scratch算法讲解】01-Scratch选择排序 少儿编程Scratch常见排序算法案例分析讲解
  2. EASBOS获取系统状态控制期间
  3. 浙大PAT 1051
  4. 小程序UI组件库合集——Vant、iView、ColorUI
  5. Java经典小案例(不定时更新)
  6. 【开箱】索尼A6000微单入手
  7. 【愚公系列】2022年01月 Django商城项目14-用户中心-界面设计
  8. 封装0603和0805的区别
  9. PCB封装尺寸-0402-0603-0805
  10. 用java怎么做微信公众号,用Java搭建微信公众号(一)构建基础请求框架