Unity Shader学习日记 part5 CG基础

在了解完Shader的基本结构之后,我们再来看看编写着色器的语言。

Shader编写语言有CG,HLSL两种,我们主要学习CG的写法。

数据类型

CG的基础变量类型

uint a=12;//无符号32位整形
int b=12;//32位整形float f=1.2f;//32位浮点型
half h=1.2h;//16位浮点型
fixed fix=1.2;//12位浮点型bool b=true;
string str="123";纹理对象句柄(理解为一个纹理就行)
sampler sam;sampler1D 用于一维纹理,通常用于对一维纹理进行采用,如从左到右的渐变色
sampler2D 用于二维纹理,最常见的纹理类型之一,用于处理二维图像纹理,比如贴图
sampler3D 用于三维纹理,通常用于体积纹理,如体积渲染
samplerCUBE 用于立方体纹理,通常用于处理环境映射登需要立方体贴图的情况
samplerRECT 用于处理矩形纹理,通常用于一些非标准的纹理映射需求他们都是用来处理纹理(Texture)数据的数据类型
注意区别在意纹理的类型和维度

可以看到,基本上和C#差不多,除此之外多了纹理对象句柄的类型。

CG的复合变量类型

复合类型也和C#差不多,数组,结构体

基础复合数据类型
数组:和C#差不多
int c[4]={1,2,3,4};
// a.length;int d[2][3]={{1,2,3},{4,5,6}};
//d.length 行
//d[0].length 列//结构体
//没有访问修饰
//申明结束加分号
//一般在函数外部申明

注意结构体的写法

CG的特殊变量类型

学了这么多知识点,其中矩阵和向量占了很大一部分,同样,CG中也为我们提供了矩阵的变量以及向量相关的变量。

这些变量的类型都是基于基本数据类型的,无非就是在基本数据类型的后面加一些数字之类的

//向量:CG语言内置的数据类型
//内置的向量类型是基于基础数据类型申明的,最大不超过4维,可以是任意数值类型
//数据类型n=数据类型(a1,...,an);fixed2 f2=fixed2(1.3,1.5);
fixed3 f3=fixed3(2,3,4);//矩阵(行列不大于4不小于1)
//数据类型 'n'x'm'={n1m1,n1m2...}
int2x3 mytest={1,2,3,3,4,6};
int4x4 test1={1,2,3,4,5,6,7,8,4,5,6,7,1,2,2,3};

其他类型的向量和矩阵我就不举例了,类似一下,大差不差。

了解了这些之后,我们再来看看一些类型的特殊用法

Bool的特殊用法

之前我们提到特殊变量类型是基于基本类型的,所以,bool类型同样能够用在特殊类型中

//bool类型同样可以用于向量的申明
//它可以用于储存一些逻辑判断结果
//比如
//float3 fa=float3(0.5,0.0,1.0);
//float3 fb=float3(0.6,-0.1,0.9;
//bool3 bc=a<b;
//结果为 boool3(true,false,false)

学习了数据类型之后,我们思考,矩阵和向量使用如此的频繁,那我我们怎么去获取这些变量中的分量值呢?这就需要Swizzle操作符

Swizzle操作符

Swizzle使用点号(.)来表示,使用就和我们去使用类的成员一样。

但是,Swizzle操作符的作用远不止这一点,我们来看看

//如:向量.xyzw,向量.rgba来获取其中的值
//使用:1。用来提取分量,2.用来重新排列分量 3.创建新的分量1.用来提取分量
fixed4 f4=fixed4(1,2,3,4);
fixed f=f4.w;
f=f4.r;2.用来重新排列分量
f4=f4.wyzx;
f4=f4.gbar;3.创建新的分量
//fixed3 f3=f4.xyz;
//fixed2 f2=f4.rg;
fixed4 f4_1=fixed4(f2,1,2);//低维创建高维,补充元素即可

我们发现,矩阵中的数据其实就是基本数据类型,那我们能不能用向量来表示呢?

向量和矩阵的特殊用法

其实向量和矩阵是可以相互使用的,就像这样

//向量和矩阵的更多用法
//1.利用向量声明矩阵
fixed4x4 f44={fixed4(1,2,3,4),fixed4(2,3,4,5),fixed4(4,5,6,7),fixed4(5,6,7,8)};
//2.获取矩阵中的元素
f=f44[0][0];//一行一列
//3.利用向量获取矩阵的某一行
f4_1=f44[0];
//4.高维转低维
fixed3x3 f33=f44;//自动取值
fixed3 f5=f;

注意的是,如果使用低维转高维,需要将欠缺的维度补齐

那么,我们再来了解了解运算表达式吧

语法相关

基本运算和流程控制

                比较运算符(和C#一样的)条件运算符(三元运算符,用法和C#一样)逻辑运算符(和C#一样,不过CG中不存在“短路”)短路:在比较的过程中,如果一边满足则不会继续比较属性运算符(和C#一样,不过%取余只能整数取余)流程控制(和C#一样)条件分支(if,switch)循环(for,while,do while)注意:虽然用法和C#一样,但是在使用的时候更多考虑性能的消耗1.尽量少的使用循环,必要情况可以减少次数和复杂度2.可以利用GPU并行性来代替循环3.尽量避免复杂的条件分支

这一部分和C#没什么区别,唯一需要注意的是逻辑运算符短路的问题。

函数相关

这一部分也和C#一样,我就不多说了

                函数相关函数的申明和用法几乎和C#中一模一样无返回值结构void name(in 参数类型 参数名,out 参数类型 参数名){函数体}name:函数名,CG中一般小写in:表示输入参数,外部传递过来的值,内部不会做更改,只会用来计算,允许有多个out:表示输出参数,由内部向外传递,函数内部必须进行初始化或者修改,允许有多个in,out可以不写,这样就可以避免in,out的特性,不过为了可读性和可维护性,建议写上void test_01(in fixed inf,out fixed outf){outf=inf+10;}

至此,CG的基本内容就结束了,接下来我们看看CG的编写

CG编写

在此之前我们先来看看CG的结构

顶点片元着色器
表面光照着色器

                                     

可以看到顶点片元着色器的结构和表面光照着色器的结构是不同的,不过他们都是使用CG代码段的方式来编写,所以我们在编写CG代码时同样要将代码放在CGPROGRAM和ENDCG之间。

在CG中最重要的就是顶点回调函数以及片元回调函数了,这也是渲染代码存放的位置

顶点/片元函数

           //顶点着色器回调函数//编译指令#pragma vertex myVert//处理顶点相关#pragma fragment myFra//处理颜色相关//POSITION,SV_POSITION,语义,用来表面参数的含义//POSITION:把模型的顶点坐标填充到输入的参数v中//SV_POSITION:输出的内容是裁剪空间中的顶点坐标float4 myVert(float4 v:POSITION):SV_POSITION{//mul是CG提供的内部函数,矩阵和向量的乘法//UNITY_MATRIX_MVP,代表一个变换矩阵,是UNITY的内置模型,观察,投影矩阵的集合//return mul(UNITY_MATRIX_MVP,v);return UnityObjectToClipPos(v*2);//和上一个等价,新的写法}//片源着色器回调函数//SV_Target:告诉着色器,把输出的颜色存储到一个渲染目标中,这里输出到默认的帧缓存中fixed4 myFra():SV_Target{return fixed4(1,0,0,1);}

可以看到最主要的部分就是申明编译指令

这个步骤决定了函数的名字以及调用。除此之外,我们可以看到,在函数的后面或者参数中还有一些代码,这一部分叫语义,它定义了参数的含义,就像POSITION:把模型的顶点坐标填充到输入的参数v中,这部分后面再说。

那么如何在函数中使用我们定义的变量呢?

非常简单,只需要申明一个同名变量即可,不过需要注意类型的对应

函数中使用自定义的变量

           ShaderLab的属性和CG变量类型的对应ShaderLab            CG类型Color,Vector         float4,half4,fixed4Range,Float,Int      float,half,fixed2D                   sampler2DCube                 samplerCube3D                   sampler3D2DArray              sampler2DArray使用是在CG中声明对应类型的同名变量即可

语义 

在上面我们基本了解了语义的基本用法。我们再来看看。

语义:修饰输入和输出参数,让shader知道从哪里读取数据,并且把数据输出到哪里

语义是什么不重要,重要的是我们需要了解的语义有哪些

 应用阶段-->顶点着色器

           常用语义应用阶段-->顶点着色器一般在顶点着色器回调函数的传入中使用POSITION:模型空间的顶点位置,通常为float4类型NORMAL:顶点法线,通常为float3类型TANGENT:顶点切线,通常为float4类型TEXCOORDn:例如:TEXCOOORD0,TEXCOORD1....该顶点的纹理坐标,通常为float2或者float4类型n 表示第n+1组纹理坐标,TEXCOOORD0 第一组纹理坐标纹理坐标:UV坐标,表示这个顶点在对于纹理图像上的位置COLOR:顶点颜色,通常为fixed4或者float4类型

   顶点着色器-->片元着色器 

           顶点着色器-->片元着色器一般在顶点着色器的返回值中使用SV_POSITION:(必须)裁剪空间中的顶点坐标COLOR0:通常用来输出第一组的顶点颜色COLOR1通常用来输出第二组颜色TEXCOORD0--TEXCOORD7通常用于输出纹理坐标

片元着色器输出 

            片元着色器输出一般在片元着色器的返回值中使用SV_Target:输出的值会存档渲染目标中如果顶点着色器和片元着色器需要更多的参数,可以通过定义结构体的方式,对参数进行封装传递

东西非常多,可以再使用中慢慢熟悉

我们想一下,这么多东西,那么再我们使用的时候必然会相当的麻烦,所以CG也内置了很多的函数,我们来看看

CG内置函数

数学相关

           //1.三角函数相关sincos(floatx,out s,out c)    同时计算x的sin和cos值并返回sin(x)                         正弦函数cos(x)                         余弦函数tan(x)                         正切函数sinh(x)                        双曲正弦函数cosh(x)                        双曲余弦函数tanh(x)                        双曲正切函数asin(x)                        反正弦函数,输入参数[-1,1],返回[-pai/2,pai/2]区间的角度值acos(x)                        反余弦函数,输入参数[-1,1],返回[0,pai]区间的角度值atan(x)                        反正切函数,输入参数[-1,1],返回[-pai/2,pai/2]区间的角度值atan2(x)                       计算y/x的反正切值,和atan功能一样,只是输入参数不同 atan(x)=atan2(x,1)
            //2.向量,矩阵相关cross(A,B)                      叉乘(传入必须为三维向量)dot(A,B)                        点乘(三维向量)mul(M,N)                        计算两个矩阵相乘 mul(M,V)                        计算矩阵和向量的相乘mul(v,m)                        计算向量和矩阵的相乘transpose(M)                    M为矩阵,计算M的转置矩阵determinant(m)                  计算矩阵的行列式因子
            //3.数值相关abs(x)ceil(x) 向上取整floor(x) 向下取整clamp(x,a,b)等等//4.其他lit(NdotL,NdotH,m)       N表示法向量,L表示入射光向量,H表示半角向量,m表示高光系数这个函数计算环境光,散射光,镜面光的 贡献,返回4维向量x表示环境光贡献,y表示散射光贡献,z表示镜面光贡献,w始终为1noise(x)                 噪声函数,返回值始终在0-1之间,对于相同的输入,始终返回相同值,不是真正的随机噪声

 几何相关

            //几何相关length(v)           向量模长normalize(v)        归一化向量  distance(p1,p2)     两个点的距离reflect(I,N)        计算反射光的方向向量,I为入射光,N为顶点法向量。I是指向顶点的,I和N必须归一化的三维向量refract(I,N,eta)    计算折射向量,I为入射,N为顶点法向量,eta为折射系数。I是指向顶点的,I和N必须归一化的三维向量

纹理相关

 //纹理相关返回值均为fixed4类型的颜色值1.二维纹理tex2D(sampler2D tex,flota2 s)       二维纹理查询等等2.立方体纹理3.其他纹理

CG内置文件

CG内置文件unity中的常用内置1.UnityCG.cginc2.Lighting.cginc3.UnityShaderVariables.cginc4.HLSLSupport.cginc等等

这些内置文件为我们提供了很多的方法,需要使用时通过#include 的方式引用即可。

来看看这些文件中常用的东西吧

//常用内容方法(UnityCG.cginc)1.float3 WorldSpaceViewDir(float4 v)输入模型空间的顶点位置,返回世界空间中从该点到摄像机的观察方向2.float3 ObjSpaceViewDir(float4 v)输入模型空间的顶点位置,返回模型空间中该点到摄像机的观察方向3.float3 WorldSpaceLightDir(float4 v)仅用于向前渲染,输入一个模型空间的顶点位置,返回世界空间中从该店到光源的光照方向(没有归一化)4.float3 ObjSpaceLightDir(float4 v)仅用于向前渲染,输入一个模型空间的顶点位置,返回模型空间中从该店到光源的光照方向(没有归一化)5.float3 UnityObjectToWorldNormal(float3 norm)把法线方向从模型空间转到世界空间中6.float3 UnityObjectToWorldDir(float3 dir)把方向矢量从模型空间转到世界空间中7.float3 UnityWorldToObjectDir(float3 dir)把方向矢量从世界空间转到模型空间中结构体(UnityCG.cginc)1.appdata_base(顶点着色器输入)顶点位置,顶点法线,第一组纹理坐标2.appdata_tan(顶点着色器输入)顶点位置,顶点法线,顶点切线,第一组纹理坐标3.appdata_img(顶点着色器输入)顶点位置,第一组纹理坐标4.appdata_full(顶点着色器输入)顶点位置,顶点法线,顶点切线,四组(或者更多)纹理坐标5.appdata_img(顶点着色器输输出)裁剪空间中的位置,纹理坐标等等变换宏矩阵等等

东西有很多,我只举例部分,感兴趣的可以到HSLS的官网查看,这部分CG与HSLS差不多。

内部函数 - Win32 apps | Microsoft Learn

具体的用法会在之后的编写中用到,这里留个印象即可。

那么到这里,CG的基础就完结啦,后面部分我们会学习到基本的光照模型,到时候我们在通过使用的方式来认识他们。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/4614.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI Agent:深度解析与未来展望

一、AI Agent的前世&#xff1a;从概念到萌芽 &#xff08;一&#xff09;早期探索 AI Agent的概念可以追溯到20世纪50年代&#xff0c;早期的AI研究主要集中在简单的规则系统上&#xff0c;这些系统的行为是确定性的&#xff0c;输出由输入决定。随着时间的推移&#xff0c;…

【24】Word:小郑-准考证❗

目录 题目 准考证.docx 邮件合并-指定考生生成准考证 Word.docx 表格内容居中表格整体相较于页面居中 考试时一定要做一问保存一问❗ 题目 准考证.docx 插入→表格→将文本转换成表格→✔制表符→确定选中第一列→单击右键→在第一列的右侧插入列→布局→合并单元格&#…

计算机网络 (46)简单网络管理协议SNMP

前言 简单网络管理协议&#xff08;SNMP&#xff0c;Simple Network Management Protocol&#xff09;是一种用于在计算机网络中管理网络节点的标准协议。 一、概述 SNMP是基于TCP/IP五层协议中的应用层协议&#xff0c;它使网络管理员能够管理网络效能&#xff0c;发现并解决网…

机器人“大脑+小脑”范式:算力魔方赋能智能自主导航

在机器人技术的发展中&#xff0c;“大脑小脑”的架构模式逐渐成为推动机器人智能化的关键。其中&#xff0c;“大脑”作为机器人的核心决策单元&#xff0c;承担着复杂任务规划、环境感知和决策制定的重要角色&#xff0c;而“小脑”则专注于运动控制和实时调整。这种分工明确…

Linux 使用 GDB 进行调试的常用命令与技巧

GDB 调试的常用命令与技巧 1. GDB 常用命令1.1 安装 GDB1.2 启动 GDB1.3 设置程序的参数1.4 设置断点1.5 启动程序并运行至断点1.6 执行一步1.7 打印变量值1.8 查看函数调用栈 2. GDB 调试 Core 文件2.1 生成 Core 文件2.2 使用 GDB 调试 Core 文件 3. GDB 调试正在运行的程序3…

光谱相机如何还原色彩

多光谱通道采集 光谱相机设有多个不同波段的光谱通道&#xff0c;可精确记录每个波长的光强信息。如 8 到 16 个甚至更多的光谱通道&#xff0c;每个通道负责特定波长范围的光信息记录。这使得相机能分辨出不同光谱组合产生的相同颜色感知&#xff0c;而传统相机的传感器通常只…

AUTOSAR从入门到精通-线控底盘技术

目录 几个高频面试题目 为何高阶智能驾驶需要线控底盘 线控底盘与传统底盘有何区别? 算法原理 线控技术发展背景 国外研究现状 国内研究现状 什么是线控底盘? 组成结构是什么? 线控底盘的发展: 线控底盘名词解释: 汽车线控系统关键技术 线控底盘的组成 电子…

跨境电商使用云手机用来做什么呢?

随着跨境电商的发展&#xff0c;越来越多的卖家开始尝试使用云手机来协助他们的业务&#xff0c;这是因为云手机具有许多优势。那么&#xff0c;具体来说&#xff0c;跨境电商使用云手机可以做哪些事情呢&#xff1f; &#xff08;一&#xff09;实现多账号登录和管理 跨境电商…

springboot项目属性配置方式

基于上篇博客 springboot项目部署到本地&#xff0c;本博客主要讲springboot项目属性配置方式&#xff0c;这篇文章将在后几天持续维护、更新。

Java 多态/向下转型/instanceof

1. 多态 1.1 概述 多态&#xff1a;事务的不同形态&#xff0c;如 动物&#xff0c;其有多种形态&#xff1a;猫&#xff0c;狗之类的&#xff1b; 1.2 使用方法 虚拟方法&#xff08;父类被重写的方法在多态中叫做虚拟方法&#xff09;调用&#xff1a; 父类引用指向子类…

【Maven】resources-plugin

在使用maven的项目中&#xff0c;它默认加载的是resources目录下的资源文件&#xff0c;像properties、xml 这类资源文件&#xff0c;但有时候可能会定义在java 源码目录下&#xff0c;这时候运行项目就会报找不到资源文件的错误 来到classpath 下&#xff0c;发现没有这个xsd…

我的创作纪念日——我与CSDN一起走过的365天

目录 一、机缘&#xff1a;旅程的开始 二、收获&#xff1a;沿路的花朵 三、日常&#xff1a;不断前行中 四、成就&#xff1a;一点小确幸 五、憧憬&#xff1a;梦中的重点 一、机缘&#xff1a;旅程的开始 最开始开始写博客是在今年一二月份的时候&#xff0c;也就是上一…

Restormer: Efficient Transformer for High-Resolution Image Restoration解读

论文地址&#xff1a;Restormer: Efficient Transformer for High-Resolution Image Restoration。 摘要 由于卷积神经网络&#xff08;CNN&#xff09;在从大规模数据中学习可推广的图像先验方面表现出色&#xff0c;这些模型已被广泛应用于图像复原及相关任务。近年来&…

Nginx location 和 proxy_pass 配置详解

概述 Nginx 配置中 location 和 proxy_pass 指令的不同组合方式及其对请求转发路径的影响。 配置效果 1. location 和 proxy_pass 都带斜杠 / location /api/ {proxy_pass http://127.0.0.1:8080/; }访问地址&#xff1a;www.hw.com/api/upload转发地址&#xff1a;http://…

RavenMarket:用AI和区块链重塑预测市场

不论是美股市场还是加密市场&#xff0c;AI都是本轮周期里的最大叙事。本轮AI的最大受益者英伟达市值超越苹果一跃成为全球第一大公司&#xff0c;加密领域围绕着AI的创新也是层出不穷&#xff0c;很多项目方开始向着AI转型。 而近期币圈最热门的板块就是AI agent&#xff0c;…

如何将自己本地项目开源到github上?

环境&#xff1a; LLMB项目 问题描述&#xff1a; 如何将自己本地项目开源到github上&#xff1f; 解决方案&#xff1a; 步骤 1: 准备本地项目 确保项目整洁 确认所有的文件都在合适的位置&#xff0c;并且项目的 README.md 文件已经完善。检查是否有敏感信息&#xff0…

【数学建模美赛速成系列】O奖论文绘图复现代码

文章目录 引言折线图 带误差棒得折线图单个带误差棒得折线图立体饼图完整复现代码 引言 美赛的绘图是非常重要得&#xff0c;这篇文章给大家分享我自己复现2024年美赛O奖优秀论文得代码&#xff0c;基于Matalab来实现&#xff0c;可以直接运行出图。 折线图 % MATLAB 官方整理…

Python新春烟花

目录 系列文章 写在前面 技术需求 完整代码 下载代码 代码分析 1. 程序初始化与显示设置 2. 烟花类 (Firework) 3. 粒子类 (Particle) 4. 痕迹类 (Trail) 5. 烟花更新与显示 6. 主函数 (fire) 7. 游戏循环 8. 总结 注意事项 写在后面 系列文章 序号直达链接爱…

通过内核模块按fd强制tcp的quickack方法

一、背景 tcp的quickack功能是为了让ack迅速回发&#xff0c;快速响应&#xff0c;减少网络通讯时延&#xff0c;属于一个优化项&#xff0c;但是tcp的quickack是有配额限制的&#xff0c;配置是16个quick&#xff0c;也就是短时间内quickack了16次以后&#xff0c;这个配额为…

大模型GUI系列论文阅读 DAY2续:《一个具备规划、长上下文理解和程序合成能力的真实世界Web代理》

摘要 预训练的大语言模型&#xff08;LLMs&#xff09;近年来在自主网页自动化方面实现了更好的泛化能力和样本效率。然而&#xff0c;在真实世界的网站上&#xff0c;其性能仍然受到以下问题的影响&#xff1a;(1) 开放领域的复杂性&#xff0c;(2) 有限的上下文长度&#xff…