Sto provando a usare i buffer uniformi ma non funziona come supposto. Ho due buffer uniformi, uno è l'illuminazione e l'altro è per materiale. Il problema è che i colori non sono quello che dovrebbero essere e cambiano ogni volta che muovo la fotocamera. Questo problema non esisteva quando usavo uniformi normali. Ecco le immagini per mostrare cosa intendo: When using uniform buffers e when using normal uniforms!Buffer OpenGL Uniform?
Questo è il mio frammento di shader:
#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);
}
io non sono sicuro che ho fatto tutto giusto, ma ecco come creo i buffer uniformi:
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: Ecco come riempio il buffer:
// 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);
Che cosa hai fatto per eseguire il debug di questo? Hai provato a stampare quali valori ottieni nello shader (semplicemente scrivendoli come output del framment shader)? Almeno con i colori, dovresti essere in grado di vedere quali valori non vengono fuori come ti aspetti. –
Inoltre, dov'è il codice che si usa per riempire quei buffer con i valori? –
@Gigi: non l'ho visto su Cat 12.1. Sembra funzionare bene per me, e io uso 2 blocchi nel mio shader di frammenti. Inoltre, hai presentato segnalazioni di bug su questo? –