自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

聚焦图形和3D引擎开发技术

Stay hungry, Stay foolish

  • 博客(266)
  • 资源 (1)
  • 收藏
  • 关注

原创 Skinned Mesh原理解析和一个最简单的实现示例

Skinned Mesh原理解析和一个最简单的实现示例 作者:n5 本文的github地址:https://github.com/happyfire/SkinnedMeshDemo

2008-10-19 23:24:00 35797 25

原创 Unity URP 中 GPU Instancing的使用

GPU Instacing开启的条件首先Shader必须兼容与Instancing。材质开启 Enable GPU InstancingSRP Batcher的优先级高于GPU Instancing,对于Game Objects,如果SRP Batcher能被使用(Shader兼容SRP Batcher,节点本身也兼容等),则就会使用SRP Batcher,即便材质开启了Enable GPU Instancing也没用。如果SPR Batcher的条件被破坏,例如使用了MaterialProper

2022-05-19 13:51:30 384

原创 Unity使用shader渲染时的操作顺序

确定Active SubShaderSubShader列表Unity在使用一个Shader Object之前,会创建一个SubShader列表,将该Shader Object中所有的SubShader加入该列表中。并且也会把fallback shader object的所有SubShader加入到这个列表中。Active SubShader选择当第一次使用这个Shader object渲染几何体时,或者当shader LOD value改变时,又或者当前激活的render pipleline改变时,

2022-04-14 12:43:36 2405

原创 Unity内置管线Projector原理分析

Unity 内置管线的Projector功能Unity内置管理的Projector功能还是比较简单的。首先给投影体加一个 Projector组件:这个Projector定义了一个视锥体,可以是透视投影也可以是平行投影。场景中和这个视锥体相交的物体会绘制投影纹理。所以总的效果就是投影体镜头上的贴图(材质)被绘制在场景物体中,例如上图的两个Plane和一个Cube。投影纹理的原理这儿使用的技术叫做 Projective Texture Mapping,使用这个关键词可以搜索到一篇论文。基本原理是对于

2022-04-01 19:38:46 4216

原创 基于Unity的软光栅实现(3):基于Job system的多核加速光栅化

文章目录系列文章导航拥抱CPU多核计算Job System简介ParallelFor Job系列文章导航本系列文章是关于本人的开源项目 URasterizer: A software rasterizer on top of Unity, accelerated by Job system & Compute Shader的总结和介绍,一共四篇。第一篇:基于Unity的软光栅实现(1):框架搭建和矩阵构造第二篇:基于Unity的软光栅实现(2):CPU单线程软光栅第三篇:基于Unity的软

2022-03-30 14:50:21 3433

原创 基于Unity的软光栅实现(2):CPU单线程软光栅

文章目录CPURasterizer渲染数据: CPURenderObjectData输入数据中间输出数据缓冲区缓冲区定义清除缓冲区视锥剔除顶点变换图元集成ClippingBackface cullingViewport transform光栅化三角形透视校正插值片段着色MSAA输出到贴图CPURasterizer本篇介绍基于CPU单线程的软光栅渲染器 CPURasterizer。包括数据准备,缓冲区构建,顶点变换,图元集成,光栅化和片段着色,MSAA等内容,基本就是一个完整的光栅化流水线了。渲染数据:

2022-03-23 16:00:53 2101 2

原创 基于Unity的软光栅实现(1):框架搭建和矩阵构造

提纲基于CPU的光栅化实现约定矩阵和变换左手系数据转右手系使用Compute Shader的GPU Driven光栅化实现

2022-03-23 00:08:58 1826 1

原创 GPU架构和Compute Shader线程规划

文章目录GPU多处理器,线程组和线程GPU多处理器,线程组和线程在GPU中有若干多处理器,一个线程组运行于一个多处理器上。为了让

2022-03-07 00:36:39 2814 1

原创 [GAMES101]现代计算机图形学课程总结4:重心坐标,作业2

文章目录重心坐标与三角形内部插值在三角形内部插值为什么要插值哪些属性需要插值如何插值重心坐标:在三角形上使用的一种坐标系统三角形顶点的重心坐标重心坐标的计算:通过三角形面积比重心的重心坐标:重心坐标公式使用重心坐标线性插值作业2总结关于作业框架的一些问题实现三角形栅格化算法以及z-buffer算法测试点是否在三角形内的具体算法:实现MSAA (2x2):首先扩大了深度缓冲和颜色缓冲为原先的4倍,并且建立一个masks缓冲来存储sub pixel是否可见。在rasterize_triangle函数中在draw

2022-02-10 23:44:33 305

原创 [GAMES101]现代计算机图形学课程总结3:Shading

文章目录概要Shading的定义Shading是局部的输入不产生阴影(shading不等于shadow)Blinn-Phong Reflectance Model漫反射 (Diffuse Reflection)光线在所有方向上均匀散射着色点能接受到的光线(能量)的计算角度和距离兰伯特漫反射Shading计算公式高光项 Specular Term (Blinn-Phong)高光强度依赖于视线方向使用half vectorBlinn-Phong高光环境光项漫反射+高光项+环境光项着色频率 Shading Fre

2022-02-10 22:46:12 358

原创 [GAMES101]现代计算机图形学课程总结2:光栅化和反走样

文章目录屏幕空间GAMES101的屏幕空间约定标准立方体到屏幕的变换光栅化光栅显示器光栅化Rasterization定义三角形-基础的形状图元,使用三角形的优点采样(Sampling)采样一个函数就是求某个点的函数值采样是图形学的核心概念光栅化是采样2D位置检查屏幕中所有像素太浪费!使用包围盒优化真实显示设备中的光栅化走样和反走样图形学中的采样Artifacts走样(Aliasing)的背后原因反走样(Antialiasing)的方法背后的原理:频域屏幕空间GAMES101的屏幕空间约定原点在屏幕

2022-02-05 12:15:25 608

原创 [GAMES101]现代计算机图形学课程总结1:线性代数和变换,作业1

文章目录向量点积点积性质点积的作用叉积叉积性质使用矩阵表示叉积叉积的作用变换仿射变换关于推导任意空间变换矩阵推导视图变换矩阵推导投影矩阵作业1向量点积点积性质点积的作用计算两个向量的夹角计算一个向量在另一个向量上的投影衡量两个向量方向的接近程度两个单位向量同向时点积为1,反向时为-1,为0时互相垂直。点积大于0时,点积越接近1说明方向越趋于相同。点积小于0,点积越接近-1说明方向越趋向于不同。分解向量在坐标轴上分解向量,只要将向量投影到其中一个坐标轴上,平行向量使用原向量减

2022-02-02 00:13:32 1802

原创 GAMES101投影矩阵推导详解和分析

GAMES101投影矩阵推导详解和分析前言GAMES101投影矩阵相关坐标系的约定正交投影矩阵的推导和OpenGL正交投影矩阵的比较正交投影clip space中顶点的w值透视投影矩阵的推导推导透视投影frustum挤压到平行投影视景体的矩阵GAMES101思考题:视景体挤压后z值为(n+f)/2的点会挤向n还是f完整的透视投影矩阵w值和clip space的取值范围前言之前推导过OpenGL的投影矩阵,学了GAMES101之后,发现老师的推导方式很有意思,且GAMES101的坐标系约定和OpenGL不

2022-01-17 19:57:18 598 5

原创 [Unity] 关于UnityEngine.Object的fake null

看一段代码:Object a = new Object();Debug.Log(a);var b = a;Debug.Log(b);DestroyImmediate(a);Debug.Log(b);输出为三个null当然一开始a 和 b 不应该是null。这儿输出为null只是因为它们指向的object的ToString()返回"null"而已。同样如果使用 == 或 != 去比较 a,也会得到a指向null的假象。在Unity的逻辑中,这个没啥用的空Object就是null。然后把上

2021-12-14 21:26:55 2350

原创 [Unity] DontDestroyOnLoad后GameObject重复创建的问题解决

问题场景假设在 Scene A中包含一个GameObject S,在其某个MonoBehaviour脚本中,执行了如下方法:private void Awake(){ s_instance = this; GameObject.DontDestroyOnLoad(gameObject); }这样,当Scene A载入时,GameObject S在Awake之后将被放入一个名字为DontDestroyOnLoad的自动创建的S

2021-09-18 11:36:50 352

原创 [Unity] 编辑器脚本中在主线程执行方法

问题来源最近在做一个Unity打包工具,使用Process开启新进程调用外部工具执行,结束后使用Exited继续流程。大概流程如下: Process pc = new Process(); //创建一个进程 pc.StartInfo.FileName = "tool.exe"; //进程名 pc.StartInfo.UseShellExecute = false; //是否使用操

2021-09-11 14:29:05 209

原创 关于ShadowMap中Shadow acne现象的解释

什么是Shadow acne先看一张图:这张图是我在GAMES202的作业1中,将光源高度调低,从而使得光线入射方向和地面之间夹角比较小,并且不做任何bias处理,从而得到比较明显的shadow acne现象。即左边地面上奇怪的花纹。产生Shadow ance的原因原因其实很简单,简单说,shadow map对于光源空间的深度的采样是离散的,shadow map上每个texel只能记录一个深度值。而计算阴影的平面,比如地面本身是连续的。在传统shadow map的第二个pass中,将任意片段所对应

2021-04-12 19:27:40 384

原创 游戏开发基础知识之垂直同步V-Sync

什么是垂直同步V-Sync垂直同步是显卡提供的一个功能,目的是将游戏帧率和显示器的刷新率进行同步。当开启V-Sync后,显卡会等待显示器本轮刷新完成,在这期间,显卡不会向显示器传输任何数据,并且通过双缓冲和页翻转(page flipping)技术确保当显示器刷新完成后获得下一帧的画面。为什么需要V-Sync呢?首先,FPS超过刷新率并不能提高实际感受到的帧率。因为你看到画面是最终要通过显示器的刷新来变化。比如显示器的刷新率是60Hz,那么如果游戏以120FPS的帧率渲染,实际上每渲染两帧才有一次更新显

2021-03-16 14:38:51 810 2

原创 Unity Prefab中MonoBehaviour脚本修改带来的序列化问题

项目中出现的问题载入一个prefab并实例化后,获取该prefab上挂载的一个MonoBehaviour组件,例如:public class Foo: MonoBehaviour{ public bool newValue = true; void Awake(){ Debug.Log(newValue); }}此时,Awake中的Log输出的是 false。分析原因Foo组件中的newValue默认为true,但是Awake时为false。这说明序列化出了问题。但是打开该pr

2021-02-08 15:15:11 585 1

原创 引擎开发随笔之资源导入

曾在十多年前看到一个大佬说,游戏引擎的核心就是资源管理。确实,游戏引擎必须要能管理好各种资源,而且不论是运行时资源还是项目工作流中的资源。今天来聊一聊资源导入,这个经常被忽略的一个引擎功能。以前我们用自研引擎做游戏几乎都会用到自定义的一些资源格式,比如模型文件格式什么的。这种自定义格式的好处是匹配自己的需求,可以根据需求优化,这是通用格式无法做到的。这种自定义资源,一般会开发专用的转换工具,将通用格式的资源转换成自定义格式的资源,并且保存在项目中。除此之外,游戏还需要对一些资源进行某种处理,比如图片如果

2020-12-26 15:04:05 236 2

原创 Unity 编辑器中修改属性值及时查看效果

需求项目中有个需求是开发一个UI适配的脚本,根据游戏运行的平台显示不同类型的UI。根据需求,游戏在运行时自动适配就可以了。但是为了方便在编辑器中查看效果,需要可以在Inspector面板中修改属性值后直接在编辑器上执行相应的适配代码,显示效果。解决方案为了在Inspector面板中修改值,我们使用一个enum属性即可,这样对应在面板上就是一个下拉列表。注意这个属性在游戏运行时是根据所在的平台动态设置的,其实并不需要public出来,也不需要序列化。但是为了能在Inspector面板中临时修改并查看效果

2020-12-02 11:04:29 2164

原创 Unity input system on-screen button crash

最近在项目中遇到一个unity input system内部的crash。大概会有类似以下报错:Assertion failedUnityEngine.InputSystem.LowLevel.<>c__DisplayClass7_0:<set_onUpdate>b__0(NativeInputUpdateType, NativeInputEventBuffer*)UnityEngineInternal.Input.NativeInputSystem:NotifyUpdate(

2020-11-14 14:50:24 396 1

原创 从零开始手撸WebGL3D引擎11: PostProcessing框架(里程碑5了)

文章目录项目状态PostProcessing基本原理框架设计目标框架结构PostProcessingChain的主要成员PostProcessing材质多pass后期效果举例:PostEffectBloom需要完善的地方下期预告项目状态本系列文章停更了好几个月了,这期间也是有很多事情,不过这个项目(mini3d.js)肯定是不会放弃的,只会不断的进化。最近几个月主要在深度研究Unity,以渲染系统为主,后期可能会出一系列文章,Unity自身一直在进化,但是底层的那些技术并没有发展特别快,结合Unity的

2020-10-19 14:26:00 681

原创 Unity .NET 4.x 相关知识

历史在Unity 2017.1之前,Unity使用的是一个相当于.NET 3.5的runtime,多年未更新。Unity 2017.1中,Unity引入了一个实验性的runtime版本,升级到.NET 4.6, 兼容C# 6。Unity 2018.1中,.NET 4.x不再是实验性的了,同时老的.NET 3.5 runtime被标记为legacy。Unity 2018.3中,.NET 4.x runtime被设置为默认。同时支持了C# 7。现状Unity 2019中已经不能再切换到老的.NE

2020-09-08 19:54:43 1617 5

原创 Unity Draw call batching小结

文章目录DrawCalls 和 Batchesdraw call就是你知道的那个draw calldraw call不一定意味着状态切换静态batching静态batching更费内存静态batching不限制物体顶点数且更有效率静态batching的优化选项静态batching的缓存区限制动态batching针对Mesh的动态batching模型顶点属性限制物体包含镜像的变换不能被动态batching材质实例不同则不能合并关于使用lightmap的物体的动态合并多Pass的shader会破坏合并动态bat

2020-08-31 00:25:26 515

原创 半透明物体渲染总结

文章目录半透明渲染要解决的问题深度测试解决可见性问题的原理渲染顺序半透明物体不能开启深度写入整体透明(内部不透明)的渲染双面透明渲染混合公式Alpha Test半透明渲染要解决的问题需要将半透明物体按照正确的顺序进行渲染,以便让它们的片元和远处已经绘制到color buffer中的片元颜色进行混合,从而达到半透明的效果。为了完成颜色的正确混合,所有半透明物体应该在不透明物体渲染完成之后进行渲染,且半透明物体之间应该是按照距离camera从远到近渲染。但是物体是若干三角形图元的集合,包含了很多的片元,无法

2020-08-04 18:34:53 2135

原创 Gamma Correction & sRGB texture

文章目录显示器gamma值的由来gamma correctionsRGB texture参考资料显示器gamma值的由来gamma correctionsRGB texture参考资料Gamma-Correction

2020-06-10 20:55:24 428

原创 法线贴图技术原理与实践

本文讲述了法线贴图技术的原理,切线空间的概念,切线空间和世界空间的转换,计算顶点切线的方法,并给出了在切线空间和世界空间使用法线贴图进行光照的shader例子。

2020-06-09 19:00:44 661 1

原创 从零开始手撸WebGL3D引擎10: 材质,前向渲染以及里程碑4

文章目录前言材质封装多个Pass创建Shader创建pass并添加到材质shader代码写在哪儿System UniformsCustom Uniforms渲染pass引擎提供的材质前向渲染scene.render()renderer.render()传入参数计算system uniform灯光规则如何叠加多个pass的光照非光照pass里程碑4Next前言本篇总结一下里程碑3到4阶段的材质和前向渲染的实现。本部分仍然处于早期,为了看到效果,很多地方只有思路没有实现,代码里有很多TODO。尽管很不完善,

2020-06-04 00:57:49 455 2

原创 从零开始手撸WebGL3D引擎9:Scene & Transform

文章目录引言将物体组织成场景一个场景是一棵N叉树场景不止是一棵树从简单开始SceneNode本地矩阵计算更新世界矩阵获取世界坐标和旋转对象-组件和ECS怀念一下C++下一篇引言相比于实现很多花哨的图形效果,写引擎需要很多很扎实的东西。比如说场景和变换就是其中之一,基础中的基础。实现场景和变换的最初的动机,是我们需要在世界中移动旋转和缩放物体,物体之间需要有层级关系,可以将A放到B的上面随着B一起运动。而在这背后是矩阵和四元数的数学。我们使用四元数保存物体的方位朝向,并且可以让物体绕任意轴旋转,可以让物体

2020-05-30 19:58:56 419

原创 谈一谈3D编程中的矩阵

行主列主,右乘左乘,空间变换,法线变换,shader中矩阵的使用,打好基础才能写好shader

2020-05-22 20:53:33 1344

原创 Unity Cg/HLSL Shader中向量和矩阵的构造方式

目录向量的构造向量使用同类型的构造器构造CG(不是所有的HLSL版本)单值构造向量使用低维向量构造高维向量CG(不是所有的HLSL版本)高维向量转换到低维向量矩阵的构造使用数值构造float3x3可以从三个向量构造从float4x4截取出float3x3参考资料向量的构造向量使用同类型的构造器构造float2 a = float2(1.0, 2.0);float3 b = float3(-1.0, 0.0, 0.0);float4 c = float4(0.0, 0.0, 0.0, 1.0);

2020-05-13 19:06:42 914

原创 从零开始手撸WebGL3D引擎8:里程碑3-一个多光源场景

目前状态暂停了一段时间后,本周又搞了几天,实现了基于多pass的多光源前向渲染,加上之前实现的基本的scene和transform,勉强可以打个分支了,暂且算作里程碑3:simple scene。虽然代码里面还有很多TODO,但勉强可以看些效果了。先上个视频: undefined 基本功能目前实现了一个简单的场景和基于组件的场景节点,支持Camera, Light 和 Mesh No

2020-05-10 16:11:27 499 2

原创 引擎开发随笔之OpenGL Shader的封装思考

在进行mini3d.js这个开源小项目的过程中,越来越体会到一个引擎的复杂性,从技术DEMO到可以完成实际工作的引擎,完全不是一个数量级的复杂度。因为工作量太大,且想做的事情太多,mini3d.js的开发笔记一直是很滞后的,当然主要原因还是开发mini3d.js对我来说已经是一个很大的工程了。为了防止时间长了忘了很多东西,以及记录一些暂时没法去做的事情,特别用随笔的形式简单记录一下,想到哪儿记到哪...

2020-04-16 13:56:43 257

原创 从零开始手撸WebGL3D引擎7:载入.obj模型以及顶点法线的计算

载入.obj格式模型.obj是文本格式的,相对比较好解析,而且可以查看,所以先暂时只支持这个格式。当然这个格式里面包含的东西不仅仅是模型数据,其实还有物体的概念,以及材质的关联。由于只是把它作为模型文件使用,所以忽略了材质的关联。材质会采用自己定义的材质,然后使用到模型上。其实这个地方没什么好说的,主要解决的问题是顶点法线的计算。顶点法线计算的时机载入.obj格式的模型时,发现有的模型没有提...

2020-02-24 14:38:36 881

原创 从零开始手撸WebGL3D引擎6:里程碑2,目前状态和展望

最近做了很多零碎的工作,归拢了一下作为里程碑2。先上截图:这是一个脚本生成的example页面,以后所有的例子可以从这个页面进入,这样就可以查看之前的示例,也方便重构代码之后回溯。这个页面我也放到了github pages上:https://happyfire.github.io/mini3d.js/examples/(但是我这儿有时候打开不了)目前,mini3d.js仍然是一个很简单的框架...

2020-02-22 20:14:00 505

原创 顶点法线计算的几种方式

首先,顶点法线都是从面法线加权平均计算得到。所以有两个维度,一是哪些面参与计算,二是权重如何计算。一 哪些面参与计算如果建模工具导出了光滑组,那么方案一是直接使用光滑组信息,属于同一个光滑组的面参与计算。方案二是同时使用光滑组信息以及面的夹角的阈值。方案三是只使用面的夹角阈值。二 权重如何计算方案一是用三角形面积作为权重方案二是用面的夹角作为权重方案三是同时使用面积和夹角作为权重...

2020-02-07 20:43:25 3338

原创 关于四元数的一些误解和问题

(先简单记录一下结论,有时间再完善)四元数可以避免gimbal lock理论上如果只使用四元数,不会有万向锁的问题。但实际上很多时候,还是在使用欧拉角,然后把欧拉角转成四元数,最后四元数再被转换成矩阵,合并到最终的Model2World变换矩阵中。这样并不能避免gimbal lock。因为你操作的旋转还是一系列绕独立轴的旋转的组合,你用欧拉角+矩阵会遇到gimbal lock (证明方法是...

2020-02-06 20:33:33 636

原创 从零开始手撸WebGL3D引擎5:Shader的封装

上一篇之后停了好久没写,但其实mini3d.js一直在进展,目前的内容够写很多篇了,但这样欠下的债就太多了。我开始思考我写这些文章的初衷,是对这个过程的记录以及思考的总结,而不是写WebGL教程。教程的问题是如果讲得很细非常花篇章,而讲得很简略又没有用处。所以本篇开始减少代码细节的描述,只重点讨论技术原理和设计思路。并且每一组文章都要紧扣着当前讨论的里程碑目标。本篇对应代码请参考:mini3d....

2020-02-01 22:56:20 531

原创 从零开始手撸WebGL3D引擎4:Mesh的封装

本篇讲述mini3d.js对静态模型的封装,目前支持三角形列,使用或不使用索引,暂不支持子模型。涉及到的类有Mesh, VertexBuffer, IndexBuffer, VertexFormat,以及预定义顶点语义VertexSemantic。总体结构一个Mesh由一个VertexBuffer和零或一个IndexBuffer构成。模型所有的顶点的属性数据采用交错数组的方式存放在Verte...

2020-01-12 15:03:41 791

WebGL Programming Guid (英文原版带目录)

WebGL Programming Guid (英文原版带目录),OpenGL ES programming Guid作者又一力作

2018-12-16

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除