mirror of
https://github.com/JoeyDeVries/LearnOpenGL.git
synced 2026-01-07 01:03:22 +08:00
Updated SSAO tutorial.
This commit is contained in:
@@ -22,7 +22,7 @@
|
|||||||
#include <learnopengl/filesystem.h>
|
#include <learnopengl/filesystem.h>
|
||||||
|
|
||||||
// Properties
|
// Properties
|
||||||
const GLuint SCR_WIDTH = 800, SCR_HEIGHT = 600;
|
const GLuint SCR_WIDTH = 1280, SCR_HEIGHT = 720;
|
||||||
|
|
||||||
// Function prototypes
|
// Function prototypes
|
||||||
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);
|
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);
|
||||||
@@ -87,12 +87,12 @@ int main()
|
|||||||
|
|
||||||
// Set samplers
|
// Set samplers
|
||||||
shaderLightingPass.Use();
|
shaderLightingPass.Use();
|
||||||
glUniform1i(glGetUniformLocation(shaderLightingPass.Program, "gPositionDepth"), 0);
|
glUniform1i(glGetUniformLocation(shaderLightingPass.Program, "gPosition"), 0);
|
||||||
glUniform1i(glGetUniformLocation(shaderLightingPass.Program, "gNormal"), 1);
|
glUniform1i(glGetUniformLocation(shaderLightingPass.Program, "gNormal"), 1);
|
||||||
glUniform1i(glGetUniformLocation(shaderLightingPass.Program, "gAlbedo"), 2);
|
glUniform1i(glGetUniformLocation(shaderLightingPass.Program, "gAlbedo"), 2);
|
||||||
glUniform1i(glGetUniformLocation(shaderLightingPass.Program, "ssao"), 3);
|
glUniform1i(glGetUniformLocation(shaderLightingPass.Program, "ssao"), 3);
|
||||||
shaderSSAO.Use();
|
shaderSSAO.Use();
|
||||||
glUniform1i(glGetUniformLocation(shaderSSAO.Program, "gPositionDepth"), 0);
|
glUniform1i(glGetUniformLocation(shaderSSAO.Program, "gPosition"), 0);
|
||||||
glUniform1i(glGetUniformLocation(shaderSSAO.Program, "gNormal"), 1);
|
glUniform1i(glGetUniformLocation(shaderSSAO.Program, "gNormal"), 1);
|
||||||
glUniform1i(glGetUniformLocation(shaderSSAO.Program, "texNoise"), 2);
|
glUniform1i(glGetUniformLocation(shaderSSAO.Program, "texNoise"), 2);
|
||||||
|
|
||||||
@@ -105,22 +105,22 @@ int main()
|
|||||||
|
|
||||||
// Set up G-Buffer
|
// Set up G-Buffer
|
||||||
// 3 textures:
|
// 3 textures:
|
||||||
// 1. Positions + depth (RGBA)
|
// 1. Positions (RGB)
|
||||||
// 2. Color (RGB)
|
// 2. Color (RGB)
|
||||||
// 3. Normals (RGB)
|
// 3. Normals (RGB)
|
||||||
GLuint gBuffer;
|
GLuint gBuffer;
|
||||||
glGenFramebuffers(1, &gBuffer);
|
glGenFramebuffers(1, &gBuffer);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);
|
glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);
|
||||||
GLuint gPositionDepth, gNormal, gAlbedo;
|
GLuint gPosition, gNormal, gAlbedo;
|
||||||
// - Position + linear depth color buffer
|
// - Position buffer
|
||||||
glGenTextures(1, &gPositionDepth);
|
glGenTextures(1, &gPosition);
|
||||||
glBindTexture(GL_TEXTURE_2D, gPositionDepth);
|
glBindTexture(GL_TEXTURE_2D, gPosition);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGB, GL_FLOAT, NULL);
|
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_MIN_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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_S, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, 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
|
// - Normal color buffer
|
||||||
glGenTextures(1, &gNormal);
|
glGenTextures(1, &gNormal);
|
||||||
glBindTexture(GL_TEXTURE_2D, gNormal);
|
glBindTexture(GL_TEXTURE_2D, gNormal);
|
||||||
@@ -221,7 +221,6 @@ int main()
|
|||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
Do_Movement();
|
Do_Movement();
|
||||||
|
|
||||||
|
|
||||||
// 1. Geometry Pass: render scene's geometry/color data into gbuffer
|
// 1. Geometry Pass: render scene's geometry/color data into gbuffer
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);
|
glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
@@ -239,7 +238,7 @@ int main()
|
|||||||
// Nanosuit model on the floor
|
// Nanosuit model on the floor
|
||||||
model = glm::mat4();
|
model = glm::mat4();
|
||||||
model = glm::translate(model, glm::vec3(0.0f, 0.0f, 5.0));
|
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));
|
model = glm::scale(model, glm::vec3(0.5f));
|
||||||
glUniformMatrix4fv(glGetUniformLocation(shaderGeometryPass.Program, "model"), 1, GL_FALSE, glm::value_ptr(model));
|
glUniformMatrix4fv(glGetUniformLocation(shaderGeometryPass.Program, "model"), 1, GL_FALSE, glm::value_ptr(model));
|
||||||
nanosuit.Draw(shaderGeometryPass);
|
nanosuit.Draw(shaderGeometryPass);
|
||||||
@@ -251,7 +250,7 @@ int main()
|
|||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
shaderSSAO.Use();
|
shaderSSAO.Use();
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, gPositionDepth);
|
glBindTexture(GL_TEXTURE_2D, gPosition);
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
glBindTexture(GL_TEXTURE_2D, gNormal);
|
glBindTexture(GL_TEXTURE_2D, gNormal);
|
||||||
glActiveTexture(GL_TEXTURE2);
|
glActiveTexture(GL_TEXTURE2);
|
||||||
@@ -278,7 +277,7 @@ int main()
|
|||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
shaderLightingPass.Use();
|
shaderLightingPass.Use();
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, gPositionDepth);
|
glBindTexture(GL_TEXTURE_2D, gPosition);
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
glBindTexture(GL_TEXTURE_2D, gNormal);
|
glBindTexture(GL_TEXTURE_2D, gNormal);
|
||||||
glActiveTexture(GL_TEXTURE2);
|
glActiveTexture(GL_TEXTURE2);
|
||||||
@@ -436,8 +435,6 @@ void Do_Movement()
|
|||||||
draw_mode = 3;
|
draw_mode = 3;
|
||||||
if (keys[GLFW_KEY_4])
|
if (keys[GLFW_KEY_4])
|
||||||
draw_mode = 4;
|
draw_mode = 4;
|
||||||
if (keys[GLFW_KEY_5])
|
|
||||||
draw_mode = 5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GLfloat lastX = 400, lastY = 300;
|
GLfloat lastX = 400, lastY = 300;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
out float FragColor;
|
out float FragColor;
|
||||||
in vec2 TexCoords;
|
in vec2 TexCoords;
|
||||||
|
|
||||||
uniform sampler2D gPositionDepth;
|
uniform sampler2D gPosition;
|
||||||
uniform sampler2D gNormal;
|
uniform sampler2D gNormal;
|
||||||
uniform sampler2D texNoise;
|
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)
|
// parameters (you'd probably want to use them as uniforms to more easily tweak the effect)
|
||||||
int kernelSize = 64;
|
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
|
// 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;
|
uniform mat4 projection;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Get input for SSAO algorithm
|
// Get input for SSAO algorithm
|
||||||
vec3 fragPos = texture(gPositionDepth, TexCoords).xyz;
|
vec3 fragPos = texture(gPosition, TexCoords).xyz;
|
||||||
vec3 normal = texture(gNormal, TexCoords).rgb;
|
vec3 normal = texture(gNormal, TexCoords).rgb;
|
||||||
vec3 randomVec = texture(texNoise, TexCoords * noiseScale).xyz;
|
vec3 randomVec = texture(texNoise, TexCoords * noiseScale).xyz;
|
||||||
// Create TBN change-of-basis matrix: from tangent-space to view-space
|
// 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
|
offset.xyz = offset.xyz * 0.5 + 0.5; // transform to range 0.0 - 1.0
|
||||||
|
|
||||||
// get sample depth
|
// 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
|
// range check & accumulate
|
||||||
float rangeCheck = smoothstep(0.0, 1.0, radius / abs(fragPos.z - sampleDepth));
|
float rangeCheck = smoothstep(0.0, 1.0, radius / abs(fragPos.z - sampleDepth));
|
||||||
occlusion += (sampleDepth >= sample.z ? 1.0 : 0.0) * rangeCheck;
|
occlusion += (sampleDepth >= sample.z + bias ? 1.0 : 0.0) * rangeCheck;
|
||||||
}
|
}
|
||||||
occlusion = 1.0 - (occlusion / kernelSize);
|
occlusion = 1.0 - (occlusion / kernelSize);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#version 330 core
|
#version 330 core
|
||||||
layout (location = 0) out vec4 gPositionDepth;
|
layout (location = 0) out vec3 gPosition;
|
||||||
layout (location = 1) out vec3 gNormal;
|
layout (location = 1) out vec3 gNormal;
|
||||||
layout (location = 2) out vec4 gAlbedoSpec;
|
layout (location = 2) out vec4 gAlbedoSpec;
|
||||||
|
|
||||||
@@ -7,20 +7,10 @@ in vec2 TexCoords;
|
|||||||
in vec3 FragPos;
|
in vec3 FragPos;
|
||||||
in vec3 Normal;
|
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()
|
void main()
|
||||||
{
|
{
|
||||||
// Store the fragment position vector in the first gbuffer texture
|
// Store the fragment position vector in the first gbuffer texture
|
||||||
gPositionDepth.xyz = FragPos;
|
gPosition = 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
|
|
||||||
// Also store the per-fragment normals into the gbuffer
|
// Also store the per-fragment normals into the gbuffer
|
||||||
gNormal = normalize(Normal);
|
gNormal = normalize(Normal);
|
||||||
// And the diffuse per-fragment color
|
// And the diffuse per-fragment color
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
out vec4 FragColor;
|
out vec4 FragColor;
|
||||||
in vec2 TexCoords;
|
in vec2 TexCoords;
|
||||||
|
|
||||||
uniform sampler2D gPositionDepth;
|
uniform sampler2D gPosition;
|
||||||
uniform sampler2D gNormal;
|
uniform sampler2D gNormal;
|
||||||
uniform sampler2D gAlbedo;
|
uniform sampler2D gAlbedo;
|
||||||
uniform sampler2D ssao;
|
uniform sampler2D ssao;
|
||||||
@@ -21,10 +21,9 @@ uniform int draw_mode;
|
|||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Retrieve data from gbuffer
|
// Retrieve data from gbuffer
|
||||||
vec3 FragPos = texture(gPositionDepth, TexCoords).rgb;
|
vec3 FragPos = texture(gPosition, TexCoords).rgb;
|
||||||
vec3 Normal = texture(gNormal, TexCoords).rgb;
|
vec3 Normal = texture(gNormal, TexCoords).rgb;
|
||||||
vec3 Diffuse = texture(gAlbedo, TexCoords).rgb;
|
vec3 Diffuse = texture(gAlbedo, TexCoords).rgb;
|
||||||
float Depth = texture(gPositionDepth, TexCoords).a;
|
|
||||||
float AmbientOcclusion = texture(ssao, TexCoords).r;
|
float AmbientOcclusion = texture(ssao, TexCoords).r;
|
||||||
|
|
||||||
// Then calculate lighting as usual
|
// Then calculate lighting as usual
|
||||||
@@ -49,11 +48,9 @@ void main()
|
|||||||
if(draw_mode == 1)
|
if(draw_mode == 1)
|
||||||
FragColor = vec4(lighting, 1.0);
|
FragColor = vec4(lighting, 1.0);
|
||||||
else if(draw_mode == 2)
|
else if(draw_mode == 2)
|
||||||
FragColor = vec4(vec3(Depth / 50.0), 1.0);
|
|
||||||
else if(draw_mode == 3)
|
|
||||||
FragColor = vec4(FragPos, 1.0);
|
FragColor = vec4(FragPos, 1.0);
|
||||||
else if(draw_mode == 4)
|
else if(draw_mode == 3)
|
||||||
FragColor = vec4(Normal, 1.0);
|
FragColor = vec4(Normal, 1.0);
|
||||||
else if(draw_mode == 5)
|
else if(draw_mode == 4)
|
||||||
FragColor = vec4(vec3(AmbientOcclusion), 1.0);
|
FragColor = vec4(vec3(AmbientOcclusion), 1.0);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user