1.Unity贝塞尔曲线编辑工具的码解原理(类似AnimationCurve)
2.Unity摄像机之焦距某点缩放
3.[3D游戏开发实践] Cocos Cyberpunk 源码解读-目录结构
4.UE4 LevelSequence源码剖析(一)
5.游戏引擎随笔 0x29:UE5 Lumen 源码解析(一)原理篇
6.CesiumJS 源码杂谈 - 从光到 Uniform
Unity贝塞尔曲线编辑工具的原理(类似AnimationCurve)
在Unity的世界里,AnimationCurve的码解魔法源自于贝塞尔曲线,但官方并未提供直接的码解Scene绘图工具来探索这一奥秘。然而,码解幸运的码解是,我在Asset Store中找到了一款免费的码解阻塞队列delay源码宝藏工具,它让贝塞尔曲线的码解绘制触手可及。 这款工具的码解源码虽简洁,但背后蕴含的码解原理却深邃。贝塞尔曲线,码解就像它的码解名字所暗示,由起点、码解终点和几个关键的码解控制点构建。如你所见,码解圈出的码解那四个点就像是乐谱上的音符,它们精准地定义了从Point 0到Point 1之间的曲线路径,每一个转折都由它们塑造。</ 更为巧妙的是,复杂的贝塞尔曲线并非孤立存在,而是由多个基础贝塞尔曲线片段巧妙拼接,就像上图中的另一段,也是由四个控制点构建而成的。这是通过一系列的数学运算,通过函数GetPoint(Point a, Point b, float t),动态计算出曲线上的任意一点位置,再通过取众多点并连接相邻点,构成了平滑的视觉效果。 源码中的Point类,就像曲线上的明珠,存储了控制点和对称位置点的信息,使得函数GetPoint的青龙大厅源码搭建调用变得直观且高效。原本需要四个点的数据,现在只需传递关键的线上点,这样的设计大大提升了使用的便利性和理解的直观性。Unity摄像机之焦距某点缩放
在游戏开发中,细致观察某些对象是必要的。通常,我们可以通过鼠标滑动来达到这一目的。在Scene面板中,我们可以直观地看到这一过程。然而,当我们观察到鼠标距离越远,消失或生成的速度越快时,且摄像机中心点与鼠标的Viewport距离始终不变,会发现实现这一功能相对复杂。因此,我上网寻找相关源码,发现只有UI上的放大方法是通过改变锚点实现的。但在非UI场景中,如何实现这一功能呢?
首先,我将Camera设置为Orthographic模式,因此需要通过改变Size来实现缩放效果。
其中,Size的值等于
我是通过横向来确定Size的,如图,一个小格子占个像素,因此
缩小时,Size值增大;相反,放大时Size值减少。下面简单解释一下原理。
假设相机在最左下点,拼接图片 c 源码鼠标点在中心点,其他如下:
size:放大后的orthographicSize(已知)
oldSize:放大前的orthographicSize(已知)
mousePos:鼠标位置的世界坐标 = Camera.ScreenToWorldPoint(Input.mousePosition)(已知)
pos:放大前Camera位置坐标 = Camera.transform.position(已知)
newPos:放大后Camera位置坐标
因此,得到以下公式
由于其他条件已知,因此可以求出对应的newPos
主要源码如下:
其中,使用了Dotween插件以实现平滑移动的效果。
[3D游戏开发实践] Cocos Cyberpunk 源码解读-目录结构
在深入解读Cocos Cyberpunk源码之前,首先,让我们打开scene-game-start场景,启动游戏预览,进入游戏场景。点击START按钮,游戏正式开始。漫游摄像机将带你漫游整个场景,再次点击START,可以进入游戏。
在电脑端按ESC键或手机端点击设置按钮,查看操作说明。接下来,让我们浏览Cocos Cyberpunk项目的目录结构。在左下角的Assets窗口中,我们可以看到项目文件的分层。
首先,animations目录中仅包含用于场景漫游的摄像机动画文件。LightFX目录存储了光照贴图,这些是光照烘焙系统自动生成的,无需手动修改。res目录是整个游戏资源的集中地,包括动画、特效、模型、智能电视应用源码shader、UI、音效等资源。
resources目录则存放动态加载的资源,当前内容较少,随着游戏的完善,资源将会增多。scene目录包含了环境反射探针文件,与场景文件名对应的文件夹存放反射贴图。scene-development目录则包含一些用于单元测试的开发场景。
scripts目录存放所有游戏逻辑脚本,而src目录可能包含项目开发过程中的测试文件。test目录同样是用于测试的,存放的文件与项目无关。scene目录则是游戏主场景,而scene-game-start则为游戏启动场景,进行UI逻辑初始化,并加载游戏主场景。
自定义管线以编辑器扩展的形式存在,可将其移至项目中。管线对应自定义管线,通过在场景中新建节点并添加pipeline/graph/pipeline-graph.ts组件来查看可视化管线图。实时探针相关组件在反射探针节点上挂载,提供实时更新功能。
反射探针节点上的ReflectionUtils脚本组件实现了实时更新探针的逻辑,适用于需要实时探针的项目。此外,Cocos Cyberpunk还实现了SphereProjection修正,使得反射更符合物体形状。
静态遮挡剔除机制在Cocos Cyberpunk中实现,api商品分享源码通过将可见关系预存入空间格子,渲染时直接查表获得渲染列表,极大提升效率。这一部分主要在scene场景中的static-occlusion-culling结点中处理。
机型适配策略在Cocos Cyberpunk中实现,根据设备性能选择渲染效果,确保流畅帧率。处理了不同设备上的效果调整,包括性能开关策略、机型分档策略,主要在href-settings.ts、gpu.ts和gpu-mobiles.ts文件中实现。
游戏逻辑方面,Cocos Cyberpunk包含完整的TPS游戏逻辑,init节点包含了特效、UI、对象池等节点,挂载的init.ts脚本组件确保游戏逻辑在主场景加载后持续运行。接下来,我们将对游戏逻辑相关源码进行深入解读。
UE4 LevelSequence源码剖析(一)
UE4的LevelSequence源码解析系列将分四部分探讨,本篇聚焦Runtime部分。Runtime代码主要位于UnrealEngine\Engine\Source\Runtime\MovieScene目录,结构上主要包括Channels、Evaluation、Sections和Tracks等核心模块。
ALevelSequenceActor是Runtime的核心,负责逐帧更新,它包含UMovieSceneSequence和ULevelSequencePlayer。ALevelSequenceActor独立于GameThread更新,并且在Actor和ActorComponent更新之前,确保其在RuntTickGroup之前执行。
IMovieScenePlaybackClient的关键接口用于绑定,编辑器通过IMovieSceneBindingOwnerInterface提供直观的蓝图绑定机制。UMovieSceneSequence是LevelSequence资源实例,它支持SpawnableObject和PossessableObject,便于控制对象的拥有和分离。
ULevelSequencePlayer作为播放控制器,由ALevelSequenceActor的Tick更新,具有指定对象在World和Sublevel中的功能,还包含用于时间控制的FMovieSceneTimeController。UMovieSceneTrack作为底层架构,由UMovieSceneSections组成,每个Section封装了Section的帧范围和对应Channel的数据。
序列的Eval过程涉及EvalTemplate和ExecutionTokens,它们协同工作模拟Track。FMovieSceneEvaluationTemplate定义了Track的模拟行为,而ExecutionTokens则是模拟过程中的最小单元。真正的模拟操作在FMovieSceneExecutionTokens的Apply函数中执行,通过BlendingAccumulator进行结果融合。
自定义UMovieSceneTrack需要定义自己的EvaluationTemplate,这部分将在编辑器拓展部分详细讲解。序列的Runtime部分展示了如何在GameThread中高效管理和模拟场景变化,为后续的解析奠定了基础。
游戏引擎随笔 0x:UE5 Lumen 源码解析(一)原理篇
Lumen 原理与核心组件介绍
实时全局光照(RTGI)一直是图形渲染领域的追求目标。UE5的Lumen是基于Epic的新一代游戏引擎开发的RTGI解决方案,它结合了SDF、Voxel Lighting、Radiosity等技术,并且支持软件和硬件光线追踪的混合使用。Lumen的复杂性在于其庞大的源码库,包含个Pass和众多文件,涉及RTGI技术的集成和优化。核心理念
Lumen聚焦于解决Indirect Lighting中的漫反射,利用粗粒度场景描述和非物理精确计算来达到实时性能。核心数学原理是渲染方程,通过Monte Carlo积分简化计算。加速结构与SDF Ray Marching
Ray Tracing依赖加速结构,但GPU并行计算有限。Lumen使用SDF的Ray Marching技术,特别是Mesh DF(距离场)和Global DF(全局距离场)来实现无需硬件支持的SWRT,分别用于短距离和长距离的光线追踪。Surface Cache与Radiance Cache
Surface Cache存储物体表面的材质属性,通过Cube Map简化获取。Radiance Cache则整合了直接光照信息,支持无限反弹全局光照。Lumen Scene与Screen Space Probe
Lumen的低精度粗粒度场景由SDF(Mesh)和Surface Cache(Material)构建,Screen Space Probe用于自适应放置并生成光照信息。Voxel Lighting与Radiosity Indirect Lighting
Voxel Lighting体素化相机周围空间,存储光照信息,通过Radiosity生成间接光照,弥补了Lumen单次Bounce的限制。World Space Probe与降噪
Word Space Probe提供更稳定的远距离光照,通过Clipmap优化性能。降噪策略包括Temporal\Spatial Filter和Importance Sampling。总结与流程
Lumen的Indirect Diffuse流程涉及多个步骤,包括Lumen Scene更新、Lighting以及Final Gather,其GPU端流程图展示了核心数据和操作。CesiumJS 源码杂谈 - 从光到 Uniform
CesiumJS 源码探索:光照与Uniform的转换之旅
CesiumJS 对光照的处理主要依赖于其底层API与WebGL着色器的交互。尽管它默认只支持一个太阳光,但通过DirectionalLight扩展,可模拟各种光照效果。光在CesiumJS中被转换为Uniform值,以统一的形式传递给着色器执行。
首先,CesiumJS的光照类型主要包括场景默认的太阳光和DirectionalLight,后者允许设定光照方向。例如,官方示例中的《Lighting》展示了如何运用DirectionalLight创建灯光效果。方向光多了一个方向属性,通常表示为单位向量。
在源码中,光照信息通过UniformState对象在每帧渲染时传递给Renderer。这个过程始于Scene.js模块的render函数,其中的uniformState会更新来自FrameState的光照参数。当Context对象执行DrawCommand时,ShaderProgram的_uniforms列表会填充来自uniformState的值,包括那些由AutomaticUniforms自动更新的,如光的属性。
光照Uniform在着色器中的应用十分广泛,如点云着色时使用czm_lightColor,冯氏着色法(Phong)材质通过czm_lightColor进行漫反射和高光计算,Globe.js则在GlobeFS片元着色器中使用czm_lightColor。在Model API的PBR着色法中,czm_lightColorHdr变量在光照阶段的计算中扮演重要角色。
总的来说,CesiumJS的光照系统通过Uniform的转换,确保光照信息在复杂渲染流程中的顺畅传递。然而,深入研究光照材质,特别是在自定义光照效果方面,仍需要进一步学习实时渲染(RealTimeRendering)的知识。
UE4-Slate源码学习(四)FSceneViewport
即视口是引擎中显示游戏画面的SWidget控件,也是编辑器中显示游戏内容的窗口。场景绘制视口(FSceneViewport)与SViewport绑定,用于场景渲染。鼠标捕获模式(EMouseCaptureMode)与鼠标锁定模式(EMouseLockMode)在项目设置中可配置,影响鼠标的交互。FSceneViewport事件处理包括鼠标按下(OnMouseButtonDown)、触摸开始(OnTouchStarted),事件响应后构造FReply,并更新几何体缓存、鼠标位置缓存。鼠标位置由绝对坐标转换为相对于视口的相对坐标。根据捕获状态和输入处理逻辑,事件最终被传递至PlayerController,通过PlayerInput管理。对于触摸输入,处理流程类似,调用InputTouch接口。
移动事件(OnMouseMove)、触摸移动(OnTouchMoved)记录鼠标的Delta和NumMouseSample累计值,Tick时处理。ProcessAccumulatedPointerInput在Tick阶段调用,处理键盘、鼠标输入,相关流程见第二章。完成输入处理后,FEngineLoop调用FinishedInputThisFrame,最终在ProcessAccumulatedPointerInput中调用InputAxis,处理至PlayerController的InputAxis,存储在PlayerInput中。其他事件如鼠标释放(OnMouseButtonUp)、触摸结束(OnTouchEnded)同样遵循类似流程。
若SWidget为视口,执行相关事件调用至ViewportClient接口,进而触发输入系统(PlayerController、PlayerInput、InputComponent)。日常游戏开发中,通过视口事件实现如旋转相机、隐藏鼠标等操作。PlayerController提供三种模式(FInputModeUIOnly、FInputModeGameAndUI、FInputModeGameOnly),通过调整SViewport和ViewportClient参数,实现不同模式下的捕获、锁定、显隐鼠标功能。所讨论内容基于UE4版本4..2。