Begin transition to new render target system
Things are definitely broken now
This commit is contained in:
parent
e8fc757d99
commit
a6a46abb36
20 changed files with 390 additions and 596 deletions
|
@ -19,6 +19,7 @@ class App;
|
|||
class Scene;
|
||||
class Input;
|
||||
class Renderer;
|
||||
class RenderTarget;
|
||||
class Physics;
|
||||
class ImGuiLayer;
|
||||
struct Timer;
|
||||
|
@ -115,7 +116,7 @@ public:
|
|||
@param index Index of the window. Default is 0.
|
||||
@return Instance of the renderer. Will not be null.
|
||||
*/
|
||||
Renderer* get_renderer(const int index = 0);
|
||||
Renderer* get_renderer();
|
||||
|
||||
/** Get the physics system.
|
||||
@return Instance of the physics system. Will not be null.
|
||||
|
@ -340,7 +341,7 @@ private:
|
|||
prism::Extent extent;
|
||||
bool quitRequested = false;
|
||||
|
||||
std::unique_ptr<Renderer> renderer;
|
||||
RenderTarget* render_target;
|
||||
};
|
||||
|
||||
std::vector<Window> _windows;
|
||||
|
@ -368,6 +369,7 @@ private:
|
|||
|
||||
std::unique_ptr<Input> _input;
|
||||
std::unique_ptr<Physics> _physics;
|
||||
std::unique_ptr<Renderer> _renderer;
|
||||
|
||||
std::vector<Timer*> _timers, _timersToRemove;
|
||||
|
||||
|
|
|
@ -126,7 +126,7 @@ void draw_renderer() {
|
|||
float render_scale = render_options.render_scale;
|
||||
if(ImGui::DragFloat("Render Scale", &render_scale, 0.1f, 1.0f, 0.1f) && render_scale > 0.0f) {
|
||||
render_options.render_scale = render_scale;
|
||||
engine->get_renderer()->resize(engine->get_renderer()->get_extent());
|
||||
engine->get_renderer()->recreate_all_render_targets();
|
||||
}
|
||||
|
||||
if(ImGui::InputInt("Shadow Resolution", &render_options.shadow_resolution)) {
|
||||
|
|
|
@ -107,8 +107,8 @@ Input* Engine::get_input() {
|
|||
return _input.get();
|
||||
}
|
||||
|
||||
Renderer* Engine::get_renderer(const int index) {
|
||||
return _windows[index].renderer.get();
|
||||
Renderer* Engine::get_renderer() {
|
||||
return _renderer.get();
|
||||
}
|
||||
|
||||
Physics* Engine::get_physics() {
|
||||
|
@ -406,6 +406,10 @@ void Engine::add_window(void* native_handle, const int identifier, const prism::
|
|||
Expects(native_handle != nullptr);
|
||||
Expects(identifier >= 0);
|
||||
|
||||
if(identifier == 0) {
|
||||
_renderer = std::make_unique<Renderer>(_gfx);
|
||||
}
|
||||
|
||||
const auto drawable_extent = platform::get_window_drawable_size(identifier);
|
||||
|
||||
_gfx->initialize_view(native_handle, identifier, drawable_extent.width, drawable_extent.height);
|
||||
|
@ -413,9 +417,7 @@ void Engine::add_window(void* native_handle, const int identifier, const prism::
|
|||
Window& window = _windows.emplace_back();
|
||||
window.identifier = identifier;
|
||||
window.extent = extent;
|
||||
window.renderer = std::make_unique<Renderer>(_gfx);
|
||||
|
||||
window.renderer->resize(drawable_extent);
|
||||
window.render_target = _renderer->allocate_render_target(drawable_extent);
|
||||
|
||||
render_ready = true;
|
||||
}
|
||||
|
@ -440,7 +442,7 @@ void Engine::resize(const int identifier, const prism::Extent extent) {
|
|||
const auto drawable_extent = platform::get_window_drawable_size(identifier);
|
||||
|
||||
_gfx->recreate_view(identifier, drawable_extent.width, drawable_extent.height);
|
||||
window->renderer->resize(drawable_extent);
|
||||
_renderer->resize_render_target(*window->render_target, drawable_extent);
|
||||
|
||||
if(identifier == 0) {
|
||||
if(_current_screen != nullptr) {
|
||||
|
@ -752,7 +754,7 @@ void Engine::render(const int index) {
|
|||
|
||||
if(index == 0) {
|
||||
if(_current_screen != nullptr && _current_screen->view_changed) {
|
||||
_windows[0].renderer->update_screen();
|
||||
_renderer->update_screen();
|
||||
_current_screen->view_changed = false;
|
||||
}
|
||||
|
||||
|
@ -763,8 +765,8 @@ void Engine::render(const int index) {
|
|||
|
||||
_app->render(commandbuffer);
|
||||
|
||||
if(window->renderer != nullptr)
|
||||
window->renderer->render(commandbuffer, _current_scene, index);
|
||||
if(_renderer != nullptr)
|
||||
_renderer->render(commandbuffer, _current_scene, *window->render_target, index);
|
||||
|
||||
_gfx->submit(commandbuffer, index);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ set(SRC
|
|||
include/renderer.hpp
|
||||
include/font.hpp
|
||||
include/pass.hpp
|
||||
include/gaussianhelper.hpp
|
||||
include/shadowpass.hpp
|
||||
include/imguipass.hpp
|
||||
include/smaapass.hpp
|
||||
|
@ -11,9 +10,9 @@ set(SRC
|
|||
include/dofpass.hpp
|
||||
include/frustum.hpp
|
||||
include/render_options.hpp
|
||||
include/rendertarget.hpp
|
||||
|
||||
src/renderer.cpp
|
||||
src/gaussianhelper.cpp
|
||||
src/shadowpass.cpp
|
||||
src/imguipass.cpp
|
||||
src/smaapass.cpp
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
class GFX;
|
||||
class GFXCommandBuffer;
|
||||
class GFXFramebuffer;
|
||||
class GFXPipeline;
|
||||
class GFXRenderPass;
|
||||
class GFXTexture;
|
||||
|
||||
class GaussianHelper {
|
||||
public:
|
||||
GaussianHelper(GFX* gfx, const prism::Extent extent);
|
||||
|
||||
GFXTexture* render(GFXCommandBuffer* commandBuffer,GFXTexture* source);
|
||||
|
||||
GFXPipeline* pipeline = nullptr;
|
||||
|
||||
GFXRenderPass* renderPass = nullptr;
|
||||
|
||||
GFXTexture* texA = nullptr, *texB = nullptr;
|
||||
GFXFramebuffer* fboA = nullptr, *fboB = nullptr;
|
||||
|
||||
private:
|
||||
prism::Extent extent;
|
||||
};
|
|
@ -11,6 +11,7 @@
|
|||
#include "render_options.hpp"
|
||||
#include "path.hpp"
|
||||
#include "shadercompiler.hpp"
|
||||
#include "rendertarget.hpp"
|
||||
|
||||
namespace ui {
|
||||
class Screen;
|
||||
|
@ -46,34 +47,22 @@ class Renderer {
|
|||
public:
|
||||
Renderer(GFX* gfx, const bool enable_imgui = true);
|
||||
~Renderer();
|
||||
|
||||
void resize(const prism::Extent extent);
|
||||
void resize_viewport(const prism::Extent extent);
|
||||
|
||||
|
||||
RenderTarget* allocate_render_target(const prism::Extent extent);
|
||||
void resize_render_target(RenderTarget& target, const prism::Extent extent);
|
||||
void recreate_all_render_targets();
|
||||
|
||||
void set_screen(ui::Screen* screen);
|
||||
void init_screen(ui::Screen* screen);
|
||||
void update_screen();
|
||||
|
||||
void startCrossfade();
|
||||
void startSceneBlur();
|
||||
void stopSceneBlur();
|
||||
|
||||
float fade = 0.0f;
|
||||
bool fading = false;
|
||||
|
||||
bool blurring = false;
|
||||
bool hasToStore = true;
|
||||
int blurFrame = 0;
|
||||
|
||||
GFXTexture* blurStore = nullptr;
|
||||
|
||||
struct ControllerContinuity {
|
||||
int elementOffset = 0;
|
||||
};
|
||||
|
||||
void render(GFXCommandBuffer* command_buffer, Scene* scene, int index);
|
||||
void render(GFXCommandBuffer* command_buffer, Scene* scene, RenderTarget& target, int index);
|
||||
|
||||
void render_screen(GFXCommandBuffer* commandBuffer, ui::Screen* screen, ControllerContinuity& continuity, RenderScreenOptions options = RenderScreenOptions());
|
||||
void render_screen(GFXCommandBuffer* commandBuffer, ui::Screen* screen, prism::Extent extent, ControllerContinuity& continuity, RenderScreenOptions options = RenderScreenOptions());
|
||||
void render_camera(GFXCommandBuffer* command_buffer, Scene& scene, Object camera_object, Camera& camera, prism::Extent extent, ControllerContinuity& continuity);
|
||||
|
||||
void create_mesh_pipeline(Material& material);
|
||||
|
@ -96,31 +85,8 @@ public:
|
|||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GFXRenderPass* getOffscreenRenderPass() const {
|
||||
return offscreenRenderPass;
|
||||
}
|
||||
|
||||
GFXTexture* offscreenColorTexture = nullptr;
|
||||
GFXTexture* offscreenDepthTexture = nullptr;
|
||||
|
||||
GFXTexture* viewportColorTexture = nullptr;
|
||||
|
||||
bool viewport_mode = false;
|
||||
prism::Extent viewport_extent;
|
||||
|
||||
bool gui_only_mode = false;
|
||||
|
||||
prism::Extent get_extent() const {
|
||||
return viewport_mode ? viewport_extent : extent;
|
||||
}
|
||||
|
||||
prism::Extent get_render_extent() const {
|
||||
const auto extent = get_extent();
|
||||
|
||||
return {static_cast<uint32_t>(std::max(int(extent.width * render_options.render_scale), 1)),
|
||||
static_cast<uint32_t>(std::max(int(extent.height * render_options.render_scale), 1))};
|
||||
}
|
||||
GFXRenderPass* offscreenRenderPass = nullptr;
|
||||
|
||||
std::unique_ptr<ShadowPass> shadow_pass;
|
||||
std::unique_ptr<SceneCapture> scene_capture;
|
||||
|
@ -146,28 +112,21 @@ public:
|
|||
|
||||
private:
|
||||
void createDummyTexture();
|
||||
void createOffscreenResources();
|
||||
void create_render_target_resources(RenderTarget& target);
|
||||
void createMeshPipeline();
|
||||
void createPostPipeline();
|
||||
void createFontPipeline();
|
||||
void createSkyPipeline();
|
||||
void createUIPipeline();
|
||||
void createGaussianResources();
|
||||
void createBRDF();
|
||||
void create_histogram_resources();
|
||||
|
||||
GFX* gfx = nullptr;
|
||||
prism::Extent extent;
|
||||
|
||||
std::vector<std::unique_ptr<RenderTarget>> render_targets;
|
||||
|
||||
ui::Screen* current_screen = nullptr;
|
||||
|
||||
// offscreen
|
||||
GFXTexture* offscreenBackTexture = nullptr;
|
||||
GFXFramebuffer* offscreenFramebuffer = nullptr;
|
||||
GFXRenderPass* offscreenRenderPass = nullptr;
|
||||
|
||||
GFXFramebuffer* viewportFramebuffer = nullptr;
|
||||
|
||||
// mesh
|
||||
GFXBuffer* sceneBuffer = nullptr;
|
||||
|
||||
|
@ -199,10 +158,7 @@ private:
|
|||
GFXTexture* average_luminance_texture = nullptr;
|
||||
|
||||
std::unique_ptr<SMAAPass> smaaPass;
|
||||
std::unique_ptr<GaussianHelper> gHelper;
|
||||
std::unique_ptr<DoFPass> dofPass;
|
||||
|
||||
std::vector<std::unique_ptr<Pass>> passes;
|
||||
|
||||
double current_render_scale = 1.0;
|
||||
};
|
||||
|
|
30
engine/renderer/include/rendertarget.hpp
Executable file
30
engine/renderer/include/rendertarget.hpp
Executable file
|
@ -0,0 +1,30 @@
|
|||
#pragma once
|
||||
|
||||
#include "common.hpp"
|
||||
#include "render_options.hpp"
|
||||
|
||||
class GFXTexture;
|
||||
class GFXFramebuffer;
|
||||
|
||||
class RenderTarget {
|
||||
public:
|
||||
prism::Extent extent;
|
||||
|
||||
prism::Extent get_render_extent() const {
|
||||
return {static_cast<uint32_t>(std::max(int(extent.width * render_options.render_scale), 1)),
|
||||
static_cast<uint32_t>(std::max(int(extent.height * render_options.render_scale), 1))};
|
||||
}
|
||||
|
||||
// offscreen
|
||||
GFXTexture* offscreenColorTexture = nullptr;
|
||||
GFXTexture* offscreenDepthTexture = nullptr;
|
||||
|
||||
GFXFramebuffer* offscreenFramebuffer = nullptr;
|
||||
|
||||
// smaa
|
||||
GFXTexture* edge_texture = nullptr;
|
||||
GFXTexture* blend_texture = nullptr;
|
||||
|
||||
GFXFramebuffer* edge_framebuffer = nullptr;
|
||||
GFXFramebuffer* blend_framebuffer = nullptr;
|
||||
};
|
|
@ -10,23 +10,21 @@ class GFXPipeline;
|
|||
class GFXRenderPass;
|
||||
class GFXTexture;
|
||||
class Renderer;
|
||||
class RenderTarget;
|
||||
|
||||
class SMAAPass {
|
||||
public:
|
||||
SMAAPass(GFX* gfx, Renderer* renderer);
|
||||
|
||||
void render(GFXCommandBuffer* command_buffer);
|
||||
void create_render_target_resources(RenderTarget& target);
|
||||
|
||||
GFXTexture* edge_texture = nullptr;
|
||||
GFXTexture* blend_texture = nullptr;
|
||||
void render(GFXCommandBuffer* command_buffer, RenderTarget& target);
|
||||
|
||||
private:
|
||||
void create_textures();
|
||||
void create_render_pass();
|
||||
void create_pipelines();
|
||||
void create_offscreen_resources();
|
||||
|
||||
prism::Extent extent;
|
||||
Renderer* renderer = nullptr;
|
||||
|
||||
GFXTexture* area_image = nullptr;
|
||||
|
@ -36,8 +34,4 @@ private:
|
|||
|
||||
GFXPipeline* edge_pipeline = nullptr;
|
||||
GFXPipeline* blend_pipeline = nullptr;
|
||||
|
||||
GFXFramebuffer* edge_framebuffer = nullptr;
|
||||
|
||||
GFXFramebuffer* blend_framebuffer = nullptr;
|
||||
};
|
||||
|
|
|
@ -17,7 +17,8 @@ DoFPass::DoFPass(GFX* gfx, Renderer* renderer) : renderer(renderer) {
|
|||
|
||||
renderpass = gfx->create_render_pass(renderPassInfo);
|
||||
|
||||
const auto extent = renderer->get_render_extent();
|
||||
//const auto extent = renderer->get_render_extent();
|
||||
const auto extent = prism::Extent();
|
||||
|
||||
GFXShaderConstant width_constant = {};
|
||||
width_constant.value = extent.width;
|
||||
|
@ -77,7 +78,9 @@ DoFPass::DoFPass(GFX* gfx, Renderer* renderer) : renderer(renderer) {
|
|||
}
|
||||
|
||||
void DoFPass::render(GFXCommandBuffer* command_buffer, Scene&) {
|
||||
const auto render_extent = renderer->get_render_extent();
|
||||
//const auto render_extent = renderer->get_render_extent();
|
||||
const auto extent = prism::Extent();
|
||||
const auto render_extent = prism::Extent();
|
||||
|
||||
// render far field
|
||||
GFXRenderPassBeginInfo beginInfo = {};
|
||||
|
@ -94,11 +97,11 @@ void DoFPass::render(GFXCommandBuffer* command_buffer, Scene&) {
|
|||
|
||||
command_buffer->set_graphics_pipeline(pipeline);
|
||||
|
||||
command_buffer->bind_texture(renderer->offscreenColorTexture, 0);
|
||||
command_buffer->bind_texture(renderer->offscreenDepthTexture, 1);
|
||||
//command_buffer->bind_texture(renderer->offscreenColorTexture, 0);
|
||||
//command_buffer->bind_texture(renderer->offscreenDepthTexture, 1);
|
||||
command_buffer->bind_texture(aperture_texture->handle, 3);
|
||||
|
||||
const auto extent = renderer->get_render_extent();
|
||||
//const auto extent = renderer->get_render_extent();
|
||||
|
||||
Vector4 params(render_options.depth_of_field_strength, 0.0, 0.0, 0.0);
|
||||
|
||||
|
@ -113,8 +116,8 @@ void DoFPass::render(GFXCommandBuffer* command_buffer, Scene&) {
|
|||
|
||||
command_buffer->set_graphics_pipeline(pipeline);
|
||||
|
||||
command_buffer->bind_texture(renderer->offscreenColorTexture, 0);
|
||||
command_buffer->bind_texture(renderer->offscreenDepthTexture, 1);
|
||||
//command_buffer->bind_texture(renderer->offscreenColorTexture, 0);
|
||||
//command_buffer->bind_texture(renderer->offscreenDepthTexture, 1);
|
||||
command_buffer->bind_texture(aperture_texture->handle, 2);
|
||||
|
||||
params.y = 1;
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
#include "gaussianhelper.hpp"
|
||||
|
||||
#include "gfx_commandbuffer.hpp"
|
||||
#include "gfx.hpp"
|
||||
|
||||
GaussianHelper::GaussianHelper(GFX* gfx, const prism::Extent extent) : extent(extent) {
|
||||
// render pass
|
||||
GFXRenderPassCreateInfo renderPassInfo = {};
|
||||
renderPassInfo.label = "Gaussian";
|
||||
renderPassInfo.attachments.push_back(GFXPixelFormat::RGBA_32F);
|
||||
|
||||
renderPass = gfx->create_render_pass(renderPassInfo);
|
||||
|
||||
// pipeline
|
||||
GFXGraphicsPipelineCreateInfo pipelineInfo = {};
|
||||
pipelineInfo.label = "Gaussian";
|
||||
pipelineInfo.shaders.vertex_src = file::Path("gaussian.vert");
|
||||
pipelineInfo.shaders.fragment_src = file::Path("gaussian.frag");
|
||||
|
||||
pipelineInfo.rasterization.primitive_type = GFXPrimitiveType::TriangleStrip;
|
||||
|
||||
pipelineInfo.shader_input.bindings = {
|
||||
{0, GFXBindingType::Texture},
|
||||
{1, GFXBindingType::PushConstant}
|
||||
};
|
||||
|
||||
pipelineInfo.shader_input.push_constants = {
|
||||
{sizeof(int), 0}
|
||||
};
|
||||
|
||||
pipelineInfo.render_pass = renderPass;
|
||||
|
||||
pipeline = gfx->create_graphics_pipeline(pipelineInfo);
|
||||
|
||||
// resources
|
||||
GFXTextureCreateInfo textureInfo = {};
|
||||
textureInfo.label = "Gaussian";
|
||||
textureInfo.width = extent.width;
|
||||
textureInfo.height = extent.height;
|
||||
textureInfo.format = GFXPixelFormat::RGBA_32F;
|
||||
textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Sampled;
|
||||
textureInfo.samplingMode = SamplingMode::ClampToEdge;
|
||||
|
||||
texA = gfx->create_texture(textureInfo);
|
||||
texB = gfx->create_texture(textureInfo);
|
||||
|
||||
GFXFramebufferCreateInfo info;
|
||||
info.attachments = {texA};
|
||||
info.render_pass = renderPass;
|
||||
|
||||
fboA = gfx->create_framebuffer(info);
|
||||
|
||||
info.attachments = {texB};
|
||||
|
||||
fboB = gfx->create_framebuffer(info);
|
||||
}
|
||||
|
||||
GFXTexture* GaussianHelper::render(GFXCommandBuffer* commandBuffer, GFXTexture* source) {
|
||||
bool horizontal = true, first_iteration = true;
|
||||
int amount = 10;
|
||||
for(int i = 0; i < amount; i++) {
|
||||
GFXRenderPassBeginInfo info = {};
|
||||
info.framebuffer = horizontal ? fboA : fboB;
|
||||
info.render_pass = renderPass;
|
||||
info.render_area.extent = extent;
|
||||
|
||||
commandBuffer->set_render_pass(info);
|
||||
|
||||
commandBuffer->set_graphics_pipeline(pipeline);
|
||||
|
||||
commandBuffer->memory_barrier();
|
||||
|
||||
int h = static_cast<int>(horizontal);
|
||||
commandBuffer->set_push_constant(&h, sizeof(int));
|
||||
commandBuffer->bind_texture(first_iteration ? source : (horizontal ? texB : texA), 0);
|
||||
|
||||
commandBuffer->draw(0, 4, 0, 1);
|
||||
|
||||
horizontal = !horizontal;
|
||||
if (first_iteration)
|
||||
first_iteration = false;
|
||||
}
|
||||
|
||||
return (horizontal ? texB : texA);
|
||||
}
|
|
@ -13,7 +13,6 @@
|
|||
#include "imguipass.hpp"
|
||||
#include "gfx.hpp"
|
||||
#include "log.hpp"
|
||||
#include "gaussianhelper.hpp"
|
||||
#include "pass.hpp"
|
||||
#include "shadowpass.hpp"
|
||||
#include "smaapass.hpp"
|
||||
|
@ -98,53 +97,85 @@ Renderer::Renderer(GFX* gfx, const bool enable_imgui) : gfx(gfx) {
|
|||
|
||||
shadow_pass = std::make_unique<ShadowPass>(gfx);
|
||||
scene_capture = std::make_unique<SceneCapture>(gfx);
|
||||
smaaPass = std::make_unique<SMAAPass>(gfx, this);
|
||||
|
||||
if(enable_imgui)
|
||||
addPass<ImGuiPass>();
|
||||
|
||||
createBRDF();
|
||||
|
||||
GFXRenderPassCreateInfo renderPassInfo = {};
|
||||
renderPassInfo.label = "Offscreen";
|
||||
renderPassInfo.attachments.push_back(GFXPixelFormat::RGBA_32F);
|
||||
renderPassInfo.attachments.push_back(GFXPixelFormat::DEPTH_32F);
|
||||
renderPassInfo.will_use_in_shader = true;
|
||||
|
||||
offscreenRenderPass = gfx->create_render_pass(renderPassInfo);
|
||||
|
||||
createMeshPipeline();
|
||||
createFontPipeline();
|
||||
createSkyPipeline();
|
||||
}
|
||||
|
||||
Renderer::~Renderer() {}
|
||||
|
||||
void Renderer::resize(const prism::Extent extent) {
|
||||
this->extent = extent;
|
||||
this->current_render_scale = render_options.render_scale;
|
||||
RenderTarget* Renderer::allocate_render_target(const prism::Extent extent) {
|
||||
auto target = std::make_unique<RenderTarget>();
|
||||
|
||||
resize_render_target(*target, extent);
|
||||
|
||||
return render_targets.emplace_back(std::move(target)).get();;
|
||||
}
|
||||
|
||||
if(!viewport_mode) {
|
||||
createOffscreenResources();
|
||||
createMeshPipeline();
|
||||
createPostPipeline();
|
||||
createFontPipeline();
|
||||
createSkyPipeline();
|
||||
createUIPipeline();
|
||||
createGaussianResources();
|
||||
|
||||
smaaPass = std::make_unique<SMAAPass>(gfx, this);
|
||||
dofPass = std::make_unique<DoFPass>(gfx, this);
|
||||
void Renderer::resize_render_target(RenderTarget& target, const prism::Extent extent) {
|
||||
target.extent = extent;
|
||||
|
||||
create_render_target_resources(target);
|
||||
smaaPass->create_render_target_resources(target);
|
||||
createPostPipeline();
|
||||
|
||||
GFXGraphicsPipelineCreateInfo pipelineInfo = {};
|
||||
pipelineInfo.label = "Text";
|
||||
|
||||
pipelineInfo.shaders.vertex_src = file::Path("text.vert");
|
||||
pipelineInfo.shaders.fragment_src = file::Path("text.frag");
|
||||
|
||||
pipelineInfo.rasterization.primitive_type = GFXPrimitiveType::TriangleStrip;
|
||||
|
||||
pipelineInfo.blending.enable_blending = true;
|
||||
pipelineInfo.blending.src_rgb = GFXBlendFactor::SrcAlpha;
|
||||
pipelineInfo.blending.dst_rgb = GFXBlendFactor::OneMinusSrcColor;
|
||||
|
||||
pipelineInfo.shader_input.bindings = {
|
||||
{4, GFXBindingType::PushConstant},
|
||||
{0, GFXBindingType::StorageBuffer},
|
||||
{1, GFXBindingType::StorageBuffer},
|
||||
{2, GFXBindingType::StorageBuffer},
|
||||
{3, GFXBindingType::Texture}
|
||||
};
|
||||
|
||||
pipelineInfo.shader_input.push_constants = {
|
||||
{sizeof(UIPushConstant), 0}
|
||||
};
|
||||
|
||||
textPipeline = gfx->create_graphics_pipeline(pipelineInfo);
|
||||
|
||||
if(worldTextPipeline == nullptr) {
|
||||
pipelineInfo.render_pass = offscreenRenderPass;
|
||||
pipelineInfo.label = "Text World";
|
||||
pipelineInfo.depth.depth_mode = GFXDepthMode::LessOrEqual;
|
||||
|
||||
worldTextPipeline = gfx->create_graphics_pipeline(pipelineInfo);
|
||||
}
|
||||
|
||||
createUIPipeline();
|
||||
|
||||
for(auto& pass : passes)
|
||||
pass->resize(extent);
|
||||
}
|
||||
|
||||
void Renderer::resize_viewport(const prism::Extent extent) {
|
||||
this->viewport_extent = extent;
|
||||
this->current_render_scale = render_options.render_scale;
|
||||
void Renderer::recreate_all_render_targets() {
|
||||
|
||||
createOffscreenResources();
|
||||
createMeshPipeline();
|
||||
createPostPipeline();
|
||||
createFontPipeline();
|
||||
createSkyPipeline();
|
||||
createUIPipeline();
|
||||
createGaussianResources();
|
||||
|
||||
smaaPass = std::make_unique<SMAAPass>(gfx, this);
|
||||
dofPass = std::make_unique<DoFPass>(gfx, this);
|
||||
|
||||
for(auto& pass : passes)
|
||||
pass->resize(get_render_extent());
|
||||
}
|
||||
|
||||
void Renderer::set_screen(ui::Screen* screen) {
|
||||
|
@ -182,12 +213,6 @@ void Renderer::init_screen(ui::Screen* screen) {
|
|||
|
||||
void Renderer::update_screen() {
|
||||
if(current_screen != nullptr) {
|
||||
if(current_screen->blurs_background) {
|
||||
startSceneBlur();
|
||||
} else {
|
||||
stopSceneBlur();
|
||||
}
|
||||
|
||||
for(auto& element : current_screen->elements) {
|
||||
if(!element.background.image.empty())
|
||||
element.background.texture = assetm->get<Texture>(file::app_domain / element.background.image);
|
||||
|
@ -195,210 +220,153 @@ void Renderer::update_screen() {
|
|||
}
|
||||
}
|
||||
|
||||
void Renderer::startCrossfade() {
|
||||
// copy the current screen
|
||||
gfx->copy_texture(offscreenColorTexture, offscreenBackTexture);
|
||||
void Renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarget& target, int index) {
|
||||
const auto extent = target.extent;
|
||||
const auto render_extent = target.get_render_extent();
|
||||
|
||||
fading = true;
|
||||
fade = 1.0f;
|
||||
}
|
||||
|
||||
void Renderer::startSceneBlur() {
|
||||
blurring = true;
|
||||
hasToStore = true;
|
||||
}
|
||||
|
||||
void Renderer::stopSceneBlur() {
|
||||
blurring = false;
|
||||
}
|
||||
|
||||
void Renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, int index) {
|
||||
if(render_options.render_scale != current_render_scale) {
|
||||
if(viewport_mode)
|
||||
resize_viewport(viewport_extent);
|
||||
else
|
||||
resize(extent);
|
||||
}
|
||||
commandbuffer->push_group("Scene Rendering");
|
||||
|
||||
const auto extent = get_extent();
|
||||
const auto render_extent = get_render_extent();
|
||||
|
||||
if(!gui_only_mode) {
|
||||
commandbuffer->push_group("Scene Rendering");
|
||||
|
||||
GFXRenderPassBeginInfo beginInfo = {};
|
||||
beginInfo.framebuffer = offscreenFramebuffer;
|
||||
beginInfo.render_pass = offscreenRenderPass;
|
||||
beginInfo.render_area.extent = render_extent;
|
||||
|
||||
bool hasToRender = true;
|
||||
if(blurring && !hasToStore)
|
||||
hasToRender = false;
|
||||
GFXRenderPassBeginInfo beginInfo = {};
|
||||
beginInfo.framebuffer = target.offscreenFramebuffer;
|
||||
beginInfo.render_pass = offscreenRenderPass;
|
||||
beginInfo.render_area.extent = render_extent;
|
||||
|
||||
ControllerContinuity continuity;
|
||||
ControllerContinuity continuity;
|
||||
|
||||
if(scene != nullptr && hasToRender) {
|
||||
commandbuffer->push_group("Shadow Rendering");
|
||||
|
||||
shadow_pass->render(commandbuffer, *scene);
|
||||
|
||||
if(scene != nullptr) {
|
||||
commandbuffer->push_group("Shadow Rendering");
|
||||
|
||||
shadow_pass->render(commandbuffer, *scene);
|
||||
|
||||
commandbuffer->pop_group();
|
||||
|
||||
if(render_options.enable_ibl) {
|
||||
commandbuffer->push_group("Scene Capture");
|
||||
scene_capture->render(commandbuffer, scene);
|
||||
commandbuffer->pop_group();
|
||||
|
||||
if(render_options.enable_ibl) {
|
||||
commandbuffer->push_group("Scene Capture");
|
||||
scene_capture->render(commandbuffer, scene);
|
||||
commandbuffer->pop_group();
|
||||
}
|
||||
|
||||
commandbuffer->set_render_pass(beginInfo);
|
||||
|
||||
const auto& cameras = scene->get_all<Camera>();
|
||||
for(auto& [obj, camera] : cameras) {
|
||||
const int actual_width = render_extent.width / cameras.size();
|
||||
|
||||
const bool requires_limited_perspective = render_options.enable_depth_of_field;
|
||||
if(requires_limited_perspective) {
|
||||
camera.perspective = transform::perspective(radians(camera.fov), static_cast<float>(actual_width) / static_cast<float>(render_extent.height), camera.near, 100.0f);
|
||||
} else {
|
||||
camera.perspective = transform::infinite_perspective(radians(camera.fov), static_cast<float>(actual_width) / static_cast<float>(render_extent.height), camera.near);
|
||||
}
|
||||
|
||||
camera.view = inverse(scene->get<Transform>(obj).model);
|
||||
|
||||
Viewport viewport = {};
|
||||
viewport.x = (actual_width * 0);
|
||||
viewport.width = actual_width;
|
||||
viewport.height = render_extent.height;
|
||||
|
||||
commandbuffer->set_viewport(viewport);
|
||||
|
||||
commandbuffer->push_group("render camera");
|
||||
|
||||
render_camera(commandbuffer, *scene, obj, camera, get_render_extent(), continuity);
|
||||
|
||||
commandbuffer->pop_group();
|
||||
}
|
||||
}
|
||||
|
||||
commandbuffer->pop_group();
|
||||
|
||||
commandbuffer->push_group("SMAA");
|
||||
|
||||
smaaPass->render(commandbuffer);
|
||||
|
||||
commandbuffer->pop_group();
|
||||
|
||||
if(render_options.enable_depth_of_field)
|
||||
dofPass->render(commandbuffer, *scene);
|
||||
|
||||
if(!viewport_mode) {
|
||||
beginInfo.framebuffer = nullptr;
|
||||
beginInfo.render_pass = nullptr;
|
||||
} else {
|
||||
beginInfo.framebuffer = viewportFramebuffer;
|
||||
beginInfo.render_pass = viewportRenderPass;
|
||||
}
|
||||
|
||||
commandbuffer->set_render_pass(beginInfo);
|
||||
|
||||
Viewport viewport = {};
|
||||
viewport.width = render_extent.width;
|
||||
viewport.height = render_extent.height;
|
||||
|
||||
commandbuffer->set_viewport(viewport);
|
||||
|
||||
commandbuffer->push_group("Post Processing");
|
||||
|
||||
commandbuffer->set_compute_pipeline(histogram_pipeline);
|
||||
|
||||
commandbuffer->bind_texture(offscreenColorTexture, 0);
|
||||
commandbuffer->bind_shader_buffer(histogram_buffer, 0, 1, sizeof(uint32_t) * 256);
|
||||
|
||||
const float lum_range = render_options.max_luminance - render_options.min_luminance;
|
||||
|
||||
Vector4 params = Vector4(render_options.min_luminance, 1.0f / lum_range, render_extent.width, render_extent.height);
|
||||
|
||||
commandbuffer->set_push_constant(¶ms, sizeof(Vector4));
|
||||
|
||||
commandbuffer->dispatch(static_cast<uint32_t>(std::ceil(render_extent.width / 16.0f)),
|
||||
static_cast<uint32_t>(std::ceil(render_extent.height / 16.0f)), 1);
|
||||
|
||||
commandbuffer->set_compute_pipeline(histogram_average_pipeline);
|
||||
|
||||
params = Vector4(render_options.min_luminance, lum_range, std::clamp(1.0f - std::exp(-(1.0f / 60.0f) * 1.1f), 0.0f, 1.0f), render_extent.width * render_extent.height);
|
||||
|
||||
commandbuffer->set_push_constant(¶ms, sizeof(Vector4));
|
||||
|
||||
commandbuffer->bind_texture(average_luminance_texture, 0);
|
||||
|
||||
commandbuffer->dispatch(1, 1, 1);
|
||||
|
||||
commandbuffer->set_graphics_pipeline(viewport_mode ? renderToViewportPipeline : postPipeline);
|
||||
|
||||
if(render_options.enable_depth_of_field)
|
||||
commandbuffer->bind_texture(dofPass->normal_field, 1);
|
||||
else
|
||||
commandbuffer->bind_texture(offscreenColorTexture, 1);
|
||||
|
||||
commandbuffer->bind_texture(offscreenBackTexture, 2);
|
||||
commandbuffer->bind_texture(smaaPass->blend_texture, 3);
|
||||
|
||||
if(auto texture = get_requested_texture(PassTextureType::SelectionSobel))
|
||||
commandbuffer->bind_texture(texture, 5);
|
||||
else
|
||||
commandbuffer->bind_texture(dummyTexture, 5);
|
||||
|
||||
commandbuffer->bind_texture(average_luminance_texture, 6);
|
||||
|
||||
if(render_options.enable_depth_of_field)
|
||||
commandbuffer->bind_texture(dofPass->far_field, 7);
|
||||
else
|
||||
commandbuffer->bind_texture(dummyTexture, 7);
|
||||
|
||||
PostPushConstants pc;
|
||||
pc.options.x = render_options.enable_aa;
|
||||
pc.options.y = fade;
|
||||
pc.options.z = render_options.exposure;
|
||||
|
||||
if(render_options.enable_depth_of_field)
|
||||
pc.options.w = 2;
|
||||
|
||||
pc.transform_ops.x = (int)render_options.display_color_space;
|
||||
pc.transform_ops.y = (int)render_options.tonemapping;
|
||||
|
||||
const auto [width, height] = render_extent;
|
||||
pc.viewport = Vector4(1.0f / static_cast<float>(width), 1.0f / static_cast<float>(height), width, height);
|
||||
|
||||
commandbuffer->set_push_constant(&pc, sizeof(PostPushConstants));
|
||||
|
||||
if(fading) {
|
||||
if(fade > 0.0f)
|
||||
fade -= 0.1f;
|
||||
else if(fade <= 0.0f) {
|
||||
fading = false;
|
||||
fade = 0.0f;
|
||||
const auto& cameras = scene->get_all<Camera>();
|
||||
for(auto& [obj, camera] : cameras) {
|
||||
const int actual_width = render_extent.width / cameras.size();
|
||||
|
||||
const bool requires_limited_perspective = render_options.enable_depth_of_field;
|
||||
if(requires_limited_perspective) {
|
||||
camera.perspective = transform::perspective(radians(camera.fov), static_cast<float>(actual_width) / static_cast<float>(render_extent.height), camera.near, 100.0f);
|
||||
} else {
|
||||
camera.perspective = transform::infinite_perspective(radians(camera.fov), static_cast<float>(actual_width) / static_cast<float>(render_extent.height), camera.near);
|
||||
}
|
||||
|
||||
camera.view = inverse(scene->get<Transform>(obj).model);
|
||||
|
||||
Viewport viewport = {};
|
||||
viewport.x = (actual_width * 0);
|
||||
viewport.width = actual_width;
|
||||
viewport.height = render_extent.height;
|
||||
|
||||
commandbuffer->set_viewport(viewport);
|
||||
|
||||
commandbuffer->push_group("render camera");
|
||||
|
||||
render_camera(commandbuffer, *scene, obj, camera, render_extent, continuity);
|
||||
|
||||
commandbuffer->pop_group();
|
||||
}
|
||||
|
||||
commandbuffer->draw(0, 4, 0, 1);
|
||||
|
||||
commandbuffer->pop_group();
|
||||
|
||||
if(current_screen != nullptr)
|
||||
render_screen(commandbuffer, current_screen, continuity);
|
||||
} else {
|
||||
GFXRenderPassBeginInfo beginInfo = {};
|
||||
beginInfo.render_area.extent = extent;
|
||||
|
||||
commandbuffer->set_render_pass(beginInfo);
|
||||
|
||||
Viewport viewport = {};
|
||||
viewport.width = extent.width;
|
||||
viewport.height = extent.height;
|
||||
|
||||
commandbuffer->set_viewport(viewport);
|
||||
}
|
||||
|
||||
commandbuffer->pop_group();
|
||||
|
||||
commandbuffer->push_group("SMAA");
|
||||
|
||||
smaaPass->render(commandbuffer, target);
|
||||
|
||||
commandbuffer->pop_group();
|
||||
|
||||
if(render_options.enable_depth_of_field)
|
||||
dofPass->render(commandbuffer, *scene);
|
||||
|
||||
beginInfo.framebuffer = nullptr;
|
||||
beginInfo.render_pass = nullptr;
|
||||
|
||||
commandbuffer->set_render_pass(beginInfo);
|
||||
|
||||
Viewport viewport = {};
|
||||
viewport.width = render_extent.width;
|
||||
viewport.height = render_extent.height;
|
||||
|
||||
commandbuffer->set_viewport(viewport);
|
||||
|
||||
commandbuffer->push_group("Post Processing");
|
||||
|
||||
commandbuffer->set_compute_pipeline(histogram_pipeline);
|
||||
|
||||
commandbuffer->bind_texture(target.offscreenColorTexture, 0);
|
||||
commandbuffer->bind_shader_buffer(histogram_buffer, 0, 1, sizeof(uint32_t) * 256);
|
||||
|
||||
const float lum_range = render_options.max_luminance - render_options.min_luminance;
|
||||
|
||||
Vector4 params = Vector4(render_options.min_luminance, 1.0f / lum_range, render_extent.width, render_extent.height);
|
||||
|
||||
commandbuffer->set_push_constant(¶ms, sizeof(Vector4));
|
||||
|
||||
commandbuffer->dispatch(static_cast<uint32_t>(std::ceil(render_extent.width / 16.0f)),
|
||||
static_cast<uint32_t>(std::ceil(render_extent.height / 16.0f)), 1);
|
||||
|
||||
commandbuffer->set_compute_pipeline(histogram_average_pipeline);
|
||||
|
||||
params = Vector4(render_options.min_luminance, lum_range, std::clamp(1.0f - std::exp(-(1.0f / 60.0f) * 1.1f), 0.0f, 1.0f), render_extent.width * render_extent.height);
|
||||
|
||||
commandbuffer->set_push_constant(¶ms, sizeof(Vector4));
|
||||
|
||||
commandbuffer->bind_texture(average_luminance_texture, 0);
|
||||
|
||||
commandbuffer->dispatch(1, 1, 1);
|
||||
|
||||
commandbuffer->set_graphics_pipeline(postPipeline);
|
||||
|
||||
if(render_options.enable_depth_of_field)
|
||||
commandbuffer->bind_texture(dofPass->normal_field, 1);
|
||||
else
|
||||
commandbuffer->bind_texture(target.offscreenColorTexture, 1);
|
||||
|
||||
commandbuffer->bind_texture(target.blend_texture, 3);
|
||||
|
||||
if(auto texture = get_requested_texture(PassTextureType::SelectionSobel))
|
||||
commandbuffer->bind_texture(texture, 5);
|
||||
else
|
||||
commandbuffer->bind_texture(dummyTexture, 5);
|
||||
|
||||
commandbuffer->bind_texture(average_luminance_texture, 6);
|
||||
|
||||
if(render_options.enable_depth_of_field)
|
||||
commandbuffer->bind_texture(dofPass->far_field, 7);
|
||||
else
|
||||
commandbuffer->bind_texture(dummyTexture, 7);
|
||||
|
||||
PostPushConstants pc;
|
||||
pc.options.x = render_options.enable_aa;
|
||||
pc.options.z = render_options.exposure;
|
||||
|
||||
if(render_options.enable_depth_of_field)
|
||||
pc.options.w = 2;
|
||||
|
||||
pc.transform_ops.x = (int)render_options.display_color_space;
|
||||
pc.transform_ops.y = (int)render_options.tonemapping;
|
||||
|
||||
const auto [width, height] = render_extent;
|
||||
pc.viewport = Vector4(1.0f / static_cast<float>(width), 1.0f / static_cast<float>(height), width, height);
|
||||
|
||||
commandbuffer->set_push_constant(&pc, sizeof(PostPushConstants));
|
||||
|
||||
commandbuffer->draw(0, 4, 0, 1);
|
||||
|
||||
commandbuffer->pop_group();
|
||||
|
||||
if(current_screen != nullptr)
|
||||
render_screen(commandbuffer, current_screen, extent, continuity);
|
||||
|
||||
commandbuffer->push_group("Extra Passes");
|
||||
|
||||
for(auto& pass : passes)
|
||||
|
@ -532,7 +500,7 @@ void Renderer::render_camera(GFXCommandBuffer* command_buffer, Scene& scene, Obj
|
|||
options.render_world = true;
|
||||
options.mvp = camera.perspective * camera.view * scene.get<Transform>(obj).model;
|
||||
|
||||
render_screen(command_buffer, screen.screen, continuity, options);
|
||||
render_screen(command_buffer, screen.screen, extent, continuity, options);
|
||||
}
|
||||
|
||||
SkyPushConstant pc;
|
||||
|
@ -558,7 +526,7 @@ void Renderer::render_camera(GFXCommandBuffer* command_buffer, Scene& scene, Obj
|
|||
gfx->copy_buffer(sceneBuffer, &sceneInfo, 0, sizeof(SceneInformation));
|
||||
}
|
||||
|
||||
void Renderer::render_screen(GFXCommandBuffer *commandbuffer, ui::Screen* screen, ControllerContinuity& continuity, RenderScreenOptions options) {
|
||||
void Renderer::render_screen(GFXCommandBuffer *commandbuffer, ui::Screen* screen, prism::Extent extent, ControllerContinuity& continuity, RenderScreenOptions options) {
|
||||
std::array<GlyphInstance, maxInstances> instances;
|
||||
std::vector<ElementInstance> elementInstances;
|
||||
std::array<StringInstance, 50> stringInstances;
|
||||
|
@ -636,7 +604,6 @@ void Renderer::render_screen(GFXCommandBuffer *commandbuffer, ui::Screen* screen
|
|||
gfx->copy_buffer(screen->instance_buffer, stringInstances.data(), 0, sizeof(StringInstance) * 50);
|
||||
gfx->copy_buffer(screen->elements_buffer, elementInstances.data(), sizeof(ElementInstance) * continuity.elementOffset, sizeof(ElementInstance) * elementInstances.size());
|
||||
|
||||
const auto extent = get_render_extent();
|
||||
const Vector2 windowSize = {static_cast<float>(extent.width), static_cast<float>(extent.height)};
|
||||
|
||||
for(auto [i, element] : utility::enumerate(screen->elements)) {
|
||||
|
@ -777,22 +744,8 @@ void Renderer::createDummyTexture() {
|
|||
gfx->copy_texture(dummyTexture, tex, sizeof(tex));
|
||||
}
|
||||
|
||||
void Renderer::createOffscreenResources() {
|
||||
GFXRenderPassCreateInfo renderPassInfo = {};
|
||||
renderPassInfo.label = "Offscreen";
|
||||
renderPassInfo.attachments.push_back(GFXPixelFormat::RGBA_32F);
|
||||
renderPassInfo.attachments.push_back(GFXPixelFormat::DEPTH_32F);
|
||||
renderPassInfo.will_use_in_shader = true;
|
||||
|
||||
offscreenRenderPass = gfx->create_render_pass(renderPassInfo);
|
||||
|
||||
renderPassInfo = {};
|
||||
renderPassInfo.label = "Offscreen Unorm";
|
||||
renderPassInfo.attachments = {GFXPixelFormat::RGBA8_UNORM};
|
||||
|
||||
unormRenderPass = gfx->create_render_pass(renderPassInfo);
|
||||
|
||||
const auto extent = get_render_extent();
|
||||
void Renderer::create_render_target_resources(RenderTarget& target) {
|
||||
const auto extent = target.get_render_extent();
|
||||
|
||||
GFXTextureCreateInfo textureInfo = {};
|
||||
textureInfo.label = "Offscreen Color";
|
||||
|
@ -802,45 +755,57 @@ void Renderer::createOffscreenResources() {
|
|||
textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Sampled;
|
||||
textureInfo.samplingMode = SamplingMode::ClampToEdge;
|
||||
|
||||
offscreenColorTexture = gfx->create_texture(textureInfo);
|
||||
|
||||
textureInfo.label = "Offscreen Back";
|
||||
offscreenBackTexture = gfx->create_texture(textureInfo);
|
||||
target.offscreenColorTexture = gfx->create_texture(textureInfo);
|
||||
|
||||
textureInfo.label = "Offscreen Depth";
|
||||
textureInfo.format = GFXPixelFormat::DEPTH_32F;
|
||||
|
||||
offscreenDepthTexture = gfx->create_texture(textureInfo);
|
||||
target.offscreenDepthTexture = gfx->create_texture(textureInfo);
|
||||
|
||||
GFXFramebufferCreateInfo framebufferInfo = {};
|
||||
framebufferInfo.render_pass = offscreenRenderPass;
|
||||
framebufferInfo.attachments.push_back(offscreenColorTexture);
|
||||
framebufferInfo.attachments.push_back(offscreenDepthTexture);
|
||||
framebufferInfo.attachments.push_back(target.offscreenColorTexture);
|
||||
framebufferInfo.attachments.push_back(target.offscreenDepthTexture);
|
||||
|
||||
offscreenFramebuffer = gfx->create_framebuffer(framebufferInfo);
|
||||
|
||||
if(viewport_mode) {
|
||||
GFXRenderPassCreateInfo renderPassInfo = {};
|
||||
renderPassInfo.label = "Viewport";
|
||||
renderPassInfo.attachments.push_back(GFXPixelFormat::RGBA8_UNORM);
|
||||
renderPassInfo.will_use_in_shader = true;
|
||||
|
||||
viewportRenderPass = gfx->create_render_pass(renderPassInfo);
|
||||
|
||||
GFXTextureCreateInfo textureInfo = {};
|
||||
textureInfo.label = "Viewport Color";
|
||||
textureInfo.width = extent.width;
|
||||
textureInfo.height = extent.height;
|
||||
textureInfo.format = GFXPixelFormat::RGBA8_UNORM;
|
||||
textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Sampled;
|
||||
textureInfo.samplingMode = SamplingMode::ClampToEdge;
|
||||
|
||||
viewportColorTexture = gfx->create_texture(textureInfo);
|
||||
|
||||
framebufferInfo.render_pass = viewportRenderPass;
|
||||
framebufferInfo.attachments = {viewportColorTexture};
|
||||
|
||||
viewportFramebuffer = gfx->create_framebuffer(framebufferInfo);
|
||||
target.offscreenFramebuffer = gfx->create_framebuffer(framebufferInfo);
|
||||
|
||||
GFXGraphicsPipelineCreateInfo pipelineInfo = {};
|
||||
pipelineInfo.label = "Post";
|
||||
|
||||
pipelineInfo.shaders.vertex_src = file::Path("post.vert");
|
||||
pipelineInfo.shaders.fragment_src = file::Path("post.frag");
|
||||
|
||||
pipelineInfo.shader_input.bindings = {
|
||||
{4, GFXBindingType::PushConstant},
|
||||
{1, GFXBindingType::Texture},
|
||||
{2, GFXBindingType::Texture},
|
||||
{3, GFXBindingType::Texture},
|
||||
{5, GFXBindingType::Texture},
|
||||
{6, GFXBindingType::Texture},
|
||||
{7, GFXBindingType::Texture}
|
||||
};
|
||||
|
||||
pipelineInfo.shader_input.push_constants = {
|
||||
{sizeof(PostPushConstants), 0}
|
||||
};
|
||||
|
||||
postPipeline = gfx->create_graphics_pipeline(pipelineInfo);
|
||||
|
||||
if(renderToTexturePipeline == nullptr) {
|
||||
pipelineInfo.label = "Render to Texture";
|
||||
pipelineInfo.render_pass = offscreenRenderPass;
|
||||
|
||||
renderToTexturePipeline = gfx->create_graphics_pipeline(pipelineInfo);
|
||||
|
||||
pipelineInfo.label = "Render to Texture (Unorm)";
|
||||
pipelineInfo.render_pass = unormRenderPass;
|
||||
|
||||
renderToUnormTexturePipeline = gfx->create_graphics_pipeline(pipelineInfo);
|
||||
|
||||
pipelineInfo.label = "Render to Viewport";
|
||||
pipelineInfo.render_pass = viewportRenderPass;
|
||||
|
||||
renderToViewportPipeline = gfx->create_graphics_pipeline(pipelineInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -851,10 +816,10 @@ void Renderer::createMeshPipeline() {
|
|||
void Renderer::createPostPipeline() {
|
||||
GFXGraphicsPipelineCreateInfo pipelineInfo = {};
|
||||
pipelineInfo.label = "Post";
|
||||
|
||||
|
||||
pipelineInfo.shaders.vertex_src = file::Path("post.vert");
|
||||
pipelineInfo.shaders.fragment_src = file::Path("post.frag");
|
||||
|
||||
|
||||
pipelineInfo.shader_input.bindings = {
|
||||
{4, GFXBindingType::PushConstant},
|
||||
{1, GFXBindingType::Texture},
|
||||
|
@ -864,16 +829,16 @@ void Renderer::createPostPipeline() {
|
|||
{6, GFXBindingType::Texture},
|
||||
{7, GFXBindingType::Texture}
|
||||
};
|
||||
|
||||
|
||||
pipelineInfo.shader_input.push_constants = {
|
||||
{sizeof(PostPushConstants), 0}
|
||||
};
|
||||
|
||||
|
||||
postPipeline = gfx->create_graphics_pipeline(pipelineInfo);
|
||||
|
||||
|
||||
pipelineInfo.label = "Render to Texture";
|
||||
pipelineInfo.render_pass = offscreenRenderPass;
|
||||
|
||||
|
||||
renderToTexturePipeline = gfx->create_graphics_pipeline(pipelineInfo);
|
||||
|
||||
pipelineInfo.label = "Render to Texture (Unorm)";
|
||||
|
@ -883,7 +848,7 @@ void Renderer::createPostPipeline() {
|
|||
|
||||
pipelineInfo.label = "Render to Viewport";
|
||||
pipelineInfo.render_pass = viewportRenderPass;
|
||||
|
||||
|
||||
renderToViewportPipeline = gfx->create_graphics_pipeline(pipelineInfo);
|
||||
}
|
||||
|
||||
|
@ -901,38 +866,6 @@ void Renderer::createFontPipeline() {
|
|||
|
||||
instanceAlignment = (int)gfx->get_alignment(sizeof(GlyphInstance) * maxInstances);
|
||||
|
||||
GFXGraphicsPipelineCreateInfo pipelineInfo = {};
|
||||
pipelineInfo.label = "Text";
|
||||
|
||||
pipelineInfo.shaders.vertex_src = file::Path("text.vert");
|
||||
pipelineInfo.shaders.fragment_src = file::Path("text.frag");
|
||||
|
||||
pipelineInfo.rasterization.primitive_type = GFXPrimitiveType::TriangleStrip;
|
||||
|
||||
pipelineInfo.blending.enable_blending = true;
|
||||
pipelineInfo.blending.src_rgb = GFXBlendFactor::SrcAlpha;
|
||||
pipelineInfo.blending.dst_rgb = GFXBlendFactor::OneMinusSrcColor;
|
||||
|
||||
pipelineInfo.shader_input.bindings = {
|
||||
{4, GFXBindingType::PushConstant},
|
||||
{0, GFXBindingType::StorageBuffer},
|
||||
{1, GFXBindingType::StorageBuffer},
|
||||
{2, GFXBindingType::StorageBuffer},
|
||||
{3, GFXBindingType::Texture}
|
||||
};
|
||||
|
||||
pipelineInfo.shader_input.push_constants = {
|
||||
{sizeof(UIPushConstant), 0}
|
||||
};
|
||||
|
||||
textPipeline = gfx->create_graphics_pipeline(pipelineInfo);
|
||||
|
||||
pipelineInfo.render_pass = offscreenRenderPass;
|
||||
pipelineInfo.label = "Text World";
|
||||
pipelineInfo.depth.depth_mode = GFXDepthMode::LessOrEqual;
|
||||
|
||||
worldTextPipeline = gfx->create_graphics_pipeline(pipelineInfo);
|
||||
|
||||
GFXTextureCreateInfo textureInfo = {};
|
||||
textureInfo.label = "UI Font";
|
||||
textureInfo.width = font.width;
|
||||
|
@ -1006,23 +939,6 @@ void Renderer::createUIPipeline() {
|
|||
worldGeneralPipeline = gfx->create_graphics_pipeline(pipelineInfo);
|
||||
}
|
||||
|
||||
void Renderer::createGaussianResources() {
|
||||
const auto extent = get_render_extent();
|
||||
|
||||
gHelper = std::make_unique<GaussianHelper>(gfx, extent);
|
||||
|
||||
GFXTextureCreateInfo textureInfo = {};
|
||||
textureInfo.label = "Blur Store";
|
||||
textureInfo.width = extent.width;
|
||||
textureInfo.height = extent.height;
|
||||
textureInfo.format = GFXPixelFormat::RGBA_32F;
|
||||
textureInfo.usage = GFXTextureUsage::Sampled;
|
||||
|
||||
blurStore = gfx->create_texture(textureInfo);
|
||||
|
||||
hasToStore = true;
|
||||
}
|
||||
|
||||
void Renderer::createBRDF() {
|
||||
GFXRenderPassCreateInfo renderPassInfo = {};
|
||||
renderPassInfo.label = "BRDF Gen";
|
||||
|
|
|
@ -9,20 +9,45 @@
|
|||
#include <AreaTex.h>
|
||||
#include <SearchTex.h>
|
||||
|
||||
SMAAPass::SMAAPass(GFX* gfx, Renderer* renderer) : renderer(renderer), extent(renderer->get_render_extent()) {
|
||||
SMAAPass::SMAAPass(GFX* gfx, Renderer* renderer) : renderer(renderer) {
|
||||
Expects(gfx != nullptr);
|
||||
Expects(renderer != nullptr);
|
||||
|
||||
create_textures();
|
||||
create_render_pass();
|
||||
create_pipelines();
|
||||
create_offscreen_resources();
|
||||
}
|
||||
|
||||
void SMAAPass::render(GFXCommandBuffer* command_buffer) {
|
||||
void SMAAPass::create_render_target_resources(RenderTarget& target) {
|
||||
auto gfx = engine->get_gfx();
|
||||
|
||||
GFXTextureCreateInfo textureInfo = {};
|
||||
textureInfo.label = "SMAA Edge";
|
||||
textureInfo.width = target.extent.width;
|
||||
textureInfo.height = target.extent.height;
|
||||
textureInfo.format = GFXPixelFormat::R16G16B16A16_SFLOAT;
|
||||
textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Sampled;
|
||||
|
||||
target.edge_texture = gfx->create_texture(textureInfo);
|
||||
|
||||
textureInfo.label = "SMAA Blend";
|
||||
target.blend_texture = gfx->create_texture(textureInfo);
|
||||
|
||||
GFXFramebufferCreateInfo framebufferInfo = {};
|
||||
framebufferInfo.attachments = {target.edge_texture};
|
||||
framebufferInfo.render_pass = render_pass;
|
||||
|
||||
target.edge_framebuffer = gfx->create_framebuffer(framebufferInfo);
|
||||
|
||||
framebufferInfo.attachments = {target.blend_texture};
|
||||
|
||||
target.blend_framebuffer = gfx->create_framebuffer(framebufferInfo);
|
||||
}
|
||||
|
||||
void SMAAPass::render(GFXCommandBuffer* command_buffer, RenderTarget& target) {
|
||||
GFXRenderPassBeginInfo beginInfo = {};
|
||||
beginInfo.clear_color.a = 0.0f;
|
||||
beginInfo.render_area.extent = extent;
|
||||
beginInfo.render_area.extent = target.extent;
|
||||
beginInfo.render_pass = render_pass;
|
||||
|
||||
struct PushConstant {
|
||||
|
@ -30,37 +55,37 @@ void SMAAPass::render(GFXCommandBuffer* command_buffer) {
|
|||
Matrix4x4 correction_matrix;
|
||||
} pc;
|
||||
|
||||
pc.viewport = Vector4(1.0f / static_cast<float>(extent.width), 1.0f / static_cast<float>(extent.height), extent.width, extent.height);
|
||||
pc.viewport = Vector4(1.0f / static_cast<float>(target.extent.width), 1.0f / static_cast<float>(target.extent.height), target.extent.width, target.extent.height);
|
||||
|
||||
// edge
|
||||
{
|
||||
beginInfo.framebuffer = edge_framebuffer;
|
||||
beginInfo.framebuffer = target.edge_framebuffer;
|
||||
command_buffer->set_render_pass(beginInfo);
|
||||
|
||||
Viewport viewport = {};
|
||||
viewport.width = extent.width;
|
||||
viewport.height = extent.height;
|
||||
viewport.width = target.extent.width;
|
||||
viewport.height = target.extent.height;
|
||||
|
||||
command_buffer->set_viewport(viewport);
|
||||
|
||||
command_buffer->set_graphics_pipeline(edge_pipeline);
|
||||
command_buffer->set_push_constant(&pc, sizeof(PushConstant));
|
||||
|
||||
command_buffer->bind_texture(renderer->offscreenColorTexture, 0); // color
|
||||
command_buffer->bind_texture(renderer->offscreenDepthTexture, 1); // depth
|
||||
command_buffer->bind_texture(target.offscreenColorTexture, 0); // color
|
||||
command_buffer->bind_texture(target.offscreenDepthTexture, 1); // depth
|
||||
|
||||
command_buffer->draw(0, 3, 0, 1);
|
||||
}
|
||||
|
||||
// blend
|
||||
{
|
||||
beginInfo.framebuffer = blend_framebuffer;
|
||||
beginInfo.framebuffer = target.blend_framebuffer;
|
||||
command_buffer->set_render_pass(beginInfo);
|
||||
|
||||
command_buffer->set_graphics_pipeline(blend_pipeline);
|
||||
command_buffer->set_push_constant(&pc, sizeof(PushConstant));
|
||||
|
||||
command_buffer->bind_texture(edge_texture, 0);
|
||||
command_buffer->bind_texture(target.edge_texture, 0);
|
||||
command_buffer->bind_texture(area_image, 1);
|
||||
command_buffer->bind_texture(search_image, 3);
|
||||
|
||||
|
@ -136,29 +161,3 @@ void SMAAPass::create_pipelines() {
|
|||
|
||||
blend_pipeline = gfx->create_graphics_pipeline(createInfo);
|
||||
}
|
||||
|
||||
void SMAAPass::create_offscreen_resources() {
|
||||
auto gfx = engine->get_gfx();
|
||||
|
||||
GFXTextureCreateInfo textureInfo = {};
|
||||
textureInfo.label = "SMAA Edge";
|
||||
textureInfo.width = extent.width;
|
||||
textureInfo.height = extent.height;
|
||||
textureInfo.format = GFXPixelFormat::R16G16B16A16_SFLOAT;
|
||||
textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Sampled;
|
||||
|
||||
edge_texture = gfx->create_texture(textureInfo);
|
||||
|
||||
textureInfo.label = "SMAA Blend";
|
||||
blend_texture = gfx->create_texture(textureInfo);
|
||||
|
||||
GFXFramebufferCreateInfo framebufferInfo = {};
|
||||
framebufferInfo.attachments = {edge_texture};
|
||||
framebufferInfo.render_pass = render_pass;
|
||||
|
||||
edge_framebuffer = gfx->create_framebuffer(framebufferInfo);
|
||||
|
||||
framebufferInfo.attachments = {blend_texture};
|
||||
|
||||
blend_framebuffer = gfx->create_framebuffer(framebufferInfo);
|
||||
}
|
||||
|
|
|
@ -129,7 +129,7 @@ public:
|
|||
virtual void asset_selected([[maybe_unused]] std::filesystem::path path, [[maybe_unused]] AssetType type) {}
|
||||
|
||||
void createDockArea();
|
||||
void drawViewport(Renderer& renderer);
|
||||
void drawViewport();
|
||||
void drawAssets();
|
||||
|
||||
// options
|
||||
|
@ -335,6 +335,8 @@ private:
|
|||
void edit_asset_mesh(const char* name, AssetPtr<Mesh>& asset);
|
||||
void edit_asset_texture(const char* name, AssetPtr<Texture>& asset);
|
||||
void edit_asset_material(const char* name, AssetPtr<Material>& asset);
|
||||
|
||||
std::unordered_map<ImGuiID, RenderTarget*> viewport_render_targets;
|
||||
};
|
||||
|
||||
inline void editPath(const char* label, std::string& path, bool editable = true, const std::function<void()> on_selected = nullptr) {
|
||||
|
|
|
@ -89,8 +89,6 @@ CommonEditor::CommonEditor(std::string id) : id(id) {
|
|||
}
|
||||
|
||||
void CommonEditor::initialize_render() {
|
||||
engine->get_renderer()->gui_only_mode = true;
|
||||
|
||||
load_thumbnail_cache();
|
||||
}
|
||||
|
||||
|
@ -705,15 +703,26 @@ void CommonEditor::createDockArea() {
|
|||
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), ImGuiDockNodeFlags_PassthruCentralNode);
|
||||
}
|
||||
|
||||
void CommonEditor::drawViewport(Renderer& renderer) {
|
||||
void CommonEditor::drawViewport() {
|
||||
const auto size = ImGui::GetContentRegionAvail();
|
||||
const auto real_size = ImVec2(size.x * platform::get_window_dpi(0), size.y * platform::get_window_dpi(0));
|
||||
|
||||
if(real_size.x <= 0 || real_size.y <= 0)
|
||||
return;
|
||||
|
||||
if(real_size.x != renderer.viewport_extent.width || real_size.y != renderer.viewport_extent.height)
|
||||
renderer.resize_viewport(real_size);
|
||||
auto window_id = ImGui::GetCurrentWindow()->ID;
|
||||
|
||||
RenderTarget* target = nullptr;
|
||||
if(viewport_render_targets.count(window_id)) {
|
||||
target = viewport_render_targets[window_id];
|
||||
|
||||
if(real_size.x != target->extent.width || real_size.y != target->extent.height)
|
||||
engine->get_renderer()->resize_render_target(*target, real_size);
|
||||
} else {
|
||||
target = engine->get_renderer()->allocate_render_target(real_size);
|
||||
|
||||
viewport_render_targets[window_id] = target;
|
||||
}
|
||||
|
||||
viewport_width = size.x;
|
||||
viewport_height = size.y;
|
||||
|
@ -724,7 +733,7 @@ void CommonEditor::drawViewport(Renderer& renderer) {
|
|||
viewport_x = mouse_pos.x - real_pos.x;
|
||||
viewport_y = mouse_pos.y - real_pos.y;
|
||||
|
||||
ImGui::Image((ImTextureID)renderer.viewportColorTexture, size);
|
||||
ImGui::Image((ImTextureID)target->offscreenColorTexture, size);
|
||||
|
||||
accepting_viewport_input = ImGui::IsWindowHovered();
|
||||
|
||||
|
@ -974,7 +983,7 @@ GFXTexture* CommonEditor::generate_common_preview(Scene& scene, const Vector3 ca
|
|||
|
||||
GFXFramebufferCreateInfo framebuffer_create_info = {};
|
||||
framebuffer_create_info.attachments = {offscreen_color_texture, offscreen_depth_texture};
|
||||
framebuffer_create_info.render_pass = renderer->getOffscreenRenderPass();
|
||||
framebuffer_create_info.render_pass = renderer->offscreenRenderPass;
|
||||
|
||||
auto offscreen_framebuffer = gfx->create_framebuffer(framebuffer_create_info);
|
||||
|
||||
|
@ -993,7 +1002,7 @@ GFXTexture* CommonEditor::generate_common_preview(Scene& scene, const Vector3 ca
|
|||
|
||||
GFXRenderPassBeginInfo begin_info = {};
|
||||
begin_info.framebuffer = offscreen_framebuffer;
|
||||
begin_info.render_pass = renderer->getOffscreenRenderPass();
|
||||
begin_info.render_pass = renderer->offscreenRenderPass;
|
||||
begin_info.render_area.extent = {thumbnail_resolution, thumbnail_resolution};
|
||||
|
||||
command_buffer->set_render_pass(begin_info);
|
||||
|
|
|
@ -42,7 +42,7 @@ void DebugPass::initialize() {
|
|||
{1, GFXBindingType::PushConstant}
|
||||
};
|
||||
|
||||
createInfo.render_pass = engine->get_renderer()->getOffscreenRenderPass();
|
||||
createInfo.render_pass = engine->get_renderer()->offscreenRenderPass;
|
||||
createInfo.rasterization.polygon_type = GFXPolygonType::Line;
|
||||
|
||||
primitive_pipeline = engine->get_gfx()->create_graphics_pipeline(createInfo);
|
||||
|
@ -159,7 +159,7 @@ void DebugPass::initialize() {
|
|||
|
||||
pipelineInfo.blending.enable_blending = true;
|
||||
|
||||
pipelineInfo.render_pass = engine->get_renderer()->getOffscreenRenderPass();
|
||||
pipelineInfo.render_pass = engine->get_renderer()->offscreenRenderPass;
|
||||
|
||||
billboard_pipeline = engine->get_gfx()->create_graphics_pipeline(pipelineInfo);
|
||||
|
||||
|
|
|
@ -10,10 +10,7 @@ class Scene;
|
|||
class Editor {
|
||||
public:
|
||||
std::string path;
|
||||
|
||||
std::unique_ptr<Renderer> renderer;
|
||||
DebugPass* debug_pass = nullptr;
|
||||
|
||||
|
||||
bool has_been_docked = false;
|
||||
bool modified = false;
|
||||
bool wants_to_close = false;
|
||||
|
|
|
@ -184,7 +184,7 @@ void MaterialEditor::draw(CommonEditor* editor) {
|
|||
if(scene != nullptr) {
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
||||
if(begin("Viewport"))
|
||||
editor->drawViewport(*renderer);
|
||||
editor->drawViewport();
|
||||
|
||||
ImGui::End();
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ void PrefabEditor::draw(CommonEditor* editor) {
|
|||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
||||
if(begin("Viewport"))
|
||||
editor->drawViewport(*renderer);
|
||||
editor->drawViewport();
|
||||
|
||||
ImGui::End();
|
||||
|
||||
|
|
|
@ -122,10 +122,7 @@ struct OpenAssetRequest {
|
|||
std::vector<OpenAssetRequest> open_requests;
|
||||
|
||||
void PrismEditor::setup_editor(Editor* editor) {
|
||||
editor->renderer = std::make_unique<Renderer>(engine->get_gfx(), false);
|
||||
editor->renderer->viewport_mode = true;
|
||||
editor->debug_pass = editor->renderer->addPass<DebugPass>();
|
||||
editor->renderer->resize_viewport({static_cast<uint32_t>(viewport_width), static_cast<uint32_t>(viewport_height)});
|
||||
|
||||
}
|
||||
|
||||
void PrismEditor::open_asset(const file::Path path) {
|
||||
|
@ -181,7 +178,7 @@ void PrismEditor::open_asset(const file::Path path) {
|
|||
|
||||
void PrismEditor::renderEditor(GFXCommandBuffer* command_buffer) {
|
||||
for (auto& editor : editors) {
|
||||
editor->renderer->render(command_buffer, editor->get_scene(), -1);
|
||||
//editor->renderer->render(command_buffer, editor->get_scene(), -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -317,10 +314,10 @@ void PrismEditor::drawUI() {
|
|||
|
||||
ImGui::DockSpace(editor_dockspace, ImVec2(0.0f, 0.0f), ImGuiDockNodeFlags_None);
|
||||
|
||||
if(should_draw && editor->renderer != nullptr) {
|
||||
debugPass = editor->debug_pass;
|
||||
if(should_draw) {
|
||||
/*debugPass = editor->debug_pass;
|
||||
if(debugPass != nullptr)
|
||||
debugPass->selected_object = selected_object;
|
||||
debugPass->selected_object = selected_object;*/
|
||||
|
||||
engine->set_current_scene(editor->get_scene());
|
||||
set_undo_stack(&editor->undo_stack);
|
||||
|
|
|
@ -156,7 +156,7 @@ void SceneEditor::draw(CommonEditor* editor) {
|
|||
if(showViewport) {
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
||||
if(begin("Viewport", &showViewport))
|
||||
editor->drawViewport(*renderer);
|
||||
editor->drawViewport();
|
||||
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
|
|
Reference in a new issue