SSAO 工作但有一个奇怪的红色覆盖
SSAO working but has a weird Red colour overlay
ssao 有效,但有 奇怪的红色叠加层,因为 ssao 当然只使用红色通道 这显示了在下图中..
红色 SSAO 问题
但是,当我执行 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 时,红色消失了,但是ssao 也一样。
执行 glClear() 后的结果。不再有 SSAO
这是您需要的所有代码...
// ------------------------------ LIGHT PASS -------------------------------- //
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
shaders[LIGHT_PASS]->UseProgram(); // Bind light pass shader
// Parse the camera position
LightPass::Render(Content::_map->GetCamera(), Content::_map->GetCamera()->GetPosition());
GBuffer::Render(); // bind the gbuffer textures (includes SSAO)
renderQuad(); // Render the screen rectangle
// -------------------------------------------------------------------- //
几何密码..
// ----------------------------- GEOMETRY PASS ----------------------------- //
GBuffer::Bind(); // Bind the world gbuffer frame buffer
shaders[GEOMETRY_PASS]->UseProgram(); // Bind geometry shader
GeometryPass::Render(); // Render geometry
glBindFramebuffer(GL_FRAMEBUFFER, 0); // Unbind the gbuffer
// --------------------------------------------------------------------- //
SSAO 密码..
static inline void Initialise(unsigned int ssao_program, unsigned int ssaoblur_program)
{
program = ssao_program;
program2 = ssaoblur_program;
// SSAO color fbo
glGenTextures(1, &ssaoColorBuffer);
glBindTexture(GL_TEXTURE_2D, ssaoColorBuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 1920, 1080, 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);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ssaoColorBuffer, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
std::cout << "SSAO Framebuffer not complete!" << std::endl;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// blur fbo
glGenFramebuffers(1, &ssaoBlurFBO);
glBindFramebuffer(GL_FRAMEBUFFER, ssaoBlurFBO);
// SSAO color buffer
glGenTextures(1, &ssaoColorBufferBlur);
glBindTexture(GL_TEXTURE_2D, ssaoColorBufferBlur);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 1920, 1080, 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);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ssaoColorBufferBlur, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
std::cout << "SSAO Framebuffer not complete!" << std::endl;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
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)
{
glm::vec3 sample(randomFloats(generator) * 2.0 - 1.0, randomFloats(generator) * 2.0 - 1.0, randomFloats(generator));
sample = glm::normalize(sample);
sample *= randomFloats(generator);
float scale = float(i) / 64.0;
// scale samples s.t. they're more aligned to center of kernel
scale = lerp(0.1f, 1.0f, scale * scale);
sample *= scale;
ssaoKernel.push_back(sample);
}
for (unsigned int i = 0; i < 16; i++)
{
glm::vec3 noise(randomFloats(generator) * 2.0 - 1.0, randomFloats(generator) * 2.0 - 1.0, 0.0f); // rotate around z-axis (in tangent space)
ssaoNoise.push_back(noise);
}
glGenTextures(1, &noiseTexture);
glBindTexture(GL_TEXTURE_2D, noiseTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, 4, 4, 0, GL_RGB, GL_FLOAT, &ssaoNoise[0]);
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_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glUseProgram(ssao_program);
glUniform1i(glGetUniformLocation(ssao_program, "gPosition"), 0); // the positions texture in the gbuffer
glUniform1i(glGetUniformLocation(ssao_program, "gNormal"), 1); // the normals texture in the gbuffer
glUniform1i(glGetUniformLocation(ssao_program, "texNoise"), 2); // the albedospec texture within the gbuffe
glUseProgram(ssaoblur_program);
glUniform1i(glGetUniformLocation(ssaoblur_program, "ssaoInput"), 0); // the positions texture in the gbuffer
}
static inline void Render(Camera* _camera)
{
// generate SSAO texture
glBindFramebuffer(GL_FRAMEBUFFER, ssaoFBO);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(program);
for (unsigned int i = 0; i < 64; ++i)
glUniform3fv(glGetUniformLocation(program, ("samples[" + std::to_string(i) + "]").c_str()), 1, glm::value_ptr(ssaoKernel[i]));
glUniformMatrix4fv(glGetUniformLocation(program, "proj"), 1, GL_FALSE, glm::value_ptr(_camera->GetProjectionMatrix()));
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, GBuffer::GetPositions());
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, GBuffer::GetNormals());
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, noiseTexture);
renderQuad();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// Blur ssao texture
glBindFramebuffer(GL_FRAMEBUFFER, ssaoBlurFBO);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(program2);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, ssaoColorBuffer);
renderQuad();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
GBuffer 顶点着色器..
#version 420 core
layout(location = 0) in vec3 position;
layout(location = 1) in vec3 texcoord;
layout(location = 2) in vec3 normal;
layout(location = 3) in vec3 tangent;
out vec3 _texcoord;
out vec3 _normal;
out vec3 _tangent;
out vec3 _frag_pos;
uniform mat4 mod;
uniform mat4 view;
uniform mat4 proj;
void main()
{
vec4 view_space = view * mod * vec4(position, 1.0);
_frag_pos = view_space.xyz;
_texcoord = texcoord;
_normal = ((view * mod) * vec4(normal, 0.0)).xyz;
_tangent = (mod * vec4(tangent, 0.0)).xyz;
gl_Position = proj * view_space;
}
GBuffer 片段着色器...
#version 420 core
layout(location = 0) out vec3 gPosition; // Position texel colour
layout(location = 1) out vec3 gNormal; // Normal texel colour
layout(location = 2) out vec4 gAlbedo; // Albedo texel colour
layout(location = 3) out vec3 gSpecular; // Cubemap texel colour
layout(location = 4) out vec3 gMetalness; // Cubemap texel colour
in vec3 _texcoord;
in vec3 _normal;
in vec3 _tangent;
in vec3 _frag_pos;
uniform vec3 camera_pos;
uniform sampler2D normal; // Normal map
uniform sampler2D albedo; // Albedo and specular map
uniform sampler2D specular; // Specular map
uniform sampler2D metalness; // Metalness map
uniform samplerCube cubemap; // Local cubemap reflection sampler
vec3 TBN()
{
vec3 Normal = normalize(_normal); // Optimise normal
vec3 Tangent = normalize(_tangent); // Optimise tangent
vec3 Bitangent = cross(Tangent, Normal); // Calculate bitangent
vec3 BumpMapNormal = texture(normal, vec2(_texcoord).st).rgb; // Assign rgb values from normal map
BumpMapNormal = 2.0 * BumpMapNormal - vec3(1.0, 1.0, 1.0); // normalise the normal map between -1 to 1
mat3 TBN = mat3(Tangent, Bitangent, Normal); // Create tangent, bitangent and normal matrix
vec3 NewNormal; // Create a new normal variable
NewNormal = TBN * vec3(BumpMapNormal.r, -BumpMapNormal.g, BumpMapNormal.b); // Flip green component for OpenGL
NewNormal = normalize(NewNormal); // Normalise the new normal
return NewNormal; // Return the newly calculated normal
}
vec4 Convolute()
{
vec4 result = vec4(0.0);
const float kernel[] = float[25] ( 0,1,2,1,0,
1,2,3,2,1,
2,3,4,3,2,
1,2,3,2,1,
0,1,2,1,0);
vec2 delta = 1.0 / textureSize(albedo, 0);
int index = 24;
for (int j = -1; j <= 1; j++)
{
for (int i = -1; i <= 1; i++)
{
//for (int k = -1; k <= 1; k++)
result += kernel[index--] * texture(albedo, vec2(_texcoord).st + (vec2(i, j) * delta));
}
}
result /= 25.0;
return result;
}
void main()
{
gPosition = _frag_pos;
gNormal = normalize(TBN());
vec3 I = normalize(_frag_pos - camera_pos); // Calculate eye to fragment direction
vec3 R = reflect(I, normalize(TBN())); // Reflect I with the vertex normal
float M = texture(metalness, vec2(_texcoord.st)).r;
//vec4 gaussian = Convolute();
gAlbedo = texture(albedo, vec2(_texcoord.st)); // Assign albedo
gSpecular = texture(specular, vec2(_texcoord.st)).rgb; // Assign specular
gMetalness = (texture(cubemap, R).rgb) * M; // Assign metalness
}
灯光着色器...
#version 420 core
out vec4 FragColor;
in vec2 _texcoord;
uniform vec3 camera_pos;
uniform sampler2D gPosition;
uniform sampler2D gNormal;
uniform sampler2D gAlbedo;
uniform sampler2D gSpecular;
uniform sampler2D gMetalness;
uniform sampler2D gSsao;
uniform vec3 lightPos;
void main(void)
{
vec3 FragPos = texture(gPosition, _texcoord).rgb;
vec3 Normal = texture(gNormal, _texcoord).rgb;
vec3 Diffuse = texture(gAlbedo, _texcoord).rgb;
float Emissive = texture(gAlbedo, _texcoord).a;
vec3 Specular = texture(gAlbedo, _texcoord).rgb;
vec3 Metalness = texture(gMetalness, _texcoord).rgb; // Reflection pass
float AmbientOcclusion = texture(gSsao, _texcoord).r;
vec3 light_colour = vec3(1.0f, 0.8, 0.7);
vec3 lighting = vec3(0.3 * Diffuse * AmbientOcclusion);
vec3 viewDir = normalize(-FragPos);
vec3 lightDir = normalize(lightPos - FragPos);
vec3 diffuse = max(dot(Normal, lightDir), 0.0) * Diffuse * light_colour; // Light colour
vec3 halfwayDir = normalize(lightDir + viewDir);
float spec = pow(max(dot(Normal, halfwayDir), 0.0), 32.0);
vec3 specular = (Specular * light_colour) * spec;
vec3 metalness = Metalness * Diffuse;
lighting += diffuse + specular + metalness;
FragColor = vec4(lighting, 1.0);
}
需要更多代码就问。感谢您提供的任何帮助
编辑
问题已修复,是由于立方体贴图反射,现在一切正常
如果查找纹理,并且纹理中不存在特定纹理通道,则函数 texture
将为绿色和蓝色通道 return 0.0 和 alpha 1.0频道。
这可以通过纹理调配参数进行更改GL_TEXTURE_SWIZZLE_R
, GL_TEXTURE_SWIZZLE_G
, GL_TEXTURE_SWIZZLE_B
and GL_TEXTURE_SWIZZLE_A
。
如果您希望绿色和蓝色通道 return 与红色通道具有相同的值,那么可以这样做:
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_RED );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED );
将此参数应用于纹理对象 ssaoColorBuffer
和 ssaoColorBufferBlur
,以解决问题。
参见OpenGL 4.6 API Core Profile Specification; 15.2. SHADER EXECUTION; page 487]:
When a texture lookup is performed in a fragment shader, the GL computes the filtered texture value ... and converts it to a texture base color Cb as shown in table 15.1,
Texture Base Texture base color Internal Format Cb Ab
RED (Rt, 0, 0) 1
RG (Rt, Gt, 0) 1
RGB (Rt, Gt, Bt) 1
RGBA (Rt, Gt, Bt) At
Table 15.1: Correspondence of filtered texture components to texture base components.
followed by swizzling the components of Cb, controlled by the values of the texture parameters TEXTURE_SWIZZLE_R
, TEXTURE_SWIZZLE_G
, TEXTURE_SWIZZLE_B
, and TEXTURE_SWIZZLE_A
. If the value of TEXTURE_SWIZZLE_R
is denoted by swizzler, swizzling computes the first component of Cs according to
if (swizzler == RED)
Cs[0] = Cb[0];
else if (swizzler == GREEN)
Cs[0] = Cb[1];
else if (swizzler == BLUE)
Cs[0] = Cb[2];
else if (swizzler == ALPHA)
Cs[0] = Ab;
else if (swizzler == ZERO)
Cs[0] = 0;
else if (swizzler == ONE)
Cs[0] = 1; // float or int depending on texture component type
ssao 有效,但有 奇怪的红色叠加层,因为 ssao 当然只使用红色通道 这显示了在下图中..
红色 SSAO 问题
但是,当我执行 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 时,红色消失了,但是ssao 也一样。
执行 glClear() 后的结果。不再有 SSAO
这是您需要的所有代码...
// ------------------------------ LIGHT PASS -------------------------------- //
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
shaders[LIGHT_PASS]->UseProgram(); // Bind light pass shader
// Parse the camera position
LightPass::Render(Content::_map->GetCamera(), Content::_map->GetCamera()->GetPosition());
GBuffer::Render(); // bind the gbuffer textures (includes SSAO)
renderQuad(); // Render the screen rectangle
// -------------------------------------------------------------------- //
几何密码..
// ----------------------------- GEOMETRY PASS ----------------------------- //
GBuffer::Bind(); // Bind the world gbuffer frame buffer
shaders[GEOMETRY_PASS]->UseProgram(); // Bind geometry shader
GeometryPass::Render(); // Render geometry
glBindFramebuffer(GL_FRAMEBUFFER, 0); // Unbind the gbuffer
// --------------------------------------------------------------------- //
SSAO 密码..
static inline void Initialise(unsigned int ssao_program, unsigned int ssaoblur_program)
{
program = ssao_program;
program2 = ssaoblur_program;
// SSAO color fbo
glGenTextures(1, &ssaoColorBuffer);
glBindTexture(GL_TEXTURE_2D, ssaoColorBuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 1920, 1080, 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);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ssaoColorBuffer, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
std::cout << "SSAO Framebuffer not complete!" << std::endl;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// blur fbo
glGenFramebuffers(1, &ssaoBlurFBO);
glBindFramebuffer(GL_FRAMEBUFFER, ssaoBlurFBO);
// SSAO color buffer
glGenTextures(1, &ssaoColorBufferBlur);
glBindTexture(GL_TEXTURE_2D, ssaoColorBufferBlur);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 1920, 1080, 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);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ssaoColorBufferBlur, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
std::cout << "SSAO Framebuffer not complete!" << std::endl;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
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)
{
glm::vec3 sample(randomFloats(generator) * 2.0 - 1.0, randomFloats(generator) * 2.0 - 1.0, randomFloats(generator));
sample = glm::normalize(sample);
sample *= randomFloats(generator);
float scale = float(i) / 64.0;
// scale samples s.t. they're more aligned to center of kernel
scale = lerp(0.1f, 1.0f, scale * scale);
sample *= scale;
ssaoKernel.push_back(sample);
}
for (unsigned int i = 0; i < 16; i++)
{
glm::vec3 noise(randomFloats(generator) * 2.0 - 1.0, randomFloats(generator) * 2.0 - 1.0, 0.0f); // rotate around z-axis (in tangent space)
ssaoNoise.push_back(noise);
}
glGenTextures(1, &noiseTexture);
glBindTexture(GL_TEXTURE_2D, noiseTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, 4, 4, 0, GL_RGB, GL_FLOAT, &ssaoNoise[0]);
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_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glUseProgram(ssao_program);
glUniform1i(glGetUniformLocation(ssao_program, "gPosition"), 0); // the positions texture in the gbuffer
glUniform1i(glGetUniformLocation(ssao_program, "gNormal"), 1); // the normals texture in the gbuffer
glUniform1i(glGetUniformLocation(ssao_program, "texNoise"), 2); // the albedospec texture within the gbuffe
glUseProgram(ssaoblur_program);
glUniform1i(glGetUniformLocation(ssaoblur_program, "ssaoInput"), 0); // the positions texture in the gbuffer
}
static inline void Render(Camera* _camera)
{
// generate SSAO texture
glBindFramebuffer(GL_FRAMEBUFFER, ssaoFBO);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(program);
for (unsigned int i = 0; i < 64; ++i)
glUniform3fv(glGetUniformLocation(program, ("samples[" + std::to_string(i) + "]").c_str()), 1, glm::value_ptr(ssaoKernel[i]));
glUniformMatrix4fv(glGetUniformLocation(program, "proj"), 1, GL_FALSE, glm::value_ptr(_camera->GetProjectionMatrix()));
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, GBuffer::GetPositions());
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, GBuffer::GetNormals());
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, noiseTexture);
renderQuad();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// Blur ssao texture
glBindFramebuffer(GL_FRAMEBUFFER, ssaoBlurFBO);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(program2);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, ssaoColorBuffer);
renderQuad();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
GBuffer 顶点着色器..
#version 420 core
layout(location = 0) in vec3 position;
layout(location = 1) in vec3 texcoord;
layout(location = 2) in vec3 normal;
layout(location = 3) in vec3 tangent;
out vec3 _texcoord;
out vec3 _normal;
out vec3 _tangent;
out vec3 _frag_pos;
uniform mat4 mod;
uniform mat4 view;
uniform mat4 proj;
void main()
{
vec4 view_space = view * mod * vec4(position, 1.0);
_frag_pos = view_space.xyz;
_texcoord = texcoord;
_normal = ((view * mod) * vec4(normal, 0.0)).xyz;
_tangent = (mod * vec4(tangent, 0.0)).xyz;
gl_Position = proj * view_space;
}
GBuffer 片段着色器...
#version 420 core
layout(location = 0) out vec3 gPosition; // Position texel colour
layout(location = 1) out vec3 gNormal; // Normal texel colour
layout(location = 2) out vec4 gAlbedo; // Albedo texel colour
layout(location = 3) out vec3 gSpecular; // Cubemap texel colour
layout(location = 4) out vec3 gMetalness; // Cubemap texel colour
in vec3 _texcoord;
in vec3 _normal;
in vec3 _tangent;
in vec3 _frag_pos;
uniform vec3 camera_pos;
uniform sampler2D normal; // Normal map
uniform sampler2D albedo; // Albedo and specular map
uniform sampler2D specular; // Specular map
uniform sampler2D metalness; // Metalness map
uniform samplerCube cubemap; // Local cubemap reflection sampler
vec3 TBN()
{
vec3 Normal = normalize(_normal); // Optimise normal
vec3 Tangent = normalize(_tangent); // Optimise tangent
vec3 Bitangent = cross(Tangent, Normal); // Calculate bitangent
vec3 BumpMapNormal = texture(normal, vec2(_texcoord).st).rgb; // Assign rgb values from normal map
BumpMapNormal = 2.0 * BumpMapNormal - vec3(1.0, 1.0, 1.0); // normalise the normal map between -1 to 1
mat3 TBN = mat3(Tangent, Bitangent, Normal); // Create tangent, bitangent and normal matrix
vec3 NewNormal; // Create a new normal variable
NewNormal = TBN * vec3(BumpMapNormal.r, -BumpMapNormal.g, BumpMapNormal.b); // Flip green component for OpenGL
NewNormal = normalize(NewNormal); // Normalise the new normal
return NewNormal; // Return the newly calculated normal
}
vec4 Convolute()
{
vec4 result = vec4(0.0);
const float kernel[] = float[25] ( 0,1,2,1,0,
1,2,3,2,1,
2,3,4,3,2,
1,2,3,2,1,
0,1,2,1,0);
vec2 delta = 1.0 / textureSize(albedo, 0);
int index = 24;
for (int j = -1; j <= 1; j++)
{
for (int i = -1; i <= 1; i++)
{
//for (int k = -1; k <= 1; k++)
result += kernel[index--] * texture(albedo, vec2(_texcoord).st + (vec2(i, j) * delta));
}
}
result /= 25.0;
return result;
}
void main()
{
gPosition = _frag_pos;
gNormal = normalize(TBN());
vec3 I = normalize(_frag_pos - camera_pos); // Calculate eye to fragment direction
vec3 R = reflect(I, normalize(TBN())); // Reflect I with the vertex normal
float M = texture(metalness, vec2(_texcoord.st)).r;
//vec4 gaussian = Convolute();
gAlbedo = texture(albedo, vec2(_texcoord.st)); // Assign albedo
gSpecular = texture(specular, vec2(_texcoord.st)).rgb; // Assign specular
gMetalness = (texture(cubemap, R).rgb) * M; // Assign metalness
}
灯光着色器...
#version 420 core
out vec4 FragColor;
in vec2 _texcoord;
uniform vec3 camera_pos;
uniform sampler2D gPosition;
uniform sampler2D gNormal;
uniform sampler2D gAlbedo;
uniform sampler2D gSpecular;
uniform sampler2D gMetalness;
uniform sampler2D gSsao;
uniform vec3 lightPos;
void main(void)
{
vec3 FragPos = texture(gPosition, _texcoord).rgb;
vec3 Normal = texture(gNormal, _texcoord).rgb;
vec3 Diffuse = texture(gAlbedo, _texcoord).rgb;
float Emissive = texture(gAlbedo, _texcoord).a;
vec3 Specular = texture(gAlbedo, _texcoord).rgb;
vec3 Metalness = texture(gMetalness, _texcoord).rgb; // Reflection pass
float AmbientOcclusion = texture(gSsao, _texcoord).r;
vec3 light_colour = vec3(1.0f, 0.8, 0.7);
vec3 lighting = vec3(0.3 * Diffuse * AmbientOcclusion);
vec3 viewDir = normalize(-FragPos);
vec3 lightDir = normalize(lightPos - FragPos);
vec3 diffuse = max(dot(Normal, lightDir), 0.0) * Diffuse * light_colour; // Light colour
vec3 halfwayDir = normalize(lightDir + viewDir);
float spec = pow(max(dot(Normal, halfwayDir), 0.0), 32.0);
vec3 specular = (Specular * light_colour) * spec;
vec3 metalness = Metalness * Diffuse;
lighting += diffuse + specular + metalness;
FragColor = vec4(lighting, 1.0);
}
需要更多代码就问。感谢您提供的任何帮助
编辑 问题已修复,是由于立方体贴图反射,现在一切正常
如果查找纹理,并且纹理中不存在特定纹理通道,则函数 texture
将为绿色和蓝色通道 return 0.0 和 alpha 1.0频道。
这可以通过纹理调配参数进行更改GL_TEXTURE_SWIZZLE_R
, GL_TEXTURE_SWIZZLE_G
, GL_TEXTURE_SWIZZLE_B
and GL_TEXTURE_SWIZZLE_A
。
如果您希望绿色和蓝色通道 return 与红色通道具有相同的值,那么可以这样做:
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_RED );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED );
将此参数应用于纹理对象 ssaoColorBuffer
和 ssaoColorBufferBlur
,以解决问题。
参见OpenGL 4.6 API Core Profile Specification; 15.2. SHADER EXECUTION; page 487]:
When a texture lookup is performed in a fragment shader, the GL computes the filtered texture value ... and converts it to a texture base color Cb as shown in table 15.1,
Texture Base Texture base color Internal Format Cb Ab RED (Rt, 0, 0) 1 RG (Rt, Gt, 0) 1 RGB (Rt, Gt, Bt) 1 RGBA (Rt, Gt, Bt) At
Table 15.1: Correspondence of filtered texture components to texture base components.
followed by swizzling the components of Cb, controlled by the values of the texture parameters
TEXTURE_SWIZZLE_R
,TEXTURE_SWIZZLE_G
,TEXTURE_SWIZZLE_B
, andTEXTURE_SWIZZLE_A
. If the value ofTEXTURE_SWIZZLE_R
is denoted by swizzler, swizzling computes the first component of Cs according toif (swizzler == RED) Cs[0] = Cb[0]; else if (swizzler == GREEN) Cs[0] = Cb[1]; else if (swizzler == BLUE) Cs[0] = Cb[2]; else if (swizzler == ALPHA) Cs[0] = Ab; else if (swizzler == ZERO) Cs[0] = 0; else if (swizzler == ONE) Cs[0] = 1; // float or int depending on texture component type