25.2.1
发布于:
今天下午好难过啊... 不该把感情全投入在一个地方的,不该自欺欺人 www ----------------- 在离开像素后我在写一个小小的个人项目,打算在春节前多完成一点(并且能有个勉勉强强的Demo 由于我即将给自己放个寒假并且下个星期就要开始一次长途旅行了, 所以... 我从2.2号会每天严格推进一部分内容,更新到这,作为打卡,直到2.7号 > 就算完不成也能证明自己做了点什么不是么.... ### 2.2 今天稍微推进了一下主线 --> pbr管线...这部分没什么可说的,堆工作量。 我打算用gltf当作渲染器的唯一模型交换格式,它官方支持pbr材质,并且另一个有意思的好处是GLTF支持骨骼和蒙皮动画(我这个项目打算重点关注的部分)。 但gltf严格来说不是模型格式,而是场景保存格式,因为它内部有层级结构,相机等信息...所以尽管有tiny_gltf这种库的存在,额外的工作还是必不可少的... 要支持gltf的hierarchy,自然又要去完善scene-graph部分。我打算把gltf的渲染封装成一个component挂在actor上,这就有点游戏引擎的样子了。 另一个小改动是资源系统支持自定义默认资源,这个改动会让debug少很多事情,同时对于texture资源系统实现了下默认资源,如果贴图加载不出来就会挂上一张亮紫色的贴图。 ### 2.3 继续推进PBR(为什么推进的这么慢呢?因为每天没多少时间呀qwq) 当然也不止有在处理这部分,之前的封装中有个遗留问题,就是UNIFORM_BUFFER_DYNAMIC和UNIFORM_BUFFER这俩东西如何区分。 在我的设想中,dynamicbuffer应该是对应于每帧都要更新的高频内存(比如物体的transform),用ringbuffer串起来,这样不用加barrier也能保证FIF之间不存在RAW,而uniformbuffer则是对于低频更新的物体,调用updatebuffer后会在前后埋下barrier,可能会造成gpu bubble但是不用每帧上传数据。 在vulkan实现中,uniform和dynamic uniform的区别就在于后者的绑定还需要再渲染的时候传入一个dynamic offset,而shader中是无区别的,于是我的反射创建descriptorset手段也失效了。当时我的做法是:如果这个uniform block的名字是以CBUFFER开头的,就把他当作一个uniform buffer,反之则是一个dynamic uniform buffer。这套机制没有怎么维护,今天细细的排查了一下,还好,没看出问题来。 我这封装了套比较simple的绑定机制,我觉得还挺不错的,大概是这样: 如果shader中有某个资源 ```layout(set = 2, binding = 2) uniform texture2D u_baseColorTex;``` 那就可以这样获取它的绑定位置: ```rs_binding_pos baseColTexBindingPos = RenderSystem::instance()->getBindingPos("u_baseColorTex", mainPassMaterial);``` 其中mainPassMaterial就是unity中的pass机制,一个物体的渲染可能由多个pass构成,而每个pass完全可以有不同的变量,比如阴影pass中我可能有衰减参数,而colorpass中就没有,通过这种方法可以获取不同pass的不同参数的绑定位置。 至于绑定就更加简单了,只需要这样: ``` renderSys->updateUniform(baseColTexBindingPos, mBaseColorTex->getRsImage(), mainPass ); ``` 这里的mainPass是这个renderable在main camera pass下特定的渲染资源,可以简单的理解为里面包含了了对应于这个pass的descriptorSets 这部分我一直想改一下,改成只要传入pass名字就好了,renderable会自己去查找对应的pass的资源,有则设置,没有则创建。(PS:得益于一些方法,字符串的比较在我这里是非常轻量的操作) ### 2.4 今日好困,明天继续把qwq ### 2.5,2.6 这两天在改材质 我之前一直都是shader+pass+renderable = 一次渲染,参数由如上所属,是通过renderable或者外部的其他人绑定的,这就导致参数的来源不太统一,导致不好序列化;而且没有材质这部分,也会导致相同的资源被重复存放,导致显存过高... 这点是我在做gltf 的material部分突然想起来的... 我还没想好材质系统改怎么设计接口,但总归来说也就:设置参数,绑定参数。而我比较纠结的是对于uniform block这种结构体应该怎么做。我个人是想做可以完全反射出来的材质,以便于未来做Editor,但是这东西 !并!不!现!实,所以只好退而求其次,要做成没那么自动的材质系统了,哭 今晚有个朋友邀我同去加格达奇,说是想看看零下三十度的老林子,但是我已经有别的规划啦...好可惜。我以前一直以为离开北京前的倒数第二站会是这个名字颇有异域风情的小地方,没想到最后还是食盐了...今年一定要去一趟呢 BTW,这个项目的计划延期,慢慢做咯... ## 2.12 在高原蹦跶了这么久,终于有落脚点了!继续开始造 材质系统也就这样了,同时把之前遗留的一些问题改了。 把Material和Shader在我这里都统一为了资源,变成资源的好处就是不用再担心生命周期的管理了。 幸好之前的资源系统做的比较扎实。 比如我想获取一个Material,在我这的资源系统写法就是: ```cpp material = ResourceSystem::instance()->getResource<Material>(ResourceName::Material, Name("NormalMaterial")); ``` 资源管理器会返回一个资源的handler,引用计数,不用担心生命周期 用户可能需要自己继承这个类,然后对uniformblock内部的参数自己写接口....比较抽象的说,但总体是这样: 假如我要写一个水的材质“WaterMaterial”,Shader需要波信息,就叫他"WaveInfo" ```cpp struct WaveInfo{ vec4 waveCenter; float Amplitude }; ``` 假设在cpp和shader代码层面两边是一样的,并且Memory layout也一样,那么就能在创建的WaterMaterial类中建立几个接口: ```cpp setAmplitude(float v); setwaveCenter(vector4 v); ``` 用这些接口修改数据,并且在每次绑定之前上传Data。 这么做的直接原因是我不想把接口体里的字段反射出来...感觉不太对劲,所以只能用户动手啦~ 修了几吨的bug 好爽,离完成预定目标又近了千分之一呢 ## 2.13 今天主要在修编译问题,继续推进gltf转为引擎scene node的进度 同时 资源化了Sampler。 sampler不资源化总觉得很拧巴,忘记在哪看到vk的sampler有创建上限,而且本身也是个重复度很高的资源,所以这么做收益大大的有。