新的起点
好久不见。 上次更新已经是一个多月之前了,技术博客也断了一段时间。 最近这段时间确实是比较忙,今年4月份的时候,我由于工作上的调动,从后端开发又被调整到了安卓应用开发的岗位。连续两年被调整到新的技术栈的工作岗位,需要从头学习,本身对我职业发展来说就是一个很大的问题。我一开始还是尝试着去接受这个变动,在经历了一段时间,体会了新的部门的工作管理流程以及一些项目交付后,我觉得这个新的岗位实在是不适合我。 因此,之前的一个月的时间,除了要学习新知识、hold住新工作,我的剩余时间都是在寻找新的工作机会。最终,找到了一个中型游戏公司的资深UE开发岗位。 所以,很开心的说,我在八月份就能够回到热爱的游戏行业了,回到自己所擅长的地方。在现公司工作了将近1000天(离职的时候应该是刚好1000天),我从一开始的能在未来重点项目发挥自己的能力,到项目被砍只能做一个无关紧要的项目,到这个项目被砍无奈转型,到最后两年内第二次转技术栈,真的是有点心力交瘁了。 希望在新的游戏岗位上,能够实现自己的价值,我也会继续持续更新这个博客,可能会更多的讲一些关于我们项目的事情了,敬请期待。
记一个关于外接显示器接口的乌龙
今天发生了一个让我又好气又好笑的乌龙。 周六一大早起来,在B站上看到一个关于地形的shader优化方法,感觉很有意思。于是乎放弃了打游戏的计划,想把这个技术在KongEngine上实现一下。 我的KongEngine现在有两个主要的分支,一个是主分支master,是一个比较稳定了的主要基于OpenGL的分支,实现了不少的渲染效果;另外一个是vulkan_support分支,这个分支主要是用来接入vulkan的功能的,目前还没完全将OpenGL的效果移植过来。我目前主要的工作分支是在vulkan_support上。 我的地形效果是放在master分支的,所以自然我需要切回到master分支。但是当我切回去并且编译之后,出现了一个令我出乎意料的报错。 嗯?什么情况? 这段代码是我之前处理shader间的引用的,利用了GLAD_GL_ARB_shading_language_include的拓展。已经很久没改过这里的代码了,怎么突然就出错了呢? 我第一反应是我的shader是不是之前改过,所以引用路径错了。但是查了好几遍,包括回退以前可用的版本,也解决不了这个问题,所以大概率和这个没...
虚幻引擎的Shader课堂之Material Expression
前言 在上一章的内容我们大致介绍了一下虚幻引擎Global Shader的相关内容,按照计划来说,接下来就是Material Shader了。不过由于最近工作比较忙,没有时间来好好整理Material Shader的内容,并且Material Shader在本系列也是比较重要的一个知识点,所以为了能把它讲清楚,我决定还是将这篇文章推迟。 因此今天我会先来介绍一个和Material Shader比较相关的概念,就是Material Expression。 Material Expression是一个非常重要的部分,它可以让我们在材质编辑器中创建一个自定义的材质节点,来实现各种各样的计算,影响最终的渲染效果。Material Shader很多时候也是通过Material Expression来应用在渲染流程中的。所以,理解Material Expression的基本概念和用法,对于掌握Material Shader的实现也非常重要。 另外这里要提一嘴的就是,本次教程所基于的引擎版本为5.5,若是有些示例代码或者方法不生效可能是版本不一致导致的,但是概念应该基本相通,可以作为参考。 M...
虚幻引擎的Shader课堂之Global Shader
前言 在上一篇关于虚幻引擎SceneViewExtension的介绍里面简单的提到了一些关于UE中的Shader的一些介绍。由于那篇文章的重点是关于SceneViewExtensionTemplate的,所以并没有将Shader这部分内容展开和整理起来。 现在回想起来,觉得如果需要对UE的渲染流程做自定义的话,弄清楚UE的不同的shader的类型,以及各自的用法还是非常有必要的,因此打算开一个系列的文章,讲讲虚幻引擎的Shader。 相比较Unity对自定义shader的开发,UE从设计上其实更鼓励使用者通过可视化节点工具来实现自定义的渲染效果,可能和UE设计上的目标人群很多是设计师和影视行业从业者等非技术人员有关。因此,在UE中实现自定义Shader开发确实存在一定门槛,不过只要稍微了解核心逻辑并辅以实践,依然是可行的。也希望这个系列内容能为读者提供具体的思路与帮助,让复杂的技术变得更易上手。 第一篇,我会先介绍一下Global Shader。 Global Shader是什么 Global Shader是UE中一类不依赖具体材质或游戏对象的着色器,它可以用来处理全局场景相关的...
虚幻引擎之浅谈SceneViewExtension
前言 我们都知道虚幻引擎是一个非常强大且使用广泛的商业引擎,在虚幻引擎的强大的渲染能力加持下,只要有质量足够好的模型,一个新手都可以得到非常逼真的渲染场景。 但是如果你是一个图形开发工程师,在虚幻引擎中定制自己的渲染过程是非常麻烦的,很有可能涉及到修改虚幻引擎的源代码,那这样一个很简单的修改调试起来都会非常的麻烦。(想起来之前做UE项目的时候,只要有引擎相关的代码更新,我们本地编译基本上就是2、3个小时起了,基本上干不了活。) 在这方面Unity的URP的灵活性就要好很多,也许是引擎的设计理念不同,Unity的可能更多的是面向技术人员,需要有更多的图形学技术能力以及自定义能力;而虚幻引擎可能更多的面向美术和设计人员,更多的是使用蓝图来实现多样的效果,提供统一且强大的渲染管线。 在虚幻引擎4.12版本中,Epic引入了SceneViewExtension,它为开发者提供了一种在场景渲染过程中插入自定义渲染逻辑的方式,通过它可以实现很多自定义渲染效果,比如后处理效果、自定义的调试信息显示等。这种机制允许开发者在不直接修改引擎核心渲染代码的前提下,扩展和定制渲染流程。 在网上Scene...
vulkan阴影贴图实践总结
前言 好了,继续我们的Vulkan之旅。 在上一次Vulkan相关的文章中,我们利用subpass实现了延迟渲染的流程。 延迟渲染实现之后,下一步当然是实现阴影了,缺少了阴影的场景看起来还是差点意思。于是乎我自然而然的计划将阴影贴图的实现提上日程。 阴影贴图的原理我这里就不再多介绍了,和OpenGL的实现原理是一致的。我们之前的文章也有介绍过阴影贴图的各种延展应用,比如说CSM(级联阴影贴图)和rsm(反射阴影贴图)。 本来想着的是我都实现过几次阴影贴图了,那这次Vulkan的接入也应该很快才对,结果由于各种各样的生活和工作的事件影响,再加上Vulkan上面有许多的细节需要调整,导致这个效果拖了大半个月才算弄好。 这篇文章简单记录一下我实现过程中踩的各种坑。 Vulkan实现阴影贴图过程中踩的坑 准备深度纹理 在准备深度纹理上就有不少细节需要关注。 VkImageCreateInfo.Usage 首先在创建深度纹理的时候,VkImageCreateInfo中的Usage需要添加采样的Flag位。这一位在延迟渲染和天空盒等没有直接对深度纹理采样的过程中是不需要添加的,只有Colo...
虚幻引擎之Android环境配置
前言 最近工作又出现了变动,去年我这个快十年游戏客户端和引擎开发经验的被调去做AI后端,迷茫了一年后今年又要被调去做安卓Native C++开发了,真的是这两年转的方向比我原来工作七八年的时间都要多。 不过至少安卓Native C++开发比后端开发更加贴合我的工作了,说不定也是件好事。周末闲来无事,想着我好像从来没有自己构建过UE的安卓工程,打算来走走这个流程。 构建安卓环境 Android Studio 要构建安卓包,首先需要下载Android Studio,在官网下载后安装即可。 安装完运行Android studio,第一次打开会做Studio的初始化,需要安装一些默认的组件,选择需要的(一般是提示的都选了)的后等待下载安装完成即可。 然后我们会进到Android Studio的欢迎界面,由于我们一般不用Android Studio来开发UE的工程,这里我们不打开我们的C++代码目录,而是直接打开More Actions->SDK Manager,在弹出来的设置界面中,选择SDK Tools,勾选NDK(Side by side)和Android SDK Comma...
Vulkan中利用subpass实现延迟渲染
前言 这又是一张平平无奇的渲染图,和上一篇文章的那张图片好像也没什么区别。从表面上看是的,在渲染效果上这张图片没有什么进步,但是这张图片是用了另外的技术实现的,也就是延迟渲染。 延迟渲染这个概念在网上有很多的资料,我也在我之前的一篇文章介绍过,所以这篇文章我不会再对延迟渲染的概念做介绍。今天这篇文章的主要内容,是如何在Vulkan中实现这个效果。 在Vulkan中实现延迟渲染 当然,延迟渲染的原理是一样的,无论是用Vulkan还是OpenGL,大概分为两个步骤: 几何阶段和光照阶段。在几何阶段搜集画面中用于光照计算的信息。 传输到光照阶段计算出最终的结果。 既然Vulkan和OpenGL实现是差不多的,为什么这里还有专门写一篇文章呢?因为在Vulkan中,可以利用RenderPass中的subpass,来将两个步骤放到同一个render pass中,这样可以减少延迟渲染两个阶段之间的额外数据处理和传输,从而提升性能。 Vulkan中的Render Pass和Subpass 在Vulkan里,Render Pass(渲染过程)是一个十分关键的概念,它对渲染操作的整体结构和流程...
Vulkan接入小总结
前言 这是一张平平无奇的渲染图,没有阴影,没有IBL,也没有反射等各种酷炫高大上的效果。 但这张平平无奇的渲染图是我断断续续花了一个月的时间才完成的结果:这是KongEngine接入Vulkan后得到的最新效果。在前面的几篇文章我也提到过,我最近一直在处理这个事,为此我将KongEngine的渲染代码重构,并将Vulkan整合进来。当然原有的OpenGL能力我还是保留着,目前的目标是先利用Vulkan还原原有的OpenGL效果。 这篇文章也不是什么Vulkan入门教程,不会系统的讲Vulkan的初始化流程是怎么样的,Render Pass和Pipeline是什么,DescriptorSet要怎么设定等等。这些内容太复杂了,很难在一篇文章内讲清楚,况且我现在也不能说是很精通。这篇文章只是会大概介绍一下KongEngine目前的Vulkan结构。 KongEngine的Vulkan结构 如下图所示: KongEngine目前将图形API的部分整合了起来,封装成了OpenGL部分和Vulkan的部分。目前这两个部分的流程还是有一定的区别,本来按照原有计划是将OpenGL的渲染流程按...
基于图像的光照-镜面反射
前言 上一篇文章介绍了IBL的漫反射部分,接下来这篇文章关注的是镜面反射的部分,也就是拆分方程的后面部分。 分割求和近似法 我们回到反射方程的镜面反射部分: $$L_o(p, \omega_o) = \int_{\Omega} \left(\frac{k_s DFG}{4(\omega_o \cdot \mathbf{n})(\omega_i \cdot \mathbf{n})}\right) L_i(p, \omega_i) \mathbf{n} \cdot \omega_i , d\omega_i$$ 我们发现这个积分的结果在积分上不是常数,他受入射光和观察视角两个因素影响。如果对所有入射光方向和所有可能的视角方向做积分,这个计算消耗十分昂贵,是没有办法这么做的。 为了解决这个问题,Epic Games提出了一个解决方案,叫做分割求和近似法。它将方程的镜面部分分割成了两个独立的部分,分别对这两个部分求卷积,并在PBR着色器重求和,用于IBL的镜面反射部分。 分割求和近似法包含两部分: 预过滤环境贴图:对不同粗糙度的环境光进行卷积,存储为mipmap层级的立方体贴图。 BR...












