【Unity Shader】Unity提供的CG/HLSL语义

2024-08-28 14:48
文章标签 提供 unity 语义 shader cg hlsl

本文主要是介绍【Unity Shader】Unity提供的CG/HLSL语义,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

主要参考《Unity Shader入门精要》一书,外加自己的一些总结


什么是语义


语义实际就是一个赋给Shader输入和输出的字符串,这个字符串表达了这个参数的含义。这些语义可以让Shader知道从哪里读取数据,并把数据输到哪里。
在DirectX10以后,有了一种新的语义类型,即系统数值语义(system-value semantics)。这类语义是以SV开头的,SV代表的就是系统数值。这些语义在渲染流水线中有特殊的含义,比如上一篇中,我们使用SV_POSITION 语义修饰顶点着色器的输出变量pos,那么就表示pos包含了可用于光栅化的变换后的顶点坐标,即齐次剪裁空间中的坐标。

Unity支持的语义

从应用阶段传递模型数据给顶点着色器时Unity支持的常用语义,表如下:



从顶点着色器传递给片元着色器时Unity支持的常用语义,表如下:


片元着色器输出时Unity支持的常用语义,表如下:




Unity中对Unity Shader 的调试方法:
1,使用假彩色图像
假彩色图像(false_color image)指的是用假彩色技术生成的一种图像。一张假彩色图像可以用于可视化一些数据,那么如何用它来对Shader 进行调试呢?
主要思想是,我们可以把需要调试的变量映射到[0,1]之间,把它们作为颜色输出到屏幕上,然后通过屏幕上显示的像素颜色来判断这个值是否正确。
作为实例,下面我们会使用假彩色图像的方式来可视化一些模型数据,如法线、切线、纹理坐标、顶点颜色,以及它们之间的运算结果等,代码如下:
Shader "Unity Shader Book/Chapter 5/False Color"{SubShader{Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct v2f {float4 pos : SV_POSITION;fixed4 color : COLOR0;};v2f vert(appdata_full v){v2f o;o.pos = UnityObjectToClipPos(v.vertex);//可视化法线方向o.color = fixed4(v.normal * 0.5 + fixed3(0.5, 0.5, 0.5), 1.0);//可视化切线方向o.color = fixed4(v.tangent * 0.5 + fixed3(0.5,0.5,0.5),1.0);//可视化副法线方向fixed3 binormal = cross(v.normal, v.tangent.xyz) * v.tangent.w;o.color = fixed4(binormal * 0.5 + fixed3(0.5, 0.5, 0.5), 1.0);//可视化第一组纹理坐标o.color = fixed4(v.texcoord.xy, 0.0, 1.0);//可视化第二组纹理坐标o.color = fixed4(v.texcoord1.xy, 0.0, 1.0);//可视化第一组纹理坐标的小数部分o.color = frac(v.texcoord);if (any(saturate(v.texcoord) - v.texcoord)){o.color.b = 0.5;}o.color.a = 1.0;//可视化第二组纹理坐标的小数部分o.color = frac(v.texcoord1);if (any(saturate(v.texcoord1) - v.texcoord1)){o.color.b = 0.5;}o.color.a = 1.0;//可视化顶点颜色o.color = v.color;return o;}fixed4 frag(v2f i) : SV_Target{return i.color;}ENDCG}}
}

上面的代码中,我们使用了Uniyt内置的一个结构体——appdata_full。可以在UnityCG.cginc 里找到它的定义:
struct appdata_full {float4 vertex : POSITION;float4 tangent : TANGENT;float3 normal : NORMAL;float4 texcoord : TEXCOORD0;float4 texcoord1 : TEXCOORD1;float4 texcoord2 : TEXCOORD2;float4 texcoord3 : TEXCOORD3;fixed4 color : COLOR;UNITY_VERTEX_INPUT_INSTANCE_ID
};

可以看出,appdata_full 几乎包含了所有的模型数据。
我们把计算得到的假彩色存储到了顶点着色器的输出结构体——v2f中的color 变量里,并且在片元着色器中输出了这个颜色。我们可以对其中的代码进行不同的注释,来观察不同运算和数据得到的效果。


Shader 整治之道

1,float、half、fixed
在CG/HLSL中,有三种精度的数值类型:float、half、fixed。这些精度将决定计算结果的数值范围,精度范围如下表:
上面的精度范围并不是绝对正确的,在不同的平台和GPU上,可能会有所不同。
尽可能使用精度较低的类型,因为这可以优化Shader的性能,这一点在移动平台上尤其重要。从它们大体的值域范围来看,我们可以使用fixed类型来存储颜色和单位矢量,如果要存储更大范围的数据可以选择half 类型,最差情况下再选择使用float。

2,避免不必要的计算
如果我们在Shader 中,尤其是片元着色器中,进行了大量的计算,那么很可能就会收到Unity的错误提示。不同的Shader Target、不同的着色器阶段,我们可以使用的临时寄存器和指令数目都是不同的。如下表:

3,慎用分支和循环语句
如果我们在Shader中使用了大量的流程控制语句,那么这个Shader的性能可能会成倍下降。解决方法就是,我们尽量把计算向流水线上端移动,比如,把放在片元着色器中的计算放到顶点着色器中,或者直接在CPU中进行预计算,再把结果传递给Shader。
4,不要除以0
不然结果不可预测。

这篇关于【Unity Shader】Unity提供的CG/HLSL语义的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1115066

相关文章

理解分类器(linear)为什么可以做语义方向的指导?(解纠缠)

Attribute Manipulation(属性编辑)、disentanglement(解纠缠)常用的两种做法:线性探针和PCA_disentanglement和alignment-CSDN博客 在解纠缠的过程中,有一种非常简单的方法来引导G向某个方向进行生成,然后我们通过向不同的方向进行行走,那么就会得到这个属性上的图像。那么你利用多个方向进行生成,便得到了各种方向的图像,每个方向对应了很多

Unity Post Process Unity后处理学习日志

Unity Post Process Unity后处理学习日志 在现代游戏开发中,后处理(Post Processing)技术已经成为提升游戏画面质量的关键工具。Unity的后处理栈(Post Processing Stack)是一个强大的插件,它允许开发者为游戏场景添加各种视觉效果,如景深、色彩校正、辉光、模糊等。这些效果不仅能够增强游戏的视觉吸引力,还能帮助传达特定的情感和氛围。 文档

Unity协程搭配队列开发Tips弹窗模块

概述 在Unity游戏开发过程中,提示系统是提升用户体验的重要组成部分。一个设计良好的提示窗口不仅能及时传达信息给玩家,还应当做到不干扰游戏流程。本文将探讨如何使用Unity的协程(Coroutine)配合队列(Queue)数据结构来构建一个高效且可扩展的Tips弹窗模块。 技术模块介绍 1. Unity协程(Coroutines) 协程是Unity中的一种特殊函数类型,允许异步操作的实现

Unity 资源 之 Super Confetti FX:点亮项目的璀璨粒子之光

Unity 资源 之 Super Confetti FX:点亮项目的璀璨粒子之光 一,前言二,资源包内容三,免费获取资源包 一,前言 在创意的世界里,每一个细节都能决定一个项目的独特魅力。今天,要向大家介绍一款令人惊艳的粒子效果包 ——Super Confetti FX。 二,资源包内容 💥充满活力与动态,是 Super Confetti FX 最显著的标签。它宛如一位

Unity数据持久化 之 一个通过2进制读取Excel并存储的轮子(4)

本文仅作笔记学习和分享,不用做任何商业用途 本文包括但不限于unity官方手册,unity唐老狮等教程知识,如有不足还请斧正​​ Unity数据持久化 之 一个通过2进制读取Excel并存储的轮子(3)-CSDN博客  这节就是真正的存储数据了   理清一下思路: 1.存储路径并检查 //2进制文件类存储private static string Data_Binary_Pa

Unity Adressables 使用说明(一)概述

使用 Adressables 组织管理 Asset Addressables 包基于 Unity 的 AssetBundles 系统,并提供了一个用户界面来管理您的 AssetBundles。当您使一个资源可寻址(Addressable)时,您可以使用该资源的地址从任何地方加载它。无论资源是在本地应用程序中可用还是存储在远程内容分发网络上,Addressable 系统都会定位并返回该资源。 您

Unity Adressables 使用说明(六)加载(Load) Addressable Assets

【概述】Load Addressable Assets Addressables类提供了加载 Addressable assets 的方法。你可以一次加载一个资源或批量加载资源。为了识别要加载的资源,你需要向加载方法传递一个键或键列表。键可以是以下对象之一: Address:包含你分配给资源的地址的字符串。Label:包含分配给一个或多个资源的标签的字符串。AssetReference Obj

在Unity环境中使用UTF-8编码

为什么要讨论这个问题         为了避免乱码和更好的跨平台         我刚开始开发时是使用VS开发,Unity自身默认使用UTF-8 without BOM格式,但是在Unity中创建一个脚本,使用VS打开,VS自身默认使用GB2312(它应该是对应了你电脑的window版本默认选取了国标编码,或者是因为一些其他的原因)读取脚本,默认是看不到在VS中的编码格式,下面我介绍一种简单快

Unity数据持久化 之 一个通过2进制读取Excel并存储的轮子(3)

本文仅作笔记学习和分享,不用做任何商业用途 本文包括但不限于unity官方手册,unity唐老狮等教程知识,如有不足还请斧正​​ Unity数据持久化 之 一个通过2进制读取Excel并存储的轮子(2) (*****生成数据结构类的方式特别有趣****)-CSDN博客 做完了数据结构类,该做一个存储类了,也就是生成一个字典类(只是声明)  实现和上一节的数据结构类的方式大同小异,所

【Unity小技巧】URP管线遮挡高亮效果

前言 在URP渲染管线环境下实现物体遮挡高亮显示效果,效果如下: Unity URP遮挡高亮 实现步骤 创建层级,为需要显示高亮效果的物体添加层级,比如Player 创建一个材质球,也就是高亮效果显示的材质球找到Universal Renderer Data Assets 4.在Assets上添加两个Render Objects组件 第一个做如下三处设置 指定遮挡层级指