• 【图形学】14 UnityShader语义(二)


    来源:《UNITY SHADER入门精要》

    1、内置的包含文件

      CGIncludes文件夹中包含所有内置的包含文件。
      DefaultResources文件夹包含一些内置的组件和功能所需的Unity Shader。
      DefaultResourcesExtra文件夹包含了所有的Unity Shader
      Editor文件夹包含了一个脚本文件,它用于定义Unity引入的Standard Shader所用的材质面板。

    2、CGIncludes中常用的文件

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H6urwkxR-1659407851651)(assets/image-20220616223204804.png)]

      其中,一些文件不用 #include 指令包含,比如 UnityShaderVariavles.cginc,它会自动默认包含。

      这里我们多看一下 UnityCG.cginc 中的常用结构体,其实这些更多应该可以自己在文件中查看的。
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pNExMDl2-1659407851652)(assets/image-20220616223803354.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bn6yAt2x-1659407851652)(assets/image-20220616224346086.png)]

    3、有关语义(semantics)的说明

      语义实际上就是让 Shader 知道,从哪里读取数据,并把数据输出到哪里,它们在 CG/HLSL 的 Shader 流水线中是不可或缺的。要注意的是,这些都是CG/HLSL提供的语义,而Unity并没有支持所有的语义。
      在DirectX 10以后,有了一种新的语义类型,就是**系统数值语义(system-value semantics)。**这类语义是以 SV 开头的,SV代 表的含义就是系统数值(system-value)。这些语义在渲染流水线中有特殊的含义。我们使用 SV_POSITION 语义去修饰顶点着色器的输出变量pos,那么就表示pos包含了可用于光栅化的变换后的顶点坐标(即齐次裁剪空间中的坐标)。
      用这些语义描述的变量是不可以随便赋值的,因为流水线需要使用它们来完成特定的目的,例如渲染引擎会把用 SV_POSITION 修饰的变量经过光栅化后显示在屏幕上。
      有时可能会看到同一个变量在不同的 Shader 里面使用了不同的语义修饰。例如,一些 Shader 会使用 POSITION 而非 SV_POSITION 来修饰顶点着色器的输出。SV_POSITION 是 DirectX10 中引入的系统数值语义,在绝大多数平台上,它和 POSITION 语义是等价的,但在某些平台(例如索尼PS4)上必须使用 SV_POSITION 来修饰顶点着色器的输出,否则无法让 Shader 正常工作。同样的例子还有 COLORSV_Target。.因此,为了让我们的Shader有更好的跨平台性,对于这些有特殊含义的变量我们最好使用以 SV 开头的语义进行修饰。

    4、Unity支持的语义

      下表总结了从应用阶段传递模型数据给顶点着色器时Unity使用的常用语义。这些语义虽然没有使用 SV 开头,但Unity内部赋予了它们特殊的含义。
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-arGgU0N7-1659407851653)(assets/image-20220616232853078.png)]

      从顶点着色器传递数据给片元着色器时Unity使用的常用语义
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8NIUCE2Q-1659407851653)(assets/image-20220617101551286.png)]

      片元着色器输出时Unity支持的常用语义
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2vXidz1T-1659407851654)(assets/image-20220617105345317.png)]

    5、UnityShader的调试方法

    ①使用假彩色图像

    ②Viusal Studio

    ③帧调试器

    6、渲染纹理的坐标差异

      我们知道,DirextX和OpenGL在采用屏幕空间坐标系的时候,采用的不同方向的坐标系,我们不仅应该把渲染结果输出到屏幕上,还可以输出到不同的渲染目标(Render Target)中。通常,Unity会为我们自动处理这种不一样的,需要翻转的问题。
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N9zHzueN-1659407851654)(assets/image-20220617114440775.png)]

      在某一种特殊情况下,Unity不会为我们自动反转,即:当我们开启了抗锯齿的时候(Edit->Project Settings->Quality->Anti Aliasing中开启)。
      Unity 首先渲染得到屏幕图像,再由硬件进行抗锯齿处理,得到一张渲染纹理来供我们进行后续处理。此时,在DirectX平台下,我们的屏幕图像并不会被Unity翻转,我们就可能需要在顶点着色器中翻转某些渲染纹理:

    #if UNITY_UV_STARTS_AT_TOP
    if (_MainTex_TexelSize.y < 0)
    	uv.y = 1 -uv.y;
    }
    #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5

      其中,UNIRT_UV_STARTS_AT_TOP 用于判断当前平台是否是 DirectX类型的平台,而当再这样的平台下开启了抗锯齿之后,主纹理的纹素大小在竖直方向上会变成负值,以方便我们对主纹理进行正确的采样。如果是,我们就需要对除主纹理外的其他的纹理采样坐标进行竖直方向上的翻转。

    7、使用内置宏来对结构体初始化

    UNITY_INITIALIZE_OUTPUT(Input, o);
    
    • 1

    8、平台差异

      在某些平台上,一些语义是等价的,比如:SV_POSITIONPOSITION,而有些时候是不等价的。

    • 使用 SV_POSITION 来描述顶点着色器输出的顶点位置。一些 Shader 使用了 POSITION 语义,但这些 Shader 无法在索尼PS4平台上或使用了细分着色器的情况下正常工作。
    • 使用 SV_Target 来描述片元着色器的输出颜色。一些 Shader 使用了 COLOR 或者 COLORO 语义,同样的,这些 Shader 无法在 索尼PS4 上正常工作。

      更多可以查看 Unity 官方文档:http://docs.unity3d.com/Manual/SL-PlatformDifferences.html

  • 相关阅读:
    [apue] 文件中的空洞
    牛客网论坛最具争议的Java面试成神笔记,GitHub已下载量已过百万
    策略模式在数据接收和发送场景的应用
    MySQL 45 讲 | 14 count(*)这么慢,我该怎么办?
    Leetcode-160 相交链表
    【广州华锐互动】消防科普VR实训展馆增强群众学习兴趣和沉浸感
    Day810.MySQL调优之事务:高并发场景下的数据库事务调优 -Java 性能调优实战
    怎么彻底粉碎文件夹?文件还能恢复吗?操作过程在这里
    【Javaweb】动态web开发核心Servlet的原始真解
    大数据技术之Hive:先导篇(一)
  • 原文地址:https://blog.csdn.net/qq_40891541/article/details/126117476