写在前面
最近利用业余时间编写了自己的引擎,取名为EagleEngine,不用把这个引擎翻译的太高大上,鹰引擎?错啦,它其实就翻译为"一个引擎", 哈哈!目前已经完成了vulkan的gfx后端与RenderPipeline层的RenderGraph逻辑,可以跨平台运行在Windows,Android,MacOS以及IOS,未来会支持WebGL/WebGPU。其它平台暂时不会支持,真正想法是移动端与Web端优先,写引擎不是为了真的哪天能商用,不敢想,仅仅是为了方便共享一些渲染的实现细节,方便一起学习,也方便自己加深理解,另外也有代码参考,方便大家下载。
很多文章会手把手搭建引擎,但是不太适合我个人,一方面引擎技术很庞杂,平时业余时间都很少,更何况还要边写引擎边共享文章,其实写技术类文章很费时,要达到尽可能完美更是难上加难,能坚持写完的人我是很佩服的。所以我会在完善引擎的过程中挑重点来作为自己的笔记来记录,在这基础上希望也能对感兴趣的朋友有帮助。下面是引擎的Github地址,有时间了帮忙点个Star哈,感兴趣的伙伴也可以一起提交些代码:
EagleEngine的GitHub地址****github.com/GengineJS/EagleEngine
大致架构
目前只完成了RENDER PIPELINE层的RenderGraph逻辑与GRAPHICS层的Vulkan API,后面会持续添加WebGPU的GFX代码,在完成FRAME LAYER层的大体逻辑后,会同步RENDER PIPELINE层的SceneCulling逻辑。
APPLICATION(应用层):Application是可以让用户直接修改渲染逻辑的层级,目前的逻辑代码如下,以"后处理"逻辑为例:
#include <EagleApplication.h>
// vertex data
const std::vector<Vertex> vertices{
{ { 1.0f, 1.0f, 0.0f }, { 1.0f, 0.0f, 0.0f }, {1.f, 0.f} },
{ { 0.0f, -1.0f, 0.0f }, { 0.0f, 0.0f, 1.0f }, {0.5f, 1.f} },
{ { -1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, {0.f, 0.f} },
};
// index data
const std::vector<uint32_t> indices{
0, 1, 2
};
struct {
glm::mat4 projectionMatrix{glm::mat4(1.0f)};
glm::mat4 modelMatrix{ glm::mat4(1.0f) };
glm::mat4 viewMatrix{ glm::mat4(1.0f) };
} uboVS;
std::shared_ptr<Buffer> uboBuff{ nullptr };
//the app entry point
std::shared_ptr<EagleRenderer> EagleSetup() {
// 应用的配置信息对象
ContextInfo info{};
// 应用名称
info.applicationName = "Blur";
// 应用的版本
info.applicationVersion = 1.12f;
// 是否启用imgui
info.guiOverlay = false;
// 创建EagleRenderer对象
auto renderer = std::make_shared<EagleRenderer>(info);
// 获取renderpipeline对象
auto pipeline = renderer->getRenderPipeline();
// 获取renderGraph对象
auto renderGraph = pipeline->getRenderGraph();
// 监听引擎的OnStart事件
renderer->once(EagleRenderer::ON_START, [&](EagleRenderer* render) {
auto device = render->getContext()->getDevice();
// 配置UniformBuffer信息
BufferInfo buff(sizeof(uboVS),
0,
BufferUsageFlag::UNIFORM,
MemoryPropertyFlag::HOST_COHERENT | MemoryPropertyFlag::HOST_VISIBLE);
// 创建UniformBuffer
uboBuff = device->createBuffer(buff);
uboBuff->update(&uboVS);
});
// 开始录制RenderGraph
renderGraph->beginFrame();
// 定义resource texture名称
std::string texName = "TriangleTex";
// 添加resource texture以及GraphPass
auto sourcePass = renderGraph->addColorTexture(texName, Format::B8G8R8A8_UNORM, info.width, info.height)
->addGraphPass("SourcePass", [&](std::shared_ptr<RenderVisitor> visitor) {//
// 设置着色器信息
visitor->setShaderDesc(FileUtils::getShadersPath()
+ "blur/triangle.vert.spv", FileUtils::getShadersPath()
+ "blur/triangle.frag.spv");
// 绑定idx与vert buffer
visitor->bindVertex(indices, vertices);
// 绑定ubobuff, {set, binding}
visitor->bindBuffer({0, 0}, uboBuff);
// 开始绘制
visitor->draw();
});
// 把resourceTexture注册为sourcePass的输出texture
sourcePass->addRenderTexture(texName, AccessState::WRITE);
ShaderDesc shaderDesc{};
shaderDesc.add(FileUtils::getShadersPath()
+ "blur/blur.vert.spv", ShaderStageFlag::VERTEX);
shaderDesc.add(FileUtils::getShadersPath()
+ "blur/blur.frag.spv", ShaderStageFlag::FRAGMENT);
// 添加上屏Pass
renderGraph->addScreenPass("OnScreen", texName, shaderDesc, {0, 1});
// 结束render graph录制
renderGraph->endFrame();
return renderer;
}
EAGLE_MAIN();
EagleSetup是EagleEngine的入口函数,该入口函数需要返回EagleRenderer对象,该对象配置了引擎渲染的所有信息。
FRAME LAYER(框架层)
:Frame Layer目前正在实现,主要是场景数据的组织,包括节点,组件(是否采用ECS还没确定),模型数据,材质数据等。RENDER PIPELINE
: 管线层会对FrameLayer层组织的数据进行管理与提交,包括场景剔除,后处理等。GRAPHICS
: Graphics即是GFX,这一层会对各渲染Api进行抽象,目前以Vulkan Api的接口为标准。
上述是EagleEngine的简单介绍,会新开一篇描述下RenderGraph的实现细节,以及与其它引擎实现的不同点。