【译文】unity可编程渲染管道#1——自定义着色器

HLSL和核心库


第1页

定义常量缓冲区。使用渲染管道核心库。支持动态批处理和GPU实例化。这是包含Unity可编写脚本的渲染的教程系列的第二部分管道。它是关于使用HLSL创建着色器并有效地渲染多个着色器通过在单个绘图调用中对它们进行批处理来对象。本教程使用Unity 2018.3.0f2。256个球,一个平局调用。

第2页

1个自定义不亮的着色器虽然我们已经使用默认的unlit着色器来测试我们的管道,但需要完整一个非常重要的自定义管道的优点需要创建自定义着色器与它合作。所以我们将创建一个自己的着色器,取代Unity的默认值不亮的着色器。

第3页

1.1 创建着色器可以通过Assets / Create / Shader中的一个选项创建着色器资源菜单。Unlit Shader是最合适的,但我们将重新开始从创建的着色器文件中删除所有默认代码。将资产命名为Unlit。不亮的着色器资产。着色器文件的基础知识在渲染2,着色器基础知识中进行了解释。如果您不熟悉编写着色器,请仔细阅读,以便了解基础知识。该获得有效着色器的最小值是使用Properties块定义Shader块加上一个带有Pass块的SubShader块。Unity会将其转换为默认值白色未点亮着色器。在之后的Shader关键字来将在使用的字符串材质的着色器下拉菜单。我们将使用My Pipeline / Unlit。着色器“我的管道/熄灭” {属性{}SubShader {通过{}}}调整Unlit Opaque材质,使其使用我们的新着色器,如果将其变为白色它还没有。带有自定义着色器的不透明不透明材质。1.2 HLSL

第4页

要编写我们自己的着色器,我们必须在其Pass块中放置一个程序。统一支持GLSL或HLSL程序。虽然GLSL用于默认着色器和同样在渲染2,Shader Fundamentals, Unity的新渲染管道着色器使用HLSL,所以我们也将它用于我们的管道。这意味着我们必须把所有我们在HLSLPROGRAM和ENDHLSL语句之间的代码。通过{HLSLPROGRAMENDHLSL}GLSL和HLSL计划有什么区别?在实践中,Unity对两者使用几乎相同的语法并负责转换每个构建目标的适当着色器代码。最大的区别是GLSL程序默认包含一些代码。HLSL程序不会隐式执行任何操作,要求我们明确包含我们需要的任何东西。那很好,因为旧的GLSL包含文件由旧的和过时的代码压缩。我们将依赖更新的HLSL包括文件。Unity着色器至少需要顶点程序和片段程序函数,每个都使用pragma编译器指令定义。我们将使用UnlitPassVertex为另一个是顶点函数和UnlitPassFragment。但是我们不会把代码放进去这些函数直接在着色器文件中。相反,我们将把HLSL代码放入单独的包含文件,我们也将其命名为Unlit,但使用hlsl扩展名。把它放进去与Unlit.shader相同的文件夹,然后将其包含在HLSL程序之后编译指令。HLSLPROGRAM#pragma vertex UnlitPassVertex#pragma片段UnlitPassFragment#include“Unlit.hlsl”ENDHLSL不幸的是,Unity没有一个方便的菜单项来创建HLSL包括文件资产。你必须自己创建它,例如通过复制Unlit.shader文件,将其文件扩展名更改为hlsl并删除着色器代码从中。

第5页

Unlit HLSL包含文件资产。在include文件中,以include guard开头,以防止重复代码如果文件被包含多一次。虽然这应该永远不会发生,但这很好练习总是为每个包含文件执行此操作。#ifndef MYRP_UNLIT_INCLUDED#define MYRP_UNLIT_INCLUDED#endif // MYRP_UNLIT_INCLUDED至少,我们必须知道顶点程序中的顶点位置,它具有输出均匀的剪辑空间位置。所以我们将定义输入和输出顶点程序的结构,都有一个float4位置。#ifndef MYRP_UNLIT_INCLUDED#define MYRP_UNLIT_INCLUDEDstruct VertexInput {float4 pos:POSITION ;};struct VertexOutput {float4 clipPos:SV_POSITION ;};#endif // MYRP_UNLIT_INCLUDED接下来,我们将定义顶点程序函数UnlitPassVertex。现在,我们将直接使用对象空间顶点位置作为剪辑空间位置。这是不正确的,但是是获得编译着色器的最快方法。我们将添加正确的空间转换后来。struct VertexOutput {float4 clipPos:SV_POSITION ;};VertexOutput UnlitPassVertex(VertexInput 输入){VertexOutput 输出;output.clipPos = input.pos;返回输出;}#endif // MYRP_UNLIT_INCLUDED

第6页

我们现在保留默认的白色,所以我们的片段程序功能可以只需将1作为float4返回。它接收内插顶点输出作为其输入,所以将其添加为参数,即使我们尚未使用它。