支持 urp不_URP学习笔记1. 关于URP

笔记当前的Unity版本:2019.3

当前最新的Unity版本:2020.2

1.概述

1.SRP是什么?

SRP即Scriptable Render Pipeline,可编程渲染管线。管线是一种用于渲染的流程,如果你不理解的话,可以将其当成一个黑盒子,输入是模型,纹理,摄像机数据,输出是一幅画面,我们所编写的着色器是渲染流程中的一环。而Unity则保留了一部分C++的核心,把渲染也移植到了C#上,之后我们可以通过SRP来构建自己的渲染管线。

2.为什么需要SRP?

第一,Unity在近年来支持了越来越多的平台,不论是Win,Linux,Mac,亦或是Android,iOS,UWP,还是PS或者Switch。不同的平台有不同的渲染函数集,D3D,OpenGL,OpenGLES,Metal。而我们使用的Unity的着色器,却采用一种语法,Shaderlab来实现。在Shaderlab的背后,所做的工作是非常复杂的。需要大量的编译指令来控制语法在不同平台上的含义。因此,Unity原本的Built-in管线不堪重负,因而需要新生力量。

第二,Built-in管线虽然适用于大部分情况,但是在某些特殊的环境下仍然不是最完美的,在很多情境下,有些人希望可以自己配置管线,来进行画面的渲染。(这需要开发者拥有非常高的水平)

3.URP和HDRP是什么?

开发渲染管线是极其困难的,至少对于大部分人来说,去接触管线都是不太“河里”的。所以Unity提供了两个开发好的管线,URP和HDRP,URP针对的主要是手机游戏,PC端的中小型游戏,而HDRP则针对3A级游戏开发。

4.为什么需要URP?

URP不仅仅是基于SRP的新型管线,同时改变了built-in管线中前向渲染光照的模式,提升了光照渲染的性能,并且可以配合ShaderGraph开发着色器。(当然,我也不清楚为什么SG只能用于URP&HDRP)相对于Built-In管线来说有较大的提升空间,是现在开发的首选。

5.Built-In管线的项目可以无缝的切换到URP吗?

我想是不可以的,Built-In之前的着色器开发大部分是由CG来完成的,而URP的着色器开发则通过HLSL(写代码的方式)或者ShaderGraph(连连看的方式)来实现。并且虽然大部分的基础概念相同,但是仍然许多细节是不一样的(语法层面上)。因而两者无法无缝切换。

2.为什么是HLSL?

在《UnityShader入门精要》中,作者使用的主要是CG语言,而在URP中,则强制要求使用HLSL语言,虽然两者在语法上大体上很类似,但是仍有细节的不同。

具体的理由也比较简单,因为CG已经是一个停止更新很久的语言了,而HLSL则是微软的造物,一直保持更新。这样的活力让Unity更加青睐于使用HLSL,事实上这个原因是一方面。另外一方面使,对于不同的平台的扩展上,CG和Built-In管线一样,已经无力负担起一些重要的职能了,作为游戏开发中极其重要的一环,选择HLSL是必然的。

2.1 HLSL为什么可以跨平台?

从小白的视角来看,HLSL是DirectX专用的着色器语言,讲道理,HLSL是不可以跨平台的。事实上,我们所谓的HLSL在一定程度上是语法层面的。(这里的意思是,我们在Unity中使用的HLSL和DirectX中的HLSL其实还是有一定的差距的)真正在编译的时候,Unity会根据平台做一定的转化,如果了解编译原理,这件事,无非是将一种代码翻译成另外一种代码。对于那些制作这些语言处理器的大厂来说,无非就是成本的考虑罢了。

2.2 HLSL对比CG

我们用一个简单的案例来说明一下两者的区别,我们要编写的这个案例比较简单,就是不做任何计算,输出一种单一的颜色。首先我们回顾一下使用CG来编写的着色器,如果我们已经通关了《UnityShader入门精要》,这对你来说是一件很简单的事情。

Shader "UShaderMagicBook/SimpleTest"{
    /*一个最基础的着色器*/

    Properties{
        _BaseColor("MyColor",Color) = (1.0,1.0,1.0,1.0)     //后面不能加分号
    }
    SubShader{
        //子着色器A

        pass{
            //第一个pass块

            CGPROGRAM
            #pragma vertex Vertex
            #pragma fragment Pixel
            /*定义你的顶点着色器的函数名称和片元着色器的函数名称,该步是必要的
            起什么名字无所谓,命名规则同C类语言命名规则
            1.区分大小写
            2.不以数字开头
            3.不能和系统关键字冲突*/
            
            fixed4 _BaseColor;
            /*光在Properties语块中定义变量是没用的,你必须在CGPROGRAM块中再次声明,Unity
            才会把变量材质面板的值填充过来*/

            float4 Vertex(float4 v:POSITION):SV_POSITION{
                /*定义顶点着色器,处理和模型顶点有关的内容
                一个顶点着色器至少要完成一件事,那就是把模型的顶点转换到
                裁剪空间*/

                return UnityObjectToClipPos(v);
                //把模型转换到裁剪空间
            }
            fixed4 Pixel():SV_TARGET{
                //计算模型表面每个像素值的颜色

                return _BaseColor;
            }
            ENDCG
        }
    }
}

现在,我们使用URP&HLSL来翻译上述代码。不用担心,逻辑难度几乎为0,所以我们把注意力放在语法的区别上就可以了。

Shader "URPNotes/SimpleTest"{
    /* 着色器的名称以及它在下拉菜单中的位置 ,这部分是不变的 */

    Properties{
        /* 着色器的输入 这部分是不变的,部分参数的类型会发生变化,在后面会说到。*/

        _BaseColor("Base Color",Color) = (1.0,1.0,1.0,1.0)
    }
    SubShader{
        /* 子着色器1,针对显卡A的着色器,这里是ShaderLab着色器的主要内容 */

        Tags{
            "RenderPipeline" = "UniversalRenderPipeline"            //一定要加这个,用于指明使用URP来渲染
            "RenderType"="Opaque"
        }
        pass{
            
            HLSLPROGRAM
            //函数块变成了HLSLPROGRAM

            #pragma vertex Vertex
            #pragma fragment Pixel
            //保持你喜欢的命名方式

            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
            //在CG中使用的cginc文件变成了HLSL文件,并且由于它们是Unity的一个扩展组件,所以需要在Packages中找到相对应的
            //库文件,里面定义了我们在URP中使用的主要的API,
            //Core.HLSL中包含了一些常用的函数,另外还有一些其他的HLSL文件,后面会逐一介绍。

            half4 _BaseColor;
            //不要忘记在这里声明变量,否则着色器无法访问属性。

            struct vertexInput{
                //顶点着色器的输入,这个是不变的,

                float4 vertex:POSITION;

            };//不要忘了分号哦

            struct vertexOutput{
                //顶点着色器的输出,同时也是片元着色器的输入

                float4 pos:SV_POSITION;
            };

            vertexOutput Vertex(vertexInput v){

                vertexOutput o;
                o.pos = TransformObjectToHClip(v.vertex.xyz);
                // TransformObjectToHClip 是
                
                return o;
            }

            half4 Pixel(vertexOutput i):SV_TARGET{
                /* 片元着色器,注意,在HLSL中,fixed4类型变成了half4类型*/

                return _BaseColor;
            }

            ENDHLSL
        }
    }
}

494e2ef406074915b7133487c7ff8ee1.png

可以运行一下,发现没有错误,我们再回头检查代码的区别。区别还是非常夸张的,首先我们抛弃了使用了很长时间的CG函数库,类似于UnityObjectToWorld这样的函数全部消失了。取而代之的是HLSL的函数库,里面有太多的函数需要我们去熟悉了。其他的地方则更多的是小的细节,比如函数库变了,引用的头文件也发生了变化。并且我们要在Tags中指明RenderPipeline。

除此之外,更多的区别是CG和HLSL之间的区别,比如fixed4类型变成了half4类型等。那么后面的章节中,我们会使用HLSL再开发一遍UnityShader入门精要当中的着色器。

3.总结

本次的内容体量不大,难度也不是非常夸张,无非是换了一个API罢了。不过如果能够随心所欲的选择ShaderGraph或者编码的方式来开发着色器,这是非常nice的一件事。

这次的代码仅有一个,我已经上传到了我的github,还是老的地址。希望大家不要吝啬自己的星星。

Github传送门​github.com
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值