(转载)(官方)UE4--图像编程----着色器开发

着色器开发

快速入门

处理着色器时,请务必将 r.ShaderDevelopmentMode 设置为 1,以将其启用。最简单的方法是编辑 ConsoleVariables.ini,以便每次加载时都进行启用。这将启用“出错时重试”以及与着色器开发相关的日志和警告。

将更改保存到 .usf 文件之后,使用 Ctrl+Shift+. 可重新编译已更改的着色器。 如果您更改包括在许多着色器中的文件(例如,common.usf),那么此操作可能需要花费一些时间。如果您想对某个材质进行迭代,那么可通过对材质进行小幅更改(例如移动节点)并使用材质编辑器中的“应用”(Apply)来触发材质重新编译。

着色器与材质

全局着色器

全局着色器是对固定几何体(例如全屏幕四边形)执行操作并且不需要与材质进行交互的着色器。示例包括阴影过滤或者后处理。在内存中,对于任何给定的全局着色器类型,只有一个着色器。

材质与网格类型

材质由一组用于控制材质渲染方式(混合模式以及双面,等等)的状态以及一组用于控制材质与各种渲染过程的交互方式的材质输入(底色、粗糙度和法线,等等)控制。

顶点工厂

材质必须支持应用于不同的网格类型,而这是通过顶点工厂来实现的。FVertexFactoryType 代表唯一的网格类型,而 FVertexFactory 实例存储每个实例的数据以支持该唯一网格类型。例如,FGPUSkinVertexFactory 存储皮肤处理所需的骨基质,以及对 GPU 皮肤顶点工厂着色器代码需要用作输入的各种顶点缓冲区的引用。顶点工厂着色器代码是一个隐式接口,由各种过程着色器用于抽取网格类型差异。顶点工厂主要由顶点着色器代码组成,但也包含一些像素着色器代码。顶点工厂着色器代码的一些重要组成部分如下:

 

函数


说明


FVertexFactoryInput


定义顶点工厂所需的顶点着色器输入。这些输入必须与 C++ 端的 FVertexFactory 中的顶点声明匹配。例如,LocalVertexFactory 的 FVertexFactoryInput 具有 float4 Position:POSITION;,对应于 FStaticMeshLODResources::SetupVertexFactory 中的位置流声明。


FVertexFactoryIntermediates


用于存储高速缓存的中间数据,该数据将在多个顶点工厂函数中使用。一个常用的示例是 TangentToLocal 矩阵,该矩阵必须根据未打包的顶点输入进行计算。


FVertexFactoryInterpolantsVSToPS


要从顶点着色器传递到像素着色器的顶点工厂数据。


VertexFactoryGetWorldPosition


此函数从顶点着色器中调用,用于获取全局空间顶点位置。对于静态网格,此函数只是使用 LocalToWorld 矩阵将局部空间位置从顶点缓冲区转换到全局空间。对于由 GPU 处理皮肤的网格,将首先处理此位置的皮肤,然后再转换到全局空间。


VertexFactoryGetInterpolantsVSToPS


将 FVertexFactoryInput 转换为 FVertexFactoryInterpolants,后者将由图形硬件进行插值,然后再传递到像素着色器。


GetMaterialPixelParameters


此函数在像素着色器中调用,并将特定于顶点工厂的插值 (FVertexFactoryInterpolants) 转换为 FMaterialPixelParameters 结构,该结构由过程像素着色器使用。

材质着色器

使用 FMaterialShaderType 的着色器是特定于过程的着色器,它们需要访问材质的某些属性,因此必须针对每个材质进行编译,但不需要访问任何网格属性。光函数过程着色器是 FMaterialShaderType 的示例。

使用 FMeshMaterialShaderType 的着色器是特定于过程的着色器,它们依赖于材质的属性和网格类型,因此必须针对每个材质/顶点工厂组合进行编译。例如,TBasePassVS / TBasePassPS需要对正向渲染过程中的所有材质输入进行评估。

材质的必需着色器集合包含在 FMaterialShaderMap 中。其类似于:

FMaterialShaderMap
    FLightFunctionPixelShader - FMaterialShaderType
    FLocalVertexFactory - FVertexFactoryType
        TDepthOnlyPS - FMeshMaterialShaderType
        TDepthOnlyVS - FMeshMaterialShaderType
        TBasePassPS - FMeshMaterialShaderType
        TBasePassVS - FMeshMaterialShaderType
        等等
    FGPUSkinVertexFactory - FVertexFactoryType
        等等

顶点工厂根据其 ShouldCache 函数包括在此矩阵中,该函数依赖于材质的使用。例如,bUsedWithSkeletalMesh 值为 true 表示包括 GPU 皮肤顶点工厂。FMeshMaterialShaderType 根据其 ShouldCache 函数包括在此矩阵中,该函数依赖于材质及顶点工厂属性。这是一种对着色器进行高速缓存的稀疏矩阵方法,这种方法会导致着色器数目迅速增加,从而占用内存并增加编译时间。相对于存储实际需要的着色器列表,主要优点是不必生成任何列表,因此在控制台上运行之前,所需的着色器始终已编译完成。UE4 通过压缩着色器来缓解着色器内存问题,并通过多内核着色器编译来缓解编译时间问题。

创建材质着色器

材质着色器类型是使用 DECLARE_SHADER_TYPE 宏来创建的:

class FLightFunctionPixelShader : public FShader { DECLARE_SHADER_TYPE(FLightFunctionPixelShader,Material);

这个宏为材质着色器类型声明必要的元数据和函数。材质着色器类型将使用 IMPLEMENT_MATERIAL_SHADER_TYPE 进行实例化:

IMPLEMENT_MATERIAL_SHADER_TYPE(,FLightFunctionPixelShader,TEXT("LightFunctionPixelShader")

这将生成材质着色器类型的全局元数据,这些元数据允许我们在运行时执行各种操作,例如使用给定的着色器类型对所有着色器进行迭代。

典型的材质像素着色器类型将先通过调用 GetMaterialPixelParameters 顶点工厂函数来创建 FMaterialPixelParameters 构造。GetMaterialPixelParameters 将特定于顶点工厂的输入转换为任何过程可能想访问的属性,例如 WorldPosition 和 TangentNormal 等等。然后,材质着色器将调用 CalcMaterialParameters,后者将写出 FMaterialPixelParameters 的其余成员,之后 FMaterialPixelParameters 完全初始化。然后,材质着色器将通过 MaterialTemplate.usf 中的函数来访问该材质的某些输入(例如,通过 GetMaterialEmissive 访问材质的自发光输入),执行一些明暗处理,然后输出该过程的最终颜色。

特殊引擎材质

UMaterial 具有一项名为 bUsedAsSpecialEngineMaterial 的设置,该设置允许将材质与任何顶点工厂类型配合使用。这意味着所有顶点工厂都随该材质一起编译,而这将是一个非常大的集合。bUsedAsSpecialEngineMaterial 用于:

  • 仅与渲染视图模式(例如照明)配合使用的材质。
  • 在发生编译错误时用作后备的材质(DefaultDecalMaterial 和 DefaultMaterial,等等)。
  • 在渲染其他材质时使用其着色器,以减少必须高速缓存的着色器数目的材质。例如,某个不透明材质的“仅深度”着色器将生成与 DefaultMaterial 相同的深度输出,因此将改为使用 DefaultMaterial 的着色器,而该不透明材质将跳过对该“仅深度”着色器的高速缓存。

着色器编译

UE4 使用流式系统以异步方式编译着色器。编译请求在没有高速缓存的着色器贴图的材质加载时排入队列,编译结果将在它们变为可用时应用,而不会阻塞引擎。这可在装入时间和编译吞吐量方面实现最佳结果,但这意味着实际平台着色器编译与请求编译的材质之间存在相当多的层。

实际编译工作在称为“着色器编译工作程序”的辅助进程中完成,这是因为平台着色器编译函数 (D3DCompile) 中通常包含不可分割区块,这些区块导致无法在单个进程中进行多内核比例调整。

调试着色器编译器

有一些设置可控制完成编译的方式,这可以简化着色器编译器的调试。您可在 BaseEngine.ini 的 [DevOptions.Shaders] 一节中找到这些设置。

 

设置


说明


bAllowCompilingThroughWorkers


是否启动 SCW 以调用编译器 DLL,或者 UE4 是否应直接调用编译器 DLL。如果禁用此设置,那么将以单内核方式执行编译。


bAllowAsynchronousShaderCompiling


是否应通过 UE4 中的另一个线程来执行编译。

如果您想直接从 UE4 中单步跳入着色器编译器 DLL(例如 CompileD3D11Shader),那么应将这两者都设置为 false。但是,编译将花费较长时间,因此请确保已对所有其他着色器进行高速缓存。

发生编译错误时重试

启用 r.ShaderDevelopmentMode 之后,您将有机会在发生着色器编译错误时重试。这对于全局着色器而言特别重要,因为无法成功编译即表示发生致命错误。

在连接调试器之后进行调试时,您将遇到断点,而编译错误会显示在 Visual Studio 输出窗口中。然后,您可 双击 错误日志,以直接转到存在问题的行。

否则,系统将显示 Yes/No 对话框

着色器高速缓存与准备

着色器编译之后,它们将存储在“派生的数据高速缓存”中。在它们的键中,包含所有编译输入(包括着色器源文件)的散列。这意味着,您每次重新启动引擎或执行 ‘recompileshaders changed‘ 时,都会自动应用对着色器源文件所作的更改。

当您修改 FShader 序列化函数时,不需要处理向后兼容性,而只需在该着色器所包括的着色器文件中添加一个空格。

准备资产时,材质着色器将直接插入到材质的包中,而全局着色器单独存储在全局着色器文件中,这使其可以在引擎启动过程中的早期加载。

调试

调试着色器的主要方法是修改着色器以输出中间结果,然后使用适当的 VisualizeTexture 命令将该结果可视化。这样就可以快速执行迭代,因为您可以迅速完成编译,而不必重新启动引擎。例如,您可以使用类似于以下的代码来验证 WorldPosition 是否正确:

OutColor = frac(WorldPosition / 1000);

然后,验证比例正确,并且结果与视图无关。但是,对于那些构建数据结构的较复杂着色器,此方法无法很好地调整比例。

转储调试信息

您还可以使用 r.DumpShaderDebugInfo=1,以将编译的所有着色器的文件保存到磁盘。就像 r.ShaderDevelopmentMode 一样,在 ConsoleVariables.ini 中进行此设置可能非常有用。文件将保存到 GameName/Saved/ShaderDebugInfo,其中包括

  • 源文件,并包括
  • 着色器的预处理版本
  • 一个批处理文件,用于使用与已使用的编译器等效的命令行选项来编译预处理版本

    如果保持此设置开启,那么会在硬盘上生成许多非常小的文件和文件夹。

迭代最佳实践

如果您正在处理全局着色器,那么 recompileshaders changed 或 Ctrl+Shift+. 是最快的迭代方法。如果着色器要花费较长时间才能完成编译,您可考虑在着色器的 ModifyCompilationEnvironment 中指定 CFLAG_StandardOptimization 作为编译标志。

如果您正在处理材质着色器,例如 BasePassPixelShader.usf,那么对单个材质执行迭代将会快得多。您每次在材质编辑器中单击“应用”按钮时,都会从磁盘重新读取着色器文件,并且仅重新编译该材质。

交叉编译器

HLSL 交叉编译器 用来将 HLSL 自动转换为用于 OpenGL 平台的 GLSL,从而使您只需针对所有平台编写一次着色器。它在离线着色器编译期间运行,并对代码执行 OpenGL 驱动程序经常遗漏的各种优化。

AsyncCompute

AsyncCompute 是某些使用特定 GPU 的 API 中提供的一项硬件功能。 它使交错能够更好更有效率地利用 GPU 中的硬件单元。

原文:https://docs.unrealengine.com/latest/CHN/Programming/Rendering/ShaderDevelopment/index.html

原文地址:https://www.cnblogs.com/wodehao0808/p/8110522.html

时间: 2024-07-31 05:29:46

(转载)(官方)UE4--图像编程----着色器开发的相关文章

(转载)(官方)UE4--图像编程----着色器开发----HLSL 交叉编译器

HLSL 交叉编译器 这个库将 高级着色语言 (HLSL) 着色器源代码编译成高级中间表示法,执行独立于设备的优化,并生成 OpenGL 着色语言 (GLSL) 兼容源代码.这个库在很大程度上基于 Mesa 的 GLSL 编译器.前端已进行大量重新编写,以解析 HLSL 并根据 HLSL 抽象语法树 (AST) 生成 Mesa IR.这个库利用 Mesa 的 IR 优化来简化代码,并根据 Mesa IR 最终生成 GLSL 源代码.GLSL 生成是以 GLSL 优化器中的工作为基础. 除了生成

GPU渲染管线与可编程着色器

本文由@浅墨_毛星云 出品,转载请注明出处.   文章链接:http://blog.csdn.net/poem_qianmo/article/details/71978861 这篇文章是解析计算机图形学界"九阴真经总纲"一般存在的<Real-Time Rendering 3rd>系列文章的第三篇.将带来RTR3第三章内容"Chapter 3 The Graphics Processing Unit 图形处理器"的总结.概括与提炼. 这章的主要内容是介绍G

OpenGL管线(用经典管线代说着色器内部)

图形管线(graphics pipeline)向来以复杂为特点,这归结为图形任务的复杂性和挑战性.OpenGL作为图形硬件标准,是最通用的图形管线版本.本文用自顶向下的思路来简单总结OpenGL图形管线,即从最高层开始,然后逐步细化到管线图中的每个框,再进一步细化到OpenGL具体函数.注意,这里用经典管线代说着色器内部,也就是OpenGL固定管线功能(Fixed-Function,相对于programmable也即可编程着色器),也会涉及着色器,但差不多仅限于“这些固定管线功能对应xx着色器”

DirectX11 With Windows SDK--26 计算着色器:入门

前言 现在开始迎来所谓的高级篇了,目前计划是计算着色器部分的内容视项目情况,大概会分3-5章来讲述. DirectX11 With Windows SDK完整目录 Github项目源码 欢迎加入QQ群: 727623616 可以一起探讨DX11,以及有什么问题也可以在这里汇报. 概述 GPU通常被设计为从一个位置或连续的位置读取并处理大量的内存数据(即流操作),而CPU则被设计为专门处理随机内存的访问. 由于顶点数据和像素数据可以分开处理,GPU架构使得它能够高度并行,在处理图像上效率非常高.但

内置着色器包含文件

Unity包含了好几个文件,这些文件可以在你自己的shader 程序中使用,提供预定义的变量和功能函数.这个操作通过标准的指令 :#include来引入. CGPROGRAM // ... #include "UnityCG.cginc" // ... ENDCG 着色器包含文件在unity中以.cginc扩展名结尾,内置的为: HLSLSupport.cginc - (自动包含)用于跨平台着色程序编译的帮助宏和定义. UnityShaderVariables.cginc - (自动包

Direct2D 1.1 开发笔记 特效篇(三) 简单的像素着色器特效

(转载请注明出处) 这次我们实现一个自定义的转变. 实现Direct2D 自定义转变Shader Models需要HLSL(High Level Shading Language)的实现. HLSL是Shader的一种实现,但是HLSL只能在D3D中使用,所以有点蛋疼. Shader被描述为显卡执行的小段程序,能够高效(并行)地执行. 没学过?没关系,笔者也没有,但是详细的不会在这里说明(你TM逗我(╯‵□′)╯︵┴─┴),请到官网中看看. D2D 特效能用 HLSL 的  4.0 及其以上版本

【浅墨Unity3D Shader编程】之三 光之城堡篇:子着色器、通道与标签的写法 &amp; 纹理混合

本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/41175585 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 邮箱: [email protected] 本文介绍了Unity中子着色器.通道和标签相关的详细概念与写法,以及纹理的设置方法,基本的纹理混合写法,写了5个Shader作为本文Shader讲解的实战内容,最后创建了一个梦幻的光之

Unity3D着色器Shader编程入门(一)

自学Unity3D也有大半年了,对Shader一直不敢入坑,最近看了些资料,以及通过自己的实践,对Shader还是有一点了解了,分享下仅作入门参考. 因Shader是对图像图像渲染的,学习前可以去了解下图形图像学及GPU编程相关的知识.强烈推荐<GPU 编程与CG 语言之阳春白雪下里巴人>,这本书网上有电子版. 还有一本是关于Unity3D的Shader开发的<Unity着色器和屏幕特效开发秘笈>该书是<Unity Shaders and Effects Cookbook&g

OpenGL官方教程——着色器语言概述

OpenGL官方教程——着色器语言概述 OpenGL官方教程——着色器语言概述 可编程图形硬件管线(流水线) 可编程顶点处理器 可编程几何处理器 可编程片元处理器 语言 可编程图形硬件管线(流水线) 将 Pertransformed Vertices (每一个待转换顶点) 传人 Programmable Vertex Processor (可编程的顶点处理器) 得到 Transformed Vertices (转换的顶点) 将 Transformed Vertices (转换的顶点) 传入 Pr