Archived
1
Fork 0

Add toggle for experimental depth of field effect

This commit is contained in:
redstrate 2020-09-22 21:47:11 -04:00
parent 24d3ac12c1
commit 91600b5f6f
8 changed files with 143 additions and 24 deletions

View file

@ -109,6 +109,9 @@ void draw_renderer() {
ImGui::DragFloat("Min Luminance", &render_options.min_luminance);
ImGui::DragFloat("Max Luminance", &render_options.max_luminance);
ImGui::Checkbox("Enable DoF", &render_options.enable_depth_of_field);
ImGui::DragFloat("DoF Strength", &render_options.depth_of_field_strength);
bool should_recompile = false;
float render_scale = render_options.render_scale;

View file

@ -15,6 +15,14 @@ public:
void render(GFXCommandBuffer* command_buffer, Scene& scene);
GFXTexture* far_field = nullptr;
GFXTexture* normal_field = nullptr;
GFXFramebuffer* far_framebuffer = nullptr;
GFXFramebuffer* normal_framebuffer = nullptr;
GFXRenderPass* renderpass = nullptr;
private:
Renderer* renderer = nullptr;

View file

@ -43,6 +43,9 @@ struct RenderOptions {
float min_luminance = -8.0f;
float max_luminance = 3.0f;
bool enable_depth_of_field = true;
float depth_of_field_strength = 3.0f;
bool dynamic_resolution = false;
double render_scale = 1.0f;

View file

@ -11,6 +11,11 @@ AssetPtr<Texture> aperture_texture;
DoFPass::DoFPass(GFX* gfx, Renderer* renderer) : renderer(renderer) {
aperture_texture = assetm->get<Texture>(file::app_domain / "textures/aperture.png");
GFXRenderPassCreateInfo renderPassInfo = {};
renderPassInfo.attachments.push_back(GFXPixelFormat::RGBA_32F);
renderpass = gfx->create_render_pass(renderPassInfo);
const auto extent = renderer->get_render_extent();
GFXShaderConstant width_constant = {};
@ -24,17 +29,58 @@ DoFPass::DoFPass(GFX* gfx, Renderer* renderer) : renderer(renderer) {
create_info.shaders.vertex_path = "dof.vert";
create_info.shaders.vertex_constants = {width_constant, height_constant};
create_info.shaders.fragment_path = "dof.frag";
create_info.render_pass = renderer->viewportRenderPass;
create_info.shader_input.bindings = {
{2, GFXBindingType::PushConstant}
};
create_info.render_pass = renderpass;
create_info.blending.enable_blending = true;
create_info.blending.src_rgb = GFXBlendFactor::SrcAlpha;
create_info.blending.dst_rgb = GFXBlendFactor::OneMinusSrcAlpha;
create_info.blending.src_rgb = GFXBlendFactor::SrcColor;
create_info.blending.dst_rgb = GFXBlendFactor::One;
create_info.blending.src_alpha = GFXBlendFactor::SrcAlpha;
create_info.blending.dst_alpha = GFXBlendFactor::OneMinusSrcAlpha;
create_info.blending.dst_alpha = GFXBlendFactor::One;
pipeline = gfx->create_graphics_pipeline(create_info);
GFXTextureCreateInfo textureInfo = {};
textureInfo.width = extent.width;
textureInfo.height = extent.height;
textureInfo.format = GFXPixelFormat::RGBA_32F;
textureInfo.usage = GFXTextureUsage::Attachment | GFXTextureUsage::Sampled;
textureInfo.samplingMode = SamplingMode::ClampToEdge;
normal_field = gfx->create_texture(textureInfo);
far_field = gfx->create_texture(textureInfo);
GFXFramebufferCreateInfo framebufferInfo = {};
framebufferInfo.render_pass = renderpass;
framebufferInfo.attachments = { normal_field };
normal_framebuffer = gfx->create_framebuffer(framebufferInfo);
framebufferInfo.attachments = { far_field };
far_framebuffer = gfx->create_framebuffer(framebufferInfo);
}
void DoFPass::render(GFXCommandBuffer* command_buffer, Scene&) {
const auto render_extent = renderer->get_render_extent();
// render far field
GFXRenderPassBeginInfo beginInfo = {};
beginInfo.framebuffer = far_framebuffer;
beginInfo.render_pass = renderpass;
command_buffer->set_render_pass(beginInfo);
Viewport viewport = {};
viewport.width = render_extent.width;
viewport.height = render_extent.height;
command_buffer->set_viewport(viewport);
command_buffer->set_graphics_pipeline(pipeline);
command_buffer->bind_texture(renderer->offscreenColorTexture, 0);
@ -43,5 +89,26 @@ void DoFPass::render(GFXCommandBuffer* command_buffer, Scene&) {
const auto extent = renderer->get_render_extent();
Vector4 params(render_options.depth_of_field_strength, 0.0, 0.0, 0.0);
command_buffer->set_push_constant(&params, sizeof(Vector4));
command_buffer->draw(0, 4, 0, extent.width * extent.height);
// render normal field
beginInfo.framebuffer = normal_framebuffer;
command_buffer->set_render_pass(beginInfo);
command_buffer->set_graphics_pipeline(pipeline);
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;
command_buffer->set_push_constant(&params, sizeof(Vector4));
command_buffer->draw(0, 4, 0, extent.width * extent.height);
}

View file

@ -225,7 +225,7 @@ void Renderer::render(Scene* scene, int index) {
if(scene != nullptr && hasToRender) {
commandbuffer->push_group("Shadow Rendering");
shadow_pass->render(commandbuffer, *scene);
commandbuffer->pop_group();
@ -242,7 +242,7 @@ void Renderer::render(Scene* scene, int index) {
for(auto& [obj, camera] : cameras) {
const int actual_width = render_extent.width / cameras.size();
camera.perspective = transform::infinite_perspective(radians(camera.fov), static_cast<float>(actual_width) / static_cast<float>(render_extent.height), camera.near);
camera.perspective = transform::perspective(radians(camera.fov), static_cast<float>(actual_width) / static_cast<float>(render_extent.height), 0.1f, 100.0f);
camera.view = inverse(scene->get<Transform>(obj).model);
Viewport viewport = {};
@ -255,7 +255,7 @@ void Renderer::render(Scene* scene, int index) {
commandbuffer->push_group("render camera");
render_camera(commandbuffer, *scene, obj, camera, get_render_extent(), continuity);
commandbuffer->pop_group();
}
}
@ -268,6 +268,8 @@ void Renderer::render(Scene* scene, int index) {
commandbuffer->pop_group();
dofPass->render(commandbuffer, *scene);
if(!viewport_mode) {
beginInfo.framebuffer = nullptr;
beginInfo.render_pass = nullptr;
@ -311,22 +313,35 @@ void Renderer::render(Scene* scene, int index) {
commandbuffer->dispatch(1, 1, 1);
commandbuffer->set_graphics_pipeline(viewport_mode ? renderToViewportPipeline : postPipeline);
commandbuffer->bind_texture(offscreenColorTexture, 1);
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)) {
if(auto texture = get_requested_texture(PassTextureType::SelectionSobel))
commandbuffer->bind_texture(texture, 4);
} else {
else
commandbuffer->bind_texture(dummyTexture, 4);
}
commandbuffer->bind_texture(average_luminance_texture, 5);
if(render_options.enable_depth_of_field)
commandbuffer->bind_texture(dofPass->far_field, 6);
else
commandbuffer->bind_texture(dummyTexture, 6);
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;
@ -346,6 +361,7 @@ void Renderer::render(Scene* scene, int index) {
commandbuffer->draw(0, 4, 0, 1);
commandbuffer->pop_group();
if(current_screen != nullptr)

View file

@ -7,16 +7,22 @@ layout(location = 0) out vec4 outColor;
layout(rgba32f, binding = 0) uniform image2D color_sampler;
layout(binding = 2) uniform sampler2D aperture_sampler;
vec4 fromLinear(vec4 linearRGB)
{
return pow(linearRGB, vec4(1.0/2.2));
}
layout(push_constant, binding = 2) uniform readonly PushConstant{
vec4 params;
};
void main() {
/*if(depth < 0.98)
discard;*/
// far field mode
if(params.y == 0) {
if(depth < 0.98)
discard;
}
if(inUV.y > 1.0 || inUV.x > 1.0)
discard;
outColor = vec4(fromLinear(imageLoad(color_sampler, inPixel)).rgb, 1.0) * texture(aperture_sampler, inUV);
outColor = vec4(imageLoad(color_sampler, inPixel).rgb, 1.0);
if(params.y == 0) {
outColor = outColor * texture(aperture_sampler, inUV);
}
}

View file

@ -7,6 +7,10 @@ layout(location = 2) out float outDepth;
layout(binding = 1) uniform sampler2D depth_sampler;
layout(push_constant, binding = 2) uniform readonly PushConstant{
vec4 params;
};
void main() {
outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
@ -17,7 +21,12 @@ void main() {
outDepth = depth;
vec2 pos = vec2(outUV * 2.0 + -1.0);
pos *= 5.0 * depth;
// far field mode
if(params.y == 0) {
pos *= params.x * depth;
}
pos += vec2(pixel.x, pixel.y);
pos *= 2.0 / vec2(width, height);
pos += vec2(-1, -1);

View file

@ -24,6 +24,7 @@ layout (binding = 2) uniform sampler2D backSampler;
layout (binding = 3) uniform sampler2D blendSampler;
layout (binding = 4) uniform sampler2D sobelSampler;
layout (binding = 5) uniform sampler2D averageLuminanceSampler;
layout (binding = 6) uniform sampler2D farFieldSampler;
float calculate_sobel() {
float x = 1.0 / viewport.z;
@ -109,12 +110,18 @@ void main() {
return;
}
bool enable_dof = options.w == 2;
vec3 sceneColor = vec3(0);
if(options.x == 1) // enable AA
sceneColor = SMAANeighborhoodBlendingPS(inUV, inOffset, colorSampler, blendSampler).rgb;
else
sceneColor = texture(colorSampler, inUV).rgb;
if(enable_dof) {
sceneColor = texture(farFieldSampler, inUV).rgb;
sceneColor += texture(colorSampler, inUV).rgb;
} else {
if(options.x == 1) // enable AA
sceneColor = SMAANeighborhoodBlendingPS(inUV, inOffset, colorSampler, blendSampler).rgb;
else
sceneColor = texture(colorSampler, inUV).rgb;
}
float sobel = 0.0;
if(textureSize(sobelSampler, 0).x > 1)
sobel = calculate_sobel();