• shaderforge 向量运算

    • Append数据维度的附加 Component Mask数据维度的分解
    • Channel Blend通道混合
    • Cross Product叉积
    • Desaturate去色
    • DDX DDY DDXY偏导数
    • distance距离
    • Dot Product点积
    • Length计算向量长度
    • Normalize归一化
    • Normal Blend法线混合
    • Reflection反射
    • Transform坐标系变换
    • Transpose矩阵转置
    • Vector Projection Vector Rejection向量投影

shaderforge 向量运算

以一张向量运算的全家福开始

Append(数据维度的附加) & Component Mask(数据维度的分解)

1. 节点说明

  • Append

用于数据维度的附加
低维数据连接到输入端,高维数据在输出端输出

Append的节点会将计算好的数据以一种颜色RGBA的形式显示出来
Append节点最多可以附加四个一维数据(因为shader中最高维度的数据类型是float4,且我们的计算最高涉及到四维)

  • Component Mask

用于数据维度的分解
高维数据连接到输入端,节点中有四个通道的选项,可以让我们控制通道的开启与关闭,并可以将任意一个通道设置成任意一个输入通道的数据。输出的是将节点在四个选项中开启的所有通道附加起来的高维数据和所有开启的单个通道。

2. UnityShader中进行数据维度附加和分解
GPU是以四维向量为基本单位来计算的。4个浮点数所组成的float4向量是GPU内置的最基本类型。使用GPU对两个float4向量进行计算,与CPU对两个整数或两个浮点数进行计算一样简单,都是只需要一个指令就可以完成。
HLSH的基本数据类型定义了float、int和bool等非向量类型,但是它们实际上都会被Complier转换成float4的向量,只要把float4向量的其中3个数值忽略,就可以把float4类型作为标量使用。

在使用float4向量中的个别数值时,可以用xyzw或rgba,都可以用来表示四维向量中的数值。但不能把它们混用,例如不能用xyba,把它视为颜色时就用rgba,否则就是用xyzw,不能把这二者混合使用。

float4 appendData = float4(float3(x,y,z),float(w))  //数据维度附加
float w = appendData.w; //或appendData.a; //数据维度的分解

Channel Blend(通道混合)

1. 节点说明

贴图的RGBA的每个通道作为遮罩控制对应的贴图
mask有几个通道那么节点显示几个输入通道
节点下拉框可以选择混合模式为summed(总和)模式还是layered(插值)模式,summed就是通道乘以对应的分量遮罩结果的总和。layered插值启用底图Btm,各个通道有次序的按照分类遮罩进行插值,可实现图层覆盖和透明度混合。
2. UnityShader实现通道混合节点的功能

  • summed
float3 summed = (_mask_var.rgb.r*_Rcol_var.rgb + _mask_var.rgb.g*_Gcol_var.rgb + _mask_var.rgb.b*_Bcol_var.rgb);
  • layered
float3 layered = (lerp( lerp( lerp( _Btm_var.rgb, _Rcol_var.rgb, _Mask_var.rgb.r ), _Gcol_var.rgb, _Mask_var.rgb.g ), _Bcol_var.rgb, _Mask_var.rgb.b ));

Cross Product(叉积)

1. 节点说明
用于给定x轴y轴求z轴

叉积的结果是一个矢量,是有方向的。

2. UnityShader的cross函数

cross(向量a,向量b)

Desaturate(去色)

1. 节点说明

2. 去色原理
为图片的RGB分别乘以权重然后加起来得到一个灰色值,并且将这个灰色值作为新的RGB值。

为什么在使彩色图变灰RGB的权重会固定为(R:0.299 G:0.587,B:0.114)?
人眼对绿色的敏感度最高,对红色的敏感度次之,对蓝色的敏感度最低,因此使用不同的权重将得到比较合理的灰度图像。实验和理论推导出来的结果是0.299、0.587、0.114。
参考:为什么在使彩色图变灰RGB的权重会固定为(R:0.299 G:0.587 B:0.114)?

3. UnityShader是实现去色

lerp(col ,dot(i.normalDir,float3(0.3,0.59,0.11)), des))

DDX DDY DDXY(偏导数)

1. 节点说明

DDX是X方向上的偏导数,DDY是Y方向上的偏导数,DDXY返回的是X和Y方向上偏导数绝对值的和。
注意:这里的偏导数不是数学意义上的偏导数而是某方向上后一像素块与前一像素块的差值。

2. 如何理解shader中的偏导数

An introduction to shader derivative functions
An introduction to shader derivative functions(译)

我们知道在光栅化的时刻,GPUs会在同一时刻并行运行很多Fragment Shader,但是并不是一个pixel一个pixel去执行的,而是将其组织在2x2的一组pixels分块中,去并行执行。而偏导数就正好是计算的这一块像素中的变化率。从上图可以看出来ddx 就是右边的像素块的值减去左边像素块的值,而ddy就是下面像素块的值减去上面像素块的值。其中的x,y代表的是屏幕坐标。
注意:偏导数ddx/y可以计算我们FragmentShader中任意的变量。向量,矩阵等等。

3. UnityShader求偏导数

ddx(n)
ddy(n)
fwidth(n)

distance(距离)

1. 节点说明

2. UnityShader的distance函数

distance(a,b)

Dot Product(点积)

1. 节点说明
用于计算两个向量的朝向关系,是相对,侧对还是背对

2. 标准点积数学意义

以两个三维标量为例子x=(a,b,c),y=(a2,b2,c2)
乘法的结果是三维数据:

x*y = (a*a2,b*b2,c*c2)

点积的结果是乘法得到三维数据相加得到的一维数据

x dot y=a*a2+b*b2+c*c2


3. Unityshader实现点积操作

  • dot standart
dot(a,b)
  • dot positive
max(0,dot(a,b))
  • dot negative
min(0,dot(a,b))
  • dot abs
abs(dot(a,b))
  • dot normalize
normalize(dot(a,b))

Length(计算向量长度)

1. 节点说明


2. UnityShader的Normalize函数

length(向量)

Normalize(归一化)

1. 节点说明

单位化向量
2. UnityShader的Normalize函数

normalize(float4)

Normal Blend(法线混合)


如果detail_x,detail_y值都为0的话,不做扰动,否则随着detail_x、detail_y的值的更改改变扰动的程度。

Reflection(反射)

1. 节点说明


2. UnityShader反射函数

reflect(I,N)

Transform(坐标系变换)

1. 节点说明

用于实现向量的坐标系空间转换,比如从世界空间到模型空间等等

2. UnityShader实现Transform结点的功能

  • 用到的unity shader内置矩阵变量
Name Value
unity_ObjectToWorld 当前的模型矩阵
unity_WorldToObject 当前的世界坐标矩阵的逆矩阵
UNITY_MATRIX_V 当前的视点矩阵
UNITY_MATRIX_MV 当前的模型*视点矩阵

- 用到的unity shader内置函数

Name Value
float3 UnityObjectToViewPos(float3 pos) 将一个位置从模型空间转换到视点空间,等价于(UNITY_MATRIX_MV, float4(pos, 1.0)).xyz

常用的坐标系有世界坐标系、模型坐标系、切线坐标系、视点坐标系,位置点可以通过矩阵乘法切换坐标系

1.world->local

float3 posW2L = mul( unity_WorldToObject, float4(pos, 0)).xyz;

2.world->tangnet

float3x3 tangentTransform = float3x3( i.tangentDir, i.bitangentDir, i.normalDir);
float3 posW2T = mul( tangentTransform, float4(pos, 0)).xyz;

简单介绍TBN切线空间以及Bitangent向量
切线空间,同局部空间、世界空间等一样,是3D图形学中众多的坐标系之一。切线空间基于网面的顶点由法线、切线、副切线构成一个互相垂直的三维坐标系。当模型网面变形时,切线坐标系必定跟着面一起运动,那么在这个坐标系里的某个点或向量,不需要变动。当整个面发生变化时,我们只需要计算面上的坐标系到世界坐标系的转换矩阵,那么定义在这个面上的点或坐标(固定的),乘以这个矩阵即可得到在世界中的坐标。这个坐标系术语里称为tangent space(或称TBN切线空间)。
一个右手坐标系的TBN切线坐标系如下图所示:


TBN切线空间的TBN这三个字母分别代表tangent、bitangent和normal向量。
tangent是顶点的切线,normal是顶点的法线,bitangent由tangent和normal叉乘(注意进行叉乘的N和T的先后顺序!在右手坐标系中是N × T,在左手坐标系中是T x N! 注意:Unity是左手坐标系)得到,是一个垂直于tangent和normal的向量bitangent。
切线坐标系转换到世界坐标系
切线空间到世界空间的转换矩阵T2W:

\begin{bmatrix}
> T_{x} & T_{y} & T_{z} \\
> B_{x} & B_{y} & B_{z} \\
> N_{x} & N_{y} & N_{z}
> \end{bmatrix}

切线空间下的法线向量乘以转换矩阵,得到世界坐标系下的切线向量

normalWorld= normalize(mul(normalTangent,T2W));

3.world->view

float3 posW2V = mul( UNITY_MATRIX_V, float4(pos, 0)).xyz;

4.local -> world

float3 posL2W = mul( unity_ObjectToWorld, float4(pos, 0)).xyz;

5.local -> tangent

float2 posL2T = mul( tangentTransform, mul( unity_ObjectToWorld, float4(pos,0) ).xyz

6.local -> view

float3 posL2W = UnityObjectToViewPos( float4(pos,0) ).xyz

7.tangent -> world

float3 posT2W = mul( float4(pos,0), tangentTransform ).xyz;

8.tangent -> local

float3 posT2L = mul( unity_WorldToObject, float4(mul( pos, tangentTransform ),0) ).xyz

9.tangent -> view

float3 posT2V = mul( UNITY_MATRIX_V, float4(mul( pos, tangentTransform ),0) ).xyz

10.view -> world

float3 posV2W = mul( float4(pos,0), UNITY_MATRIX_V ).xyz;

11.view -> local

float3 posV2L = mul( float4(pos,0), UNITY_MATRIX_MV ).xyz

12.view -> tangent

float3 posv2T = mul( tangentTransform, mul( float4(pos,0), UNITY_MATRIX_V ).xyz ).xyz

Transpose(矩阵转置)

1. 节点说明

输出矩阵的转置矩阵
2. Transpose的数学意义

wiki关于transpose matrix(转置矩阵)的说明

在线性代数中,转置矩阵是一个按照对角线翻转一个矩阵的操作,交换矩阵行和列的索引号生成一个新的矩阵,称之为AT(也写作A’,Atr,tA,At),
转换矩阵的行和列生成这是开关矩阵的行和列索引通过产生另一个矩阵表示为(还写了′,Atr,tA或)。它是由下列任何一项等价的动作实现的:
- 从它的主对角线(从左上方到右下角)反射A以获得。
- 把A的行写作AT的列。
- 把A的列写作AT的行。

形式上,AT的第i行,第j列元素是A的第j行,第i列元素:

{\displaystyle \left[\mathbf {A} ^{\mathrm {T} }\right]_{ij}=\left[\mathbf {A} \right]_{ji}}

如果A是一个m×n矩阵,那么AT是一个n×m矩阵。
1858年,英国数学家Arthur Cayley引入了矩阵的转置。

3. UnityShader进行transpose(矩阵转置)操作

transpose(float4x4)

Vector Projection & Vector Rejection(向量投影)

1. 节点说明

  • Vector Projection


  • Vector Rejection


2. Vector Rejection的数学意义

wiki关于Vector Projection和Vector Rejection的说明


一个向量a对一个非零向量b的向量投影是a到b所在直线的正交投影。它是一个b方向上的向量,定义为


a1是一个标量,称为a到b的标量投影。b是b方向上的单位向量,因此标量投影定义为


操作符 · 代表点积操作, |a| 代表向量a的长度,θ代表a和b之间的夹角。标量投影等价于投影向量的带正负的长度值,如果投影向量的方向与b的方向相反的话标量投影为负数。

有时我们称从a出发垂直于b的向量为a到b的rejection向量(不知道怎么翻译rejection vector合适),它是a向垂直于b的平面的正交投影。一个向量的projection a1和rejection a2还是向量,a1和a2的和是a,那么就得到了rejection的公式:

3. UnityShader获取projection和rejection
projection

float3 a = float3(0,4,3);
float3 b = float3(0,4,0);
float3 projectionOfab = b * dot(a,b) / dot(b,b);

rejection

float3 a = float3(0,4,3);
float3 b = float3(0,4,0);
float3 rejectionOfab = (a - (b * dot(a,b)/dot(b,b)));

【shaderforge学习笔记】 Vector Operations(向量运算)相关推荐

  1. 计算机图形学基础学习笔记-其一:向量与线性代数

    计算机图形学基础学习笔记-其一:向量与线性代数 前言 计算机图形学概述 向量(矢量) 点乘 叉乘 点乘,叉乘与直角坐标系 矩阵 前言 GAMES101现代计算机图形学入门的学习笔记 正在为TA实习攒作 ...

  2. 抽象代数学习笔记(5) 运算

    抽象代数学习笔记(5)运算 "运算"这个名词大家从小学就应该接触了,比如"四则运算"等等.不过在那个时候,运算一直是一个很模糊的概念,究竟什么是运算?我们接触的 ...

  3. 日常python学习笔记DAY 8---集合运算(交集、并集、超集和差集)

    日常python学习笔记DAY 8-集合运算(交集.并集.超集和差集) ''' 集合的运算有交并超差以及堆成差集合 ''' #求交集 & .intersection() .intersecti ...

  4. opencv进阶学习笔记3:像素运算和图像亮度对比度调节

    基础版传送门: python3+opencv学习笔记汇总目录(适合基础入门学习) 进阶版目录: python+opencv进阶版学习笔记目录(适合有一定基础) 像素运算 要求两张图大小,以及格式(np ...

  5. sheng的学习笔记-Vector源码分析

    概述 Vector底层也是数组,跟ArrayList很像(先看下ArrayList,再看Vector会很轻松),ArrayList可参考下文,并且由于效率低,已经被淘汰了,大概瞅瞅得了 sheng的学 ...

  6. opencv学习笔记17:梯度运算之laplacian算子及其应用

    laplacian算子理论 前文介绍了sobel算子及其函数使用 和scharr算子及其函数使用 使用方法 不同算子比较 sobel,和scharr算子:右边121列-左边121列.右边-3,10,3 ...

  7. opencv学习笔记16:梯度运算之scharr算子及其函数使用

    前文介绍了sobel算子 opencv学习笔记14:sobel算子及其函数使用 scharr算子理论 系数和sobel不一样,其他一样. scharr函数使用 dst=cv2.Scharr(src,d ...

  8. python中向量长度_Python线性代数学习笔记——什么是向量?实现我们自己的向量...

    上一篇已经说明了为什么要学习线性代数? 下面我们正式开始学习 一切从向量开始 什么是向量,究竟为什么引⼊向量? 从研究一个数,变成了研究一组数,向量表示的就是一组数 学过中学物理都知道力,速度,加速度 ...

  9. OpenCV学习笔记:矩阵/向量处理

    环境:CentOS7 g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-16) $ pkg-config --modversion opencv 2.4.13 总体上讲: ...

最新文章

  1. Redis多机功能之复制
  2. 【公开课预告】百度语言与知识最新技术成果详解
  3. HDU 5938 Four Operations 【字符串处理,枚举,把数字字符串变为数值】
  4. 中累计直方图_试验研究中的利器强大的直方图和箱线图
  5. android源码分析(一) - 语言切换机制
  6. ELMAH--Using HTTP Modules and Handlers to Create Pluggable ASP.NET Components 77 out of 90 rated th
  7. 最新版云铺购ds网系统全开源可运营程序源码
  8. UE4 Datasmith 格式简述
  9. koreader下载_Koreader阅读器app免费安装最新版|Koreader阅读器2018手机最新版下载_v1.0_9ht安卓下载...
  10. JAVA必备——Struts
  11. python正则表达式和数据库
  12. 测试raid10下的服务器性能,Raid5 Raid10性能测试
  13. 代数余子式与伴随矩阵
  14. python 控制鼠标滚轮_python-pyautogui控制鼠标键盘自动操作
  15. 数据库——如何求出候选码
  16. 关于.net的一则笑话(无奈一笑)
  17. Transfer Learning 迁移学习的相关知识
  18. anistropic filer
  19. Codeforces 517 #A
  20. 一步步带你了解分布式数据库的架构演变之路!

热门文章

  1. 人脸识别与膜虹识别_虹膜识别技术和人脸识别技术的区别是什么
  2. FZUOJ Problem 2178 礼品配送
  3. Android热修复之AndFix
  4. VMware公司SpringSource部门宣布收购Gemstone Systems公司
  5. kpatch 内核热补丁几个使用问题记录
  6. VB与C#的区别(转载)
  7. xxxx不必xx尽,留些xxxx
  8. java 日历签到功能_Android 在日历的基础上实现签到功能
  9. zfoo中的providers和consumers标签
  10. php弱类型比较,php弱类型问题总结