Mon programme est une pièce avec un projecteur au centre (représenté par la sphère).Comment puis-je changer mon fragment shader pour permettre 2 projecteurs de plus?
Je veux ajouter 2 autres lumières dans les coins de la pièce, mais je ne suis pas sûr de savoir comment changer la fonction main
dans mon fragment shader pour le permettre. J'ai édité mon programme principal pour définir les propriétés de 2 nouvelles lumières et les lier au fragment shader.
Fragment Shader
#version 330 core
#define MAX_MATERIALS 12
#define MAX_LIGHTS 3
// 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 int uMaterialIndex;
uniform LightProperties uLightingProperties[MAX_LIGHTS];
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)
{
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;
}
// set output color
fColor = colour;
}
programme principal
#define MAX_LIGHTS 3
#define MAX_MATERIALS 12
// 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[MAX_LIGHTS];
MaterialProperties g_materialProperties[MAX_MATERIALS];
// Meshes
Vertex* g_pMeshVertices[MAX_MESH] = { NULL }; // pointer to mesh vertices
GLint g_numberOfVertices[MAX_MESH] = { 0 }; // number of vertices in the mesh
GLint* g_pMeshIndices[MAX_MESH] = { NULL }; // pointer to mesh indices
GLint g_numberOfFaces[MAX_MESH] = { 0 }; // number of faces in the mesh
GLuint g_IBO[4]; // index buffer object identifier
GLuint g_VBO[5]; // vertex buffer object identifier
GLuint g_VAO[5]; // vertex array object identifier
GLuint g_shaderProgramID = 0; // shader program identifier
// Values for spotlight
glm::vec3 g_spotlight_ambient(0.2f, 0.2f, 0.2f);
glm::vec3 g_spotlight_diffuse(0.5f, 0.5f, 0.5f);
glm::vec3 g_spotlight_specular(0.0f, 0.5f, 0.5f);
// locations in shader
GLuint g_MVP_Index;
GLuint g_M_Index = 0;
GLuint g_viewPointIndex = 0;
GLuint g_lightPositionIndex[MAX_LIGHTS];
GLuint g_lightAmbientIndex[MAX_LIGHTS];
GLuint g_lightDiffuseIndex[MAX_LIGHTS];
GLuint g_lightSpecularIndex[MAX_LIGHTS];
GLuint g_lightShininessIndex[MAX_LIGHTS];
GLuint g_lightAttenuationIndex[MAX_LIGHTS];
GLuint g_lightCutoffAngleIndex[MAX_LIGHTS];
GLuint g_lightDirectionIndex[MAX_LIGHTS];
GLuint g_materialIndex = 0;
GLuint g_materialAmbientIndex[MAX_MATERIALS];
GLuint g_materialDiffuseIndex[MAX_MATERIALS];
GLuint g_materialSpecularIndex[MAX_MATERIALS];
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");
g_lightPositionIndex[0] = glGetUniformLocation(g_shaderProgramID, "uLightingProperties[0].position");
g_lightAmbientIndex[0] = glGetUniformLocation(g_shaderProgramID, "uLightingProperties[0].ambient");
g_lightDiffuseIndex[0] = glGetUniformLocation(g_shaderProgramID, "uLightingProperties[0].diffuse");
g_lightSpecularIndex[0] = glGetUniformLocation(g_shaderProgramID, "uLightingProperties[0].specular");
g_lightShininessIndex[0] = glGetUniformLocation(g_shaderProgramID, "uLightingProperties[0].shininess");
g_lightAttenuationIndex[0] = glGetUniformLocation(g_shaderProgramID, "uLightingProperties[0].attenuation");
g_lightCutoffAngleIndex[0] = glGetUniformLocation(g_shaderProgramID, "uLightingProperties[0].cutoffAngle");
g_lightDirectionIndex[0] = glGetUniformLocation(g_shaderProgramID, "uLightingProperties[0].direction");
g_lightPositionIndex[1] = glGetUniformLocation(g_shaderProgramID, "uLightingProperties[1].position");
g_lightAmbientIndex[1] = glGetUniformLocation(g_shaderProgramID, "uLightingProperties[1].ambient");
g_lightDiffuseIndex[1] = glGetUniformLocation(g_shaderProgramID, "uLightingProperties[1].diffuse");
g_lightSpecularIndex[1] = glGetUniformLocation(g_shaderProgramID, "uLightingProperties[1].specular");
g_lightShininessIndex[1] = glGetUniformLocation(g_shaderProgramID, "uLightingProperties[1].shininess");
g_lightAttenuationIndex[1] = glGetUniformLocation(g_shaderProgramID, "uLightingProperties[1].attenuation");
g_lightCutoffAngleIndex[1] = glGetUniformLocation(g_shaderProgramID, "uLightingProperties[1].cutoffAngle");
g_lightDirectionIndex[1] = glGetUniformLocation(g_shaderProgramID, "uLightingProperties[1].direction");
g_lightPositionIndex[2] = glGetUniformLocation(g_shaderProgramID, "uLightingProperties[2].position");
g_lightAmbientIndex[2] = glGetUniformLocation(g_shaderProgramID, "uLightingProperties[2].ambient");
g_lightDiffuseIndex[2] = glGetUniformLocation(g_shaderProgramID, "uLightingProperties[2].diffuse");
g_lightSpecularIndex[2] = glGetUniformLocation(g_shaderProgramID, "uLightingProperties[2].specular");
g_lightShininessIndex[2] = glGetUniformLocation(g_shaderProgramID, "uLightingProperties[2].shininess");
g_lightAttenuationIndex[2] = glGetUniformLocation(g_shaderProgramID, "uLightingProperties[2].attenuation");
g_lightCutoffAngleIndex[2] = glGetUniformLocation(g_shaderProgramID, "uLightingProperties[2].cutoffAngle");
g_lightDirectionIndex[2] = glGetUniformLocation(g_shaderProgramID, "uLightingProperties[2].direction");
g_materialIndex = glGetUniformLocation(g_shaderProgramID, "uMaterialIndex"); // to change the index for material in fragment shader
// Find location for uniform matrix (material properties)
for (int i = 0; i < MAX_MATERIALS; i++) {
std::string str = "uMaterialProperties[" + std::to_string(i);
g_materialAmbientIndex[i] = glGetUniformLocation(g_shaderProgramID, (str + "].ambient").data());
g_materialDiffuseIndex[i] = glGetUniformLocation(g_shaderProgramID, (str + "].diffuse").data());
g_materialSpecularIndex[i] = glGetUniformLocation(g_shaderProgramID, (str + "].specular").data());
}
...
// initialise light and material properties
g_lightProperties[0].position = glm::vec4(0.0f, 2.0f, 0.0f, 1.0f);
g_lightProperties[0].ambient = glm::vec4(g_spotlight_ambient[0], g_spotlight_ambient[1], g_spotlight_ambient[2], 1.0f);
g_lightProperties[0].diffuse = glm::vec4(g_spotlight_diffuse[0], g_spotlight_diffuse[1], g_spotlight_diffuse[2], 1.0f);
g_lightProperties[0].specular = glm::vec4(g_spotlight_specular[0], g_spotlight_specular[1], g_spotlight_specular[2], 1.0f);
g_lightProperties[0].shininess = 10.0f;
g_lightProperties[0].attenuation = glm::vec3(1.0f, 0.0f, 0.0f);
g_lightProperties[0].cutoffAngle = 150.0f;
g_lightProperties[0].direction = glm::vec3(0.0f, -1.0f, 0.0f);
g_lightProperties[1].position = glm::vec4(-2.0f, 2.0f, 0.0f, 1.0f);
g_lightProperties[1].ambient = glm::vec4(g_spotlight_ambient[0], g_spotlight_ambient[1], g_spotlight_ambient[2], 1.0f);
g_lightProperties[1].diffuse = glm::vec4(g_spotlight_diffuse[0], g_spotlight_diffuse[1], g_spotlight_diffuse[2], 1.0f);
g_lightProperties[1].specular = glm::vec4(g_spotlight_specular[0], g_spotlight_specular[1], g_spotlight_specular[2], 1.0f);
g_lightProperties[1].shininess = 10.0f;
g_lightProperties[1].attenuation = glm::vec3(1.0f, 0.0f, 0.0f);
g_lightProperties[1].cutoffAngle = 150.0f;
g_lightProperties[1].direction = glm::vec3(0.0f, -1.0f, 0.0f);
g_lightProperties[2].position = glm::vec4(2.0f, 2.0f, 0.0f, 1.0f);
g_lightProperties[2].ambient = glm::vec4(g_spotlight_ambient[0], g_spotlight_ambient[1], g_spotlight_ambient[2], 1.0f);
g_lightProperties[2].diffuse = glm::vec4(g_spotlight_diffuse[0], g_spotlight_diffuse[1], g_spotlight_diffuse[2], 1.0f);
g_lightProperties[2].specular = glm::vec4(g_spotlight_specular[0], g_spotlight_specular[1], g_spotlight_specular[2], 1.0f);
g_lightProperties[2].shininess = 10.0f;
g_lightProperties[2].attenuation = glm::vec3(1.0f, 0.0f, 0.0f);
g_lightProperties[2].cutoffAngle = 150.0f;
g_lightProperties[2].direction = glm::vec3(0.0f, -1.0f, 0.0f);
...
}
// 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[0]); // make VAO active
// Set uniform matrix for material properties
for (int i = 0; i < MAX_MATERIALS; i++) {
glUniform4fv(g_materialAmbientIndex[i], 1, &g_materialProperties[i].ambient[0]);
glUniform4fv(g_materialDiffuseIndex[i], 1, &g_materialProperties[i].diffuse[0]);
glUniform4fv(g_materialSpecularIndex[i], 1, &g_materialProperties[i].specular[0]);
}
// Set uniform matrix for light properties
for (int i = 0; i < MAX_LIGHTS; i++) {
glUniform4fv(g_lightPositionIndex[i], 1, &g_lightProperties[i].position[0]);
glUniform4fv(g_lightAmbientIndex[i], 1, &g_lightProperties[i].ambient[0]);
glUniform4fv(g_lightDiffuseIndex[i], 1, &g_lightProperties[i].diffuse[0]);
glUniform4fv(g_lightSpecularIndex[i], 1, &g_lightProperties[i].specular[0]);
glUniform1fv(g_lightShininessIndex[i], 1, &g_lightProperties[i].shininess);
glUniform3fv(g_lightAttenuationIndex[i], 1, &g_lightProperties[i].attenuation[0]);
glUniform1fv(g_lightCutoffAngleIndex[i], 1, &g_lightProperties[i].cutoffAngle);
glUniform3fv(g_lightDirectionIndex[i], 1, &g_lightProperties[i].direction[0]);
}
...
}
int main(void)
{
...
// 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 600' ");
// 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[0].cutoffAngle, " group='Spotlight' min=-180.0 max=180.0 step=1.0 ");
TwAddVarRW(TweakBar, "Direction: x", TW_TYPE_FLOAT, &g_lightProperties[0].direction[0], " group='Spotlight' min=-1.0 max=1.0 step=0.1");
TwAddVarRW(TweakBar, "Direction: y", TW_TYPE_FLOAT, &g_lightProperties[0].direction[1], " group='Spotlight' min=-1.0 max=1.0 step=0.1");
TwAddVarRW(TweakBar, "Direction: z", TW_TYPE_FLOAT, &g_lightProperties[0].direction[2], " group='Spotlight' min=-1.0 max=1.0 step=0.1");
// create transformation entries
TwAddVarRW(TweakBar, "A Red", TW_TYPE_FLOAT, &g_spotlight_ambient[0], " group='Ambient' min=-1.0 max=1.0 step=0.01");
TwAddVarRW(TweakBar, "A Green", TW_TYPE_FLOAT, &g_spotlight_ambient[1], " group='Ambient' min=-1.0 max=1.0 step=0.01");
TwAddVarRW(TweakBar, "A Blue", TW_TYPE_FLOAT, &g_spotlight_ambient[2], " group='Ambient' min=-1.0 max=1.0 step=0.01");
TwAddVarRW(TweakBar, "D Red", TW_TYPE_FLOAT, &g_spotlight_diffuse[0], " group='Diffuse' min=-1.0 max=1.0 step=0.01");
TwAddVarRW(TweakBar, "D Green", TW_TYPE_FLOAT, &g_spotlight_diffuse[1], " group='Diffuse' min=-1.0 max=1.0 step=0.01");
TwAddVarRW(TweakBar, "D Blue", TW_TYPE_FLOAT, &g_spotlight_diffuse[2], " group='Diffuse' min=-1.0 max=1.0 step=0.01");
TwAddVarRW(TweakBar, "S Red", TW_TYPE_FLOAT, &g_spotlight_specular[0], " group='Specular' min=-1.0 max=1.0 step=0.01");
TwAddVarRW(TweakBar, "S Green", TW_TYPE_FLOAT, &g_spotlight_specular[1], " group='Specular' min=-1.0 max=1.0 step=0.01");
TwAddVarRW(TweakBar, "S Blue", TW_TYPE_FLOAT, &g_spotlight_specular[2], " group='Specular' min=-1.0 max=1.0 step=0.01");
TwAddVarRW(TweakBar, "Light", TW_TYPE_BOOLCPP, &g_switchOn, " group='Toggle ON/OFF' ");
TwAddVarRW(TweakBar, "Disco", TW_TYPE_BOOLCPP, &g_disco_mode, " group='Toggle ON/OFF' ");
// 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);
update_scene(); // update the scene
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
}
...
}
vous êtes un travailleur miracle – Zolly
@Zolly Non, mais 2 décennies d'expérience en programmation. – Rabbid76
woah c'est beaucoup. On dirait im dans 18 ans – Zolly