实现FXAA
parent
bc118b0a20
commit
fc75668c68
|
@ -363,3 +363,4 @@ MigrationBackup/
|
|||
FodyWeavers.xsd
|
||||
/UnitTest/Qt.x64.runsettings
|
||||
/ArchitectureColoredPainting/ClassDiagram.cd
|
||||
/ArchitectureColoredPainting/res/Shaders/Fxaa3_11.glsl
|
||||
|
|
|
@ -213,6 +213,7 @@
|
|||
<None Include="res\Shaders\skybox.frag" />
|
||||
<None Include="res\Shaders\skybox.vert" />
|
||||
<None Include="res\Shaders\ssgi.comp" />
|
||||
<None Include="res\Shaders\tone_mapping.comp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtMoc Include="src\Editor\EditorWidgetComponent\StrokeStyleWidget.h" />
|
||||
|
|
|
@ -464,6 +464,7 @@
|
|||
<None Include="res\Shaders\pageId_downsample.comp">
|
||||
<Filter>Resource Files\Shaders</Filter>
|
||||
</None>
|
||||
<None Include="res\Shaders\tone_mapping.comp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtUic Include="EditorWidgetItem.ui">
|
||||
|
|
|
@ -81,6 +81,16 @@
|
|||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="fxaaCheckBox">
|
||||
<property name="text">
|
||||
<string>FXAA</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
<file>Shaders/cubemap_prefilter.frag</file>
|
||||
<file>Shaders/brdf_lut.comp</file>
|
||||
<file>Shaders/pageId_downsample.comp</file>
|
||||
<file>Shaders/tone_mapping.comp</file>
|
||||
</qresource>
|
||||
<qresource prefix="/qt/etc">
|
||||
<file>qt.conf</file>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -184,22 +184,15 @@ void main()
|
|||
{
|
||||
ivec2 pixelLocation = ivec2(gl_GlobalInvocationID.xy);
|
||||
|
||||
|
||||
//vec3 albedo = pow(texelFetch(gBaseColor, pixelLocation, 0).rgb, vec3(2.2));
|
||||
vec3 albedo = pow(imageLoad(gBaseColor, pixelLocation).rgb, vec3(2.2));
|
||||
vec4 baseColor = imageLoad(gBaseColor, pixelLocation);
|
||||
if(baseColor.a == 0) return;
|
||||
vec3 albedo = pow(baseColor.rgb, vec3(2.2));
|
||||
float metallic = texelFetch(gMetallicRoughness, pixelLocation, 0).r;
|
||||
float roughness = texelFetch(gMetallicRoughness, pixelLocation, 0).g;
|
||||
|
||||
vec3 worldPos = texelFetch(gPosition, pixelLocation,0).xyz;
|
||||
vec3 normal = texelFetch(gNormal, pixelLocation,0).xyz;
|
||||
vec3 normal = texelFetch(gNormal, pixelLocation,0).xyz;
|
||||
|
||||
if(normal==vec3(0))
|
||||
{
|
||||
//vec3 color = mainLightRadiance;
|
||||
//imageStore(gBaseColor, pixelLocation, vec4(color, 1.0));
|
||||
imageStore(gBaseColor, pixelLocation, vec4(0));
|
||||
return;
|
||||
}
|
||||
normal = normalize(normal);
|
||||
|
||||
vec3 V = normalize(camPos - worldPos);
|
||||
|
|
|
@ -1,32 +1,24 @@
|
|||
#version 450 core
|
||||
out vec4 FragColor;
|
||||
layout (location = 0) out vec4 FragColor;
|
||||
in vec3 WorldPos;
|
||||
|
||||
uniform samplerCube environmentMap;
|
||||
uniform float exposure = 1;
|
||||
|
||||
vec3 ACESToneMapping(vec3 color)
|
||||
vec4 encodeRGBM(vec3 color)
|
||||
{
|
||||
const float A = 2.51;
|
||||
const float B = 0.03;
|
||||
const float C = 2.43;
|
||||
const float D = 0.59;
|
||||
const float E = 0.14;
|
||||
return (color * (A * color + B)) / (color * (C * color + D) + E);
|
||||
if(dot(color,color)==0)
|
||||
return vec4(0,0,0,1);
|
||||
vec4 rgbm;
|
||||
float range = 8;
|
||||
color /= range;
|
||||
rgbm.a = clamp(max(max(color.r, color.g), max(color.b, 1e-6)), 0.0, 1.0);
|
||||
rgbm.a = ceil(rgbm.a * 255.0) / 255.0;
|
||||
rgbm.rgb = color / rgbm.a;
|
||||
return rgbm;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 color = texture(environmentMap, WorldPos).rgb;
|
||||
|
||||
// HDR tonemap
|
||||
//envColor = envColor / (envColor + vec3(1.0));
|
||||
|
||||
color *= exposure;
|
||||
color = ACESToneMapping(color);
|
||||
|
||||
// gamma correct
|
||||
color = pow(color, vec3(1.0/2.2));
|
||||
|
||||
FragColor = vec4(color, 1.0);
|
||||
FragColor = encodeRGBM(color);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
#version 450 core
|
||||
|
||||
layout (local_size_x = 8, local_size_y = 8) in;
|
||||
|
||||
layout(rgba8, binding = 0) uniform image2D gBaseColor;
|
||||
|
||||
uniform float exposure = 1;
|
||||
|
||||
vec3 ACESToneMapping(vec3 color)
|
||||
{
|
||||
const float A = 2.51;
|
||||
const float B = 0.03;
|
||||
const float C = 2.43;
|
||||
const float D = 0.59;
|
||||
const float E = 0.14;
|
||||
return (color * (A * color + B)) / (color * (C * color + D) + E);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 pixelLocation = ivec2(gl_GlobalInvocationID.xy);
|
||||
vec4 rgbm = imageLoad(gBaseColor, pixelLocation);
|
||||
vec3 color = 8 * rgbm.rgb * rgbm.a;
|
||||
color *= exposure;
|
||||
color = ACESToneMapping(color);
|
||||
float luma = sqrt(dot(color.rgb, vec3(0.299, 0.587, 0.114)));
|
||||
imageStore(gBaseColor, pixelLocation, vec4(color, luma));
|
||||
}
|
|
@ -185,13 +185,60 @@ namespace Renderer
|
|||
pbrShader.release();
|
||||
}
|
||||
|
||||
FinalPass::FinalPass(GladGLContext* gl, unsigned int& frameWidth, unsigned int& frameHeight, GLuint& gBaseColor, float& exposure)
|
||||
SkyboxPass::SkyboxPass(GladGLContext* gl, QOpenGLFramebufferObject*& fbo, QMatrix4x4& projection, QMatrix4x4& view, GLuint& skyCubemap)
|
||||
: RenderPass(gl)
|
||||
, skyBoxShader(":Shaders/skybox.vert", ":Shaders/skybox.frag")
|
||||
, fbo(fbo)
|
||||
, projection(projection)
|
||||
, view(view)
|
||||
, skyCubemap(skyCubemap)
|
||||
{
|
||||
skyBoxShader.bind();
|
||||
skyBoxShader.setUniformValue("environmentMap", environmentMapBinding);
|
||||
skyBoxShader.release();
|
||||
}
|
||||
|
||||
void SkyboxPass::dispatch()
|
||||
{
|
||||
if (fbo->bind())
|
||||
{
|
||||
skyBoxShader.bind();
|
||||
gl->Disable(GL_CULL_FACE);
|
||||
skyBoxShader.setUniformValue("view", view);
|
||||
skyBoxShader.setUniformValue("projection", projection);
|
||||
gl->BindTextureUnit(environmentMapBinding, skyCubemap);
|
||||
IblUtils::renderCube(gl);
|
||||
skyBoxShader.release();
|
||||
fbo->release();
|
||||
}
|
||||
}
|
||||
|
||||
ToneMappingPass::ToneMappingPass(GladGLContext* gl, unsigned int& frameWidth, unsigned int& frameHeight, GLuint& gBaseColor, float& exposure)
|
||||
: RenderPass(gl)
|
||||
, toneMappingShader(":Shaders/tone_mapping.comp")
|
||||
, frameWidth(frameWidth)
|
||||
, frameHeight(frameHeight)
|
||||
, gBaseColor(gBaseColor)
|
||||
, exposure(exposure)
|
||||
{}
|
||||
|
||||
void ToneMappingPass::dispatch()
|
||||
{
|
||||
toneMappingShader.bind();
|
||||
toneMappingShader.setUniformValue("exposure", exposure);
|
||||
gl->BindImageTexture(0, gBaseColor, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8);
|
||||
gl->DispatchCompute(ceil(frameWidth / 8.), ceil(frameHeight / 8.), 1);
|
||||
toneMappingShader.release();
|
||||
}
|
||||
|
||||
|
||||
|
||||
FinalPass::FinalPass(GladGLContext* gl, unsigned int& frameWidth, unsigned int& frameHeight, GLuint& gBaseColor)
|
||||
: RenderPass(gl)
|
||||
, finalShader(":Shaders/final.vert", ":Shaders/final.frag")
|
||||
, frameWidth(frameWidth)
|
||||
, frameHeight(frameHeight)
|
||||
, gBaseColor(gBaseColor)
|
||||
, exposure(exposure)
|
||||
{
|
||||
finalShader.bind();
|
||||
finalShader.setUniformValue("gBaseColor", gBaseColorBinding);
|
||||
|
@ -226,7 +273,8 @@ namespace Renderer
|
|||
gl->Viewport(0, 0, frameWidth, frameHeight);
|
||||
gl->Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
finalShader.bind();
|
||||
finalShader.setUniformValue("exposure", exposure);
|
||||
finalShader.setUniformValue("enableFxaa", enableFxaa);
|
||||
finalShader.setUniformValue("RCPFrame", QVector2D(1.f / frameWidth, 1.f / frameHeight));
|
||||
gl->BindTextureUnit(gBaseColorBinding, gBaseColor);
|
||||
quadVAO.bind();
|
||||
gl->DrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
@ -234,28 +282,8 @@ namespace Renderer
|
|||
finalShader.release();
|
||||
}
|
||||
|
||||
SkyboxPass::SkyboxPass(GladGLContext* gl, QMatrix4x4& projection, QMatrix4x4& view, float& exposure, GLuint& skyCubemap)
|
||||
: RenderPass(gl)
|
||||
, skyBoxShader(":Shaders/skybox.vert", ":Shaders/skybox.frag")
|
||||
, projection(projection)
|
||||
, view(view)
|
||||
, exposure(exposure)
|
||||
, skyCubemap(skyCubemap)
|
||||
void FinalPass::setEnableFxaa(bool enable)
|
||||
{
|
||||
skyBoxShader.bind();
|
||||
skyBoxShader.setUniformValue("environmentMap", environmentMapBinding);
|
||||
skyBoxShader.release();
|
||||
}
|
||||
|
||||
void SkyboxPass::dispatch()
|
||||
{
|
||||
skyBoxShader.bind();
|
||||
gl->Disable(GL_CULL_FACE);
|
||||
skyBoxShader.setUniformValue("view", view);
|
||||
skyBoxShader.setUniformValue("projection", projection);
|
||||
skyBoxShader.setUniformValue("exposure", exposure);
|
||||
gl->BindTextureUnit(environmentMapBinding, skyCubemap);
|
||||
IblUtils::renderCube(gl);
|
||||
skyBoxShader.release();
|
||||
enableFxaa = enable;
|
||||
}
|
||||
}
|
|
@ -98,35 +98,52 @@ namespace Renderer
|
|||
brdfLUTBinding = 7;
|
||||
};
|
||||
|
||||
class SkyboxPass : public RenderPass
|
||||
{
|
||||
public:
|
||||
SkyboxPass(GladGLContext* gl, QOpenGLFramebufferObject*& fbo, QMatrix4x4& projection, QMatrix4x4& view, GLuint& skyCubemap);
|
||||
void dispatch();
|
||||
private:
|
||||
Shader skyBoxShader;
|
||||
QOpenGLFramebufferObject*& fbo;
|
||||
QMatrix4x4& projection;
|
||||
QMatrix4x4& view;
|
||||
GLuint& skyCubemap;
|
||||
|
||||
constexpr static GLint environmentMapBinding = 0;
|
||||
};
|
||||
|
||||
class ToneMappingPass : public RenderPass
|
||||
{
|
||||
public:
|
||||
ToneMappingPass(GladGLContext* gl, unsigned int& frameWidth, unsigned int& frameHeight, GLuint& gBaseColor, float& exposure);
|
||||
void dispatch();
|
||||
|
||||
private:
|
||||
Shader toneMappingShader;
|
||||
unsigned int& frameWidth;
|
||||
unsigned int& frameHeight;
|
||||
GLuint& gBaseColor;
|
||||
float& exposure;
|
||||
};
|
||||
|
||||
class FinalPass : public RenderPass
|
||||
{
|
||||
public:
|
||||
FinalPass(GladGLContext* gl, unsigned int& frameWidth, unsigned int& frameHeight, GLuint& gBaseColor, float& exposure);
|
||||
FinalPass(GladGLContext* gl, unsigned int& frameWidth, unsigned int& frameHeight, GLuint& gBaseColor);
|
||||
void dispatch();
|
||||
void setEnableFxaa(bool enable);
|
||||
private:
|
||||
Shader finalShader;
|
||||
unsigned int& frameWidth;
|
||||
unsigned int& frameHeight;
|
||||
GLuint& gBaseColor;
|
||||
float& exposure;
|
||||
|
||||
QOpenGLBuffer quadVBO;
|
||||
QOpenGLVertexArrayObject quadVAO;
|
||||
constexpr static GLint gBaseColorBinding = 0;
|
||||
bool enableFxaa = true;
|
||||
};
|
||||
|
||||
class SkyboxPass : public RenderPass
|
||||
{
|
||||
public:
|
||||
SkyboxPass(GladGLContext* gl, QMatrix4x4& projection, QMatrix4x4& view, float& exposure, GLuint& skyCubemap);
|
||||
void dispatch();
|
||||
private:
|
||||
Shader skyBoxShader;
|
||||
QMatrix4x4& projection;
|
||||
QMatrix4x4& view;
|
||||
float& exposure;
|
||||
GLuint& skyCubemap;
|
||||
|
||||
constexpr static GLint environmentMapBinding = 0;
|
||||
};
|
||||
}
|
|
@ -92,6 +92,11 @@ void Renderer::RendererGLWidget::setExposure(float exposure)
|
|||
this->exposure = exposure;
|
||||
}
|
||||
|
||||
void Renderer::RendererGLWidget::setEnableFxaa(bool enable)
|
||||
{
|
||||
finalPass->setEnableFxaa(enable);
|
||||
}
|
||||
|
||||
QOpenGLTexture randomMap(QOpenGLTexture::Target2D);
|
||||
|
||||
void GLAPIENTRY messageCallback(GLenum source,
|
||||
|
@ -126,7 +131,7 @@ void RendererGLWidget::initializeGL()
|
|||
gl->Enable(GL_DEPTH_TEST);
|
||||
gl->DepthFunc(GL_LEQUAL);
|
||||
gl->Enable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
||||
gl->ClearColor(0, 0, 0, 1);
|
||||
gl->ClearColor(0, 0, 0, 0);
|
||||
|
||||
vtManager = std::make_unique<VirtualTextureManager>(gl.get());
|
||||
model = new Model(context(), vtManager.get());
|
||||
|
@ -136,8 +141,10 @@ void RendererGLWidget::initializeGL()
|
|||
pageIDCallbackPass = std::make_unique<PageIDCallbackPass>(gl.get(), frameWidth, frameHeight, fboPtr, gbuffers, gPageID, *vtManager);
|
||||
lightingPass = std::make_unique<LightingPass>(gl.get(), frameWidth, frameHeight, view, camera, light,
|
||||
gBaseColor, gNormal, gPosition, gMetallicRoughness, shadowGbuffer, irradianceMap, prefilterMap, brdfLUTTexture);
|
||||
finalPass = std::make_unique<FinalPass>(gl.get(), frameWidth, frameHeight, gBaseColor, exposure);
|
||||
skyboxPass = std::make_unique<SkyboxPass>(gl.get(), projection, view, exposure, skyCubemap);
|
||||
skyboxPass = std::make_unique<SkyboxPass>(gl.get(), fboPtr, projection, view, skyCubemap);
|
||||
toneMappingPass = std::make_unique<ToneMappingPass>(gl.get(), frameWidth, frameHeight, gBaseColor, exposure);
|
||||
finalPass = std::make_unique<FinalPass>(gl.get(), frameWidth, frameHeight, gBaseColor);
|
||||
|
||||
|
||||
depthInitProgramPtr = new QOpenGLShaderProgram;
|
||||
if (!depthInitProgramPtr->addShaderFromSourceFile(QOpenGLShader::Compute, ":/Shaders/depth_init.comp"))
|
||||
|
@ -207,8 +214,10 @@ void RendererGLWidget::paintGL()
|
|||
gl->Finish();
|
||||
vtManager->commitMutex.unlock();
|
||||
lightingPass->dispatch();
|
||||
finalPass->dispatch();
|
||||
skyboxPass->dispatch();
|
||||
toneMappingPass->dispatch();
|
||||
finalPass->dispatch();
|
||||
|
||||
|
||||
gl->EndQuery(GL_TIME_ELAPSED);
|
||||
GLuint frameDuration;
|
||||
|
@ -270,6 +279,9 @@ void RendererGLWidget::resizeGL(int width, int height)
|
|||
{
|
||||
//BaseColor
|
||||
gbuffers[0] = fboPtr->texture();
|
||||
gl->BindTexture(GL_TEXTURE_2D, gbuffers[0]);
|
||||
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
gl->GenTextures(9, gbuffers + 1);
|
||||
//Normal
|
||||
|
|
|
@ -34,6 +34,7 @@ namespace Renderer
|
|||
void setMainLightPitch(float pitch);
|
||||
void setMainLightYaw(float yaw);
|
||||
void setExposure(float exposure);
|
||||
void setEnableFxaa(bool enable);
|
||||
protected:
|
||||
void initializeGL() override;
|
||||
void paintGL() override;
|
||||
|
@ -64,8 +65,10 @@ namespace Renderer
|
|||
std::unique_ptr<GeometryPass> geometryPass;
|
||||
std::unique_ptr<PageIDCallbackPass> pageIDCallbackPass;
|
||||
std::unique_ptr<LightingPass> lightingPass;
|
||||
std::unique_ptr<FinalPass> finalPass;
|
||||
std::unique_ptr<SkyboxPass> skyboxPass;
|
||||
std::unique_ptr<ToneMappingPass> toneMappingPass;
|
||||
std::unique_ptr<FinalPass> finalPass;
|
||||
|
||||
|
||||
QOpenGLShaderProgram* depthInitProgramPtr = nullptr;
|
||||
QOpenGLShaderProgram* depthMipmapProgramPtr = nullptr;
|
||||
|
|
|
@ -65,6 +65,10 @@ Renderer::RendererWidget::RendererWidget(QWidget* parent)
|
|||
emit openPaintingFile(paintingPath);
|
||||
});
|
||||
|
||||
QObject::connect(ui.fxaaCheckBox, &QCheckBox::toggled, this, [&](bool checked) {
|
||||
ui.openGLWidget->setEnableFxaa(checked);
|
||||
});
|
||||
|
||||
QObject::connect(ui.lightRadianceSlider, &QSlider::valueChanged, [&](int value) {
|
||||
ui.openGLWidget->setMainLightRadiance(value / 10.f * QVector3D(0.7529, 0.7450, 0.6784).normalized());
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue