当前位置: 首页 > news >正文

Shader属性讲解+Cg语言讲解

CPU调用GPU传递数据

        修改Render组件的material属性

在脚本中更改游戏物体材质颜色代码示例:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class TestFixedColor : MonoBehaviour
{void Start(){//创建预制体GameObject prefab = Resources.Load<GameObject>("Prefabs/TestFixedColor");//创建到场景中GameObject testFixedColor=Instantiate<GameObject>(prefab);//获得MeshRender(材质在渲染器下)MeshRenderer meshRenderer= testFixedColor.GetComponent<MeshRenderer>();//获得材质,修改Shader的颜色属性//render.material可以获得材质球//材质下面的SetXXX()函数,可以修改材质球的属性,材质球的属性和Shader有关联关系//所以修改材质球的属性,进而会影响到shader的执行//参数1:shader中需要修改的属性名称//参数2:需要修改的值//meshRenderer.material.SetColor("_Color",Color.blue);//设置自定义颜色meshRenderer.material.SetColor("_Color", new Color(59f/255f,118f/255f,72f/255f,1f));}
}

Shader支持的属性类型

        颜色:向Shader传递颜色值

        浮点数:传递数字,作为阈值

        范围:具有最大值,最小值的数

        四维向量:传递一个向量或点

        2D纹理

                MipMaps:一个纹理存储时,会生成多个质量的纹理,根据摄像机和物体的距离,

                显示相应质量的纹理 

        Rect纹理        

                和2D纹理类似,不支持MipMaps

        Cube纹理

                实现天空盒,实现金属对全局环境的反光

以上纹理在Shader文件中的示例:

Shader "CreateTest/FixedTexture"
{Properties{//2D纹理属性_MainTex("主纹理",2D) = "white"{}//Rect纹理_RectTex("Rect纹理",Rect)=""{}//盒子纹理_CubeTex("Cube纹理",Cube)=""{}//浮点常数_Float("浮点数",Float)=12//齐次坐标(点,向量)_Vector("齐次坐标",Vector)=(1,1,1,0)//数字范围_Range("透明度范围",Range(0,1))=1}SubShader{Pass{//固定管线着色器贴纹理SetTexture[_MainTex]{//将设置的纹理合并到物体上Combine texture}}}
}

材质球相关显示:

Cg语言介绍

        可编程管线语言(3种)

                GLSL:支持OpenGL接口

                HLSL:支持DirectX接口

                Cg:C for Graphic,支持两种图形化接口,由NVIDIA开发,Cg允许对顶点变换和

                像素着色进行编程

        介绍

                Cg支持的7种数据类型:1.float,2.half,3.int,4.fixed,5.bool,6.sampler*,7.string。

                Cg提供了内置的向量数据类型(built-in vector data types),内置的向量数据类型

                基于基础数据类型。

                        例如:float4,表示float类型的四元向量。

                        注意:向量最长不能超过四元,即在Cg程序中可以声明float1,float2,float3,float4

                        类型的数组变量,但是不能声明超过四元的向量。

                向量初始化的方式一般为:float4 array=float4(1.0,2.0,3.0,4.0);

                Cg提供矩阵数据类型,不过最大的维数不能超过4*4阶。

                         例:float4x2 matrix3;//表示4*2阶矩阵,包含8个float类型数据。

                        矩阵的初始化方式为:float2x3 matrix5={1.0,2.0,3.0,4.0,5.0,6.0};

                着色程序中,数组通常使用的目的:作为从外部应用程序传入大量参数输出到Cg

                的顶点程序中的形参接口。

                简言数组数据类型在Cg程序中的作用是:作为函数的形参,用于大量数据的传递。

                Cg声明数据变量:                       

                        float a[10];//声明一个数组,包含10个float类型数据

                        float4 b[10];//声明一个数组,包含10个float4类型向量数据

                对数组进行初始化的方式为:float a[4]={1.0,2.0,3.0,4.0};//初始化一个数组

                获取数组长度:float a[2]={1.0,2.0};  int nLen=a.Length;

                声明多维数组以及初始化的方式如下所示:

                        float b[2][3] = {{0.0,0.0,0.0},{1.0,1.0,1.0}};

                对多维数组取长度的方式为:

                        int length1=b.length;  //length1值为2

                        int length2=b[0].length;//length2值为3

                数组和矩阵有些类似,但并不相同

                        例:4*4阶数组的声明:float M[4][4];

                                4阶矩阵的声明方式:float4x4 M;

                前者是一个数据结构,包含16个float类型数据,后者是一个4阶矩阵数据。

                注意:进行数组变量声明时,一定要指定数组长度,除非是作为函数参数而声明

                的形参数组。

                Cg语言支持结构体(structure),实际上Cg中的结构体的声明、使用和C++非常

                类似(只是类似,不是相同)。

                声明一个该结构体类型的变量,代码如下:

struct myAdd
{float val;float add(float x){return val+x;    }
};
myAdd s;

                 注意:在当前的所有的profile版本下,如果结构体的一个成员函数使用了成员变量,

                则该成员变量要声明在前。此外,成员函数是否可以重载依赖于使用的profile版本。 

                Cg中的类型转换和C语言中的类型转换很类似,C语言中类型转换可以是强制类

                型转换,也可以是隐式转换,如果是后者,则数据类型从低精度向高精度转换。

                在Cg语言中也是如此。例:

                        float a = 1.0;

                        half b=2.0;

                        float c=a+b;//等价于float c=a+(float)b\

                Cg语言中对于常量数据可以加上类型后缀,表示该数据的类型,例如:

                        float a = 1.0;

                        float b=a+2.0h;//2.0h为half类型常量数据,运算是需要做类型转换

                常量的类型后缀(type suffix)有3种:

                        1.f:表示float;

                        2.h:表示half;

                        3.x:表示fixed;

                Cg语言表达式允许对向量使用所有的boolean operator,如果是二元操作符,则被操

                作的两个向量的长度必须一致。表达式中向量的每个分量都进行一对一的运算,最

                后返回的结果是一个bool类型的向量,长度和操作数向量一致。例如:

                        float3 a = float3(0.5,0.0,1.0);

                        float3 b=float3(0.6,-0.1,0.9);

                        bool3 c = a<b;

                运算后向量c的结果为bool3(true,false,false);

                逻辑操作符也可以对向量使用,返回的变量类型是同样长度的内置bool向量。

                 C/C++的宏:函数是调用结构,宏是替换代码。

                注意:Cg中的逻辑与(&&)和逻辑或(||)不存在C中的短路现象(short-circuiting,

                即只用就算一个操作数的bool值即可),而是参与运算的操作数据都进行bool分析。

                短路现象        

                        bool con1=true

                        int a = 10

                        int b = 20

                        con1||(a>b)

                        con1如果为true,在C中,ab的值不会比较,但是Cg会比较所有条件

                        

                        $a=true

                        $a||$b=true

                        if(!$a){

                                $b=true

                        }

               Cg语言对向量的数学操作提供了内置的支持,需要注意的是:求余操作符%。只能在

                int类型数据间进行,否则编译器会提示错误信息:

                error C1021:operands to "%" must be integral.

                可以使用Cg语言中的swizzle操作符(.)将一个向量的成员取出组成一个新的向

                量。swizzle操作符被GPU硬件高效支持。

                swizzle操作符后接x,y,z,w分别表示原始向量的第一个,第二个,第三个,第四个元素;

                swizzle操作符后接r,g,b,a的含义与前者等同。不过为了程序的易读性,建议对于表示

                颜色值的向量,使用swizzle操作符后接r,g,b和a的方式。

                        float4(a,b,c,d).xyz;//等价于float3(a,b,c)

                        float4(a,b,c,d).xyy;//等价于float3(a,b,b)

                        float4(a,b,c,d).wzyx;//等价于float3(d,c,b,a)

                        float4(a,b,c,d).w;//等价于float d

                注意:Swizzle操作符只能对结构体和向量使用,不能对数组使用。

                Cg中的控制流语句和循环语句与C语言类似。

                条件语句有:if,if-else,if-else if-else;

                循环语句有:while,for;

                break,continue语句可以在for和while语句中使用。

                Cg中创造了一系列独特的关键字,这些关键字不但用于指定输入图元的数据含义

                (是位置信息,还是法向量信息),本质也则对应着这些图元数据存放的硬件资源

                (寄存器或者纹理),称之为语义词(Semantics),通常也根据其用法称之为绑

                定语义词(binding semantics)。

                除语义词外,Cg中还提供了三个关键字:in,out,inout。用于表示函数的输入参数的

                传递方式,称为输入\输出关键字,这组关键字可以和语义词合用表达硬件上不同的

                存储位置,即同一个语义词,使用in关键字修辞和out关键词修辞,表示的图形硬件

                上不同的寄存器。

                Cg语言还提供两个修辞符:uniform用于指定变量的数据初始化方式;const关键字

                表示被修辞变量为常量变量。

                Cg语言将数据流分为两类:

                1.Varying inputs,即数据流输入图元信息的各种组成要素。

                2.Uniform inputs,表示一些与三维渲染有关的离散信息数据,这些数据通常由应用程

                序传入,并通常不会随着图元信息的变化而变化,如材质对光的反射信息,运动矩阵

                等。

                注意:uniform修辞的变量的值是从外部传入的,所以Cg程序(顶点程序和片段程序)

                中通常使用uniform参数修辞函数形参,不容许声明一个用uniform修辞的局部变量!

                Cg输入语义与输出语义的区别

                语义:是两个处理阶段(顶点程序、片段程序)之间的输入/输出数据和寄存器之间

                的桥梁,同时语义通常也表示数据的含义,如POSITION一般表示参数种存放的数据

                是顶点位置。

                语义:只对两个处理阶段的输入/输出数据有意义,也就是说语义只有在入口函数中才

                有效,在内部函数(一个阶段的内部处理函数,和下一个阶段没有数据传递关系)的

                无效,被忽略。

                语义:分为输入语义和输出语义,输入语义和输出语义是有区别的

                Cg常用语义:

                POSITION,BLENDWEIGHT,NORMAL,TANGENT,BINORMAL,PSIZE,BLENDINDICES,

                TEXCOORD0---TEXCOORD7

                参数使用语义使用举例:in float4 modelPos:POSITION

                顶点着色程序的输出语义:示例代码

void main v(float4 position:POSITION,out float4 oposition:POSITION,uriform float4x4 modelViewProj)
{//oposition=mul(modelViewProj,position);
}

               为了保持顶点程序输出语义和片段程序输入语义的一致性,通常使用相同的struct类型

                数据作为两者之间的传递,这是一种非常方便的写法,推荐使用。例如: 

struct VertexIn{
float4 position:POSITION;
float4 normal:NORMAL;
};
struct VertexScreen{
float4 oPosition:POSITION;
float4 objectPos:TEXCOORD0;
float4 objectNormal:TEXCOORD1;
};

                注意:当使用struct结构中的成员变量绑定语义时,需要注意到顶点着色程序中使用

                的POSITION语义词,是不会被片段程序所使用的。 

                语义绑定方法

                入口函数输入\输出数据的绑定语义有四种方法:

                1.绑定语义放在函数的参数列表的参数声明后面中:

[const][in|out|inout]<type><identifier>[:<binding-semantic>][=<initializer>]

                2.绑定语义可以放在结构体(struct)的成员变量后面:

struct <struct-tag>{
<type><identifier>[:<binding-semantic>];
};

                3.绑定语义词可以放在函数声明的后面,其形式为:

<type><identifier>(<parameter-list>)[:<binding-semantic]{
<body>
}

                4.最后一种语义绑定的方法是,将绑定语义词放在全局非静态变量的声明后面。其形

                式为:

<type><identifier>[:<binding-semantic>][=<initializer>];

                Cg标准函数库

                和C的标准函数库类似,Cg提供了一系列内建的标准函数。这些函数用于执行数学上

                的通用计算或通用算法(纹理映射等)。 

                Cg标准函数库主要分为五个部分:

                1.数学函数(Mathematical Functions);

                2.几何函数(Geometric Functions);

                3.纹理映射函数(TextureMapFunctions);

                4.偏导数函数(Derivative Functions);

                5.调试函数(Debugging Function);

 该系列专栏为网课课程笔记,仅用于学习参考。       

                

        

相关文章:

  • 【codeforces思维题】前缀和的巧妙应用(2053B)
  • CF912E
  • 跨团队协作时流程不统一,如何协调
  • HarmonyOS:1.7
  • stm32教程:HC-SR04超声波模块
  • 是否可以使用非被动 S4P 文件进行反嵌?
  • KAN 与 MLP 的深入比较
  • Spring Boot Actuator 详细使用说明(完整代码与配置)
  • 第五篇:linux之vim编辑器、用户相关
  • 精准管控,安全护航 -Acrel-2000 电力监控系统助力配电房数字化升级
  • [企业应用开发] 十年稳定使用体验谈:Bex5 企业内部系统开发平台实践总结
  • 基于机器学习的多光谱遥感图像分类方法研究与定量评估
  • Linux与Anaconda环境部署与管理(运维交接)
  • Windows 同步-Windows 单向链表和互锁链表
  • OpenCV物体计数示例
  • docker本地虚拟机配置
  • 课外知识:isinstance()与issubclass()的区别
  • Filename too long 错误
  • 《TCP/IP详解 卷1:协议》之第四、五章:ARP RARP
  • C#使用sftp远程拷贝文件
  • 五一节,和人民照相馆一起找回“拍照”的仪式感
  • 上海银行换帅:顾建忠出任党委书记,金煜辞任董事长
  • 《哪吒2》延长放映至5月31日,当前全球票房已超157亿
  • 对话地铁读书人|豪宅房产经纪人:读书使我免于抑郁
  • 根据学习教育安排,上海市委中心组专题学习总书记力戒形式主义官僚主义重要论述
  • 牛市早报|国常会:要持续稳定股市,4月LPR今日公布