mirror of
https://github.com/JoeyDeVries/LearnOpenGL.git
synced 2026-01-02 04:37:54 +08:00
Updated SSAO tutorial.
This commit is contained in:
@@ -22,7 +22,7 @@
|
||||
#include <learnopengl/filesystem.h>
|
||||
|
||||
// Properties
|
||||
const GLuint SCR_WIDTH = 800, SCR_HEIGHT = 600;
|
||||
const GLuint SCR_WIDTH = 1280, SCR_HEIGHT = 720;
|
||||
|
||||
// Function prototypes
|
||||
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);
|
||||
@@ -87,12 +87,12 @@ int main()
|
||||
|
||||
// Set samplers
|
||||
shaderLightingPass.Use();
|
||||
glUniform1i(glGetUniformLocation(shaderLightingPass.Program, "gPositionDepth"), 0);
|
||||
glUniform1i(glGetUniformLocation(shaderLightingPass.Program, "gPosition"), 0);
|
||||
glUniform1i(glGetUniformLocation(shaderLightingPass.Program, "gNormal"), 1);
|
||||
glUniform1i(glGetUniformLocation(shaderLightingPass.Program, "gAlbedo"), 2);
|
||||
glUniform1i(glGetUniformLocation(shaderLightingPass.Program, "ssao"), 3);
|
||||
shaderSSAO.Use();
|
||||
glUniform1i(glGetUniformLocation(shaderSSAO.Program, "gPositionDepth"), 0);
|
||||
glUniform1i(glGetUniformLocation(shaderSSAO.Program, "gPosition"), 0);
|
||||
glUniform1i(glGetUniformLocation(shaderSSAO.Program, "gNormal"), 1);
|
||||
glUniform1i(glGetUniformLocation(shaderSSAO.Program, "texNoise"), 2);
|
||||
|
||||
@@ -105,22 +105,22 @@ int main()
|
||||
|
||||
// Set up G-Buffer
|
||||
// 3 textures:
|
||||
// 1. Positions + depth (RGBA)
|
||||
// 1. Positions (RGB)
|
||||
// 2. Color (RGB)
|
||||
// 3. Normals (RGB)
|
||||
GLuint gBuffer;
|
||||
glGenFramebuffers(1, &gBuffer);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);
|
||||
GLuint gPositionDepth, gNormal, gAlbedo;
|
||||
// - Position + linear depth color buffer
|
||||
glGenTextures(1, &gPositionDepth);
|
||||
glBindTexture(GL_TEXTURE_2D, gPositionDepth);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGB, GL_FLOAT, NULL);
|
||||
GLuint gPosition, gNormal, gAlbedo;
|
||||
// - Position buffer
|
||||
glGenTextures(1, &gPosition);
|
||||
glBindTexture(GL_TEXTURE_2D, gPosition);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGB, GL_FLOAT, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gPositionDepth, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gPosition, 0);
|
||||
// - Normal color buffer
|
||||
glGenTextures(1, &gNormal);
|
||||
glBindTexture(GL_TEXTURE_2D, gNormal);
|
||||
@@ -221,7 +221,6 @@ int main()
|
||||
glfwPollEvents();
|
||||
Do_Movement();
|
||||
|
||||
|
||||
// 1. Geometry Pass: render scene's geometry/color data into gbuffer
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
@@ -239,7 +238,7 @@ int main()
|
||||
// Nanosuit model on the floor
|
||||
model = glm::mat4();
|
||||
model = glm::translate(model, glm::vec3(0.0f, 0.0f, 5.0));
|
||||
model = glm::rotate(model, -90.0f, glm::vec3(1.0, 0.0, 0.0));
|
||||
model = glm::rotate(model, glm::radians(-90.0f), glm::vec3(1.0, 0.0, 0.0));
|
||||
model = glm::scale(model, glm::vec3(0.5f));
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderGeometryPass.Program, "model"), 1, GL_FALSE, glm::value_ptr(model));
|
||||
nanosuit.Draw(shaderGeometryPass);
|
||||
@@ -251,7 +250,7 @@ int main()
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
shaderSSAO.Use();
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, gPositionDepth);
|
||||
glBindTexture(GL_TEXTURE_2D, gPosition);
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, gNormal);
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
@@ -278,7 +277,7 @@ int main()
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
shaderLightingPass.Use();
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, gPositionDepth);
|
||||
glBindTexture(GL_TEXTURE_2D, gPosition);
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, gNormal);
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
@@ -318,10 +317,10 @@ void RenderQuad()
|
||||
{
|
||||
GLfloat quadVertices[] = {
|
||||
// Positions // Texture Coords
|
||||
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
|
||||
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
|
||||
1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
|
||||
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
|
||||
1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
|
||||
};
|
||||
// Setup plane VAO
|
||||
glGenVertexArrays(1, &quadVAO);
|
||||
@@ -349,47 +348,47 @@ void RenderCube()
|
||||
{
|
||||
GLfloat vertices[] = {
|
||||
// Back face
|
||||
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, // Bottom-left
|
||||
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, // top-right
|
||||
0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, // bottom-right
|
||||
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, // top-right
|
||||
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, // bottom-left
|
||||
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f,// top-left
|
||||
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, // Bottom-left
|
||||
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, // top-right
|
||||
0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, // bottom-right
|
||||
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, // top-right
|
||||
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, // bottom-left
|
||||
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f,// top-left
|
||||
// Front face
|
||||
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom-left
|
||||
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, // bottom-right
|
||||
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // top-right
|
||||
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // top-right
|
||||
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, // top-left
|
||||
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom-left
|
||||
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom-left
|
||||
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, // bottom-right
|
||||
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // top-right
|
||||
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // top-right
|
||||
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, // top-left
|
||||
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom-left
|
||||
// Left face
|
||||
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // top-right
|
||||
-0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top-left
|
||||
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // bottom-left
|
||||
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // bottom-left
|
||||
-0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // bottom-right
|
||||
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // top-right
|
||||
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // top-right
|
||||
-0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top-left
|
||||
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // bottom-left
|
||||
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // bottom-left
|
||||
-0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // bottom-right
|
||||
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // top-right
|
||||
// Right face
|
||||
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // top-left
|
||||
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // bottom-right
|
||||
0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top-right
|
||||
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // bottom-right
|
||||
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // top-left
|
||||
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // bottom-left
|
||||
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // top-left
|
||||
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // bottom-right
|
||||
0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top-right
|
||||
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // bottom-right
|
||||
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // top-left
|
||||
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // bottom-left
|
||||
// Bottom face
|
||||
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, // top-right
|
||||
0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f, // top-left
|
||||
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,// bottom-left
|
||||
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, // bottom-left
|
||||
-0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, // bottom-right
|
||||
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, // top-right
|
||||
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, // top-right
|
||||
0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f, // top-left
|
||||
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,// bottom-left
|
||||
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, // bottom-left
|
||||
-0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, // bottom-right
|
||||
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, // top-right
|
||||
// Top face
|
||||
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,// top-left
|
||||
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom-right
|
||||
0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, // top-right
|
||||
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom-right
|
||||
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,// top-left
|
||||
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f // bottom-left
|
||||
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,// top-left
|
||||
0.5f, 0.5f , 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom-right
|
||||
0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, // top-right
|
||||
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom-right
|
||||
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,// top-left
|
||||
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f // bottom-left
|
||||
};
|
||||
glGenVertexArrays(1, &cubeVAO);
|
||||
glGenBuffers(1, &cubeVBO);
|
||||
@@ -436,8 +435,6 @@ void Do_Movement()
|
||||
draw_mode = 3;
|
||||
if (keys[GLFW_KEY_4])
|
||||
draw_mode = 4;
|
||||
if (keys[GLFW_KEY_5])
|
||||
draw_mode = 5;
|
||||
}
|
||||
|
||||
GLfloat lastX = 400, lastY = 300;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
out float FragColor;
|
||||
in vec2 TexCoords;
|
||||
|
||||
uniform sampler2D gPositionDepth;
|
||||
uniform sampler2D gPosition;
|
||||
uniform sampler2D gNormal;
|
||||
uniform sampler2D texNoise;
|
||||
|
||||
@@ -10,17 +10,18 @@ uniform vec3 samples[64];
|
||||
|
||||
// parameters (you'd probably want to use them as uniforms to more easily tweak the effect)
|
||||
int kernelSize = 64;
|
||||
float radius = 1.0;
|
||||
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(800.0f/4.0f, 600.0f/4.0f);
|
||||
const vec2 noiseScale = vec2(1280.0/4.0, 720.0/4.0);
|
||||
|
||||
uniform mat4 projection;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Get input for SSAO algorithm
|
||||
vec3 fragPos = texture(gPositionDepth, TexCoords).xyz;
|
||||
vec3 fragPos = texture(gPosition, TexCoords).xyz;
|
||||
vec3 normal = texture(gNormal, TexCoords).rgb;
|
||||
vec3 randomVec = texture(texNoise, TexCoords * noiseScale).xyz;
|
||||
// Create TBN change-of-basis matrix: from tangent-space to view-space
|
||||
@@ -42,11 +43,11 @@ void main()
|
||||
offset.xyz = offset.xyz * 0.5 + 0.5; // transform to range 0.0 - 1.0
|
||||
|
||||
// get sample depth
|
||||
float sampleDepth = -texture(gPositionDepth, offset.xy).w; // Get depth value of kernel sample
|
||||
float sampleDepth = texture(gPosition, offset.xy).z; // Get depth value of kernel sample
|
||||
|
||||
// range check & accumulate
|
||||
float rangeCheck = smoothstep(0.0, 1.0, radius / abs(fragPos.z - sampleDepth ));
|
||||
occlusion += (sampleDepth >= sample.z ? 1.0 : 0.0) * rangeCheck;
|
||||
float rangeCheck = smoothstep(0.0, 1.0, radius / abs(fragPos.z - sampleDepth));
|
||||
occlusion += (sampleDepth >= sample.z + bias ? 1.0 : 0.0) * rangeCheck;
|
||||
}
|
||||
occlusion = 1.0 - (occlusion / kernelSize);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#version 330 core
|
||||
layout (location = 0) out vec4 gPositionDepth;
|
||||
layout (location = 0) out vec3 gPosition;
|
||||
layout (location = 1) out vec3 gNormal;
|
||||
layout (location = 2) out vec4 gAlbedoSpec;
|
||||
|
||||
@@ -7,20 +7,10 @@ in vec2 TexCoords;
|
||||
in vec3 FragPos;
|
||||
in vec3 Normal;
|
||||
|
||||
const float NEAR = 0.1;
|
||||
const float FAR = 50.0f;
|
||||
float LinearizeDepth(float depth)
|
||||
{
|
||||
float z = depth * 2.0 - 1.0; // Back to NDC
|
||||
return (2.0 * NEAR * FAR) / (FAR + NEAR - z * (FAR - NEAR));
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
// Store the fragment position vector in the first gbuffer texture
|
||||
gPositionDepth.xyz = FragPos;
|
||||
// And store linear depth into gPositionDepth's alpha component
|
||||
gPositionDepth.a = LinearizeDepth(gl_FragCoord.z); // Divide by far to store depth in range 0.0 - 1.0
|
||||
gPosition = FragPos;
|
||||
// Also store the per-fragment normals into the gbuffer
|
||||
gNormal = normalize(Normal);
|
||||
// And the diffuse per-fragment color
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
out vec4 FragColor;
|
||||
in vec2 TexCoords;
|
||||
|
||||
uniform sampler2D gPositionDepth;
|
||||
uniform sampler2D gPosition;
|
||||
uniform sampler2D gNormal;
|
||||
uniform sampler2D gAlbedo;
|
||||
uniform sampler2D ssao;
|
||||
@@ -21,10 +21,9 @@ uniform int draw_mode;
|
||||
void main()
|
||||
{
|
||||
// Retrieve data from gbuffer
|
||||
vec3 FragPos = texture(gPositionDepth, TexCoords).rgb;
|
||||
vec3 FragPos = texture(gPosition, TexCoords).rgb;
|
||||
vec3 Normal = texture(gNormal, TexCoords).rgb;
|
||||
vec3 Diffuse = texture(gAlbedo, TexCoords).rgb;
|
||||
float Depth = texture(gPositionDepth, TexCoords).a;
|
||||
float AmbientOcclusion = texture(ssao, TexCoords).r;
|
||||
|
||||
// Then calculate lighting as usual
|
||||
@@ -49,11 +48,9 @@ void main()
|
||||
if(draw_mode == 1)
|
||||
FragColor = vec4(lighting, 1.0);
|
||||
else if(draw_mode == 2)
|
||||
FragColor = vec4(vec3(Depth / 50.0), 1.0);
|
||||
else if(draw_mode == 3)
|
||||
FragColor = vec4(FragPos, 1.0);
|
||||
else if(draw_mode == 4)
|
||||
else if(draw_mode == 3)
|
||||
FragColor = vec4(Normal, 1.0);
|
||||
else if(draw_mode == 5)
|
||||
else if(draw_mode == 4)
|
||||
FragColor = vec4(vec3(AmbientOcclusion), 1.0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user