实现SSAO
parent
865f2be548
commit
7bee8eb5dc
|
@ -213,6 +213,8 @@
|
||||||
<None Include="res\Shaders\shadow_mapping.comp" />
|
<None Include="res\Shaders\shadow_mapping.comp" />
|
||||||
<None Include="res\Shaders\skybox.frag" />
|
<None Include="res\Shaders\skybox.frag" />
|
||||||
<None Include="res\Shaders\skybox.vert" />
|
<None Include="res\Shaders\skybox.vert" />
|
||||||
|
<None Include="res\Shaders\ssao.comp" />
|
||||||
|
<None Include="res\Shaders\ssao_blur.comp" />
|
||||||
<None Include="res\Shaders\ssgi.comp" />
|
<None Include="res\Shaders\ssgi.comp" />
|
||||||
<None Include="res\Shaders\tone_mapping.comp" />
|
<None Include="res\Shaders\tone_mapping.comp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -466,6 +466,8 @@
|
||||||
</None>
|
</None>
|
||||||
<None Include="res\Shaders\tone_mapping.comp" />
|
<None Include="res\Shaders\tone_mapping.comp" />
|
||||||
<None Include="res\Shaders\painting_shadow.frag" />
|
<None Include="res\Shaders\painting_shadow.frag" />
|
||||||
|
<None Include="res\Shaders\ssao.comp" />
|
||||||
|
<None Include="res\Shaders\ssao_blur.comp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<QtUic Include="EditorWidgetItem.ui">
|
<QtUic Include="EditorWidgetItem.ui">
|
||||||
|
|
|
@ -81,6 +81,16 @@
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="ssaoCheckBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>SSAO</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="fxaaCheckBox">
|
<widget class="QCheckBox" name="fxaaCheckBox">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
<file>Shaders/pageId_downsample.comp</file>
|
<file>Shaders/pageId_downsample.comp</file>
|
||||||
<file>Shaders/tone_mapping.comp</file>
|
<file>Shaders/tone_mapping.comp</file>
|
||||||
<file>Shaders/painting_shadow.frag</file>
|
<file>Shaders/painting_shadow.frag</file>
|
||||||
|
<file>Shaders/ssao.comp</file>
|
||||||
|
<file>Shaders/ssao_blur.comp</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
<qresource prefix="/qt/etc">
|
<qresource prefix="/qt/etc">
|
||||||
<file>qt.conf</file>
|
<file>qt.conf</file>
|
||||||
|
|
|
@ -5,7 +5,7 @@ layout (local_size_x = 8, local_size_y = 8) in;
|
||||||
layout(rgba8, binding = 0) uniform image2D gBaseColor;
|
layout(rgba8, binding = 0) uniform image2D gBaseColor;
|
||||||
uniform sampler2D gNormal;
|
uniform sampler2D gNormal;
|
||||||
uniform sampler2D gPosition;
|
uniform sampler2D gPosition;
|
||||||
uniform sampler2D gMetallicRoughness;
|
uniform sampler2D gMetallicRoughnessAO;
|
||||||
uniform sampler2DArray gShadowMap;
|
uniform sampler2DArray gShadowMap;
|
||||||
|
|
||||||
uniform samplerCube irradianceMap;
|
uniform samplerCube irradianceMap;
|
||||||
|
@ -187,8 +187,9 @@ void main()
|
||||||
vec4 baseColor = imageLoad(gBaseColor, pixelLocation);
|
vec4 baseColor = imageLoad(gBaseColor, pixelLocation);
|
||||||
if(baseColor.a == 0) return;
|
if(baseColor.a == 0) return;
|
||||||
vec3 albedo = pow(baseColor.rgb, vec3(2.2));
|
vec3 albedo = pow(baseColor.rgb, vec3(2.2));
|
||||||
float metallic = texelFetch(gMetallicRoughness, pixelLocation, 0).r;
|
float metallic = texelFetch(gMetallicRoughnessAO, pixelLocation, 0).r;
|
||||||
float roughness = texelFetch(gMetallicRoughness, pixelLocation, 0).g;
|
float roughness = texelFetch(gMetallicRoughnessAO, pixelLocation, 0).g;
|
||||||
|
float ambientOcclusion = 1.0 - texelFetch(gMetallicRoughnessAO, pixelLocation, 0).b;
|
||||||
|
|
||||||
vec3 worldPos = texelFetch(gPosition, pixelLocation,0).xyz;
|
vec3 worldPos = texelFetch(gPosition, pixelLocation,0).xyz;
|
||||||
vec3 normal = (texelFetch(gNormal, pixelLocation,0).xyz - vec3(0.5)) * 2;
|
vec3 normal = (texelFetch(gNormal, pixelLocation,0).xyz - vec3(0.5)) * 2;
|
||||||
|
@ -224,7 +225,7 @@ void main()
|
||||||
float NdotL = max(dot(normal, L), 0.0);
|
float NdotL = max(dot(normal, L), 0.0);
|
||||||
vec3 Lo = (kD * albedo / PI + specular) * radiance * NdotL;
|
vec3 Lo = (kD * albedo / PI + specular) * radiance * NdotL;
|
||||||
|
|
||||||
vec3 ambient = ambientLighting(normal, V, F0, albedo, metallic, roughness, 1);
|
vec3 ambient = ambientLighting(normal, V, F0, albedo, metallic, roughness, 1) * ambientOcclusion;
|
||||||
|
|
||||||
int debugLayer;
|
int debugLayer;
|
||||||
float shadow = ShadowCalculation(worldPos, normal, debugLayer);
|
float shadow = ShadowCalculation(worldPos, normal, debugLayer);
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
#version 450 core
|
||||||
|
|
||||||
|
layout (local_size_x = 8, local_size_y = 8) in;
|
||||||
|
|
||||||
|
layout(rgba8, binding = 1) uniform image2D gMetallicRoughnessAO;
|
||||||
|
|
||||||
|
uniform sampler2D gPosition;
|
||||||
|
uniform sampler2D gNormal;
|
||||||
|
uniform sampler2D texNoise;
|
||||||
|
|
||||||
|
uniform vec3 samples[64];
|
||||||
|
|
||||||
|
// parameters (you'd probably want to use them as uniforms to more easily tweak the effect)
|
||||||
|
int kernelSize = 32;
|
||||||
|
float radius = 0.5;
|
||||||
|
float bias = 0.025;
|
||||||
|
|
||||||
|
// tile noise texture over screen based on screen dimensions divided by noise size
|
||||||
|
const vec2 noiseScale = vec2(1./4.0, 1./4.0);
|
||||||
|
|
||||||
|
uniform mat4 projection;
|
||||||
|
uniform mat4 view;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
ivec2 pixelLocation = ivec2(gl_GlobalInvocationID.xy);
|
||||||
|
|
||||||
|
// get input for SSAO algorithm
|
||||||
|
vec3 worldPos = texelFetch(gPosition, pixelLocation, 0).xyz;
|
||||||
|
vec3 fragPos = (view * vec4(worldPos, 1.0)).xyz;
|
||||||
|
vec3 normal = normalize((texelFetch(gNormal, pixelLocation, 0).xyz - vec3(0.5)) * 2);
|
||||||
|
vec3 randomVec = normalize(texture(texNoise, vec2(pixelLocation) * noiseScale).xyz);
|
||||||
|
// create TBN change-of-basis matrix: from tangent-space to view-space
|
||||||
|
vec3 tangent = normalize(randomVec - normal * dot(randomVec, normal));
|
||||||
|
vec3 bitangent = cross(normal, tangent);
|
||||||
|
mat3 TBN = mat3(tangent, bitangent, normal);
|
||||||
|
// iterate over the sample kernel and calculate occlusion factor
|
||||||
|
float occlusion = 0.0;
|
||||||
|
for(int i = 0; i < kernelSize; ++i)
|
||||||
|
{
|
||||||
|
// get sample position
|
||||||
|
vec3 samplePos = TBN * samples[i]; // from tangent to view-space
|
||||||
|
samplePos = fragPos + samplePos * radius;
|
||||||
|
|
||||||
|
// project sample position (to sample texture) (to get position on screen/texture)
|
||||||
|
vec4 offset = vec4(samplePos, 1.0);
|
||||||
|
offset = projection * offset; // from view to clip-space
|
||||||
|
offset.xyz /= offset.w; // perspective divide
|
||||||
|
offset.xyz = offset.xyz * 0.5 + 0.5; // transform to range 0.0 - 1.0
|
||||||
|
|
||||||
|
// get sample depth
|
||||||
|
float sampleDepth = (view * vec4(texture(gPosition, offset.xy).xyz, 1.0)).z; // get depth value of kernel sample
|
||||||
|
|
||||||
|
// range check & accumulate
|
||||||
|
float rangeCheck = smoothstep(0.0, 1.0, radius / abs(fragPos.z - sampleDepth));
|
||||||
|
occlusion += (sampleDepth >= samplePos.z + bias ? 1.0 : 0.0) * rangeCheck;
|
||||||
|
}
|
||||||
|
occlusion = occlusion / kernelSize;
|
||||||
|
|
||||||
|
vec4 color = imageLoad(gMetallicRoughnessAO, pixelLocation);
|
||||||
|
color.b = occlusion;
|
||||||
|
imageStore(gMetallicRoughnessAO, pixelLocation, color);
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
#version 450 core
|
||||||
|
|
||||||
|
layout (local_size_x = 8, local_size_y = 8) in;
|
||||||
|
|
||||||
|
layout(rgba8, binding = 1) uniform image2D gMetallicRoughnessAO;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
ivec2 pixelLocation = ivec2(gl_GlobalInvocationID.xy);
|
||||||
|
float result = 0.0;
|
||||||
|
for (int x = -1; x < 2; ++x)
|
||||||
|
{
|
||||||
|
for (int y = -1; y < 2; ++y)
|
||||||
|
{
|
||||||
|
ivec2 samplePos = pixelLocation + ivec2(x, y);
|
||||||
|
samplePos = clamp(samplePos, ivec2(0), imageSize(gMetallicRoughnessAO) - ivec2(1));
|
||||||
|
result += imageLoad(gMetallicRoughnessAO, samplePos).b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vec4 color = imageLoad(gMetallicRoughnessAO, pixelLocation);
|
||||||
|
color.b = result / (3.0 * 3.0);
|
||||||
|
imageStore(gMetallicRoughnessAO, pixelLocation, color);
|
||||||
|
}
|
|
@ -25,7 +25,7 @@ namespace Renderer
|
||||||
// Default camera values
|
// Default camera values
|
||||||
static constexpr float YAW = -90.0f;
|
static constexpr float YAW = -90.0f;
|
||||||
static constexpr float PITCH = 0.0f;
|
static constexpr float PITCH = 0.0f;
|
||||||
static constexpr float SPEED = 200.f;
|
static constexpr float SPEED = 2.f;
|
||||||
static constexpr float SENSITIVITY = 0.1f;
|
static constexpr float SENSITIVITY = 0.1f;
|
||||||
static constexpr float ZOOM = 45.0f;
|
static constexpr float ZOOM = 45.0f;
|
||||||
// camera Attributes
|
// camera Attributes
|
||||||
|
|
|
@ -87,7 +87,6 @@ void Renderer::Model::loadModel(QString path)
|
||||||
|
|
||||||
|
|
||||||
aiMatrix4x4 transform;
|
aiMatrix4x4 transform;
|
||||||
aiMatrix4x4::Scaling(aiVector3D(1 / 0.008), transform);
|
|
||||||
processNode(scene->mRootNode, scene, transform * scene->mRootNode->mTransformation);
|
processNode(scene->mRootNode, scene, transform * scene->mRootNode->mTransformation);
|
||||||
AABB.clear();
|
AABB.clear();
|
||||||
AABB.emplace_back(minPos.x, minPos.y, minPos.z);
|
AABB.emplace_back(minPos.x, minPos.y, minPos.z);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include <glad/gl.h>
|
#include <glad/gl.h>
|
||||||
#include "RenderPass.h"
|
#include "RenderPass.h"
|
||||||
#include "IblUtils.h"
|
#include "IblUtils.h"
|
||||||
|
#include <random>
|
||||||
|
|
||||||
namespace Renderer
|
namespace Renderer
|
||||||
{
|
{
|
||||||
|
@ -132,6 +133,75 @@ namespace Renderer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SsaoPass::SsaoPass(GladGLContext* gl, unsigned int& frameWidth, unsigned int& frameHeight, GLuint& gNormal, GLuint& gPosition, GLuint& gMetallicRoughness, QMatrix4x4& projection, QMatrix4x4& view)
|
||||||
|
: RenderPass(gl)
|
||||||
|
, ssaoShader(":/Shaders/ssao.comp")
|
||||||
|
, blurShader(":/Shaders/ssao_blur.comp")
|
||||||
|
, frameWidth(frameWidth)
|
||||||
|
, frameHeight(frameHeight)
|
||||||
|
, gNormal(gNormal)
|
||||||
|
, gPosition(gPosition)
|
||||||
|
, gMetallicRoughness(gMetallicRoughness)
|
||||||
|
, projection(projection)
|
||||||
|
, view(view)
|
||||||
|
{
|
||||||
|
// generate sample kernel
|
||||||
|
// ----------------------
|
||||||
|
std::uniform_real_distribution<GLfloat> randomFloats(0.0, 1.0); // generates random floats between 0.0 and 1.0
|
||||||
|
std::default_random_engine generator;
|
||||||
|
for (unsigned int i = 0; i < 64; ++i)
|
||||||
|
{
|
||||||
|
QVector3D sample(randomFloats(generator) * 2.0 - 1.0, randomFloats(generator) * 2.0 - 1.0, randomFloats(generator));
|
||||||
|
sample.normalize();
|
||||||
|
sample *= randomFloats(generator);
|
||||||
|
float scale = float(i) / 64.0;
|
||||||
|
|
||||||
|
// scale samples s.t. they're more aligned to center of kernel
|
||||||
|
scale = std::lerp(0.1f, 1.0f, scale * scale);
|
||||||
|
sample *= scale;
|
||||||
|
ssaoKernel.push_back(sample);
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate noise texture
|
||||||
|
// ----------------------
|
||||||
|
std::vector<glm::vec3> ssaoNoise;
|
||||||
|
for (unsigned int i = 0; i < 16; i++)
|
||||||
|
// rotate around z-axis (in tangent space)
|
||||||
|
ssaoNoise.emplace_back(randomFloats(generator) * 2.0 - 1.0, randomFloats(generator) * 2.0 - 1.0, 0.0f);
|
||||||
|
|
||||||
|
gl->GenTextures(1, &noiseTexture);
|
||||||
|
gl->BindTexture(GL_TEXTURE_2D, noiseTexture);
|
||||||
|
gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, 4, 4, 0, GL_RGB, GL_FLOAT, &ssaoNoise[0]);
|
||||||
|
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
|
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
|
|
||||||
|
ssaoShader.bind();
|
||||||
|
ssaoShader.setUniformValue("gNormal", gNormalBinding);
|
||||||
|
ssaoShader.setUniformValue("gPosition", gPositionBinding);
|
||||||
|
ssaoShader.setUniformValue("texNoise", texNoiseBinding);
|
||||||
|
ssaoShader.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SsaoPass::dispatch()
|
||||||
|
{
|
||||||
|
ssaoShader.bind();
|
||||||
|
ssaoShader.setUniformValueArray("samples", ssaoKernel.data(), ssaoKernel.size());
|
||||||
|
ssaoShader.setUniformValue("projection", projection);
|
||||||
|
ssaoShader.setUniformValue("view", view);
|
||||||
|
gl->BindTextureUnit(gNormalBinding, gNormal);
|
||||||
|
gl->BindTextureUnit(gPositionBinding, gPosition);
|
||||||
|
gl->BindTextureUnit(texNoiseBinding, noiseTexture);
|
||||||
|
gl->BindImageTexture(1, gMetallicRoughness, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8);
|
||||||
|
gl->DispatchCompute(ceil(frameWidth / 8.), ceil(frameHeight / 8.), 1);
|
||||||
|
ssaoShader.release();
|
||||||
|
|
||||||
|
blurShader.bind();
|
||||||
|
gl->DispatchCompute(ceil(frameWidth / 8.), ceil(frameHeight / 8.), 1);
|
||||||
|
blurShader.release();
|
||||||
|
}
|
||||||
|
|
||||||
LightingPass::LightingPass(GladGLContext* gl, unsigned int& frameWidth, unsigned int& frameHeight, QMatrix4x4& view, Camera& camera, Light& light, GLuint& gBaseColor, GLuint& gNormal, GLuint& gPosition, GLuint& gMetallicRoughness, GLuint& shadowGbuffer, GLuint& irradianceMap, GLuint& prefilterMap, GLuint& brdfLUTTexture)
|
LightingPass::LightingPass(GladGLContext* gl, unsigned int& frameWidth, unsigned int& frameHeight, QMatrix4x4& view, Camera& camera, Light& light, GLuint& gBaseColor, GLuint& gNormal, GLuint& gPosition, GLuint& gMetallicRoughness, GLuint& shadowGbuffer, GLuint& irradianceMap, GLuint& prefilterMap, GLuint& brdfLUTTexture)
|
||||||
: RenderPass(gl)
|
: RenderPass(gl)
|
||||||
, pbrShader(":/Shaders/shadow_mapping.comp")
|
, pbrShader(":/Shaders/shadow_mapping.comp")
|
||||||
|
@ -149,7 +219,7 @@ namespace Renderer
|
||||||
pbrShader.bind();
|
pbrShader.bind();
|
||||||
pbrShader.setUniformValue("gNormal", gNormalBinding);
|
pbrShader.setUniformValue("gNormal", gNormalBinding);
|
||||||
pbrShader.setUniformValue("gPosition", gPositionBinding);
|
pbrShader.setUniformValue("gPosition", gPositionBinding);
|
||||||
pbrShader.setUniformValue("gMetallicRoughness", gMetallicRoughnessBinding);
|
pbrShader.setUniformValue("gMetallicRoughnessAO", gMetallicRoughnessBinding);
|
||||||
pbrShader.setUniformValue("gShadowMap", gShadowMapBinding);
|
pbrShader.setUniformValue("gShadowMap", gShadowMapBinding);
|
||||||
pbrShader.setUniformValue("irradianceMap", irradianceMapBinding);
|
pbrShader.setUniformValue("irradianceMap", irradianceMapBinding);
|
||||||
pbrShader.setUniformValue("prefilterMap", prefilterMapBinding);
|
pbrShader.setUniformValue("prefilterMap", prefilterMapBinding);
|
||||||
|
@ -284,4 +354,5 @@ namespace Renderer
|
||||||
{
|
{
|
||||||
enableFxaa = enable;
|
enableFxaa = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -23,7 +23,7 @@ namespace Renderer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ShadowMapPass(GladGLContext* gl, GLuint& shadowFboHandle, int& shadowMapResolution, Light& light, Model*& model);
|
ShadowMapPass(GladGLContext* gl, GLuint& shadowFboHandle, int& shadowMapResolution, Light& light, Model*& model);
|
||||||
void dispatch();
|
void dispatch() override;
|
||||||
private:
|
private:
|
||||||
Shader modelShadowShader, paintingShadowShader;
|
Shader modelShadowShader, paintingShadowShader;
|
||||||
GLuint& shadowFboHandle;
|
GLuint& shadowFboHandle;
|
||||||
|
@ -38,7 +38,7 @@ namespace Renderer
|
||||||
public:
|
public:
|
||||||
GeometryPass(GladGLContext* gl, unsigned int& frameWidth, unsigned int& frameHeight,
|
GeometryPass(GladGLContext* gl, unsigned int& frameWidth, unsigned int& frameHeight,
|
||||||
QOpenGLFramebufferObject*& fbo, Model*& model, QMatrix4x4& projection, QMatrix4x4& view);
|
QOpenGLFramebufferObject*& fbo, Model*& model, QMatrix4x4& projection, QMatrix4x4& view);
|
||||||
void dispatch();
|
void dispatch() override;
|
||||||
private:
|
private:
|
||||||
Shader modelShader, paintingShader, plainShader;
|
Shader modelShader, paintingShader, plainShader;
|
||||||
unsigned int& frameWidth;
|
unsigned int& frameWidth;
|
||||||
|
@ -54,7 +54,7 @@ namespace Renderer
|
||||||
public:
|
public:
|
||||||
PageIDFeedbackPass(GladGLContext* gl, unsigned int& frameWidth, unsigned int& frameHeight, QOpenGLFramebufferObject*& fbo,
|
PageIDFeedbackPass(GladGLContext* gl, unsigned int& frameWidth, unsigned int& frameHeight, QOpenGLFramebufferObject*& fbo,
|
||||||
GLuint* gBuffers, GLuint& gPageID, VirtualTextureManager& vtManager);
|
GLuint* gBuffers, GLuint& gPageID, VirtualTextureManager& vtManager);
|
||||||
void dispatch();
|
void dispatch() override;
|
||||||
private:
|
private:
|
||||||
Shader pageIdDownsampleShader;
|
Shader pageIdDownsampleShader;
|
||||||
unsigned int& frameWidth;
|
unsigned int& frameWidth;
|
||||||
|
@ -65,6 +65,28 @@ namespace Renderer
|
||||||
VirtualTextureManager& vtManager;
|
VirtualTextureManager& vtManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SsaoPass : public RenderPass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SsaoPass(GladGLContext* gl, unsigned int& frameWidth, unsigned int& frameHeight, GLuint& gNormal, GLuint& gPosition, GLuint& gMetallicRoughness, QMatrix4x4& projection, QMatrix4x4& view);
|
||||||
|
void dispatch() override;
|
||||||
|
private:
|
||||||
|
Shader ssaoShader, blurShader;
|
||||||
|
std::vector<QVector3D> ssaoKernel;
|
||||||
|
GLuint noiseTexture;
|
||||||
|
unsigned int& frameWidth;
|
||||||
|
unsigned int& frameHeight;
|
||||||
|
GLuint& gNormal;
|
||||||
|
GLuint& gPosition;
|
||||||
|
GLuint& gMetallicRoughness;
|
||||||
|
QMatrix4x4& projection;
|
||||||
|
QMatrix4x4& view;
|
||||||
|
|
||||||
|
constexpr static GLuint gNormalBinding = 1,
|
||||||
|
gPositionBinding = 2,
|
||||||
|
texNoiseBinding = 3;
|
||||||
|
};
|
||||||
|
|
||||||
class LightingPass : public RenderPass
|
class LightingPass : public RenderPass
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -72,7 +94,7 @@ namespace Renderer
|
||||||
QMatrix4x4& view, Camera& camera, Light& light,
|
QMatrix4x4& view, Camera& camera, Light& light,
|
||||||
GLuint& gBaseColor, GLuint& gNormal, GLuint& gPosition, GLuint& gMetallicRoughness,
|
GLuint& gBaseColor, GLuint& gNormal, GLuint& gPosition, GLuint& gMetallicRoughness,
|
||||||
GLuint& shadowGbuffer, GLuint& irradianceMap, GLuint& prefilterMap, GLuint& brdfLUTTexture);
|
GLuint& shadowGbuffer, GLuint& irradianceMap, GLuint& prefilterMap, GLuint& brdfLUTTexture);
|
||||||
void dispatch();
|
void dispatch() override;
|
||||||
private:
|
private:
|
||||||
Shader pbrShader;
|
Shader pbrShader;
|
||||||
unsigned int& frameWidth;
|
unsigned int& frameWidth;
|
||||||
|
@ -102,7 +124,7 @@ namespace Renderer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SkyboxPass(GladGLContext* gl, QOpenGLFramebufferObject*& fbo, QMatrix4x4& projection, QMatrix4x4& view, GLuint& skyCubemap);
|
SkyboxPass(GladGLContext* gl, QOpenGLFramebufferObject*& fbo, QMatrix4x4& projection, QMatrix4x4& view, GLuint& skyCubemap);
|
||||||
void dispatch();
|
void dispatch() override;
|
||||||
private:
|
private:
|
||||||
Shader skyBoxShader;
|
Shader skyBoxShader;
|
||||||
QOpenGLFramebufferObject*& fbo;
|
QOpenGLFramebufferObject*& fbo;
|
||||||
|
@ -117,7 +139,7 @@ namespace Renderer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ToneMappingPass(GladGLContext* gl, unsigned int& frameWidth, unsigned int& frameHeight, GLuint& gBaseColor, float& exposure);
|
ToneMappingPass(GladGLContext* gl, unsigned int& frameWidth, unsigned int& frameHeight, GLuint& gBaseColor, float& exposure);
|
||||||
void dispatch();
|
void dispatch() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Shader toneMappingShader;
|
Shader toneMappingShader;
|
||||||
|
@ -131,7 +153,7 @@ namespace Renderer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FinalPass(GladGLContext* gl, unsigned int& frameWidth, unsigned int& frameHeight, GLuint& gBaseColor);
|
FinalPass(GladGLContext* gl, unsigned int& frameWidth, unsigned int& frameHeight, GLuint& gBaseColor);
|
||||||
void dispatch();
|
void dispatch() override;
|
||||||
void setEnableFxaa(bool enable);
|
void setEnableFxaa(bool enable);
|
||||||
private:
|
private:
|
||||||
Shader finalShader;
|
Shader finalShader;
|
||||||
|
|
|
@ -19,7 +19,7 @@ static int sunSpeed = 10;
|
||||||
|
|
||||||
RendererGLWidget::RendererGLWidget(QWidget* parent)
|
RendererGLWidget::RendererGLWidget(QWidget* parent)
|
||||||
: QOpenGLWidget(parent)
|
: QOpenGLWidget(parent)
|
||||||
, camera(QVector3D(0.0f, 100.0f, 0.0f))
|
, camera(QVector3D(0.0f, 1.0f, 0.0f))
|
||||||
, light(&camera)
|
, light(&camera)
|
||||||
{
|
{
|
||||||
//startTimer();
|
//startTimer();
|
||||||
|
@ -97,6 +97,11 @@ void Renderer::RendererGLWidget::setEnableFxaa(bool enable)
|
||||||
finalPass->setEnableFxaa(enable);
|
finalPass->setEnableFxaa(enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Renderer::RendererGLWidget::setEnableSsao(bool enable)
|
||||||
|
{
|
||||||
|
enableSsao = enable;
|
||||||
|
}
|
||||||
|
|
||||||
QOpenGLTexture randomMap(QOpenGLTexture::Target2D);
|
QOpenGLTexture randomMap(QOpenGLTexture::Target2D);
|
||||||
|
|
||||||
void GLAPIENTRY messageCallback(GLenum source,
|
void GLAPIENTRY messageCallback(GLenum source,
|
||||||
|
@ -139,6 +144,7 @@ void RendererGLWidget::initializeGL()
|
||||||
shadowMapPass = std::make_unique<ShadowMapPass>(gl.get(), shadowFboHandle, shadowMapResolution, light, model);
|
shadowMapPass = std::make_unique<ShadowMapPass>(gl.get(), shadowFboHandle, shadowMapResolution, light, model);
|
||||||
geometryPass = std::make_unique<GeometryPass>(gl.get(), frameWidth, frameHeight, fboPtr, model, projection, view);
|
geometryPass = std::make_unique<GeometryPass>(gl.get(), frameWidth, frameHeight, fboPtr, model, projection, view);
|
||||||
pageIDFeedbackPass = std::make_unique<PageIDFeedbackPass>(gl.get(), frameWidth, frameHeight, fboPtr, gbuffers, gPageID, *vtManager);
|
pageIDFeedbackPass = std::make_unique<PageIDFeedbackPass>(gl.get(), frameWidth, frameHeight, fboPtr, gbuffers, gPageID, *vtManager);
|
||||||
|
ssaoPass = std::make_unique<SsaoPass>(gl.get(), frameWidth, frameHeight, gNormal, gPosition, gMetallicRoughness, projection, view);
|
||||||
lightingPass = std::make_unique<LightingPass>(gl.get(), frameWidth, frameHeight, view, camera, light,
|
lightingPass = std::make_unique<LightingPass>(gl.get(), frameWidth, frameHeight, view, camera, light,
|
||||||
gBaseColor, gNormal, gPosition, gMetallicRoughness, shadowGbuffer, irradianceMap, prefilterMap, brdfLUTTexture);
|
gBaseColor, gNormal, gPosition, gMetallicRoughness, shadowGbuffer, irradianceMap, prefilterMap, brdfLUTTexture);
|
||||||
skyboxPass = std::make_unique<SkyboxPass>(gl.get(), fboPtr, projection, view, skyCubemap);
|
skyboxPass = std::make_unique<SkyboxPass>(gl.get(), fboPtr, projection, view, skyCubemap);
|
||||||
|
@ -213,6 +219,8 @@ void RendererGLWidget::paintGL()
|
||||||
pageIDFeedbackPass->dispatch();
|
pageIDFeedbackPass->dispatch();
|
||||||
//gl->Finish();
|
//gl->Finish();
|
||||||
//vtManager->commitMutex.unlock();
|
//vtManager->commitMutex.unlock();
|
||||||
|
if (enableSsao)
|
||||||
|
ssaoPass->dispatch();
|
||||||
lightingPass->dispatch();
|
lightingPass->dispatch();
|
||||||
skyboxPass->dispatch();
|
skyboxPass->dispatch();
|
||||||
toneMappingPass->dispatch();
|
toneMappingPass->dispatch();
|
||||||
|
@ -293,12 +301,16 @@ void RendererGLWidget::resizeGL(int width, int height)
|
||||||
gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, frameWidth, frameHeight, 0, GL_RGB, GL_FLOAT, NULL);
|
gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, frameWidth, frameHeight, 0, GL_RGB, GL_FLOAT, NULL);
|
||||||
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, gbuffers[2], 0);
|
gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, gbuffers[2], 0);
|
||||||
//MetallicRoughness
|
//R: Metallic, G: Roughness, B: AO
|
||||||
gl->BindTexture(GL_TEXTURE_2D, gbuffers[3]);
|
gl->BindTexture(GL_TEXTURE_2D, gbuffers[3]);
|
||||||
gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RG8, frameWidth, frameHeight, 0, GL_RG, GL_UNSIGNED_BYTE, NULL);
|
gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, frameWidth, frameHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||||
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, gbuffers[3], 0);
|
gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, gbuffers[3], 0);
|
||||||
//gPageID
|
//gPageID
|
||||||
gl->BindTexture(GL_TEXTURE_2D, gbuffers[4]);
|
gl->BindTexture(GL_TEXTURE_2D, gbuffers[4]);
|
||||||
|
|
|
@ -35,6 +35,7 @@ namespace Renderer
|
||||||
void setMainLightYaw(float yaw);
|
void setMainLightYaw(float yaw);
|
||||||
void setExposure(float exposure);
|
void setExposure(float exposure);
|
||||||
void setEnableFxaa(bool enable);
|
void setEnableFxaa(bool enable);
|
||||||
|
void setEnableSsao(bool enable);
|
||||||
protected:
|
protected:
|
||||||
void initializeGL() override;
|
void initializeGL() override;
|
||||||
void paintGL() override;
|
void paintGL() override;
|
||||||
|
@ -56,6 +57,8 @@ namespace Renderer
|
||||||
int shadowMapResolution;
|
int shadowMapResolution;
|
||||||
float exposure = 0.8;
|
float exposure = 0.8;
|
||||||
|
|
||||||
|
bool enableSsao = true;
|
||||||
|
|
||||||
QMatrix4x4 projection;
|
QMatrix4x4 projection;
|
||||||
QMatrix4x4 view;
|
QMatrix4x4 view;
|
||||||
|
|
||||||
|
@ -64,6 +67,7 @@ namespace Renderer
|
||||||
std::unique_ptr<ShadowMapPass> shadowMapPass;
|
std::unique_ptr<ShadowMapPass> shadowMapPass;
|
||||||
std::unique_ptr<GeometryPass> geometryPass;
|
std::unique_ptr<GeometryPass> geometryPass;
|
||||||
std::unique_ptr<PageIDFeedbackPass> pageIDFeedbackPass;
|
std::unique_ptr<PageIDFeedbackPass> pageIDFeedbackPass;
|
||||||
|
std::unique_ptr<SsaoPass> ssaoPass;
|
||||||
std::unique_ptr<LightingPass> lightingPass;
|
std::unique_ptr<LightingPass> lightingPass;
|
||||||
std::unique_ptr<SkyboxPass> skyboxPass;
|
std::unique_ptr<SkyboxPass> skyboxPass;
|
||||||
std::unique_ptr<ToneMappingPass> toneMappingPass;
|
std::unique_ptr<ToneMappingPass> toneMappingPass;
|
||||||
|
|
|
@ -68,6 +68,9 @@ Renderer::RendererWidget::RendererWidget(QWidget* parent)
|
||||||
QObject::connect(ui.fxaaCheckBox, &QCheckBox::toggled, this, [&](bool checked) {
|
QObject::connect(ui.fxaaCheckBox, &QCheckBox::toggled, this, [&](bool checked) {
|
||||||
ui.openGLWidget->setEnableFxaa(checked);
|
ui.openGLWidget->setEnableFxaa(checked);
|
||||||
});
|
});
|
||||||
|
QObject::connect(ui.ssaoCheckBox, &QCheckBox::toggled, this, [&](bool checked) {
|
||||||
|
ui.openGLWidget->setEnableSsao(checked);
|
||||||
|
});
|
||||||
|
|
||||||
QObject::connect(ui.lightRadianceSlider, &QSlider::valueChanged, [&](int value) {
|
QObject::connect(ui.lightRadianceSlider, &QSlider::valueChanged, [&](int value) {
|
||||||
ui.openGLWidget->setMainLightRadiance(value / 10.f * QVector3D(0.7529, 0.7450, 0.6784).normalized());
|
ui.openGLWidget->setMainLightRadiance(value / 10.f * QVector3D(0.7529, 0.7450, 0.6784).normalized());
|
||||||
|
|
Loading…
Reference in New Issue