Почему не отображаются изменения в моих свойствах материала?

Я делаю пустую комнату с 4 стенами, 1 этаж и 1 потолок.

введите описание изображения здесь

Я добавил массив единообразных переменных в фрагментный шейдер для каждой стены / пола / потолка.
Я корректирую этот раздел кода (ниже) и пытаюсь заставить дальнюю стену выглядеть красной, но после выполнения ничего не меняется. Это остается синим. Это почему?

static void init(GLFWwindow* window)
{
...

// Wall 1 (Far)
g_materialProperties_plane[1].ambient = glm::vec4(1.0f, 0.0f, 0.0f, 1.0f);
g_materialProperties_plane[1].diffuse = glm::vec4(1.0f, 0.0f, 0.0f, 1.0f);
g_materialProperties_plane[1].specular = glm::vec4(0.2f, 0.7f, 1.0f, 1.0f);

...
}

Полная программа

#define MAX_MATERIALS 6

// struct for lighting properties
struct LightProperties
{
vec4 position;
vec4 ambient;
vec4 diffuse;
vec4 specular;
float shininess;
vec3 attenuation;
float cutoffAngle;
vec3 direction;
};

// struct for material properties
struct MaterialProperties
{
vec4 ambient;
vec4 diffuse;
vec4 specular;
};

LightProperties g_lightProperties;
MaterialProperties g_materialProperties_plane[6];

// struct for vertex attributes
struct Vertex_plane
{
GLfloat position[3];
GLfloat normal[3];
};

GLuint g_VBO;                   // vertex buffer object identifier
GLuint g_VAO = 0;               // vertex array object identifier
GLuint g_shaderProgramID = 0;   // shader program identifier

// locations in shader
GLuint g_MVP_Index;
GLuint g_M_Index = 0;
GLuint g_viewPointIndex = 0;
GLuint g_lightPositionIndex = 0;
GLuint g_lightAmbientIndex = 0;
GLuint g_lightDiffuseIndex = 0;
GLuint g_lightSpecularIndex = 0;
GLuint g_lightShininessIndex = 0;
GLuint g_lightAttenuationIndex = 0;
GLuint g_lightCutoffAngleIndex = 0;
GLuint g_lightDirectionIndex = 0;
GLuint g_materialAmbientIndex[MAX_MATERIALS];
GLuint g_materialDiffuseIndex[MAX_MATERIALS];
GLuint g_materialSpecularIndex[MAX_MATERIALS];

glm::mat4 g_modelMatrix_plane[6];   // object's model matrix (4 walls + 1 ceiling + 1 floor)
glm::mat4 g_viewMatrix;             // view matrix
glm::mat4 g_projectionMatrix;       // projection matrix
glm::vec3 g_viewPoint;              // view point

Camera g_camera;            // camera

GLuint g_windowWidth = 1200;        // window dimensions
GLuint g_windowHeight = 1000;
bool g_wireFrame = false;       // wireframe on or off

static void init(GLFWwindow* window)
{
glEnable(GL_DEPTH_TEST);    // enable depth buffer test

// create and compile our GLSL program from the shader files
g_shaderProgramID = loadShaders("PerFragLightingVS.vert", "PerFragLightingFS.frag");

// find the location of shader variables
GLuint positionIndex = glGetAttribLocation(g_shaderProgramID, "aPosition");
GLuint normalIndex = glGetAttribLocation(g_shaderProgramID, "aNormal");
g_MVP_Index = glGetUniformLocation(g_shaderProgramID, "uModelViewProjectionMatrix");
g_M_Index = glGetUniformLocation(g_shaderProgramID, "uModelMatrix");
g_viewPointIndex = glGetUniformLocation(g_shaderProgramID, "uViewPoint");// Material
g_materialAmbientIndex[0] = glGetUniformLocation(g_shaderProgramID, "uMaterialProperties[0].ambient");
g_materialDiffuseIndex[0] = glGetUniformLocation(g_shaderProgramID, "uMaterialProperties[0].diffuse");
g_materialSpecularIndex[0] = glGetUniformLocation(g_shaderProgramID, "uMaterialProperties[0].specular");

g_materialAmbientIndex[1] = glGetUniformLocation(g_shaderProgramID, "uMaterialProperties[1].ambient");
g_materialDiffuseIndex[1] = glGetUniformLocation(g_shaderProgramID, "uMaterialProperties[1].diffuse");
g_materialSpecularIndex[1] = glGetUniformLocation(g_shaderProgramID, "uMaterialProperties[1].specular");

g_materialAmbientIndex[2] = glGetUniformLocation(g_shaderProgramID, "uMaterialProperties[2].ambient");
g_materialDiffuseIndex[2] = glGetUniformLocation(g_shaderProgramID, "uMaterialProperties[2].diffuse");
g_materialSpecularIndex[2] = glGetUniformLocation(g_shaderProgramID, "uMaterialProperties[2].specular");

g_materialAmbientIndex[3] = glGetUniformLocation(g_shaderProgramID, "uMaterialProperties[3].ambient");
g_materialDiffuseIndex[3] = glGetUniformLocation(g_shaderProgramID, "uMaterialProperties[3].diffuse");
g_materialSpecularIndex[3] = glGetUniformLocation(g_shaderProgramID, "uMaterialProperties[3].specular");

g_materialAmbientIndex[4] = glGetUniformLocation(g_shaderProgramID, "uMaterialProperties[4].ambient");
g_materialDiffuseIndex[4] = glGetUniformLocation(g_shaderProgramID, "uMaterialProperties[4].diffuse");
g_materialSpecularIndex[4] = glGetUniformLocation(g_shaderProgramID, "uMaterialProperties[4].specular");

g_materialAmbientIndex[5] = glGetUniformLocation(g_shaderProgramID, "uMaterialProperties[5].ambient");
g_materialDiffuseIndex[5] = glGetUniformLocation(g_shaderProgramID, "uMaterialProperties[5].diffuse");
g_materialSpecularIndex[5] = glGetUniformLocation(g_shaderProgramID, "uMaterialProperties[5].specular");

// initialise model matrix to the identity matrix
g_modelMatrix_plane[0] = g_modelMatrix_plane[1] = g_modelMatrix_plane[2] = g_modelMatrix_plane[3]
= g_modelMatrix_plane[4] = g_modelMatrix_plane[5] = g_modelMatrix_plane[6] = glm::mat4(1.0f);

...

// Material Properties - Planes
// Floor
g_materialProperties_plane[0].ambient = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
g_materialProperties_plane[0].diffuse = glm::vec4(0.2f, 0.7f, 1.0f, 1.0f);
g_materialProperties_plane[0].specular = glm::vec4(0.2f, 0.7f, 1.0f, 1.0f);
// Wall 1 (Far)
g_materialProperties_plane[1].ambient = glm::vec4(1.0f, 0.0f, 0.0f, 1.0f);
g_materialProperties_plane[1].diffuse = glm::vec4(1.0f, 0.0f, 0.0f, 1.0f);
g_materialProperties_plane[1].specular = glm::vec4(0.2f, 0.7f, 1.0f, 1.0f);
// Wall 2 (Left)
g_materialProperties_plane[2].ambient = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
g_materialProperties_plane[2].diffuse = glm::vec4(0.2f, 0.7f, 1.0f, 1.0f);
g_materialProperties_plane[2].specular = glm::vec4(0.2f, 0.7f, 1.0f, 1.0f);
// Wall 3 (Right)
g_materialProperties_plane[3].ambient = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
g_materialProperties_plane[3].diffuse = glm::vec4(0.2f, 0.7f, 1.0f, 1.0f);
g_materialProperties_plane[3].specular = glm::vec4(0.2f, 0.7f, 1.0f, 1.0f);
// Wall 4 (Near)
g_materialProperties_plane[4].ambient = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
g_materialProperties_plane[4].diffuse = glm::vec4(0.2f, 0.7f, 1.0f, 1.0f);
g_materialProperties_plane[4].specular = glm::vec4(0.2f, 0.7f, 1.0f, 1.0f);
// Ceiling
g_materialProperties_plane[5].ambient = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
g_materialProperties_plane[5].diffuse = glm::vec4(0.2f, 0.7f, 1.0f, 1.0f);
g_materialProperties_plane[5].specular = glm::vec4(0.2f, 0.7f, 1.0f, 1.0f);

// generate identifier for VBOs and copy data to GPU
glGenBuffers(1, &g_VBO);
glBindBuffer(GL_ARRAY_BUFFER, g_VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertices_plane), g_vertices_plane, GL_STATIC_DRAW);

// generate identifiers for VAO
glGenVertexArrays(1, &g_VAO);

// create VAO and specify VBO data
glBindVertexArray(g_VAO);
glBindBuffer(GL_ARRAY_BUFFER, g_VBO);
glVertexAttribPointer(positionIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex_plane), reinterpret_cast<void*>(offsetof(Vertex_plane, position)));
glVertexAttribPointer(normalIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex_plane), reinterpret_cast<void*>(offsetof(Vertex_plane, normal)));

glEnableVertexAttribArray(positionIndex);   // enable vertex attributes
glEnableVertexAttribArray(normalIndex);
}

// function used to render the scene
static void render_scene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear colour buffer and depth buffer

glUseProgram(g_shaderProgramID);    // use the shaders associated with the shader program

glBindVertexArray(g_VAO);       // make VAO active

// set uniform shader variables
glm::mat4 MVP = glm::mat4(1.0f);

// Floor
MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_modelMatrix_plane[0];
glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
glUniformMatrix4fv(g_M_Index, 1, GL_FALSE, &g_modelMatrix_plane[0][0][0]);
glUniform3fv(g_viewPointIndex, 1, &g_viewPoint[0]);
glDrawArrays(GL_TRIANGLES, 0, 6);
// Wall 1 (Far wall)
MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_modelMatrix_plane[1];
glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
glUniformMatrix4fv(g_M_Index, 1, GL_FALSE, &g_modelMatrix_plane[1][0][0]);
glUniform3fv(g_viewPointIndex, 1, &g_viewPoint[0]);
glDrawArrays(GL_TRIANGLES, 0, 6);
// Wall 2 (Left wall)
MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_modelMatrix_plane[2];
glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
glUniformMatrix4fv(g_M_Index, 1, GL_FALSE, &g_modelMatrix_plane[2][0][0]);
glUniform3fv(g_viewPointIndex, 1, &g_viewPoint[0]);
glDrawArrays(GL_TRIANGLES, 0, 6);
// Wall 3 (Right wall)
MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_modelMatrix_plane[3];
glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
glUniformMatrix4fv(g_M_Index, 1, GL_FALSE, &g_modelMatrix_plane[3][0][0]);
glUniform3fv(g_viewPointIndex, 1, &g_viewPoint[0]);
glDrawArrays(GL_TRIANGLES, 0, 6);
// Wall 4 (Near wall)
MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_modelMatrix_plane[4];
glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
glUniformMatrix4fv(g_M_Index, 1, GL_FALSE, &g_modelMatrix_plane[4][0][0]);
glUniform3fv(g_viewPointIndex, 1, &g_viewPoint[0]);
glDrawArrays(GL_TRIANGLES, 0, 6);
// Ceiling
MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_modelMatrix_plane[5];
glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
glUniformMatrix4fv(g_M_Index, 1, GL_FALSE, &g_modelMatrix_plane[5][0][0]);
glUniform3fv(g_viewPointIndex, 1, &g_viewPoint[0]);
glDrawArrays(GL_TRIANGLES, 0, 6);

glUniform4fv(g_lightPositionIndex, 1, &g_lightProperties.position[0]);
glUniform4fv(g_lightAmbientIndex, 1, &g_lightProperties.ambient[0]);
glUniform4fv(g_lightDiffuseIndex, 1, &g_lightProperties.diffuse[0]);
glUniform4fv(g_lightSpecularIndex, 1, &g_lightProperties.specular[0]);
glUniform1fv(g_lightShininessIndex, 1, &g_lightProperties.shininess);
glUniform3fv(g_lightAttenuationIndex, 1, &g_lightProperties.attenuation[0]);
glUniform1fv(g_lightCutoffAngleIndex, 1, &g_lightProperties.cutoffAngle);
glUniform3fv(g_lightDirectionIndex, 1, &g_lightProperties.direction[0]);

// Material Properties - Planes
// Floor
glUniform4fv(g_materialAmbientIndex[0], 1, &g_materialProperties_plane[0].ambient[0]);
glUniform4fv(g_materialDiffuseIndex[0], 1, &g_materialProperties_plane[0].diffuse[0]);
glUniform4fv(g_materialSpecularIndex[0], 1, &g_materialProperties_plane[0].specular[0]);
// Wall 1 (Far)
glUniform4fv(g_materialAmbientIndex[1], 1, &g_materialProperties_plane[1].ambient[0]);
glUniform4fv(g_materialDiffuseIndex[1], 1, &g_materialProperties_plane[1].diffuse[0]);
glUniform4fv(g_materialSpecularIndex[1], 1, &g_materialProperties_plane[1].specular[0]);
// Wall 2 (Left)
glUniform4fv(g_materialAmbientIndex[2], 1, &g_materialProperties_plane[2].ambient[0]);
glUniform4fv(g_materialDiffuseIndex[2], 1, &g_materialProperties_plane[2].diffuse[0]);
glUniform4fv(g_materialSpecularIndex[2], 1, &g_materialProperties_plane[2].specular[0]);
// Wall 3 (Right)
glUniform4fv(g_materialAmbientIndex[3], 1, &g_materialProperties_plane[3].ambient[0]);
glUniform4fv(g_materialDiffuseIndex[3], 1, &g_materialProperties_plane[3].diffuse[0]);
glUniform4fv(g_materialSpecularIndex[3], 1, &g_materialProperties_plane[3].specular[0]);
// Wall 4 (Near)
glUniform4fv(g_materialAmbientIndex[4], 1, &g_materialProperties_plane[4].ambient[0]);
glUniform4fv(g_materialDiffuseIndex[4], 1, &g_materialProperties_plane[4].diffuse[0]);
glUniform4fv(g_materialSpecularIndex[4], 1, &g_materialProperties_plane[4].specular[0]);
// Ceiling
glUniform4fv(g_materialAmbientIndex[5], 1, &g_materialProperties_plane[5].ambient[0]);
glUniform4fv(g_materialDiffuseIndex[5], 1, &g_materialProperties_plane[5].diffuse[0]);
glUniform4fv(g_materialSpecularIndex[5], 1, &g_materialProperties_plane[5].specular[0]);

glFlush();  // flush the pipeline
}

int main(void)
{
GLFWwindow* window = NULL;  // pointer to a GLFW window handle
TwBar *TweakBar;            // pointer to a tweak bar

glfwSetErrorCallback(error_callback);   // set error callback function

// initialise GLFW
if (!glfwInit())
{
// if failed to initialise GLFW
exit(EXIT_FAILURE);
}

// minimum OpenGL version 3.3
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);

// create a window and its OpenGL context
window = glfwCreateWindow(g_windowWidth, g_windowHeight, "Tutorial", NULL, NULL);

// if failed to create window
if (window == NULL)
{
glfwTerminate();
exit(EXIT_FAILURE);
}

glfwMakeContextCurrent(window); // set window context as the current context
glfwSwapInterval(1);            // swap buffer interval

// initialise GLEW
if (glewInit() != GLEW_OK)
{
// if failed to initialise GLEW
cerr << "GLEW initialisation failed" << endl;
exit(EXIT_FAILURE);
}

// set key callback function
glfwSetKeyCallback(window, key_callback);
glfwSetCursorPosCallback(window, cursor_position_callback);
glfwSetMouseButtonCallback(window, mouse_button_callback);

// use sticky mode to avoid missing state changes from polling
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);

// use mouse to move camera, hence use disable cursor mode
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);

// initialise AntTweakBar
TwInit(TW_OPENGL_CORE, NULL);

// give tweak bar the size of graphics window
TwWindowSize(g_windowWidth, g_windowHeight);
TwDefine(" TW_HELP visible=false ");    // disable help menu
TwDefine(" GLOBAL fontsize=3 ");        // set large font size

// create a tweak bar
TweakBar = TwNewBar("Main");
TwDefine(" Main label='Controls' refresh=0.02 text=light size='220 200' ");

// create display entries
TwAddVarRW(TweakBar, "Wireframe", TW_TYPE_BOOLCPP, &g_wireFrame, " group='Display' ");

// display a separator
TwAddSeparator(TweakBar, NULL, NULL);

// create spotlight entries
TwAddVarRW(TweakBar, "Cutoff", TW_TYPE_FLOAT, &g_lightProperties.cutoffAngle, " group='Spotlight' min=-180.0 max=180.0 step=1.0 ");
TwAddVarRW(TweakBar, "Direction: x", TW_TYPE_FLOAT, &g_lightProperties.direction[0], " group='Spotlight' min=-1.0 max=1.0 step=0.1");
TwAddVarRW(TweakBar, "Direction: y", TW_TYPE_FLOAT, &g_lightProperties.direction[1], " group='Spotlight' min=-1.0 max=1.0 step=0.1");
TwAddVarRW(TweakBar, "Direction: z", TW_TYPE_FLOAT, &g_lightProperties.direction[2], " group='Spotlight' min=-1.0 max=1.0 step=0.1");

// initialise rendering states
init(window);

// the rendering loop
while (!glfwWindowShouldClose(window))
{
g_camera.update(window);    // update camera

if (g_wireFrame)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

render_scene();     // render the scene

glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

TwDraw();           // draw tweak bar(s)

glfwSwapBuffers(window);    // swap buffers
glfwPollEvents();           // poll for events
}

// clean up
glDeleteProgram(g_shaderProgramID);
glDeleteBuffers(1, &g_VBO);
glDeleteVertexArrays(1, &g_VAO);

// uninitialise tweak bar
TwTerminate();

// close the window and terminate GLFW
glfwDestroyWindow(window);
glfwTerminate();

exit(EXIT_SUCCESS);
}

Фрагмент шейдера

#version 330 core

#define MAX_MATERIALS 6

// interpolated values from the vertex shaders
in vec3 vNormal;
in vec3 vPosition;

// uniform input data
struct LightProperties
{
vec4 position;
vec4 ambient;
vec4 diffuse;
vec4 specular;
float shininess;
vec3 attenuation;
float cutoffAngle;
vec3 direction;
};

struct MaterialProperties
{
vec4 ambient;
vec4 diffuse;
vec4 specular;
};

uniform LightProperties uLightingProperties;
uniform MaterialProperties uMaterialProperties[MAX_MATERIALS];
uniform vec3 uViewPoint;

// output data
out vec3 fColor;

void main()
{
// calculate vectors for lighting
vec3 N = normalize(vNormal);
vec3 L;
float attenuation = 1.0f;

// calculate the attenuation based on distance
L = (uLightingProperties.position).xyz - vPosition;
float distance = length(L);
L = normalize(L);
attenuation = 1/(uLightingProperties.attenuation.x
+ uLightingProperties.attenuation.y * distance
+ uLightingProperties.attenuation.z * distance * distance);

vec3 V = normalize(uViewPoint - vPosition);
vec3 R = reflect(-L, N);

// the direction of the spotlight
vec3 direction = normalize(uLightingProperties.direction);
// the angle between the vector from the light to the fragment’s position and the spotlight’s direction
float angle = degrees(acos(dot(-L, direction)));

vec3 colour = vec3(0.0f, 0.0f, 0.0f);

// only compute if angle is less than the cutoff angle
if(angle <= uLightingProperties.cutoffAngle)
{
for(int i = 0; i < MAX_MATERIALS; i++){
// calculate Phong lighting
vec4 ambient  = uLightingProperties.ambient * uMaterialProperties[i].ambient;
vec4 diffuse  = uLightingProperties.diffuse * uMaterialProperties[i].diffuse * max(dot(L, N), 0.0);
vec4 specular = vec4(0.0f, 0.0f, 0.0f, 1.0f);

if(dot(L, N) > 0.0f)
{
specular = uLightingProperties.specular * uMaterialProperties[i].specular
* pow(max(dot(V, R), 0.0), uLightingProperties.shininess);
}

colour = (attenuation * (diffuse + specular)).rgb + ambient.rgb;
// fade the spotlight's intensity linearly with angle
colour *= 1.0f - angle/uLightingProperties.cutoffAngle;
}
}

// set output color
fColor = colour;
}

0

Решение

Проблема внутри шейдерного фрагмента:

for(int i = 0; i < MAX_MATERIALS; i++){
....

colour = (attenuation * (diffuse + specular)).rgb + ambient.rgb;
// fade the spotlight's intensity linearly with angle
colour *= 1.0f - angle/uLightingProperties.cutoffAngle;
}

В каждой итерации цикла for присваивайте переменную color,
В конце содержание color ОС была рассчитана на последней итерации цикла (i=5).

Вам не нужен цикл, но вы должны установить соответствующий индекс материала равной переменной, прежде чем рисовать сетку.

// The index of the material which should be applied to the mesh,
// which is currently drawn.
uniform int uMaterialIndex;

.....

void main()
{
.....

vec3 colour = vec3(0.0f, 0.0f, 0.0f);
if (angle <= uLightingProperties.cutoffAngle)
{
int i = uMaterialIndex;

// calculate Phong lighting
vec4 ambient  = uLightingProperties.ambient * uMaterialProperties[i].ambient;
vec4 diffuse  = uLightingProperties.diffuse * uMaterialProperties[i].diffuse * max(dot(L, N), 0.0);
vec4 specular = vec4(0.0f, 0.0f, 0.0f, 1.0f);

if (dot(L, N) > 0.0f)
{
specular = uLightingProperties.specular * uMaterialProperties[i].specular
* pow(max(dot(V, R), 0.0), uLightingProperties.shininess);
}

colour = (attenuation * (diffuse + specular)).rgb + ambient.rgb;
// fade the spotlight's intensity linearly with angle
colour *= 1.0f - angle/uLightingProperties.cutoffAngle;
}

.....
}

Когда вы рисуете сетку, вам нужно обновить единую переменную:

GLuint g_materialIndex;

g_materialIndex = glGetUniformLocation(g_shaderProgramID, "uMaterialIndex");

glUniform1i(g_materialIndex, materialIndex); // materialIndex in range 0 to 5
glDrawArrays(GL_TRIANGLES, 0, 6);
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]