Skip to content

Commit

Permalink
Camera Post-processing (#78)
Browse files Browse the repository at this point in the history
1. Added Physically-based bloom.
2. Added screen space ambient occlusion (SSAO).
3. Added screen space reflection (SSR).
4. Adjusted Demo scene.
  • Loading branch information
edisonlee0212 authored Dec 23, 2024
1 parent 51cc48d commit 6c8c522
Show file tree
Hide file tree
Showing 31 changed files with 1,818 additions and 597 deletions.
9 changes: 4 additions & 5 deletions EvoEngine_App/DemoApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ void SetupDemoScene(DemoSetup demo_setup, ApplicationInfo& application_info) {
application_info.application_name = "Rendering Demo";
application_info.project_path = resource_folder_path / "Example Projects/Rendering/Rendering.eveproj";
ProjectManager::SetActionAfterNewScene([&](const std::shared_ptr<Scene>& scene) {
scene->environment.ambient_light_intensity = 0.1f;
scene->environment.ambient_light_intensity = 0.4f;
#pragma region Set main camera to correct position and rotation
const auto main_camera = scene->main_camera.Get<Camera>();
main_camera->Resize({640, 480});
Expand Down Expand Up @@ -311,10 +311,10 @@ void SetupDemoScene(DemoSetup demo_setup, ApplicationInfo& application_info) {
const auto point_light_right_material = ProjectManager::CreateTemporaryAsset<Material>();
point_light_right_renderer->material.Set<Material>(point_light_right_material);
point_light_right_material->material_properties.albedo_color = glm::vec3(1.0, 0.8, 0.0);
point_light_right_material->material_properties.emission = 100.0f;
point_light_right_material->material_properties.emission = 10.0f;
point_light_right_renderer->mesh = Resources::GetResource<Mesh>("PRIMITIVE_SPHERE");
const auto point_light_right = scene->GetOrSetPrivateComponent<PointLight>(point_light_right_entity).lock();
point_light_right->diffuse_brightness = 4;
point_light_right->diffuse_brightness = 30;
point_light_right->light_size = 0.02f;
point_light_right->linear = 0.5f;
point_light_right->quadratic = 0.1f;
Expand Down Expand Up @@ -380,8 +380,6 @@ void SetupDemoScene(DemoSetup demo_setup, ApplicationInfo& application_info) {
main_camera_transform.SetPosition(glm::vec3(0, -4, 25));
scene->SetDataComponent(main_camera_entity, main_camera_transform);
scene->GetOrSetPrivateComponent<PlayerController>(main_camera_entity);
// auto postProcessing = scene->GetOrSetPrivateComponent<PostProcessing>(mainCameraEntity).lock();

const auto surface_material = ProjectManager::CreateTemporaryAsset<Material>();
const auto border_texture =
std::dynamic_pointer_cast<Texture2D>(ProjectManager::GetOrCreateAsset("Textures/border.png"));
Expand Down Expand Up @@ -441,6 +439,7 @@ void SetupDemoScene(DemoSetup demo_setup, ApplicationInfo& application_info) {
Entity dle = scene->CreateEntity("Directional Light");
auto dlc = scene->GetOrSetPrivateComponent<DirectionalLight>(dle).lock();
dlc->diffuse = glm::vec3(1.0f);
dlc->diffuse_brightness = 3.f;
ltw.SetScale(glm::vec3(0.5f));

Entity ple = scene->CreateEntity("Point Light 1");
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#extension GL_ARB_shading_language_include : enable

#include "PerFrame.glsl"

layout (location = 0) out vec4 outSrcColor;
layout (location = 1) out vec4 outResultColor;

layout (location = 0) in VS_OUT {
vec2 TexCoord;
} fs_in;

layout(set = 1, binding = 0) uniform sampler2D inColor;

void main()
{
vec2 texCoord = fs_in.TexCoord;
outSrcColor = texture(inColor, texCoord);

outResultColor = vec4(max(vec3(0.00001f), texture(inColor, texCoord).xyz - vec3(1.0f)), 1.0f);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@



// This shader performs downsampling on a texture,
// as taken from Call Of Duty method, presented at ACM Siggraph 2014.
// This particular method was customly designed to eliminate
// "pulsating artifacts and temporal stability issues".

// Remember to add bilinear minification filter for this texture!
// Remember to use a floating-point texture format (for HDR)!
// Remember to use edge clamping for this texture!
layout(set = 1, binding = 0) uniform sampler2D srcTexture;

layout (location = 0) in VS_OUT {
vec2 TexCoord;
} fs_in;

layout (location = 0) out vec4 downsample;
layout(push_constant) uniform EE_BLOOM_CONSTANTS{
vec2 srcResolution;
int mipLevel;
int padding;
};

vec3 PowVec3(vec3 v, float p)
{
return vec3(pow(v.x, p), pow(v.y, p), pow(v.z, p));
}

const float invGamma = 1.0 / 2.2;
vec3 ToSRGB(vec3 v) { return PowVec3(v, invGamma); }

float sRGBToLuma(vec3 col)
{
//return dot(col, vec3(0.2126f, 0.7152f, 0.0722f));
return dot(col, vec3(0.299f, 0.587f, 0.114f));
}

float KarisAverage(vec3 col)
{
// Formula is 1 / (1 + luma)
float luma = sRGBToLuma(ToSRGB(col)) * 0.25f;
return 1.0f / (1.0f + luma);
}


void main()
{
vec2 texCoord = fs_in.TexCoord;
vec2 srcTexelSize = 1.0f / srcResolution;
float x = srcTexelSize.x;
float y = srcTexelSize.y;

// Take 13 samples around current texel:
// a - b - c
// - j - k -
// d - e - f
// - l - m -
// g - h - i
// === ('e' is the current texel) ===
vec3 a = texture(srcTexture, vec2(texCoord.x - 2 * x, texCoord.y + 2 * y)).rgb;
vec3 b = texture(srcTexture, vec2(texCoord.x, texCoord.y + 2 * y)).rgb;
vec3 c = texture(srcTexture, vec2(texCoord.x + 2 * x, texCoord.y + 2 * y)).rgb;

vec3 d = texture(srcTexture, vec2(texCoord.x - 2 * x, texCoord.y)).rgb;
vec3 e = texture(srcTexture, vec2(texCoord.x, texCoord.y)).rgb;
vec3 f = texture(srcTexture, vec2(texCoord.x + 2 * x, texCoord.y)).rgb;

vec3 g = texture(srcTexture, vec2(texCoord.x - 2 * x, texCoord.y - 2 * y)).rgb;
vec3 h = texture(srcTexture, vec2(texCoord.x, texCoord.y - 2 * y)).rgb;
vec3 i = texture(srcTexture, vec2(texCoord.x + 2 * x, texCoord.y - 2 * y)).rgb;

vec3 j = texture(srcTexture, vec2(texCoord.x - x, texCoord.y + y)).rgb;
vec3 k = texture(srcTexture, vec2(texCoord.x + x, texCoord.y + y)).rgb;
vec3 l = texture(srcTexture, vec2(texCoord.x - x, texCoord.y - y)).rgb;
vec3 m = texture(srcTexture, vec2(texCoord.x + x, texCoord.y - y)).rgb;

// Apply weighted distribution:
// 0.5 + 0.125 + 0.125 + 0.125 + 0.125 = 1
// a,b,d,e * 0.125
// b,c,e,f * 0.125
// d,e,g,h * 0.125
// e,f,h,i * 0.125
// j,k,l,m * 0.5
// This shows 5 square areas that are being sampled. But some of them overlap,
// so to have an energy preserving downsample we need to make some adjustments.
// The weights are the distributed, so that the sum of j,k,l,m (e.g.)
// contribute 0.5 to the final color output. The code below is written
// to effectively yield this sum. We get:
// 0.125*5 + 0.03125*4 + 0.0625*4 = 1
vec3 result = e * 0.125f;
result += (a + c + g + i) * 0.03125f;
result += (b + d + f + h) * 0.0625f;
result += (j + k + l + m) * 0.125f;

vec3 groups[5];
switch (mipLevel)
{
case 0:
// We are writing to mip 0, so we need to apply Karis average to each block
// of 4 samples to prevent fireflies (very bright subpixels, leads to pulsating
// artifacts).
groups[0] = (a + b + d + e) * (0.125f / 4.0f);
groups[1] = (b + c + e + f) * (0.125f / 4.0f);
groups[2] = (d + e + g + h) * (0.125f / 4.0f);
groups[3] = (e + f + h + i) * (0.125f / 4.0f);
groups[4] = (j + k + l + m) * (0.5f / 4.0f);
groups[0] *= KarisAverage(groups[0]);
groups[1] *= KarisAverage(groups[1]);
groups[2] *= KarisAverage(groups[2]);
groups[3] *= KarisAverage(groups[3]);
groups[4] *= KarisAverage(groups[4]);
result = groups[0] + groups[1] + groups[2] + groups[3] + groups[4];
result = max(result, 0.0001f);
break;
default:
result = e * 0.125f;
result += (a + c + g + i) * 0.03125f;
result += (b + d + f + h) * 0.0625f;
result += (j + k + l + m) * 0.125f;
break;
}

downsample = vec4(result, 1.0f);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#extension GL_ARB_shading_language_include : enable

layout (location = 0) out vec4 FragColor;
layout (location = 0) in VS_OUT {
vec2 TexCoord;
} fs_in;

layout(set = 1, binding = 0) uniform sampler2D originalColor;
layout(set = 1, binding = 1) uniform sampler2D bloomColor;

void main()
{
vec2 texCoord = fs_in.TexCoord;
vec4 color = texture(originalColor, texCoord);
FragColor = vec4(clamp(color.xyz, vec3(0.0f), vec3(1.0f)) + texture(bloomColor, texCoord).xyz, color.w);
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@



// This shader performs downsampling on a texture,
// as taken from Call Of Duty method, presented at ACM Siggraph 2014.
// This particular method was customly designed to eliminate
// "pulsating artifacts and temporal stability issues".

// Remember to add bilinear minification filter for this texture!
// Remember to use a floating-point texture format (for HDR)!
// Remember to use edge clamping for this texture!
layout(set = 1, binding = 0) uniform sampler2D srcTexture;

layout (location = 0) in VS_OUT {
vec2 TexCoord;
} fs_in;

layout (location = 0) out vec4 upsample;
layout(push_constant) uniform EE_BLOOM_CONSTANTS{
float filterRadius;
};
void main()
{
vec2 texCoord = fs_in.TexCoord;
// The filter kernel is applied with a radius, specified in texture
// coordinates, so that the radius will vary across mip resolutions.
float x = filterRadius;
float y = filterRadius;

// Take 9 samples around current texel:
// a - b - c
// d - e - f
// g - h - i
// === ('e' is the current texel) ===
vec4 a = texture(srcTexture, vec2(texCoord.x - x, texCoord.y + y)).rgba;
vec4 b = texture(srcTexture, vec2(texCoord.x, texCoord.y + y)).rgba;
vec4 c = texture(srcTexture, vec2(texCoord.x + x, texCoord.y + y)).rgba;

vec4 d = texture(srcTexture, vec2(texCoord.x - x, texCoord.y)).rgba;
vec4 e = texture(srcTexture, vec2(texCoord.x, texCoord.y)).rgba;
vec4 f = texture(srcTexture, vec2(texCoord.x + x, texCoord.y)).rgba;

vec4 g = texture(srcTexture, vec2(texCoord.x - x, texCoord.y - y)).rgba;
vec4 h = texture(srcTexture, vec2(texCoord.x, texCoord.y - y)).rgba;
vec4 i = texture(srcTexture, vec2(texCoord.x + x, texCoord.y - y)).rgba;

// Apply weighted distribution, by using a 3x3 tent filter:
// 1 | 1 2 1 |
// -- * | 2 4 2 |
// 16 | 1 2 1 |
upsample = e * 4.0f;
upsample += (b + d + f + h)* 2.0f;
upsample += (a + c + g + i);
upsample *= 1.0f / 16.0f;
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
#extension GL_ARB_shading_language_include : enable

#include "SSRConstants.glsl"

precision highp float;

layout (location = 0) out vec4 FragColor;

layout (location = 0) in VS_OUT {
Expand All @@ -12,6 +8,12 @@ layout (location = 0) in VS_OUT {

layout(set = 0, binding = 0) uniform sampler2D image;


layout(push_constant) uniform BLUR_CONSTANTS{
int horizontal;
float weight[5];
};

void main()
{
vec2 tex_offset = 1.0 / textureSize(image, 0); // gets size of single texel
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#extension GL_ARB_shading_language_include : enable

layout (location = 0) out vec4 FragColor;

layout (location = 0) in VS_OUT {
vec2 TexCoord;
} fs_in;

layout(set = 1, binding = 17) uniform sampler2D inDepth;
layout(set = 1, binding = 18) uniform sampler2D inNormal;
layout(set = 1, binding = 19) uniform sampler2D inMaterial;

layout(set = 0, binding = 0) uniform sampler2D image;


layout(push_constant) uniform BLUR_CONSTANTS{
int horizontal;
float camera_near;
float camera_far;
float avoid_distance;
float weight[5];

};

float linearize_depth(float ndcDepth) {
return camera_near * camera_far / (camera_far - ndcDepth * (camera_far - camera_near));
}

void main()
{
vec2 tex_offset = 1.0 / textureSize(image, 0); // gets size of single texel
vec4 current = texture(image, fs_in.TexCoord).rgba;

vec4 result = current * weight[0]; // current fragment's contribution

float depth = linearize_depth(texture(inDepth, fs_in.TexCoord).x);

float max_depth_diff = avoid_distance;

if(horizontal != 0)
{
for(int i = 1; i < 5; ++i)
{
vec2 coord1 = fs_in.TexCoord + vec2(tex_offset.x * i, 0.0);
float depth1 = linearize_depth(texture(inDepth, coord1).x);

if(abs(depth1 - depth) < max_depth_diff) result += texture(image, coord1).rgba * weight[i];
else result += current * weight[i];

vec2 coord2 = fs_in.TexCoord - vec2(tex_offset.x * i, 0.0);
float depth2 = linearize_depth(texture(inDepth, coord2).x);

if(abs(depth2 - depth) < max_depth_diff) result += texture(image, coord2).rgba * weight[i];
else result += current * weight[i];
}
}
else
{
for(int i = 1; i < 5; ++i)
{
vec2 coord1 = fs_in.TexCoord + vec2(0.0, tex_offset.y * i);
float depth1 = linearize_depth(texture(inDepth, coord1).x);
if(abs(depth1 - depth) < max_depth_diff) result += texture(image, coord1).rgba * weight[i];
else result += current * weight[i];

vec2 coord2 = fs_in.TexCoord - vec2(0.0, tex_offset.y * i);
float depth2 = linearize_depth(texture(inDepth, coord2).x);
if(abs(depth2 - depth) < max_depth_diff) result += texture(image, coord2).rgba * weight[i];
else result += current * weight[i];
}
}
FragColor = result;
}
Loading

0 comments on commit 6c8c522

Please sign in to comment.