Rendering frameworks rarely implement just a single shader, as in our simple example.Typically, a dedicated system is needed to handle the variety of materials, shading models, and shaders used by the application.

渲染框架很少只实现一个着色器,就像我们简单的例子一样。通常,需要一个专用系统来处理应用程序使用的各种材质、着色模型和着色器。

As explained in earlier chapters, a shader is a program for one of the GPU’s programmable shader stages. As such, it is a low-level graphics API resource and not something with which artists would interact directly. In contrast, a material is an artist-facing encapsulation of the visual appearance of a surface. Materials sometimes also describe non-visual aspects, such as collision properties, which we will not discuss further because they are outside the scope of this book.

如前几章所述,着色器是GPU的一个可编程着色器阶段的程序。因此,它是一个低等级图形API资源,而不是艺术家可以直接与之交互的东西。相比之下,材质是面向艺术家的表面视觉外观封装。材料有时也描述非视觉方面,如碰撞属性,我们不会进一步讨论,因为它们超出了本书的范围。

While materials are implemented via shaders, this is not a simple one-to-one correspondence.In different rendering situations, the same material may use different shaders. A shader can also be shared by multiple materials. The most common case is parameterized materials. In its simplest form, material parameterization requires two types of material entities: material templates and material instances. Each material template describes a class of materials and has a set of parameters that can be assigned numerical, color, or texture values depending on the parameter type. Each material instance corresponds to a material template plus a specific set of values for all of its parameters. Some rendering frameworks such as the Unreal Engine allow for a more complex, hierarchical structure, with material templates deriving from other templates at multiple levels.

虽然材质是通过着色器实现的,但这并不是简单的一对一的对应关系。在不同的渲染情况下,相同的材质可能使用不同的着色器。一个着色器也可以由多种材质共享。最常见的情况是参数化材质。最简单的形式是,材质参数化需要两种类型的材质实体:材质模板和材质实例。每个材质模板描述一类材质,并具有一组参数,可以根据参数类型为这些参数指定数值、颜色或纹理值。每个材质实例对应于一个材质模板及其所有参数的一组特定值。一些渲染框架,如虚幻引擎,允许更复杂的层次结构,材质模板从其他模板在多个层次上派生。

Parameters may be resolved at runtime, by passing uniform inputs to the shader program, or at compile time, by substituting values before the shader is compiled. A common type of compile-time parameter is a boolean switch that controls the activation of a given material feature. This can be set by artists via a checkbox in the material user interface or procedurally by the material system, e.g., to reduce shader cost for distant objects where the visual effect of the feature is negligible.

可以在运行时通过将统一输入传递给着色器程序来解析参数,或者在编译时通过在着色器被编译之前替换值来解析参数。一种常见的编译时参数是布尔开关,它控制给定材料特征的激活。这可以由美工人员通过材质用户界面中的复选框来设置,或者由材质系统按程序来设置,例如,在特征的视觉效果可以忽略的情况下,减少远处对象的着色器成本。

While the material parameters may correspond one-to-one with the parameters of the shading model, this is not always the case. A material may fix the value of a given shading model parameter, such as the surface color, to a constant value.Alternately, a shading model parameter may be computed as the result of a complex series of operations taking multiple material parameters, as well as interpolated vertex or texture values, as inputs. In some cases, parameters such as surface position,surface orientation, and even time may also factor into the calculation. Shading based on surface position and orientation is especially common in terrain materials.For example, the height and surface normal can be used to control a snow effect,blending in a white surface color on high-altitude horizontal and almost-horizontal surfaces. Time-based shading is common in animated materials, such as a flickering neon sign.

虽然材质参数可能与着色模型的参数一一对应,但情况并非总是如此。材质可以将给定的着色模型参数(如表面颜色)的值固定为恒定值。或者,可将多个材料参数以及内插顶点或纹理值作为输入,作为一系列复杂运算的结果来计算着色模型参数。在某些情况下,表面位置、表面方向甚至时间等参数也可能是计算的因素。基于表面位置和方向的着色在地形材质中尤其常见。例如,高度和曲面法线可用于控制雪效果,在高海拔水平和几乎水平的曲面上混合白色的曲面颜色。基于时间的着色在动画材质中很常见,例如闪烁的霓虹灯。

One of the most important tasks of a material system is dividing various shader functions into separate elements and controlling how these are combined. There are many cases where this type of composition is useful, including the following:

材质系统最重要的任务之一是将各种着色器功能划分为独立的元素,并控制这些元素的组合方式。在许多情况下,这种类型的组合是有用的,包括以下情况:

• Composing surface shading with geometric processing, such as rigid transforms,vertex blending, morphing, tessellation, instancing, and clipping. These bits of functionality vary independently: Surface shading depends on the material, and geometry processing depends on the mesh. So, it is convenient to author them separately and have the material system compose them as needed.

用几何处理合成表面着色,如刚性变换、顶点混合、变形、镶嵌、实例化和剪裁。这些功能各不相同:表面着色取决于材质,几何体处理取决于网格。因此,单独编写它们并让材质系统根据需要组合它们是很方便的。

• Composing surface shading with compositing operations such as pixel discard and blending. This is particularly relevant to mobile GPUs, where blending is typically performed in the pixel shader. It is often desirable to select these operations independently of the material used for surface shading.

使用像素丢弃和混合等合成操作合成表面着色。这尤其与移动GPU相关,其中混合通常在像素着色器中执行。通常希望独立于用于表面着色的材料来选择这些操作。

• Composing the operations used to compute the shading model parameters with the computation of the shading model itself. This allows authoring the shading model implementation once and reusing it in combination with various different methods for computing the shading model parameters.

将用于计算着色模型参数的操作与着色模型本身的计算相结合。这允许创作着色模型实现一次,并结合用于计算着色模型参数的各种不同方法来重用它。

• Composing individually selectable material features with each other, the selection logic, and the rest of the shader. This enables writing the implementation of each feature separately.

将可单独选择的材质特征彼此、选择逻辑和着色器的其余部分组合在一起。这使得可以分别编写每个特性的实现。

• Composing the shading model and computation of its parameters with light source evaluation: computing the values of clight and l at the shaded point for each light source. Techniques such as deferred rendering (discussed in Chapter 20) change the structure of this composition. In rendering frameworks that support multiple such techniques, this adds an additional layer of complexity.

用光源评估组成着色模型并计算其参数:计算每个光源在着色点处的clight和l值。延迟渲染(在第20章中讨论)等技术改变了这种构图的结构。在支持多种此类技术的渲染框架中,这又增加了一层复杂性。

It would be convenient if the graphics API provided this type of shader code modularity as a core feature. Sadly, unlike CPU code, GPU shaders do not allow for post-compilation linking of code fragments. The program for each shader stage is compiled as a unit. The separation between shader stages does offer some limited modularity, which somewhat fits the first item on our list: composing surface shading (typically performed in the pixel shader) with geometric processing (typically performed in other shader stages). But the fit is not perfect, since each shader performs other operations as well, and the other types of composition still need to be handled.Given these limitations, the only way that the material system can implement all these types of composition is at the source-code level. This primarily involves string operations such as concatenation and replacement, often performed via C-style preprocessing directives such as #include, #if, and #define.

如果图形API提供这种类型的着色器代码模块化作为核心特性,将会非常方便。遗憾的是,与CPU代码不同,GPU着色器不允许代码片段的编译后链接。每个着色器阶段的程序作为一个单元进行编译。着色器阶段之间的分离确实提供了一些有限的模块化,这在某种程度上符合我们列表中的第一项:将表面着色(通常在像素着色器中执行)与几何处理(通常在其他着色器阶段执行)结合起来。但是拟合并不完美,因为每个着色器还执行其他操作,并且仍然需要处理其他类型的合成。考虑到这些限制,material系统能够实现所有这些类型的组合的唯一方式是在源代码级别。这主要涉及字符串操作,比如连接和替换,通常通过C风格的预处理指令来执行,比如#include、#if和#define。

Early rendering systems had a relatively small number of shader variants, and often each one was written manually. This has some benefits. For example, each variant can be optimized with full knowledge of the final shader program. However,this approach quickly becomes impractical as the number of variants grows. When taking all the different parts and options into account, the number of possible different shader variants is huge. This is why modularity and composability are so crucial.

早期的渲染系统具有相对较少数量的着色器变体,并且通常每个都是手动编写的。这有一些好处。例如,可以利用最终着色器程序的全部知识来优化每个变体。然而,随着变体数量的增加,这种方法很快变得不切实际。当考虑到所有不同的部分和选项时,可能的不同着色器变体的数量是巨大的。这就是模块化和可组合性如此重要的原因。

The first question to be resolved when designing a system for handling shader variants is whether selection between different options is performed at runtime via dynamic branching, or at compile time via conditional preprocessing. On older hardware,dynamic branching was often impossible or extremely slow, so runtime selection was not an option. Variants were then all handled at compile time, including all possible combinations of counts of the different light types

当设计用于处理着色器变量的系统时,要解决的第一个问题是,不同选项之间的选择是在运行时通过动态分支来执行,还是在编译时通过条件预处理来执行。在较老的硬件上,动态分支通常是不可能的或者非常慢,所以运行时选择不是一个选项。然后在编译时处理所有的变体,包括不同光类型的计数的所有可能的组合

In contrast, current GPUs handle dynamic branching quite well, especially when the branch behaves the same for all pixels in a draw call. Today much of the functionality variation, such as the number of lights, is handled at runtime. However, adding a large amount of functional variation to a shader incurs a different cost: an increase in register count and a corresponding reduction in occupancy, and thus performance.See Section 18.4.5 for more details. So, compile-time variation is still valuable. It avoids including complex logic that will never be executed.

相比之下,当前的GPU可以很好地处理动态分支,特别是当分支在draw调用中对所有像素表现相同时。如今,许多功能变化,比如灯的数量,都是在运行时处理的。然而,向着色器添加大量的功能变化会导致不同的成本:寄存器数量增加,占用率相应降低,从而降低性能。更多详情见第18.4.5节。因此,编译时变化仍然是有价值的。它避免包含永远不会执行的复杂逻辑。

As an example, let us imagine an application that supports three different types of lights. Two light types are simple: point and directional. The third type is a generalized spotlight that supports tabulated illumination patterns and other complex features, requiring a significant amount of shader code to implement. However, say the generalized spotlight is used relatively rarely, with less than 5% of the lights in the application being this type. In the past, a separate shader variant would be compiled for each possible combination of counts of the three light types, to avoid dynamic branching. While this would not be needed today, it may still be beneficial to compile two separate variants, one for the case when the count of generalized spotlights is equal to or greater than 1, and one for the case where the count of such lights is exactly 0.Due to its simpler code, the second variant (which is most commonly used) is likely to have lower register occupancy and thus higher performance.

作为一个例子,让我们想象一个支持三种不同类型灯光的应用程序。有两种简单的光源类型:点光源和平行光。第三种类型是通用聚光灯,支持列表照明模式和其他复杂功能,需要大量着色器代码来实现。然而,一般的聚光灯很少使用,应用中只有不到5%的灯光是这种类型。过去,为了避免动态分支,会为三种灯光类型的计数的每个可能组合编译一个单独的着色器变体。虽然现在不需要这样做,但编译两个单独的变量可能仍然是有益的,一个用于广义聚光灯的计数等于或大于1的情况,另一个用于这种灯光的计数正好为0的情况。由于代码更简单,第二种变体(最常用的)可能具有更低的寄存器占用率,从而具有更高的性能。

Modern material systems employ both runtime and compile-time shader variation.Even though the full burden is no longer handled only at compile time, the overall complexity and number of variations keep increasing, so a large number of shader variants still need to be compiled. For example, in some areas of the game Destiny: The Taken King, over 9000 compiled shader variations were used in a single frame.The number of possible variations can be much larger, e.g., the Unity rendering system has shaders with close to 100 billion possible variants. Only the variants that are actually used are compiled, but the shader compilation system had to be redesigned to handle the huge number of possible variants.

现代材质系统采用运行时和编译时着色器变体。即使全部负担不再仅在编译时处理,整体复杂性和变化的数量仍在增加,因此仍需要编译大量着色器变量。例如,在游戏《命运:夺命之王》的某些区域,一帧中使用了超过9000个编译过的着色器变体。可能变化的数量可以大得多,例如,Unity渲染系统具有接近1000亿个可能变化的着色器。只有实际使用的变量被编译,但是着色器编译系统必须重新设计以处理大量可能的变量。

Material-system designers employ different strategies to address these design goals. Although these are sometimes presented as mutually exclusive system architectures, these strategies can be—and usually are—combined in the same system.These strategies include the following:

材料系统设计师采用不同的策略来实现这些设计目标。尽管这些策略有时表现为相互排斥的系统架构,但它们可以——而且通常是——组合在同一个系统中。这些战略包括以下内容:

• Code reuse—Implementing functions in shared files, using #include preprocessor directives to access those functions from any shader that needs them.

代码重用——在共享文件中实现函数,使用#include预处理器指令从任何需要这些函数的着色器中访问这些函数。

• Subtractive—A shader, often referred to as an ¨ubershader or supershader, that aggregates a large set of functionality, using a combination of compiletime preprocessor conditionals and dynamic branching to remove unused parts and to switch between mutually exclusive alternatives.

减法——一种着色器,通常称为超级着色器或超级着色器,它聚合了一大组功能,使用compiletime预处理器条件和动态分支的组合来删除未使用的部分,并在互斥的选项之间切换。

• Additive—Various bits of functionality are defined as nodes with input and output connectors, and these are composed together. This is similar to the code reuse strategy but is more structured. The composition of nodes can be done via text [342] or a visual graph editor. The latter is intended to make it easier for non-engineers, such as technical artists, to author new material templates [1750, 1802]. Typically only part of the shader is accessible to visual graph authoring. For example, in the Unreal Engine the graph editor can only affect the computation of shading model inputs [1802]. See Figure 5.13.

附加——各种功能被定义为具有输入和输出连接器的节点,这些节点被组合在一起。这类似于代码重用策略,但是更加结构化。节点的组成可以通过文本[342]或可视图形编辑器来完成。后者旨在使非工程师,如技术艺术家,更容易创作新的材料模板[1750,1802]。通常,可视化图形创作只能访问着色器的一部分。例如,在虚幻引擎中,图形编辑器只能影响着色模型输入的计算[1802]。参见图5.13。

Figure 5.13. The Unreal Engine material editor. Note the tall node on the right side of the node graph. The input connectors of this node correspond to various shading inputs used by the rendering engine, including all the shading model parameters. (Material sample courtesy of Epic Games.)

图5.13。虚幻引擎材质编辑器。请注意节点图右侧的高节点。该节点的输入连接器对应于渲染引擎使用的各种着色输入,包括所有着色模型参数。(材料样本由Epic Games提供。)

• Template-based—An interface is defined, into which different implementations can be plugged as long as they conform to that interface. This is a bit more formal than the additive strategy and is typically used for larger chunks of functionality.A common example for such an interface is the separation between the calculation of shading model parameters and the computation of the shading model itself. The Unreal Engine [1802] has different “material domains,” including the Surface domain for computing shading model parameters and the Light Function domain for computing a scalar value that modulates clight for a given light source. A similar “surface shader” structure also exists in Unity [1437].Note that deferred shading techniques (discussed in Chapter 20) enforce a similar structure, with the G-buffer serving as the interface.

基于模板——定义了一个接口,只要符合该接口,不同的实现就可以插入到该接口中。这比加法策略更正式一些,通常用于较大的功能块。这种接口的一个常见例子是着色模型参数的计算和着色模型本身的计算之间的分离。虚幻引擎[1802]具有不同的“材料域”,包括用于计算着色模型参数的表面域和用于计算为给定光源调制clight的标量值的光函数域。类似的“表面着色器”结构也存在于Unity [1437]中。请注意,延迟着色技术(在第20章中讨论)使用G缓冲区作为接口来执行类似的结构。

For more specific examples, several chapters in the (now free) book WebGL Insights [301] discuss how a variety of engines control their shader pipelines. Besides composition, there are several other important design considerations for modern material systems, such as the need to support multiple platforms with minimal duplication of shader code. This includes variations in functionality to account for performance and capability differences among platforms, shading languages, and APIs. The Destiny shader system [1750] is a representative solution to this type of problem. It uses a proprietary preprocessor layer that takes shaders written in a custom shading language dialect. This allows writing platform-independent materials with automatic translation to different shading languages and implementations. The Unreal Engine [1802] and Unity [1436] have similar systems.

对于更具体的例子,在(现在免费的)书WebGL Insights [301]中的几个章节讨论了各种引擎如何控制它们的着色器管线。除了合成之外,现代材质系统还有其他几个重要的设计考虑因素,例如需要支持多个平台,同时尽可能减少着色器代码的重复。这包括功能上的变化,以说明平台、着色语言和API之间的性能和功能差异。命运着色器系统[1750]是这类问题的代表性解决方案。它使用专有的预处理器层,该层采用以自定义着色语言方言编写的着色器。这允许编写独立于平台的材料,自动翻译成不同的着色语言和实现。虚幻引擎[1802]和Unity [1436]有类似的系统。

The material system also needs to ensure good performance. Besides specialized compilation of shading variants, there are a few other common optimizations the material system can perform. The Destiny shader system and the Unreal Engine automatically detect computations that are constant across a draw call (such as the warm and cool color computation in the earlier implementation example) and move it outside of the shader. Another example is the scoping system used in Destiny to differentiate between constants that are updated at different frequencies (e.g., once per frame, once per light, once per object) and update each set of constants at the appropriate times to reduce API overhead.

材料系统也需要保证良好的性能。除了专门编译着色变体之外,材质系统还可以执行其他一些常见的优化。Destiny着色器系统和Unreal引擎自动检测在绘制调用中保持不变的计算(如早期实现示例中的暖色和冷色计算),并将其移出着色器。另一个例子是Destiny中使用的范围系统,用于区分以不同频率更新的常数(例如,每帧一次、每光一次、每物体一次),并在适当的时间更新每组常数以减少API开销。

As we have seen, implementing a shading equation is a matter of deciding what parts can be simplified, how frequently to compute various expressions, and how the user is able to modify and control the appearance. The ultimate output of the rendering pipeline is a color and blend value. The remaining sections on antialiasing,transparency, and image display detail how these values are combined and modified for display.

正如我们所看到的,实现一个着色方程就是决定哪些部分可以简化,计算各种表达式的频率,以及用户如何能够修改和控制外观。渲染管道的最终输出是颜色和混合值。关于抗锯齿、透明度和图像显示的其余部分详细说明了如何组合和修改这些值以进行显示。

Real-Time Rendering——5.3.3 Material Systems 材质系统相关推荐

  1. Untiy3D Material 材质系统

    材质系统在任何引擎里面都算一个大模块,我也遍了解遍写,写到哪里算哪里. 里面涉及到材质属性系统,底层Shader模块和纹理Texture模块.所以比较复杂,如果理解材质系统,那就能控制整个游戏画面渲染 ...

  2. Paper:《Hidden Technical Debt in Machine Learning Systems—机器学习系统中隐藏的技术债》翻译与解读

    Paper:<Hidden Technical Debt in Machine Learning Systems-机器学习系统中隐藏的技术债>翻译与解读 导读:机器学习系统中,隐藏多少技术 ...

  3. OpenGL material light材质灯光的实例

    OpenGL material light材质灯光 先上图,再解答. 完整主要的源代码 源代码剖析 先上图,再解答. 完整主要的源代码 #include <glad/glad.h> #in ...

  4. AR涂涂乐⭐二、 给material赋予材质、移除material、调整扫描框透明度

    1.给material赋予材质: 在Project新建materials文件夹,新建material, 在其shader选项中选择Mobile--Particles--Additive,将制作好的不同 ...

  5. Google Filament 源码学习(六):Material System (五) - 材质系统框架

    目录 Introduction Filament 工程简化 删除 Filament 工程中非核心内容 根目录保留 build文件夹中保留 filament文件夹中保留 libs文件夹中保留 third ...

  6. 第 3 章 Systems architecture(系统架构)

    3.1. 集群(Cluster) 集群有很多实现方法,分为硬件和软件,集群可以在不同网络层面上实现 实现IP轮循(Bind DNS) 硬件四层交换(硬件负载均衡设备 F5 BIG IP) 软件四层交换 ...

  7. Google Filament 源码学习(五):Material System (四) - 材质系统 API

    目录 Shader public APIs Introduction Types Math Matrices Frame constants Vertex only Fragment only Han ...

  8. Discrete-time systems(离散时间系统)

    一.分类 1)连续时间系统与离散时间系统 连续时间系统的数学模型用微分方程描述 离散时间系统的数学模型用差分方程描述 2)即时系统与动态系统 即时系统:当前输出只有当前输入有关,与过去的输入无关. 动 ...

  9. USACO 2.3.5 Money Systems 货币系统

    题目描述: 给你一个n种面值的货币系统,求组成面值为m的货币有多少种方案.样例:设n=3,m=10,要求输入和输出的格式如下: 输入格式: 3  10       //3种面值组成面值为10的方案 1 ...

  10. 批量 材质 调整_寒霜引擎的PBR实践3.0(一)材质篇

    随着对游戏美术品质要求的提高,对整个开发从流程pipeline到从业人员的素质要求都开始增加.传统的美术工作流因为依赖个人的经验和感觉,所以在制作大体量项目的过程中很难达到理想效果.而这时,由项目组内 ...

最新文章

  1. 蚂蚁金服-支付风险识别亚军方案!
  2. 图文解读助你理解和使用正则表达式
  3. webpack 配置文件.conf.js 浅理解
  4. python优先级排序_Python实现优先级队列结构的方法详解
  5. 从一个极简的微服务架构开始
  6. vfp赋值超过7位出错_JDK1.7下的HashMap的源码分析
  7. [html] 怎样去除iOS和Android中的输入URL地址的控件条呢?
  8. python 获取 字典中的指定键_python中字典方法的详细教程
  9. JDBC——实现通用的查询
  10. matlab 发音,MATLAB,MATLAB language,音标,读音,翻译,英文例句,英语词典
  11. python可以制作大型游戏_python能做游戏吗-python能开发游戏吗
  12. [转载] 网络硬件发展史
  13. 交叉编译linux内核实例(最详细)总结
  14. 物联网实时内核 vnRTOS 免费开源
  15. 软件测试就是点点点?你想的太简单了......
  16. 学习笔记——Kaggle_Digit Recognizer (SVM算法 Python实现)
  17. android 百度音乐 api,[新]百度mp3接口(baidu mp3 api)
  18. 以太网驱动详解之RMII、SMII、GMII、RGMII接口
  19. 【论文阅读】面部表情识别综述(2018年)(Deep Facial Expression Recognition: A Survey)
  20. 解决ip无法自动分配

热门文章

  1. c语言 逻辑 与或非
  2. 网络计算机不能打印,如果共享打印机后局域网计算机无法打印,该怎么办?
  3. 百度富文本编辑器插入视频链接相关问题
  4. 实战HTML:部分美团首页静态界面
  5. 基于JAVA的免费天气预报接口查询
  6. 反入侵体系建设入门-攻击场景梳理
  7. Java打造RPC框架(四):支持zookeeper与负载均衡
  8. 谢烟客---------Linux之Aho Weinberger Kernighan
  9. Excel教程:必会的大数据录入技巧|Excel入门
  10. 常威来了(变量和常量)简单易懂