Estoy tratando de usar tampones uniformes pero no funciona como se supone. Tengo dos buffers uniformes, uno es iluminación y el otro es material. El problema es que los colores no son lo que se supone que deben ser y cambian cada vez que muevo la cámara. Este problema no existía cuando usaba uniformes normales. Aquí hay fotos para mostrar lo que quiero decir: When using uniform buffers y when using normal uniforms!OpenGL Uniform buffers?
Esta es mi fragmento de sombreado:
#version 400 // Fragment Shader
uniform layout(std140);
in vec3 EyePosition;
in vec3 EyeNormal;
in vec2 TexCoord;
out vec4 FragColor;
uniform sampler2D Texture;
uniform LightBlock
{
vec4 Position;
vec4 Intensity;
} Light;
uniform MaterialBlock
{
vec4 Ambient;
vec4 Diffuse;
} Material;
vec4 PointLight(in int i, in vec3 ECPosition, in vec3 ECNormal)
{
vec3 n = normalize(ECNormal);
vec3 s = normalize(Light.Position.xyz - ECPosition);
return Light.Intensity * (Material.Ambient + Material.Diffuse * max(dot(s, n), 0.0));
}
void main()
{
FragColor = texture(Texture, TexCoord);
FragColor *= PointLight(0, EyePosition, EyeNormal);
}
No estoy seguro de que he hecho todo bien, pero es cómo creo los buffers uniformes aquí:
glGenBuffers(1, &light_buffer);
glGenBuffers(1, &material_buffer);
glBindBuffer(GL_UNIFORM_BUFFER, light_buffer);
glBufferData(GL_UNIFORM_BUFFER, sizeof(LightBlock), nullptr, GL_DYNAMIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, material_buffer);
glBufferData(GL_UNIFORM_BUFFER, sizeof(MaterialBlock), nullptr, GL_DYNAMIC_DRAW);
GLuint program = Shaders.GetProgram();
light_index = glGetUniformBlockIndex(program, "LightBlock");
material_index = glGetUniformBlockIndex(program, "MaterialBlock");
glUniformBlockBinding(program, light_index, 0);
glUniformBlockBinding(program, material_index, 1);
glBindBufferBase(GL_UNIFORM_BUFFER, 0, light_buffer);
glBindBufferBase(GL_UNIFORM_BUFFER, 1, material_buffer);
EDIT: He aquí cómo llenar el tampones:
// Global structures
struct LightBlock
{
Vector4 Position; // Vector4 is a vector class I made
Vector4 Intensity;
};
struct MaterialBlock
{
Vector4 Ambient;
Vector4 Diffuse;
};
// This is called for every object rendered
LightBlock Light;
Light.Position = Vector3(0.0f, 5.0f, 5.0f) * Camera.GetCameraMatrix();
Light.Intensity = Vector4(1.0f);
glBindBuffer(GL_UNIFORM_BUFFER, light_buffer);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(LightBlock), &Light);
MaterialBlock Material;
Material.Diffuse = Vector4(1.0f);
Material.Ambient = Material.Diffuse * Vector4(0.3f);
glBindBuffer(GL_UNIFORM_BUFFER, material_buffer);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(MaterialBlock), &Material);
¿Qué ha hecho para depurar esto? ¿Has intentado imprimir qué valores obtienes en el sombreador (simplemente escribiéndolos como salida del sombreador de fragmentos)? Al menos con los colores, debería poder ver qué valores no están saliendo como espera. –
Además, ¿dónde está el código que usa para llenar esos almacenamientos intermedios con valores? –
@Gigi: No he visto esto en los Cat 12.1. Parece funcionar bien para mí, y uso 2 bloques en mi sombreador de fragmentos. Además, ¿ha archivado informes de fallas sobre esto? –