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

程序喵星人 程序喵星人     2022-10-06     771

关键词:

HLSL 交叉编译器

 

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

除了生成 GLSL 代码以外,这个编译器还将全局一致变量打包成数组以便轻松高效地进行设置,提供一种反射机制以通知高级代码需要哪些一致变量,并提供映射信息以使高级代码在运行时可通过索引而非名称来绑定资源。

UnrealBuildTool 不会检测对外部库(例如 HLSLCC)进行的更改。 当您重新构建 HLSLCC 库时,请在 OpenGLShaders.cpp 中添加一个空格,以便强制重新链接该模块。

主库入口点是 HLSLCrossCompile。此函数使用所请求的选项执行根据源 HLSL 生成 GLSL 代码所需执行的所有步骤。每个阶段的摘要如下所示:

 

操作

说明

预处理

代码通过类似于 C 的预处理器运行。此阶段是可选的,您可使用 NoPreprocess 标志省略此阶段。虚幻引擎会在编译前使用 MCPP 执行预处理,从而跳过此步骤。

解析

解析 HLSL 源代码以生成抽象语法树。此工作在 _mesa_hlsl_parse 函数中完成。词法分析器和解析器分别由 flex 和 bison 生成。有关更多信息,请参阅关于解析的小节。

编译

将 AST 编译为 Mesa 中间表示法。此过程在 _mesa_ast_to_hir 函数中发生。在此阶段,编译器执行隐式转换、函数重载解析、生成内部函数的指令等功能。将生成 GLSL 主入口点。请参阅“生成 GLSL 主入口点”。此阶段会将输入及输出变量的全局声明添加到 IR,计算 HLSL 入口点的输入,调用 HLSL 入口点,并将输出写入全局输出变量。

优化

对 IR 执行多遍优化,包括直接插入函数、消除无用代码、传播常量、消除公共的子表达式,等等。有关详细信息,请参阅“优化 IR”,尤其是参阅 do_optimization_pass

一致变量打包

将全局一致变量打包成数组并保留映射信息,以便引擎可将参数与一致变量数组的相关部分绑定。有关详细信息,请参阅“打包一致变量”。

最终优化

打包一致变量之后,将对 IR 运行第二遍优化,以简化打包一致变量时生成的代码。

生成 GLSL

最后,将经过优化的 IR 转换为 GLSL 源代码。从 IR 到 GLSL 的转换相对简单。除了生成所有构造及一致变量缓冲区的定义以及源代码本身以外,还会在文件开头的注释中写入一个映射表。虚幻引擎将解析这个映射表,以便绑定参数。有关详细信息,请参阅“生成 GLSL”,尤其是参阅 ir_gen_glsl_visitor 类。

解析

HLSL 解析器分为两部分:词法分析器和解析器。词法分析器通过使正则表达式与相应的标记匹配,将 HLSL 输入标记化。源文件是 hlsl_lexer.ll,并由 flex 处理以生成 C 代码。每一行都以一个正则表达式开头,后跟以 C 代码编写的语句。该正则表达式匹配时,将执行相应的 C 代码。状态存储在许多以 "yy" 为前缀的全局变量中。

解析器将规则与标记化输入匹配,以解释语言的语法并构建 AST。源文件是 hlsl_parser.yy,并由 bison 处理以生成 C 代码。对 bison 所使用的语法进行全面说明超出了本文档的范畴,但通过检视 HLSL 解析器可了解一些基本信息。通常,您将规则定义为与某个以递归方式求值的标记序列匹配。规则匹配时,将执行一些相应的 C 代码,这使您能够构建自己的 AST。C 代码块中的语法如下所示:

$$ = 解析此规则的结果,这通常是抽象语法树中的节点 $1、$2,等等 = 当前规则所匹配的子规则的输出

对词法分析器或解析器进行更改后,必须使用 flex 和 bison 重新生成 C 代码。GenerateParsers 批处理文件可处理此任务,但您必须根据系统上 flex 和 bison 的安装位置来设置目录。README 文件中包含的信息说明了使用的版本,以及可以从什么位置下载用于 Windows 的二进制文件。

编译

在编译期间,将遍历 AST 并使用 AST 来生成 IR 指令。您应掌握的一个重要概念是,IR 是非常低级别的操作序列。因此,它不会执行隐式转换或任何具有隐式转换性质的操作:所有操作都必须显式地执行。

下面是一些有趣的常用函数:

apply_type_conversion - 此函数将一种类型的值转换为另一种类型(如果有可能的话)。是执行隐式转换还是显式转换由参数控制。

arithmetic_result_type 等- 这组函数确定对输入值应用操作的结果类型。

validate_assignment - 确定某个 rvalue 是否可赋予特定类型的 lvalue。必要时,将应用允许的隐式转换。

do_assignment - 将 rvalue 赋予 lvalue(如果可使用 validate_assignment 完成)。

ast_expression::hir - 将 AST 中的表达式节点转换为一组 IR 指令。

process_initializer - 将初始化表达式应用于变量。

ast_struct_specifier::hir - 构建聚集类型,以表示所声明的结构。

ast_cbuffer_declaration::hir - 构建常量缓冲区布局的构造,并将其存储为一致变量块。

process_mul - 这是用于处理 HLSL 内部乘法的特殊代码。

match_function_by_name - 根据输入参数的名称和列表来查找函数特征符。

rank_parameter_lists - 对两个参数列表进行比较,并指定数字排名以指示这两个列表的匹配程度。这是一个辅助函数,用于执行重载解析:排名最低的特征符将胜出,如果有任何特征符的排名与排名最低的特征符相同,那么将函数调用声明为具有歧义。排名为零表示精确匹配。

gen_texture_op - 处理内置 HLSL 纹理和取样对象的方法调用。

_mesa_glsl_initialize_functions - 生成 HLSL 内部函数的内置函数。大部分函数(例如 sin 和 cos)会生成 IR 代码以执行操作,但某些函数(例如 transpose 和 determinant)会保留函数调用以推迟操作,使其由驱动程序的 GLSL 编译器执行。

扩展编译器

下面是一些有关实现某些类型的功能的提示:

新表达式

 ir_expression_operation 枚举添加一个条目。
 ir_expression 构造函数中,处理您的新表达式,以根据输入操作数的类型来设置表达式的类型化结果。
如果有可能,请向 ir_expression::constant_expression_value 添加一个处理程序,以便在编译时对常量表达式进行求值。
 ir_validate::visit_leave(ir_expression *ir) 添加一个处理程序,以验证该表达式的正确性。
 GLSLExpressionTable 添加一个条目,以将该表达式映射到 GLSL 表达式。
修改词法分析器,使其识别该表达式的标记(如果适用的话)。
修改解析器以使其识别该标记,并创建适当的 ast_expression 节点(如果适用的话)。

内部函数

 _mesa_glsl_initialize_functions 添加内置函数定义。
在大部分情况下,内部函数将直接映射到单个表达式。如果是这样,您只需添加新的 ir_expression 并使用 make_intrinsic_genType 来生成内部函数。

类型

添加 glsl_type,以在 IR 中表示您的类型。您可将其添加到 _mesa_glsl_initialize_types,或添加到其中一个内置类型表,例如 glsl_type::builtin_core_types。对于模板化类型,请参阅 glsl_type::get_sampler_instance 作为示例。
修改词法分析器以使其识别必要的标记,并修改解析器以使其与您的标记匹配。请参阅 Texture2DArray 作为示例。
修改解析器以使其识别该标记,并创建必要的类型说明符。texture_type_specifier_nonarray 是一个不错的示例。
修改 ast_type_specifier::hir,以执行创建用户定义类型所需的任何处理。请参阅结构的处理作为示例。
修改 ast_type_specifier::glsl_type 以返回适当的 glsl_type
如果类型包含方法,请修改 _mesa_ast_field_selection_to_hir 以处理这些方法。请参阅 gen_texture_op 作为示例。

属性、标志和限定符

将属性/标志/限定符添加到任何需要它们的 IR 和/或 AST 节点。
修改词法分析器,使其识别必要的标记。
修改解析器,以根据需要添加语法规则。例如,如果您要添加对 [loop] 属性的支持,请修改 iteration_statement 规则以接受其前面的可选属性。操作如下:将 iteration_statement 更改为 base_iteration_statement,并添加

iteration_statement:

iteration_attr base_iteration_statement
{
    // result is the iteration statement
    $$ = $2;
    // apply attribute
    $$->attr = $1;
}
base_iteration_statement
{
    // pass thru if no attribute
    $$ = $1;
}

最后,在编译器中任何需要了解该属性的位置进行修改。

 

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

(转载)(官方)ue4--图像编程----着色器开发----异步计算(asynccompute)

异步计算(AsyncCompute) 渲染硬件接口(RHI)现支持XboxOne的异步计算(AsyncCompute)。此法可运行与渲染异步的 dispatch() 调用,有效利用未使用的GPU资源(计算单元(CU)、寄存器和带宽)。异步计算使用单独的上下文... 查看详情

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

HLSL交叉编译器 这个库将 高级着色语言(HLSL) 着色器源代码编译成高级中间表示法,执行独立于设备的优化,并生成 OpenGL着色语言(GLSL) 兼容源代码。这个库在很大程度上基于Mesa的GLSL编译器。前端已进行大量重... 查看详情

(转载)(官方)ue4--图形编程

图形编程 引擎中的渲染器模块管理并渲染场景,而场景拥有和每个世界场景相关的可渲染信息。它包括所有绘制规则和着色器的定义。RHI模块是渲染API的接口,是图形编程的另一个关键组件。图形编程总览 包含许多可研... 查看详情

(转载)(官方)ue4--图像编程----parallelrenderingoverview

ParallelRenderingOverview 本页面的内容:Stage1Stage2Stage3SynchronizationDebuggingIntheolddaysbeforeParallelrenderingwasanoptiontherewasjusttheGameThreadandtheRenderThread.TheGameThreadwouldenqueueRende 查看详情

(转载)(官方)ue4--图像编程----图形编程总览

图形编程总览 入门虚幻引擎4(UE4)中有许多渲染代码,因此要通过粗略的观察来迅速了解渲染状况是较为困难。阅读代码时,比较好的入手之处是“FDeferredShadingSceneRenderer::Render”,这是渲染线程中渲染新帧之处。此外,执... 查看详情

(转载)(官方)ue4--图像编程----线程渲染

线程渲染 渲染线程在虚幻引擎4(UE4)中,整个渲染器在其自身的线程中执行操作,该线程位于游戏线程的一两帧后。执行渲染操作时,必须仔细地考虑内存读写,确保线程安全,以及行为的确定性。功能行为取决于两个线... 查看详情

(转载)(官方)ue4--图像编程----粒子发射器技术指南

粒子发射器技术指南 本页面的内容:粒子发射器引用ParticleEmitterInstance结构体ParticleModuleTypeDataBase类示例粒子发射器TypeDataModule声明TypeDataModule的实现粒子发射器声明粒子发射器实现结果创建新的发射器类型需要自定义的Particl... 查看详情

(转载)(官方)ue4--坐标空间术语

坐标空间术语 空间 虚幻引擎中的坐标空间别名描述Tangent(切线空间) 为正交坐标系(插值后将发生偏移),可为左手或右手坐标系。TangentToLocal(切线空间到局部空间)变换仅包含旋转变换,因此它是标准正交坐标系... 查看详情

opencv-图像着色(采用dnn模块导入深度学习模型)(代码片段)

...者:Steven版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处实现原理    图像着色最早是应用在图像修复方面,将一些过去的黑白旧照根据预设色盘上色,得到色彩饱... 查看详情

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

本文由@浅墨_毛星云 出品,转载请注明出处。   文章链接: http://blog.csdn.net/poem_qianmo/article/details/71978861这篇文章是解析计算机图形学界“九阴真经总纲”一般存在的《Real-TimeRendering3rd》系列文章的第三篇。将带... 查看详情

(转载)(官网)ue4--character

角色 通过给Pawn类添加一个CharacterMovementComponent、CapsuleComponent和SkeletalMesh,将Pawn类扩展为了具有更高功能的Charater(角色)类。设计Character类的目的是让其表示直立的玩家,这些玩家可以在世界中走动、跑动、跳跃、飞行及... 查看详情

directx11withwindowssdk--26计算着色器:入门(代码片段)

...数据可以分开处理,GPU架构使得它能够高度并行,在处理图像上效率非常高。但是一些非图像应用程序也能够利用GPU强大的并行计算能力以获得效益。GPU用在非图像用途的应用程序可以称之为:通用GPU(GPGPU)编程。GPU需要数据并... 查看详情

(转载)ue4容器tarraytmap的使用

版权声明:本文为博主原创文章,未经博主允许不得转载。 目录(?)[+] ue中特有容器的使用1、Log日志宏输出到屏幕上的调试日志会覆盖,在outputlog窗口则可以全部显示,所以先写个打日志的宏DECLARE_LOG_CATEGORY_EXTERN(MyContaimTe... 查看详情

(转载)vs2010/mfc编程入门之五十(图形图像:gdi对象之画笔cpen)

 上一节中鸡啄米讲了CDC类及其屏幕绘图函数,本节的主要内容是GDI对象之画笔CPen。       GDI对象       在MFC中,CGdiObject类是GDI对象的基类,通过查阅MSDN我们可以看到,CGdiOb... 查看详情

将 UInt8 组件类型的纹理传递给 Metal 计算着色器

...2018-05-2402:54:17【问题描述】:我有一个以编程方式生成的图像,我想将此图像作为纹理发送到计算着色器。我生成此图像的方式是将每个RGBA分量计算为UInt8值,并将它们组合成UInt32并将其存储在图像的缓冲区中。我使用以下代码 查看详情

[ue4]着色器绑定(shaderbinding)

    当我们在ue4中制作了一个美术材质之后,引擎本身会为我们做很多事情,它会把结点翻译为hlsl,生成多个shader变体,并在多个meshpass中去选择性的调用所需的shader,其中一个重要的过程就是获取shader绑定... 查看详情

(转载)(官网)ue4--gamemode和gamestate

GameMode和GameState 本页面的内容:GameModesGameState两个主要类负责处理进行中游戏的相关信息:GameMode 和 GameState。即使最开放的游戏也拥有基础规则,而这些规则构成了 GameMode。在最基础的层面上,这些规则包括:出... 查看详情

我正在为图像重新着色,但不想重新着色透明背景

】我正在为图像重新着色,但不想重新着色透明背景【英文标题】:I\'mrecoloringanimageandIdon\'twanttorecolorthetransparentbackground【发布时间】:2022-01-0915:06:33【问题描述】:defrecoltest():filenamusda=filedialog.askdirectory()print(filenamusda)globalentrys... 查看详情