热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Shader山下(十七)语义Semantic

当在编写Cg或者HLSL着色器程序的时候,我们需要使用语义(Semantic)来指明输入输出变量的“意图”。例如下面的这段Shader代码:ShaderCustomVF{
当在编写Cg或者HLSL着色器程序的时候,我们需要使用语义(Semantic)来指明输入输出变量的“意图”。

例如下面的这段Shader代码:

Shader "Custom/VF" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200

Pass {
Tags { "LightMode" = "ForwardBase" }

CGPROGRAM

#pragma multi_compile_fwdbase

#pragma vertex vert
#pragma fragment frag

#include "UnityCG.cginc"

sampler2D _MainTex;

float4 _MainTex_ST;

struct a2v {
float4 vertex : POSITION;
fixed3 normal : NORMAL;
fixed4 texcoord : TEXCOORD0;
fixed4 color : COLOR;
};

struct v2f {
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};

v2f vert(a2v v) {
v2f o;

//Transform the vertex to projection space
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
//Get the UV coordinates
o.uv = TRANSFORM_TEX (v.texcoord, _MainTex);

return o;
}

float4 frag(v2f i) : COLOR {
fixed4 texColor = tex2D(_MainTex, i.uv);

return texColor;
}
ENDCG
}
}
FallBack "Diffuse"
}


其中a2v结构里变量后面用冒号隔开的就是语义。

a2v作为vert函数的输入,它里面所标识的语义用来告诉Unity我们需要什么样的数据。

此外,我们看到frag方法名的后面也添加了COLOR语义,这是告诉Unity,这个方法输出一个色彩值,然后Unity就可以把这个色彩值写入GPU。

你可能会注意到vert的输出frag的输入v2f结构里的变量也使用了语义。大部分语义是你可以随便使用的,为了方便vert和frag之间传递数据,但是有一个例外,就是:

float4 pos : POSITION;

这个必须声明为float4类型,并添加POSITION(或SV_Position,二者区别稍后会讲到)。因为GPU需要知道顶点转换到裁剪空间(参考Shader山下(十六)坐标空间与转换矩阵)的坐标,而这个坐标便是由vertex shader提供的。


Direct3D 10定义了一种新的语义类型,叫做系统数值语义(system-value semantics),它们都是以SV_打头。例如POSITION对应SV_POSITION,COLOR对应SV_Target,DEPTH对应SV_Depth(深度)。虽然对于开发者来讲,它们之间并没有什么明显的区别,但是平台之间的兼容性,却给我们带来了烦恼,例如XBox one就只支持SV语义,而Direct3D 9就不支持SV语义(所以还是windows自己家打起来了)。所以开发的时候还需要注意。


此外还有几个特殊的语义:

VPOS:屏幕像素坐标,用于片段着色器,需要添加#pragma target 3.0编译指令。

例如:
Shader "Unlit/Screen Position"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0

// note: no SV_POSITION in this struct
struct v2f {
float2 uv : TEXCOORD0;
};

v2f vert (
float4 vertex : POSITION, // vertex position input
float2 uv : TEXCOORD0, // texture coordinate input
out float4 outpos : SV_POSITION // clip space position output
)
{
v2f o;
o.uv = uv;
outpos = UnityObjectToClipPos(vertex);
return o;
}

sampler2D _MainTex;

fixed4 frag (v2f i, UNITY_VPOS_TYPE screenPos : VPOS) : SV_Target
{
// screenPos.xy will contain pixel integer coordinates.
// use them to implement a checkerboard pattern that skips rendering
// 4x4 blocks of pixels

// checker value will be negative for 4x4 blocks of pixels
// in a checkerboard pattern
screenPos.xy = floor(screenPos.xy * 0.25) * 0.5;
float checker = -frac(screenPos.r + screenPos.g);

// clip HLSL instruction stops rendering a pixel if value is negative
clip(checker);

// for pixels that were kept, read the texture and output it
fixed4 c = tex2D (_MainTex, i.uv);
return c;
}
ENDCG
}
}
}

因为对于大多数平台,VPOS语义修饰的屏幕坐标变量类型是float4,但是对于Direct3D9确实float2,所以要使用UNITY_VPOS_TYPE这个宏来作为screenPos的类型。

VFACE:被渲染的面是否朝向摄像机,用于片段着色器,需要添加#pragma target 3.0编译指令。

例如:
Shader "Unlit/Face Orientation"
{
Properties
{
_ColorFront ("Front Color", Color) = (1,0.7,0.7,1)
_ColorBack ("Back Color", Color) = (0.7,1,0.7,1)
}
SubShader
{
Pass
{
Cull Off // turn off backface culling

CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0

float4 vert (float4 vertex : POSITION) : SV_POSITION
{
return UnityObjectToClipPos(vertex);
}

fixed4 _ColorFront;
fixed4 _ColorBack;

fixed4 frag (fixed facing : VFACE) : SV_Target
{
// VFACE input positive for frontbaces,
// negative for backfaces. Output one
// of the two colors depending on that.
return facing > 0 ? _ColorFront : _ColorBack;
}
ENDCG
}
}
}

SV_VertexID:这是一个无符号的整形变量,表示顶点的ID,用于顶点着色器,需要添加#pragma target 3.5编译指令。

例如:
Shader "Unlit/VertexID"
{
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.5

struct v2f {
fixed4 color : TEXCOORD0;
float4 pos : SV_POSITION;
};

v2f vert (
float4 vertex : POSITION, // vertex position input
uint vid : SV_VertexID // vertex ID, needs to be uint
)
{
v2f o;
o.pos = UnityObjectToClipPos(vertex);
// output funky colors based on vertex ID
float f = (float)vid;
o.color = half4(sin(f/10),sin(f/100),sin(f/1000),0) * 0.5 + 0.5;
return o;
}

fixed4 frag (v2f i) : SV_Target
{
return i.color;
}
ENDCG
}
}
}




推荐阅读
  • 如何高效学习鸿蒙操作系统:开发者指南
    本文探讨了开发者如何更有效地学习鸿蒙操作系统,提供了来自行业专家的建议,包括系统化学习方法、职业规划建议以及具体的开发技巧。 ... [详细]
  • C/C++ 应用程序的安装与卸载解决方案
    本文介绍了如何使用Inno Setup来创建C/C++应用程序的安装程序,包括自动检测并安装所需的运行库,确保应用能够顺利安装和卸载。 ... [详细]
  • Java虚拟机及其发展历程
    Java虚拟机(JVM)是每个Java开发者日常工作中不可或缺的一部分,但其背后的运作机制却往往显得神秘莫测。本文将探讨Java及其虚拟机的发展历程,帮助读者深入了解这一关键技术。 ... [详细]
  • 本文将深入探讨 Unreal Engine 4 (UE4) 中的距离场技术,包括其原理、实现细节以及在渲染中的应用。距离场技术在现代游戏引擎中用于提高光照和阴影的效果,尤其是在处理复杂几何形状时。文章将结合具体代码示例,帮助读者更好地理解和应用这一技术。 ... [详细]
  • Flutter 核心技术与混合开发模式深入解析
    本文深入探讨了 Flutter 的核心技术,特别是其混合开发模式,包括统一管理模式和三端分离模式,以及混合栈原理。通过对比不同模式的优缺点,帮助开发者选择最适合项目的混合开发策略。 ... [详细]
  • 如何使用Maven将依赖插件一并打包进JAR文件
    本文详细介绍了在使用Maven构建项目时,如何将所需的依赖插件一同打包进最终的JAR文件中,以避免手动部署依赖库的麻烦。 ... [详细]
  • STM32代码编写STM32端不需要写关于连接MQTT服务器的代码,连接的工作交给ESP8266来做,STM32只需要通过串口接收和发送数据,间接的与服务器交互。串口三配置串口一已 ... [详细]
  • 一、使用Microsoft.Office.Interop.Excel.DLL需要安装Office代码如下:2publicstaticboolExportExcel(S ... [详细]
  • egg实现登录鉴权(七):权限管理
    权限管理包含三部分:访问页面的权限,操作功能的权限和获取数据权限。页面权限:登录用户所属角色的可访问页面的权限功能权限:登录用户所属角色的可访问页面的操作权限数据权限:登录用户所属 ... [详细]
  • Gradle 是 Android Studio 中默认的构建工具,了解其基本配置对于开发效率的提升至关重要。本文将详细介绍如何在 Gradle 中定义和使用共享变量,以确保项目的一致性和可维护性。 ... [详细]
  • 本文探讨了Linux环境下线程私有数据(Thread-Specific Data, TSD)的概念及其重要性,介绍了如何通过TSD技术避免多线程间全局变量冲突的问题,并提供了具体的实现方法和示例代码。 ... [详细]
  • ArcBlock 发布 ABT 节点 1.0.31 版本更新
    2020年11月9日,ArcBlock 区块链基础平台发布了 ABT 节点开发平台的1.0.31版本更新,此次更新带来了多项功能增强与性能优化。 ... [详细]
  • 视觉Transformer综述
    本文综述了视觉Transformer在计算机视觉领域的应用,从原始Transformer出发,详细介绍了其在图像分类、目标检测和图像分割等任务中的最新进展。文章不仅涵盖了基础的Transformer架构,还深入探讨了各类增强版Transformer模型的设计思路和技术细节。 ... [详细]
  • 本文探讨了如何通过优化 DOM 操作来提升 JavaScript 的性能,包括使用 `createElement` 函数、动画元素、理解重绘事件及处理鼠标滚动事件等关键主题。 ... [详细]
  • 龙蜥社区开发者访谈:技术生涯的三次蜕变 | 第3期
    龙蜥社区的开发者们通过自己的实践和经验,推动着开源技术的发展。本期「龙蜥开发者说」聚焦于一位资深开发者的三次技术转型,分享他在龙蜥社区的成长故事。 ... [详细]
author-avatar
别他妈给脸不要脸别动老子东西
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有