-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c930f5e
commit f36901d
Showing
24 changed files
with
434 additions
and
58 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
#version 450 core | ||
|
||
layout (binding = 0) uniform sampler2D u_ScreenTexture; | ||
layout (binding = 1) uniform sampler2D u_Mask; | ||
|
||
in vec2 v_UV; | ||
in vec2 v_Pos; | ||
|
||
out vec4 FragColor; | ||
|
||
void main() | ||
{ | ||
vec3 finalColor = vec3(0.0); | ||
vec3 originalColor = texture(u_ScreenTexture, v_UV).rgb; | ||
|
||
float maskValue = texture(u_Mask, v_UV).r; | ||
|
||
if (maskValue > 0.0) | ||
{ | ||
float offset = 1.0 / 150.0; | ||
|
||
vec2 box[9] = vec2[]( | ||
vec2(-offset, offset), vec2(0.0, offset), vec2(offset, offset), | ||
vec2(-offset, 0.0), vec2(0.0f, 0.0), vec2(offset, 0.0), | ||
vec2(-offset, -offset), vec2(0.0, -offset), vec2(offset, -offset) | ||
); | ||
|
||
float kernel[9] = float[]( | ||
0.0625, 0.125, 0.0625, | ||
0.125, 0.25, 0.125, | ||
0.0625, 0.125, 0.0625 | ||
); | ||
|
||
vec3 sampleTex[9]; | ||
for(int i = 0; i < 9; i++) | ||
{ | ||
sampleTex[i] = vec3(texture(u_ScreenTexture, v_UV + box[i])); | ||
} | ||
|
||
vec3 blurredColor = vec3(0.0); | ||
for(int i = 0; i < 9; i++) | ||
blurredColor += sampleTex[i] * kernel[i]; | ||
|
||
finalColor = mix(originalColor, blurredColor, maskValue); | ||
} | ||
else | ||
{ | ||
finalColor = originalColor; | ||
} | ||
|
||
FragColor = vec4(finalColor, 1.0); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#version 450 core | ||
layout (location = 0) in vec2 a_Pos; | ||
layout (location = 1) in vec2 a_UV; | ||
|
||
out vec2 v_UV; | ||
out vec2 v_Pos; | ||
|
||
void main() | ||
{ | ||
v_UV = a_UV; | ||
v_Pos = a_Pos; | ||
gl_Position = vec4(a_Pos, 0.0, 1.0); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
#include "PostProcessor.h" | ||
|
||
#include "RHI/Shader.h" | ||
#include "RHI/Texture.h" | ||
#include "Renderer.h" | ||
|
||
#include "Resources/TextureManager.h" | ||
|
||
namespace elv { | ||
|
||
constexpr std::uint16_t kDefaultMaskThreshold = 64; | ||
constexpr std::uint16_t kMaskWidth = 128; | ||
constexpr std::uint16_t kMaskHeight = 96; | ||
constexpr std::uint16_t kMaskDataSize = kMaskWidth * kMaskHeight; | ||
|
||
constexpr float kMaxIntensity = 255.0f; | ||
constexpr std::uint16_t kCheckboardSquareSize = 8; | ||
constexpr std::uint16_t kExpGradientRate = 3; | ||
|
||
PostProcessor::PostProcessor() | ||
: m_renderTargetPostProcessor(RenderTarget::Create()) | ||
{ | ||
} | ||
|
||
void PostProcessor::Init(const std::uint32_t width, const std::uint32_t height) | ||
{ | ||
m_blurShader = ShaderManager::Load("post_processing", "post_processing.vert", "post_processing.frag"); | ||
m_renderTargetPostProcessor->Init(width, height); | ||
|
||
BlurMaskThreshold = kDefaultMaskThreshold; | ||
BuildBlurMask(BlurGradientMaskType::Linear); | ||
} | ||
|
||
void PostProcessor::BuildBlurMask(const BlurGradientMaskType type) | ||
{ | ||
GradientMaskType = type; | ||
|
||
std::uint8_t* data = new std::uint8_t[kMaskDataSize]; | ||
|
||
switch (type) { | ||
case BlurGradientMaskType::Linear: | ||
CreateLinearGradientMask(data); | ||
break; | ||
case BlurGradientMaskType::Checkboard: | ||
CreateCheckerboarGradientMask(data); | ||
break; | ||
case BlurGradientMaskType::Triangular: | ||
CreateTriangularGradientMask(data); | ||
break; | ||
case BlurGradientMaskType::Radial: | ||
CreateRadialGradientMask(data); | ||
break; | ||
case BlurGradientMaskType::Exponential: | ||
CreateExponentialGradientMask(data); | ||
break; | ||
} | ||
|
||
m_blurMaskTexture = textures::Load("blur_mask", kMaskWidth, kMaskHeight, 1); | ||
m_blurMaskTexture->SetData(data, false); | ||
|
||
delete[] data; | ||
} | ||
|
||
std::shared_ptr<Texture> PostProcessor::Process(Renderer* renderer, const std::shared_ptr<Texture>& src) | ||
{ | ||
if (IsBlurEnabled) { | ||
m_renderTargetPostProcessor->Bind(); | ||
renderer->EnableDepthTesting(false); | ||
renderer->ClearBufferBit(Renderer::BufferBitType::Color); | ||
|
||
m_blurShader->Bind(); | ||
|
||
src->BindToSlot(0); | ||
m_blurMaskTexture->BindToSlot(1); | ||
|
||
renderer->RenderNDCQuad(); | ||
|
||
return m_renderTargetPostProcessor->GetColorTextureAttachment(); | ||
} | ||
|
||
return src; | ||
} | ||
|
||
void PostProcessor::OnWindowResized(const std::uint32_t width, const std::uint32_t height) | ||
{ | ||
m_renderTargetPostProcessor->Resize(width, height); | ||
} | ||
|
||
void PostProcessor::CreateLinearGradientMask(unsigned char* data) | ||
{ | ||
for (int y = 0; y < kMaskHeight; ++y) { | ||
memset(data + y * kMaskWidth, 0, BlurMaskThreshold); | ||
memset(data + y * kMaskWidth + BlurMaskThreshold, static_cast<std::uint8_t>(kMaxIntensity), kMaskWidth - BlurMaskThreshold); | ||
} | ||
} | ||
|
||
void PostProcessor::CreateCheckerboarGradientMask(unsigned char* data) | ||
{ | ||
for (int y = 0; y < kMaskHeight; ++y) { | ||
memset(data + y * kMaskWidth, 0, BlurMaskThreshold); | ||
for (int x = BlurMaskThreshold; x < kMaskWidth; ++x) { | ||
data[y * kMaskWidth + x] = ((x / kCheckboardSquareSize) + (y / kCheckboardSquareSize)) % 2 == 0 ? 0 : static_cast<std::uint8_t>(kMaxIntensity); | ||
} | ||
} | ||
} | ||
|
||
void PostProcessor::CreateTriangularGradientMask(unsigned char* data) | ||
{ | ||
for (int y = 0; y < kMaskHeight; ++y) { | ||
memset(data + y * kMaskWidth, 0, BlurMaskThreshold); | ||
for (int x = BlurMaskThreshold; x < kMaskWidth; ++x) { | ||
const float intensity = (x + y) / static_cast<float>(kMaskWidth + kMaskHeight) * kMaxIntensity; | ||
data[y * kMaskWidth + x] = static_cast<std::uint8_t>(intensity); | ||
} | ||
} | ||
} | ||
|
||
void PostProcessor::CreateRadialGradientMask(unsigned char* data) | ||
{ | ||
const int centerX = (kMaskWidth - BlurMaskThreshold) / 2; | ||
const int centerY = kMaskHeight / 2; | ||
const float maxDistance = sqrt(static_cast<float>((centerX) * (centerX) + (centerY) * (centerY))); | ||
|
||
for (int y = 0; y < kMaskHeight; ++y) { | ||
memset(data + y * kMaskWidth, 0, BlurMaskThreshold); | ||
for (int x = BlurMaskThreshold, i = 0; x < kMaskWidth; ++x, ++i) { | ||
const float distance = sqrt(static_cast<float>((i - centerX) * (i - centerX) + (y - centerY) * (y - centerY))); | ||
const float intensity = distance / maxDistance * kMaxIntensity; | ||
|
||
data[y * kMaskWidth + x] = static_cast<std::uint8_t>(intensity); | ||
} | ||
} | ||
} | ||
|
||
void PostProcessor::CreateExponentialGradientMask(unsigned char* data) | ||
{ | ||
for (int y = 0; y < kMaskHeight; ++y) { | ||
memset(data + y * kMaskWidth, 0, BlurMaskThreshold); | ||
for (int x = BlurMaskThreshold, i = 0; x < kMaskWidth; ++x, ++i) { | ||
const float intensity = expf(kExpGradientRate * i / static_cast<float>(kMaskWidth - BlurMaskThreshold)) * kMaxIntensity; | ||
data[y * kMaskWidth + x] = static_cast<std::uint8_t>(intensity); | ||
} | ||
} | ||
} | ||
|
||
int PostProcessor::GetMaskTextureId() const | ||
{ | ||
return m_blurMaskTexture->GetId(); | ||
} | ||
} // namespace elv |
Oops, something went wrong.