EagleEngine与一个引擎

Number of views 143

写在前面

最近利用业余时间编写了自己的引擎,取名为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的实现细节,以及与其它引擎实现的不同点。

0 Answers