- 博客(28)
- 资源 (1)
- 收藏
- 关注
原创 Unity切线空间转换
切线空间是一个非常重要的空间。这体现在两个点,首先它的xy方向是UV方向,所以将纹理坐标和空间坐标建立了关联。其次它的z方向是法线,这很方便基于切线空间定义法线贴图。所以它的用途一个是用来处理法线贴图,这非常常用。另外就是可以利用它和贴图UV对应,比如视差贴图可以用来确纹理坐标定偏移。它是Unity坐标系中唯二使用右手坐标系的空间,另外一个是观察空间。这很容易看出来,Unity中纹理坐标是从左下角开始的,往右侧是U方向,往上是V方向,按照右手定则Z轴是正方向。本文主要分析切线空间与其他空间的转换。
2023-04-18 11:24:19 1201 2
原创 曲面细分和细分区别
有两个经常被混淆的概念,曲面细分(Subdivision surfaces)和细分(Tessellation or Subdivision)。我们知道细分是一种增加面的方法,但是它只是增加多边形对象的点数,新增的顶点仍然在原来的平面上。曲面细分使用比如 catmull-clark 算法将将曲面做适当的变形,这个过程会改变所有旧的顶点和新顶点的位置,从而产生平滑的结果。
2023-04-17 23:05:41 890
原创 片元着色器线性插值探究
在片元着色器中,我们会使用大量通过顶点着色器线性插值得到的变量,比如世界空间位置,世界空间法线方向,世界空间切线方向。我们知道片元着色器任何一个值都是三角面线性插值的结果,然而投影变换并非线性变换,不禁要问,这样插值的结果是准确的吗?
2023-04-16 18:43:33 376
原创 Unity模型正反面
有个很常见的概念——正反面。我们经常使用这个概念,比如Unity的cull命令:Unity中的正反面是由顶点顺序(winding order)决定的,Mesh的每个顶点都有一个索引,三角形包含三个顶点的索引。按照索引从大到小遍历,会产生两种情况:如果Mesh的顶点顺序是顺时针,就认为是正面;如果Mesh的顶点顺序是逆时针,就认为是反面。如上图,左侧三角面顶点分别是012,遍历顺序逆时针为反面。右侧三角面顶点分别是021,遍历顺序顺时针为正面。
2023-04-13 00:05:06 1331
原创 Unity Job System基本介绍
3. 依赖于blittable-types,不能使用引用类型。并且常用的一些数据需要改写成vector types以利用Burst对SIMD指令的优化,需要尽量使用Unity.Mathematics类型代替旧的类型,这种替换和改写需要工作量。1. 需要自己手动控制资源回收,这个过程需要更加小心,因为C#不再会做安全性检查,需要由开发者自己保证资源回收正确。2. 跟线性流程不同,我们必须手动控制多线程依赖关系,保证资源同步并且不会发生竞争。适合处理成为CPU瓶颈,并且依赖性不强,可以通过并发优化的工作。
2023-04-08 10:02:14 326
原创 Unity OnValidate使用
OnValidate方法是一个仅限编辑器的函数,在Unity加载脚本或检查器中的值更改时调用。4. 更改GameObject active状态不会调用OnValidate,只有OnDisable和OnEnable会被调用。1. OnValidate不受播放模式影响,只要其值发生变化,在非播放状态下也会被调用(可以用于非播放模式修改参数后更新)。5. 初始加载时,无论enabled状态和active状态如何,都会被调用多次。2. 不受enabled状态影响,即使其所在的脚本被禁用,修改值时也会被正常调用。
2023-04-07 16:26:53 3382
原创 Unity Transform与Hierachy
Editor左上角有一个Tool Handle Position,有两个选项,Pivot和Center,Center是指相对当前选中物体的中心,是渲染包围盒的中心。也就是说,为了得到子物体的模型变换矩阵,Unity需要将各自Transform的矩阵做相乘,从最后的层级逐项往上累乘,当层级过多时,这不可避免会产生一些成本。当选中多个物体时, Center代表围绕所有物体的中心(中心位置是所有物体的包围盒中心)旋转,而Pivot代表围绕每个物体各自的原点。上面给出的矩阵运算顺序是左乘,需要从右往左阅读。
2023-04-06 22:49:34 266
原创 Unity Compute Shader介绍和用法
但有的时候我们不想这样,而是每次写入数据的位置是可变的,并且可能在一次绘制当中,覆盖之前写好的像素。用上面的方法,可以实现非常高效的Instancing,因为此时CPU向GPU传递的数据大大减少了,不再需要每帧为每个物体传递位置信息,甚至不用传递mesh(DrawProcedural的情况)。compute shader没有subpass和pass,也没有renderqueue,这是因为它固定在GPU渲染流程开始时进行,不直接创建drawcall,而是其输出在后面的渲染阶段使用。
2023-04-06 15:27:12 1307
原创 Unity Procedural Instancing材质属性无效问题解决
这一行加了一个static标注,意味着此时定义的所有材质属性变量都成了static,但是static变量意思是其值是不可改变的,无法被Shader或者Material的SetFloat,SetColor...之类的方法修改,更要命的是,这种定义方式加上了分号也杜绝了直接赋值,变量被固定初始化为0,而不是在材质中配置好的属性值。2. 在做Procedural Instancing时,定义的shader不要UNITY_INSTANCING_XXX的语法,直接定义变量就可以。
2023-04-05 17:45:58 654
原创 Unity Mesh从obj文件到GPU
在之前的法线和UV坐标数据中可以看到,顶点和这些数据存在一对多的关系,以正方体为例,每个顶点对应3个方向的法线,在UV数据中,有14-8=6个重复顶点。可以看到顶点数发生了变化,原本只有8个顶点,现在变成了24个,每个顶点有其自身的normal、tangent和uv,占用空间变成了24*(12+12+16+8)/1024=1.125KB。每个面可以包含三个(三角面)或更多元素(四边面或者多边形面),每个元素的顶点是必须的,后面的vt(纹理坐标)和vn(法线)是可选的。纹理坐标为什么是14个?
2023-04-05 09:23:41 338
原创 Unity垂直同步:帧率和刷新率
帧率(英语:frame rate)是用于测量显示帧数的度量。测量单位为“每秒显示帧数”(frame per second,FPS)或“赫兹”,一般来说FPS用于描述视频、电子绘图或游戏每秒播放多少帧。显示器的刷新率是指显示器每秒绘制新图像的次数。其单位为赫兹 (Hz)。例如,如果您的显示器刷新率为 144 Hz,这是指它每秒钟会刷新图像 144 次。帧率直接依赖于显卡的输出速度,跟渲染速度有关,取决于CPU和GPU侧的性能,GPU瓶颈和GPU瓶颈都会导致帧率下降。
2023-04-03 20:53:48 3434 1
原创 Gerstner Wave 理解
先看上半部分的sin波,红点代表平衡位置,黑点代表表面的偏移位置。实际上水面波也会在传播方向上运动,我们在日常生活中也经常看到,比如飘在水面的叶子也会在波传播的方向上左右晃动,而非单纯的上下移动。假设是不可压缩流体,表面质点分布均匀的话,我们知道在波峰的位置,由于表面往上移动,必须要有水流来填补下面的空间,这意味着周边质点汇集。可以清晰的看到表面质点的汇集和分散现象,同时这里给出了质点的受力分析:水体表面的质点受到重力(向下)和水的压力(指向表面法线方向),两者结合的合力组成了匀速圆周运动的向心力。
2023-04-01 13:27:14 501
原创 法线贴图的旋转
实际上不对,法线下一步是通过TBN矩阵变换到世界空间,而TBN矩阵是基于原始的UV方向的,其实就是Tangent(切线)是沿着uv坐标系的u的方向。这意味着上一步计算得到的切线空间的法线必须是基于原始的uv坐标系计算的。这里的Tangent是ObjectSpace的切线,但是切线变换是在顶点着色器完成的,到片段着色器时只有WorldSpace的切线了,所以这个实现起来比较麻烦,不常用。这次讲法线贴图的旋转。另一种解法是调整法线,既然TBN需要的是旋转前的法线,那么将法线逆旋转回去就可以了。
2023-03-30 12:58:03 529
原创 Perlin Noise的本质
Perlin Noise是一种Gradient Noise,是基于网格梯度的噪声。你可能会疑惑,为什么它能得到效果很好的噪声效果,现在来探究一下它的本质。大多数时候我们接触到的是二维的Perlin Noise,也就是下面这种情况:在二维网格中每个节点生成一个梯度向量,然后每个点跟周围的梯度点乘,最后使用平滑函数做插值。
2023-03-23 13:35:20 449
原创 Perlin noise的值域
那么为什么很多资料认为值域是正负1呢,实际上是因为梯度向量G,按照Perline Noise的定义,这个G是需要归一化的,但总所周知归一化需要开根号,这个开销是比较大的,特别是需要实时生成大规模向量场的时候,所以在很多实际应用中,只会保证G向量的x和y都介于-1到1之间。我们反推一下,既然P能取极值,那么四个顶点处的G*V都需要取极值,四个顶点处的距离向量我们已经求出来了,那么很显然当梯度G的方向和距离向量V同向时G*V最大,反向时G*V最小。5. 使用4中计算的平滑后的坐标,对3中的结果做双线性插值。
2023-03-22 16:47:16 176
原创 Shadertoy导出到Unity
ShaderToy是一个很棒的Shader网站Shadertoy BETA,里面有很多很好的效果可以参考。它提供了一个网页编辑工具,可以很方便的查看和保存shader。 但是它也存在一些缺点: 1.没有调试功能,只能使用简单的假彩色ShaderMan是一个将ShaderToy转换成CG/HLSL语言的工具,这一步可以直接得到转换后的Material和Shader,使用方法参考其介绍,到这一步已经可以将材质应用于物体查看效果。
2023-03-22 14:12:41 581
原创 像素平滑公式比较
平滑公式用于对原本离散的数值进行插值,得到平缓的过渡效果,在图形学中有广泛的应用。本文列举了常用的几种平滑函数,比如线性平滑,三次多项式平滑(smoothstep),6次多项式平滑,提供了一种更好的平滑方式-导数平滑
2023-03-21 21:02:38 767
原创 Unity TAA和动态模糊比较
对于动态模糊,重投影是为了跟历史帧融合。设P4是上一帧中的和P1具有相同的UV的点(对应相机的同一个像素点),并且可以由P2重投影得到。动态模糊和TAA都需要跟历史帧做Blend,但目的不一样,前者是达到跟历史像素平均模糊的效果,而TAA则是只想融合一个像素点内部不同位置,用来提高采样质量减少走样。TAA是一种时域的AA,跟动态模糊有相似的点,又有不同的地方,如果不熟悉的话建议先看一下之前写的动态模糊介绍。所以说,动态模糊是对相同像素位置不同空间位置像素的混合,TAA则是对相同空间位置不同像素位置的混合。
2023-03-20 22:04:10 507
原创 Unity动态模糊理论和实现
这告诉我们要如何做动态模糊,需要将当前点和之前若干像素取平均值。这有个隐含参数是需要平均的像素点的个数N,这取决于曝光时间,时间越长,t越大需要平均的像素点越多。动态模糊-历史缓存Blend 首先是比较简单的实现方式,从原理分析出发,那么可以保存这N帧的图像然后对相邻N帧取平均。但直接创建N个缓存贴图成本太高,可以只使用一个缓存用Blend代替另外一种方法不需要使用中间缓存,而是作为一种后处理效果直接在屏幕空间实现,需要计算速度向量,根据重投影来计算像素速度
2023-03-20 20:17:42 1584
原创 Unity TAA Jittering公式推导
其中Offset的xy介于[-0.5, 0.5]之间,到这一步作用已经很明显了,1除以屏幕分辨率得到的是每个像素的长宽,乘以Offset代表偏移的长度,表示往像素在水平和垂直分别偏移最多0.5个像素。因为坐标值只涉及到xy的修改,所以后面都只看xy,下一步是到NDC空间。实际上没有区别,只是这里Offset值域不一样,这里的是[0, 1]先不管Jitter的数值是多少,我们把Jitter带入到投影矩阵中。区别只是这里的分母多减了1,结果变成了。现在把最初的Jitter数值带入进去。在很多实现当中,比如。
2023-03-18 17:34:57 315
原创 Unity SRP世界空间重建
世界空间重建解决的是:当我们在不透明物体渲染完成,想要知道深度缓存中保存当前渲染的物体的世界空间位置。这个功能还是比较常用的,一些后处理效果比如雾效,ScreenSpace效果都基于此。 重建世界空间有两种情况,一种是基于后处理的,我们已经在屏幕空间了,不再是渲染场景中的物体而是直接处理屏幕输出。还有一种是基于场景已有物体渲染的,比如透明物体渲染。本文介绍这两种重建方法在SRP中的实现。
2023-03-17 21:30:28 763
原创 Unity Editor绘制时分辨率减一
复现环境:Unity 2021.3.16 SRP 在测试FXAA时发现一个bug,Unity Editor中渲染的CameraTarget的分辨率,和camera.pixelWidth并不相同,前者比后者少1。
2023-03-15 02:34:50 433
原创 Unity FXAA Edge Blending细节分析
分析Unity FXAA的Edge Blending的实现细节,可以有效缓解阶梯形走样,解决中间边界采样与手动平均不匹配的问题
2023-03-13 23:36:29 358
原创 Unity SRP Batcher报错
Unity SRP Batcher报错 Builtin property offset in cbuffer overlap other stages
2023-02-03 16:19:52 445
原创 Processing 椭圆运动模拟
用Processing练习写的一个椭圆运动模拟,代码为java格式,完整代码附在下文。在setup函数中配置行星位置(init_pos)和初速度(init_vel)。设初速度为(x, y),当y = 0时可以模拟圆周运动,其他情况可以模拟椭圆运动。当椭圆的离心率很大时,会出现下图的轨道进动的现象,这实际上是由误差累积导致的:模拟程序初始化时是设置的偏远日点的速度,椭圆轨道近日点速度和远日点速度约成反比,因此离心率越高,近日点速度越大。而软件计算和更新位置是恒定速度的,速度过快导致微小计算误差通过乘以
2022-04-21 18:21:33 1002
原创 Visual Studio 2022 include和lib路径问题
最近安装了Visual Studio 2022,想试下opengl,首先是用cmake尝试编译,结果编译不过,一直报错 LINK : fatal error LNK1104: 无法打开文件“ucrtd.lib”然后我新建了一个工程,导入了glfw的包打算编译一下,结果好家伙,一编译一大堆报错,全是什么 E1696 无法打开 源 文件 crtdbg.h之类的网上说什么重装windows 10 sdk的,试了完全不起作用。我又试下装了VS2019,这个是没有问题的,开始怀疑是系统依赖路径的锅,于是我打开
2022-01-15 07:30:37 16567 3
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人