ARCore之路-环境理解之Cg语言

版权声明:David Wang原创ARCore文章,仅供学习研究之用,不得用于任何商业目的,未经授权不得转载! https://blog.csdn.net/yolon3000/article/details/82820361

  虽然Surface Shader是Unity极力推动的编写Shader的方式,但由于Surface Shader做了大量的封装,屏蔽了很多底层实现细节,包括光照、顶点变换、材质使用等,在提供了更简单的使用之余也丧失了灵活性,下面我们只对vertex shaders 和 fragment shaders进行学习,读者可以参阅官方文档以了解更多Surface Shader细节。

一、vertex & fragment shaders基本结构

Shader "DavidWang/vertexAndFragment"{
    SubShader{
        pass{
                CGPROGRAM
                 #pragma vertex vert
                 #pragma fragment frag
                  void vert(in float2 objPos:POSITION, out float4 pos:POSITION)
                 {
                        pos = float4(objPos,0,1);
                  }
                 void frag(out float4 col:COLOR)
                 {
                      col = float4(1,0,0,1);
                 }
                ENDCG
        }
    }
    Fallback "Mobile/VertexLit"
}

  Vertex & Frament Shader至少有一个pass通道,一个pass就是对场景的一次渲染。在ShaderLab语法中需要使用关键词“CGPROGRAM”和“ENDCG”将Cg代码段包含起来才能编译使用,需要注意的是这两个关键词都是大写的。#pragma vertex vert指令的意思是使用vert函数来做Vertex shader的处理工作, #pragma fragment fragt指令的意思是使用fragt函数来做Fragment shader的处理工作,即这是分别指定了执行顶点和片段处理的函数。

  Vertex shader会对顶点做一系列的处理,最主要的是把顶点坐标从物体Local空间转换成齐次裁减空间的齐次坐标,同时进行必要的光照处理,把处理后的数据传递给Fragment shader程序,Fragment shader拿到顶点程序处理后的数据继续进行最终的计算。Fragment shader最主要的工作是对纹理进行采样、对颜色进行最终的合成,其输出是颜色值。

  在上例中,“void vert(in float2 objPos:POSITION, out float4 pos:POSITION)” 中有两个参数,其中第一个参数中的“in”表示引擎提供的输入,“float2”表示数据的类型为二阶的向量,参数名“objPos”冒号后需要带上语义,语义指的是顶点程序和片段程序能够被识别的变量,这里使用“POSITION”。第二个参数中“out”表示输出,数据类型为“float4”,语义也是“POSITION”。如果顶点程序要输出一个“POSITION”语义的变量,这个变量必须要以“float4”四阶向量的形式。“void frag(out float4 col:COLOR)”使用语义为“COLOR”的变量作为输出,这里使用“out float4 col:COLOR”作为颜色变量的输出,语义“COLOR”就是指“COLOR0”。

  语义词“POSITION”,“COLOR”不仅仅是表示数据类型,更重要的是指示出数据存放的位置,这些语义词都有特定的含义。
  Cg 语言所有 vertex profile 支持的输入语义关键词有: POSITION、BLENDWEIGHT、NORMAL、 TANGENT、 BINORMAL、 PSIZE、BLENDINDICES、TEXCOORD0—TEXCOORD7。
  Cg 语言所有 vertex profile 支持的输出和 fragment profile 输入语义关键词有:POSITION 、PSIZE 、FOG,COLOR0-COLOR1、TEXCOORD0-TEXCOORD7 。
   Cg 语言所有 fragment profile 支持的输出语义关键词有:COLOR 。

  示例shader是最简单但又是结构完整的vertex shaders 和 fragment shaders,读者务必了解。关于输入输出语义更详细的说明超出了本章的内容,请读者查阅相关资料。

这里写图片描述

二、profile

  一个Cg profile定义了一个“被特定图形硬件或API所支持的Cg语言子集”,任意一种shader language都是基于可编程图形硬件的(寄存器、指令集等),这也就意味着,不同的图形硬件对应着不同的功能子集。这些可选的语言功能包括某些控制结构和标准库函数。profile还定义了数据类型的精度,并且指定数据类型是否全部支持或仅部分支持。profile按照功能可以划分为vertex profile和fragment profile,而vertex profile和fragment profile又基于OpenGL和DirectX的不同版本或扩展,划分为各种版本。

  profile是语言的一种特性,在不同的处理方法中会拥有不同的特性。在特殊情况下,语言profile就是关于一个使用for或者while循环的限制,意思就是有些情况下它不支持for或者while循环,有些profile仅仅loop循环。Cg不支持goto、switch、case、default等保留关键字;也不支持指针和指针相关的运算能力;Cg支持数组,但是有尺寸和维度的限制;Cg没有枚举和联合;Cg在结构体当中没有位成员;Cg中所有的整型都是有符号,没有signed关键字。

  Cg有绑定语义,比如POSITON、COLOR0等;Cg内建有swizzle操作;对于一个值来说,swizzle操作可以允许进行拼凑一个向量或矩阵;swizzle操作可以去访问所有的分量;数据有不同的有限的类型,主要的类型有float、half、fixed,片段profile必须支持这三种数据类型,但是可以选择使用half或fixed去实现float,顶点profile要求实现half和float,但是可以选择实现halp和float,顶点profile可以忽略支持fixed,Cg允许profile去忽略支持运行时的int,实际上会把int转换成float;Cg中的操作很多都是对于向量的操作,可以对向量的基本元素进行操作,Cg中也有?问号表达式,没有全局的非静态变量;Cg有新的sampler*集合;函数拥有默认参数;函数和它们的操作可以被重载;变量可以定义在任何地方,但要在使用之前定义就行等等。

三、Cg基本数据类型

  Cg支持7种基本的数据类型

数据类型 说明
float 32 位浮点数据,一个符号位。浮点数据类型被所有的 profile 支持。
half 16 位浮点数据。
int 32 位整形数据,有些 profile 会将 int 类型作为 float 类型使用。
fixed 12 位定点数,被所有的 fragment profiles 所支持。
bool 布尔数据,通常用于 if 和条件操作符( ?: ) ,布尔数据类型被所有的profiles 支持。
simpler* 纹理对象的句柄( the handle to a texture object ) ,分为 6 类: sampler, sampler1D, sampler2D, sampler3D, samplerCUBE, 和 samplerRECT 。

  Cg还提供了内置的向量数据类型 (built-in vector data types) ,内置的向量数据类型基于基础数据类型。 例如: float4, 表示 float 类型的 4 元向量; bool4, 表示 bool类型 4 元向量。
注意: 向量最长不能超过 4 元, 即在 Cg 程序中可以声明 float1 、 float2 、 float3 、float4 类型的数组变量,但是不能声明超过 4 元的向量。

参考文献

1、Cg语言的基础 Cg语言的基础
2、profile和基本数据类型 profile和基本数据类型

猜你喜欢

转载自blog.csdn.net/yolon3000/article/details/82820361