700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Unity 内置渲染管线转URP

Unity 内置渲染管线转URP

时间:2021-10-18 09:25:11

相关推荐

Unity 内置渲染管线转URP

一、CG 替换 HLSL

未使用光照计算的shader升级后不做修改仍然可以使用,但是可能会不兼容SRP Batcher,所以仍然需要修改,使用了光照计算的shader必须要修改。

SubShader的Tags中增加 “RenderPipeline”="UniversalPipeline"声明

要保证多pass物体正确绘制,需要确保有个pass打上UniversalForward的tag,其余pass有SRPDefaultUnlit的tag也行,没有也行。

HLSLPROGRAM 替换 CGPROGRAM

HLSLINCLUDE 替换 INCLUDE

ENDHLSL 替换 ENDCG

fixed替换为:half或者float

FallBack

FallBack “Hidden/Universal Render Pipeline/FallbackError”

LightMode

"LightMode" 要改为URP支持的模式, 比如 "LightMode" = "Forward" 替换为 "LightMode" = "UniversalForward"其他常用URP的mode类型:"LightMode" = "Universal2D""LightMode" = "Meta""LightMode" = "DepthOnly""LightMode" = "ShadowCaster"

使用URP ShaderLibrary引用Core.hlsl替换内置渲染管线中的UnityCG.cginc

#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" 替换 #include "UnityCG.cginc"

其他库类似:

#include "Lighting.HLSLinc"替换为:#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"#include "Packages/com.unity.render-pipelines.universal/Shaders/LitForwardPass.hlsl"阴影:#include "Packages/com.unity.render-pipelines.universal/Shaders/ShadowCasterPass.hlsl"

内置结构体、内置函数 和矩阵

appdata_full 这种结构体不能用了,如何一一替换我就不举例了

内置函数 和矩阵需要查阅Packages/Universal RP/ShaderLibrary/UnityInput

内置结构体、函数需要查阅

Packages/Universal RP/ShaderLibrary/Input

Packages/Universal RP/ShaderLibrary/Core

使用 TransformObjectToHClip 替换 UnityObjectToClipPos

或者改成如下写法:

Varyings vert(Attributes IN) {Varyings OUT;VertexPositionInputs positionInputs = GetVertexPositionInputs(IN.positionOS.xyz);OUT.positionCS = positionInputs.positionCS;// Or this ://OUT.positionCS = TransformObjectToHClip(IN.positionOS.xyz);OUT.uv = TRANSFORM_TEX(IN.uv, _BaseMap);OUT.color = IN.color;return OUT;}

GetVertexPositionInputs计算不同坐标系中的位置,结果包含世界坐标系坐标,观察坐标系坐标,裁剪坐标系坐标,标准设备坐标系坐标,未使用到的坐标不会被包含到编译出的shader中,所以不会有额外的不必要的计算量。TRANSFORM_TEX 在内置渲染管线和URP中都可以用。GetVertexNormalInputs 可以将法线和切线从对象坐标系变换到世界坐标系。也可以用 TransformObjectToWorldNormal(IN.normalOS) 代替。

VertexNormalInputs normalInputs = GetVertexNormalInputs(IN.normalOS, IN.tangentOS);

在URP中纹理和采样器的定义改成如下写法:

// 将_BaseMap声明为Texture2D对象TEXTURE2D(_MainTex);// 将_BaseMap声明为Texture2D对象SAMPLER(sampler_MainTex);float4 frag (v2f i) : SV_Target{float4 col = SAMPLE_TEXTURE2D(_BaseMap,sampler_BaseMap, i.texcoord);return col;}

区分 multi_compile 和 shader_feature,剥离不需要的编译选项,减少shader变体。

/p/77043332

/p/8750704a2f4c

URP不支持表面着色器,URP ShaderLibrary 中处理光照计算的函数在 Lighting.hlsl中,该文件需要手动include。

//这些编译指令用于接收阴影#pragma multi_compile _ _MAIN_LIGHT_SHADOWS#pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE#pragma multi_compile _ _SHADOWS_SOFT#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"

当使用Lighting.hlsl支持光照和阴影,应该添加下面的编译选项,如果没有定义,ShaderLibrary会跳过一些计算。

// Main Light Shadows#pragma multi_compile _ _MAIN_LIGHT_SHADOWS#pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE// Additional Lights & Shadows#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS// Soft Shadows#pragma multi_compile _ _SHADOWS_SOFT// Other (Mixed lighting, baked lightmaps, fog)#pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE#pragma multi_compile _ DIRLIGHTMAP_COMBINED#pragma multi_compile _ LIGHTMAP_ON#pragma multi_compile_fog// Supporting shadows will also require passing a positionWS, // and shadowCoord into the fragment shader, again you'll have // to see the Lighting sections for actual examples.

接受投影:

#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"#pragma multi_compile _ _MAIN_LIGHT_SHADOWS#pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADEfloat4 frag (v2f i) : SV_Target{float4 shadowCoords = TransformWorldToShadowCoord(i.worldPos);Light mainLight = GetMainLight(shadowCoords);//阴影实时遮挡half shadow = mainLight.shadowAttenuation;return shadow;}

被投影:

//新加一个passUsePass "Universal Render Pipeline/Lit/ShadowCaster"

为了处理雾,使用ComputeFogFactor 和 MixFog 函数。

#pragma multi_compile_fogstruct Varyings {...half fogFactor : TEXCOORD5;// or whatever unused texcoord// if none are unused pack it together with a half3 or something}...// In the vertex shader :half fogFactor = ComputeFogFactor(positionInputs.positionCS.z);// In the fragment, just before returning the color :color.rgb = MixFog(color.rgb, IN.fogFactor);

二、多Pass问题:

在URP中是使用的single-pass前向渲染,也就是单Pass。

转URP的时候我们会发现 以前多Pass的shader会异常,只会渲染第一个Pass。

如果我们确实需要多Pass怎么办?

我们可以通过设置第一个Pass的LightMode为:UniversalForward就行了。

例如:

Shader "lcl/Shader" {Properties {_Color("Color", Color) = (1,1,1,1)_MainTex("Albedo", 2D) = "white" {}} SubShader {LOD 100Lighting OffPass{Tags {"LightMode"="UniversalForward"}...}Pass {Tags {"LightMode"="SRPDefaultUnlit"}...}}

但是不推荐多Pass渲染,因为会打断 SRP Batcher,使DrawCall增加。(当然 如果没使用SRP Batcher则不影响)

具体什么是SRP Batcher可以参考这里

/p/165574008

/p/165388825

·如果确实需要可以通过RendererFeatures实现多Pass效果

三、兼容SRP Batcher:

首先需要勾选 SRP Batcher。

shader代码修改:

Shader中所有的内置属性例如unity_ObjectToWorldunity_SHAr等,都要在一个名为UnityPerDraw的CBUFFER中声明;

所有的Material属性都要在一个名为UnityPerMaterial的CBUFFER中声明。

CBUFFER_START(UnityPerMaterial)//PropertiesCBUFFER_ENDCBUFFER_START(UnityPerDraw)float4x4 unity_ObjectToWorld;CBUFFER_END

例如:

Properties{_Color1 ("Color 1", Color) = (1,1,1,1)_Color2 ("Color 2", Color) = (1,1,1,1)}//原本的写法//float4 _Color1;//float4 _Color2;//兼容SRP Batcher的写法CBUFFER_START(UnityPerMaterial)float4 _Color1;float4 _Color2;CBUFFER_ENDCBUFFER_START(UnityPerDraw)float4x4 unity_ObjectToWorld;CBUFFER_END

如果shader报错:Shader error in ‘Unlit/SampleUnlit’: redefinition of ‘unity_ObjectToWorld’,重复定义,如果自己的shader代码里面没有,那么就是引入了其他的库文件里面包含了该变量。

最后,我们看Shader的面板,如果出现了类似的提示:

则表示 该属性 未包含在 CBUFFER_START(UnityPerMaterial) 里面。

注意:如果Shader使用了多Pass渲染,则会打断 SRP Batcher。

参考链接:

/p/254810253

/wannaconquer/article/details/114092927

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。