Browse Source

antialiasing

Kajetan Johannes Hammerle 3 years ago
parent
commit
9792505220

+ 11 - 1
client/Game.cpp

@@ -122,6 +122,16 @@ void Game::tick() {
             renderSettings.bump = 0.0f;
         }
     }
+    if(control.keys.factor.getDownTime() == 1) {
+        if(renderSettings.factor == 1) {
+            renderSettings.factor = 2;
+        } else if(renderSettings.factor == 2) {
+            renderSettings.factor = 3;
+        } else {
+            renderSettings.factor = 1;
+        }
+        renderSettings.dirtyFactor = true;
+    }
 }
 
 void Game::renderWorld(float lag, Renderer& renderer) const {
@@ -247,4 +257,4 @@ void Game::updateDistances() {
     for(uint i = 0; i < cameraPoints.getLength(); i++) {
         cameraPoints[i].distance = distance(i, 10000);
     }
-}
+}

+ 1 - 1
client/Main.cpp

@@ -100,4 +100,4 @@ int main() {
         glfwPollEvents();
     }
     return 0;
-}
+}

+ 2 - 1
client/input/Keys.cpp

@@ -25,7 +25,7 @@ std::ostream& operator<<(std::ostream& os, const Keys::Key& k) {
 
 Keys::Keys() : left(keys[0]), right(keys[1]), up(keys[2]), down(keys[3]), jump(keys[4]), sneak(keys[5]),
 camLeft(keys[6]), camRight(keys[7]), camUp(keys[8]), camDown(keys[9]), test(keys[10]), test2(keys[11]), test3(keys[12]),
-test4(keys[13]), test5(keys[14]), test6(keys[15]) {
+test4(keys[13]), test5(keys[14]), test6(keys[15]), factor(keys[16]) {
     keys[0].glfwKey = GLFW_KEY_A;
     keys[1].glfwKey = GLFW_KEY_D;
     keys[2].glfwKey = GLFW_KEY_W;
@@ -42,6 +42,7 @@ test4(keys[13]), test5(keys[14]), test6(keys[15]) {
     keys[13].glfwKey = GLFW_KEY_G;
     keys[14].glfwKey = GLFW_KEY_H;
     keys[15].glfwKey = GLFW_KEY_U;
+    keys[16].glfwKey = GLFW_KEY_F;
 }
 
 void Keys::release(int key) {

+ 2 - 1
client/input/Keys.h

@@ -31,7 +31,7 @@ public:
     };
 
 private:
-    Key keys[16];
+    Key keys[17];
 
 public:
     Keys();
@@ -51,6 +51,7 @@ public:
     const Key& test4;
     const Key& test5;
     const Key& test6;
+    const Key& factor;
 
     void release(int key);
     void press(int key);

+ 14 - 5
client/rendering/Engine.cpp

@@ -21,6 +21,10 @@ shaders(shaders), framebuffers(fb), size(size), renderSettings(renderSettings),
 }
 
 void Engine::renderTick(float lag, const Game& game) {
+    if(renderSettings.dirtyFactor) {
+        framebuffers.setFactor(renderSettings.factor);
+    }
+
     updateWorldProjection();
     updateWorldView();
 
@@ -29,7 +33,6 @@ void Engine::renderTick(float lag, const Game& game) {
     }
     renderWorld(lag, game);
     if(renderSettings.ssao) {
-
         renderSSAO();
     }
     renderPostWorld();
@@ -76,8 +79,8 @@ void Engine::renderSSAO() {
     rProj.translate(0.5f, 0.5f, 0.5f).scale(0.5f).mul(worldProj);
 
     shaders.ssao.setMatrix("proj", rProj.getValues());
-    shaders.ssao.setInt("width", size.width);
-    shaders.ssao.setInt("height", size.height);
+    shaders.ssao.setInt("width", size.width * renderSettings.factor);
+    shaders.ssao.setInt("height", size.height * renderSettings.factor);
     framebuffers.world.bindPositionTexture(0);
     framebuffers.world.bindNormalTexture(1);
     framebuffers.world.bindColorTexture(2);
@@ -93,7 +96,7 @@ void Engine::renderSSAO() {
 }
 
 void Engine::renderPostWorld() {
-    GLWrapper::prepareMainFramebuffer();
+    framebuffers.antialias.bind();
     shaders.postWorld.use();
     framebuffers.world.bindColorTexture(0);
     framebuffers.ssaoBlur.bindRedTexture(1);
@@ -103,6 +106,13 @@ void Engine::renderPostWorld() {
     shaders.postWorld.setInt("shadows", renderSettings.shadows);
     shaders.postWorld.setFloat("bump", renderSettings.bump);
     rectangle.draw();
+
+    GLWrapper::prepareMainFramebuffer();
+    glViewport(0, 0, size.width, size.height);
+    shaders.antialias.use();
+    shaders.antialias.setInt("radius", renderSettings.factor);
+    framebuffers.antialias.bindColorTexture(0);
+    rectangle.draw();
 }
 
 void Engine::renderTextOverlay(float lag, const Game& game) {
@@ -126,7 +136,6 @@ void Engine::updateWorldProjection() {
     frustum.setProjection(worldProj, size.width, size.height);
 
     if(!renderSettings.shadows) {
-
         return;
     }
     worldShadowProj.setToIdentity();

+ 12 - 2
client/rendering/Framebuffers.cpp

@@ -4,7 +4,8 @@ Framebuffers::Framebuffers(const WindowSize& size) :
 world(size, Framebuffer::POSITION | Framebuffer::NORMAL | Framebuffer::COLOR | Framebuffer::RED | Framebuffer::DEPTH),
 ssao(size, Framebuffer::RED),
 ssaoBlur(size, Framebuffer::RED),
-shadow(size, Framebuffer::DEPTH) {
+shadow(size, Framebuffer::DEPTH),
+antialias(size, Framebuffer::COLOR) {
 }
 
 void Framebuffers::resize(uint width, uint height) {
@@ -12,8 +13,17 @@ void Framebuffers::resize(uint width, uint height) {
     ssao.resize(width, height);
     ssaoBlur.resize(width, height);
     shadow.resize(width, height);
+    antialias.resize(width, height);
 }
 
 bool Framebuffers::hasError() const {
-    return world.hasError() || ssao.hasError() || ssaoBlur.hasError() || shadow.hasError();
+    return world.hasError() || ssao.hasError() || ssaoBlur.hasError() || shadow.hasError() || antialias.hasError();
+}
+
+void Framebuffers::setFactor(int factor) {
+    world.setFactor(factor);
+    ssao.setFactor(factor);
+    ssaoBlur.setFactor(factor);
+    shadow.setFactor(factor);
+    antialias.setFactor(factor);
 }

+ 2 - 0
client/rendering/Framebuffers.h

@@ -8,11 +8,13 @@ struct Framebuffers final {
     Framebuffers(const WindowSize& size);
     void resize(uint width, uint height);
     bool hasError() const;
+    void setFactor(int factor);
 
     Framebuffer world;
     Framebuffer ssao;
     Framebuffer ssaoBlur;
     Framebuffer shadow;
+    Framebuffer antialias;
 };
 
 #endif

+ 2 - 1
client/rendering/RenderSettings.cpp

@@ -1,4 +1,5 @@
 #include "client/rendering/RenderSettings.h"
 
-RenderSettings::RenderSettings() : ssao(true), shadows(false), testRadius(0.004f), testBias(0.003f), bump(0.5f) {
+RenderSettings::RenderSettings() : ssao(true), shadows(false), testRadius(0.004f), testBias(0.003f), bump(0.5f),
+factor(1), dirtyFactor(false) {
 }

+ 2 - 0
client/rendering/RenderSettings.h

@@ -11,6 +11,8 @@ struct RenderSettings final {
     float testRadius;
     float testBias;
     float bump;
+    int factor;
+    bool dirtyFactor;
 };
 
 #endif

+ 3 - 2
client/rendering/Shaders.cpp

@@ -6,10 +6,11 @@ ssao("resources/shader/ssaoVertex.vs", "resources/shader/ssaoFragment.fs"),
 ssaoBlur("resources/shader/ssaoBlurVertex.vs", "resources/shader/ssaoBlurFragment.fs"),
 shadow("resources/shader/worldShadowVertex.vs", "resources/shader/worldShadowFragment.fs"),
 postWorld("resources/shader/worldPostVertex.vs", "resources/shader/worldPostFragment.fs"),
-text("resources/shader/textVertex.vs", "resources/shader/textFragment.fs") {
+text("resources/shader/textVertex.vs", "resources/shader/textFragment.fs"),
+antialias("resources/shader/antialiasVertex.vs", "resources/shader/antialiasFragment.fs") {
 }
 
 bool Shaders::hasError() const {
     return world.hasError() || ssao.hasError() || ssaoBlur.hasError() || shadow.hasError() || postWorld.hasError() ||
-            text.hasError();
+            text.hasError() || antialias.hasError();
 }

+ 1 - 0
client/rendering/Shaders.h

@@ -13,6 +13,7 @@ struct Shaders final {
     Shader shadow;
     Shader postWorld;
     Shader text;
+    Shader antialias;
 };
 
 #endif

+ 10 - 2
client/rendering/wrapper/Framebuffer.cpp

@@ -2,8 +2,8 @@
 
 #include "client/rendering/wrapper/Framebuffer.h"
 
-Framebuffer::Framebuffer(const WindowSize& size, uint mode, bool texCompare) : mode(mode), textures(0),
-buffer(0), error(false) {
+Framebuffer::Framebuffer(const WindowSize& size, uint mode, bool texCompare) : size(size), mode(mode), textures(0),
+buffer(0), error(false), factor(1) {
     glGenFramebuffers(1, &buffer);
     glBindFramebuffer(GL_FRAMEBUFFER, buffer);
 
@@ -50,11 +50,14 @@ bool Framebuffer::hasError() const {
 }
 
 void Framebuffer::bind() const {
+    glViewport(0, 0, size.width * factor, size.height * factor);
     glBindFramebuffer(GL_FRAMEBUFFER, buffer);
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
 }
 
 void Framebuffer::resize(uint width, uint height) const {
+    width *= factor;
+    height *= factor;
     for(uint i = 0; i < 6; i++) {
         if(mode & data[i].mask) {
             glBindTexture(GL_TEXTURE_2D, textures[i]);
@@ -122,3 +125,8 @@ const char* Framebuffer::getErrorString(GLenum error) const {
     }
     return "unknown error";
 }
+
+void Framebuffer::setFactor(int factor) {
+    this->factor = factor;
+    resize(size.width, size.height);
+}

+ 4 - 0
client/rendering/wrapper/Framebuffer.h

@@ -34,6 +34,8 @@ public:
     void bindRedTexture(uint textureUnit) const;
     void bindTangentTexture(uint textureUnit) const;
     void bindDepthTexture(uint textureUnit) const;
+    
+    void setFactor(int factor);
 
 private:
     void genTexture(uint index, uint width, uint height);
@@ -41,10 +43,12 @@ private:
     void bindTexture(uint textureUnit, GLuint texture) const;
     const char* getErrorString(GLenum error) const;
 
+    const WindowSize& size;
     uint mode;
     Array<GLuint, 6> textures;
     GLuint buffer;
     bool error;
+    int factor;
 
     struct Data final {
         uint mask;

+ 1 - 1
client/rendering/wrapper/Window.cpp

@@ -10,7 +10,7 @@ Window::Window(const WindowSize& size, const char* windowName) : window(nullptr)
     glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
     glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
-
+    
     window = glfwCreateWindow(size.width, size.height, windowName, nullptr, nullptr);
     if(window == nullptr) {
         std::cout << "could not create window\n";

+ 20 - 0
resources/shader/antialiasFragment.fs

@@ -0,0 +1,20 @@
+#version 430
+
+layout (binding = 0) uniform sampler2D colorSamp;
+
+in vec2 varTex;
+out vec4 color;
+
+uniform int radius;
+
+void main() {
+    vec2 texelSize = 1.0 / vec2(textureSize(colorSamp, 0));
+    color = vec4(0.0, 0.0, 0.0, 0.0);
+    for(float x = 0; x < radius; x++) {
+        for(float y = 0; y < radius; y++) {
+            vec2 offset = vec2(x, y) * texelSize;
+            color += texture(colorSamp, varTex + offset);
+        }
+    }
+    color /= (radius * radius);
+}  

+ 11 - 0
resources/shader/antialiasVertex.vs

@@ -0,0 +1,11 @@
+#version 430
+
+layout (location = 0) in vec3 position;
+layout (location = 1) in vec2 tex;
+
+out vec2 varTex;
+
+void main(void) { 
+    gl_Position = vec4(position, 1.0);
+    varTex = tex;
+}

+ 2 - 3
resources/shader/worldPostFragment.fs

@@ -16,10 +16,9 @@ out vec4 color;
 const vec3 light = vec3(-0.280166, -0.573576, -0.769751);
 
 void main() {
+    color = vec4(texture(colorSamp, varTex).xyz, 1.0);
     if(ssao) {
-        color = vec4(texture(colorSamp, varTex).xyz * (texture(ssaoSamp, varTex).r + 0.5), 1.0);
-    } else {
-        color = vec4(texture(colorSamp, varTex).xyz, 1.0);
+        color = vec4(color.xyz * (texture(ssaoSamp, varTex).r + 0.5), 1.0);
     }
     if(shadows) {
         float f = texture(shadowSamp, varTex).r;