返回
OpenGL ES for Android:点光源、聚光灯和阳光的多重光照效果
Android
2023-09-22 13:50:38
在学习过光照、材质、投光物之后,我们把这些效果结合起来。我们显示这样的效果:在阳光照射下,有几个点光源,同时有一个聚光灯,此时在不同位置的物体被光照的效果。
定向光的计算可以参考前面的章节,这里不再赘述。
需要注意的是,在传入点光源的数据时,传入的参数名需要以:pointLight..作为前缀,传入的参数名需要以:spotLight..作为前缀。
struct PointLight {
vec3 position;
vec3 ambient;
vec3 diffuse;
vec3 specular;
float constant;
float linear;
float quadratic;
};
struct SpotLight {
vec3 position;
vec3 direction;
vec3 ambient;
vec3 diffuse;
vec3 specular;
float constant;
float linear;
float quadratic;
float cutOff;
float outerCutOff;
};
// ...
void setPointLight(int index, const PointLight& light) {
char name[16];
sprintf(name, "pointLights[%d]", index);
glUniform3fv(glGetUniformLocation(program, name), 1, &light.position[0]);
sprintf(name, "pointLights[%d].ambient", index);
glUniform3fv(glGetUniformLocation(program, name), 1, &light.ambient[0]);
sprintf(name, "pointLights[%d].diffuse", index);
glUniform3fv(glGetUniformLocation(program, name), 1, &light.diffuse[0]);
sprintf(name, "pointLights[%d].specular", index);
glUniform3fv(glGetUniformLocation(program, name), 1, &light.specular[0]);
sprintf(name, "pointLights[%d].constant", index);
glUniform1f(glGetUniformLocation(program, name), light.constant);
sprintf(name, "pointLights[%d].linear", index);
glUniform1f(glGetUniformLocation(program, name), light.linear);
sprintf(name, "pointLights[%d].quadratic", index);
glUniform1f(glGetUniformLocation(program, name), light.quadratic);
}
// ...
void setSpotLight(int index, const SpotLight& light) {
char name[16];
sprintf(name, "spotLights[%d]", index);
glUniform3fv(glGetUniformLocation(program, name), 1, &light.position[0]);
sprintf(name, "spotLights[%d].direction", index);
glUniform3fv(glGetUniformLocation(program, name), 1, &light.direction[0]);
sprintf(name, "spotLights[%d].ambient", index);
glUniform3fv(glGetUniformLocation(program, name), 1, &light.ambient[0]);
sprintf(name, "spotLights[%d].diffuse", index);
glUniform3fv(glGetUniformLocation(program, name), 1, &light.diffuse[0]);
sprintf(name, "spotLights[%d].specular", index);
glUniform3fv(glGetUniformLocation(program, name), 1, &light.specular[0]);
sprintf(name, "spotLights[%d].constant", index);
glUniform1f(glGetUniformLocation(program, name), light.constant);
sprintf(name, "spotLights[%d].linear", index);
glUniform1f(glGetUniformLocation(program, name), light.linear);
sprintf(name, "spotLights[%d].quadratic", index);
glUniform1f(glGetUniformLocation(program, name), light.quadratic);
sprintf(name, "spotLights[%d].cutOff", index);
glUniform1f(glGetUniformLocation(program, name), light.cutOff);
sprintf(name, "spotLights[%d].outerCutOff", index);
glUniform1f(glGetUniformLocation(program, name), light.outerCutOff);
}
// ...
// 以下为示例代码,您需要根据自己的实际场景进行调整。
PointLight pointLights[4] = {
{
vec3(0.0f, 1.0f, 0.0f),
vec3(0.1f, 0.1f, 0.1f),
vec3(1.0f, 1.0f, 1.0f),
vec3(1.0f, 1.0f, 1.0f),
1.0f,
0.09f,
0.032f
},
{
vec3(2.0f, 3.0f, -4.0f),
vec3(0.1f, 0.1f, 0.1f),
vec3(1.0f, 1.0f, 1.0f),
vec3(1.0f, 1.0f, 1.0f),
1.0f,
0.09f,
0.032f
},
{
vec3(-2.0f, 3.0f, -4.0f),
vec3(0.1f, 0.1f, 0.1f),
vec3(1.0f, 1.0f, 1.0f),
vec3(1.0f, 1.0f, 1.0f),
1.0f,
0.09f,
0.032f
},
{
vec3(0.0f, 3.0f, 4.0f),
vec3(0.1f, 0.1f, 0.1f),
vec3(1.0f, 1.0f, 1.0f),
vec3(1.0f, 1.0f, 1.0f),
1.0f,
0.09f,
0.032f
}
};
SpotLight spotLight = {
vec3(0.0f, 5.0f, 0.0f),
vec3(0.0f, -1.0f, 0.0f),
vec3(0.1f, 0.1f, 0.1f),
vec3(1.0f, 1.0f, 1.0f),
vec3(1.0f, 1.0f, 1.0f),
1.0f,
0.09f,
0.032f,
cos(radians(12.5f)),
cos(radians(17.5f))
};
// ...
for (int i = 0; i < 4; i++) {
setPointLight(i, pointLights[i]);
}
setSpotLight(0, spotLight);
通过上述代码,您将能够在您的 Android 项目中实现点光源、聚光灯和阳光的多重光照效果。
我希望这个教程对您有所帮助。如果您有任何问题,请随时提出。