Improved volumetric performance

This commit is contained in:
Antoine Pilote
2023-07-05 09:57:09 -04:00
parent c2b80eb2f9
commit 9b973784c1
5 changed files with 106 additions and 16 deletions

View File

@@ -22,15 +22,14 @@ uniform sampler2D u_Input;
void main() {
vec2 texelSize = 1.0 / vec2(textureSize(u_Input, 0));
float result = 0.0;
vec4 result = vec4(0);
for (int x = -2; x < 2; ++x)
{
for (int y = -2; y < 2; ++y)
{
vec2 offset = vec2(float(x), float(y)) * texelSize;
result += texture(u_Input, UV + offset).r;
result += texture(u_Input, UV + offset);
}
}
float channel = result / (4.0 * 4.0);
FragColor = vec4(channel, channel, channel, 1.0);
FragColor = result / (4.0 * 4.0);
}

View File

@@ -0,0 +1,67 @@
#shader vertex
#version 460 core
layout(location = 0) in vec3 VertexPosition;
layout(location = 1) in vec2 UVPosition;
out flat vec2 UV;
void main()
{
UV = UVPosition;
gl_Position = vec4(VertexPosition, 1.0f);
}
#shader fragment
#version 460 core
out vec4 FragColor;
in vec2 UV;
uniform sampler2D u_Input;
uniform sampler2D u_Depth;
const float SHARPNESS = 10.0f;
const float KERNEL_RADIUS = 8.0f;
void main() {
vec2 texelSize = 1.0 / vec2(textureSize(u_Input, 0));
vec4 result = vec4(0);
float centerDepth = texture(u_Depth, UV).r;
float totalWeight = 0.0f;
for (int x = -2; x < 2; ++x)
{
vec2 offset = vec2(float(x), float(0)) * texelSize;
vec2 uv = UV + offset;
float depth = texture(u_Depth, uv).r;
const float blurSigma = float(KERNEL_RADIUS) * 0.5f;
const float blurFalloff = 1.0 / (2.0 * blurSigma * blurSigma);
float depthDiff = abs(depth - centerDepth) * SHARPNESS;
float weight = exp2(-x * x * blurFalloff - depthDiff * depthDiff);
totalWeight += weight;
result += texture(u_Input, uv) * weight;
}
for (int y = -2; y < 2; ++y)
{
vec2 offset = vec2(float(0), float(y)) * texelSize;
vec2 uv = UV + offset;
float depth = texture(u_Depth, uv).r;
const float blurSigma = float(KERNEL_RADIUS) * 0.5f;
const float blurFalloff = 1.0 / (2.0 * blurSigma * blurSigma);
float depthDiff = abs(depth - centerDepth) * SHARPNESS;
float weight = exp2(-y * y * blurFalloff - depthDiff * depthDiff);
totalWeight += weight;
result += texture(u_Input, uv) * weight;
}
FragColor = result / totalWeight;
}

View File

@@ -22,6 +22,11 @@ void main()
#shader fragment
#version 460 core
float ditherPattern[4][4] = { { 0.0f, 0.5f, 0.125f, 0.625f},
{ 0.75f, 0.22f, 0.875f, 0.375f},
{ 0.1875f, 0.6875f, 0.0625f, 0.5625},
{ 0.9375f, 0.4375f, 0.8125f, 0.3125} };
in mat4 InvView;
in mat4 InvProjection;
@@ -52,7 +57,7 @@ const float PI = 3.141592653589793f;
// Mie scaterring approximated with Henyey-Greenstein phase function.
float ComputeScattering(float lightDotView)
{
float result = 1.0f - u_FogAmount * u_FogAmount;
float result = 1.0f - u_FogAmount ;
result /= (4.0f * PI * pow(1.0f + u_FogAmount * u_FogAmount - (2.0f * u_FogAmount) * lightDotView, 1.5f));
return result;
}
@@ -64,7 +69,7 @@ vec3 ComputeVolumetric(vec3 FragPos, Light light)
float rayLength = length(rayVector); // Length of the raymarched
//if(rayLength > 1000.0)
// return vec3(0.0, 0.0, 0.0);
// return vec3(1.0, 1.0, 1.0);
float stepLength = rayLength / u_StepCount; // Step length
vec3 rayDirection = rayVector / rayLength;
vec3 step = rayDirection * stepLength; // Normalized to step length direction
@@ -91,12 +96,12 @@ vec3 ComputeVolumetric(vec3 FragPos, Light light)
//accumFog = vec3(projCoords.x, projCoords.y, 1.0);
}
currentPosition += step; //* ditherPattern[int(gl_FragCoord.x) % 4][int(gl_FragCoord.y) % 4];
currentPosition += step * ditherPattern[int(gl_FragCoord.x) % 4][int(gl_FragCoord.y) % 4];
//accumFog = vec3(projCoords);
}
accumFog /= u_StepCount;
return accumFog * 5.0;
return accumFog * 4.0;
}
// Converts depth to World space coords.
@@ -125,7 +130,7 @@ void main()
fog += ComputeVolumetric(globalFragmentPosition, u_Lights[i]);
}
FragColor = vec4(fog, 1.0f);
FragColor = vec4(fog, 1.0);
//FragColor = vec4(mix(fog, ComputeVolumetric(globalFragmentPosition, u_Lights[0]), 0.9f), 0.01);
//FragColor = vec4(globalFragmentPosition * 10.0, 1.0f);
//FragColor = vec4(globalFragmentPosition.xyz * 100.0, 1.0f);

View File

@@ -20,6 +20,9 @@ namespace Nuake {
{
mFinalFramebuffer = CreateScope<FrameBuffer>(true, mSize);
mFinalFramebuffer->SetTexture(CreateRef<Texture>(mSize, GL_RGBA, GL_RGBA16F, GL_FLOAT));
mVolumetricFramebuffer = CreateScope<FrameBuffer>(true, mSize);
mVolumetricFramebuffer->SetTexture(CreateRef<Texture>(mSize, GL_RGBA, GL_RGBA16F, GL_FLOAT));
}
void Volumetric::Resize(Vector2 size)
@@ -28,14 +31,15 @@ namespace Nuake {
return;
mSize = size * mRenderRatio;
mFinalFramebuffer->QueueResize(mSize);
mVolumetricFramebuffer->QueueResize(mSize);
mVolumetricFramebuffer->QueueResize(mSize);
}
void Volumetric::Draw(Matrix4 projection, Matrix4 view, const Vector3& camPos, std::vector<LightComponent>& lights)
{
mFinalFramebuffer->Bind();
mFinalFramebuffer->Clear();
mVolumetricFramebuffer->Bind();
{
mVolumetricFramebuffer->Clear();
RenderCommand::Disable(RendererEnum::FACE_CULL);
auto cameraPosition = Vector3(view[3]);
@@ -62,17 +66,30 @@ namespace Nuake {
volumetricShader->SetUniform1f(u_light + "strength", light.Strength);
}
Renderer::DrawQuad();
}
mVolumetricFramebuffer->Unbind();
// Blur
mFinalFramebuffer->Bind();
{
mFinalFramebuffer->Clear();
Shader* blurShader = ShaderManager::GetShader("resources/Shaders/blur.shader");
blurShader->Bind();
//blurShader->SetUniformTex("u_Depth", mDepth, 1);
blurShader->SetUniformTex("u_Input", mVolumetricFramebuffer->GetTexture().get());
Renderer::DrawQuad();
}
mFinalFramebuffer->Unbind();
/*
if (ImGui::Begin("Volumetric debug"))
{
ImGui::Image((void*)(uintptr_t)(mFinalFramebuffer->GetTexture()->GetID()), ImGui::GetContentRegionAvail(), ImVec2(0, 1), ImVec2(1, 0));
}
ImGui::End();
/*
if (ImGui::Begin("Volumetric debug depth"))
{
ImGui::Image((void*)(uintptr_t)(mDepth->GetID()), ImGui::GetContentRegionAvail(), ImVec2(0, 1), ImVec2(1, 0));

View File

@@ -10,11 +10,13 @@ namespace Nuake {
{
private:
uint32_t mStepCount = 50;
float mRenderRatio = 1.0f;
float mRenderRatio = 0.75f;
float mFogAmount = 0.4f;
Vector2 mSize;
Texture* mDepth;
Scope<FrameBuffer> mVolumetricFramebuffer;
Scope<FrameBuffer> mFinalFramebuffer;
public: