opengl-es - Phong 着色器不起作用
问题描述
我想使用 phong 着色来渲染。我使用 OpenGL ES 3.0 并实现了 gouraud 着色并且它有效。但是当我使用 phong 着色渲染对象时,它不起作用。我认为我的着色器代码有问题,但我找不到它在哪里。
这是顶点着色器
#version 300 es
precision highp float;
uniform mat4 ModelViewProjectionMatrix;
uniform mat4 ModelViewMatrix;
uniform mat3 ModelViewMatrixInvTrans;
layout (location = 0) in vec3 v_position;
layout (location = 1) in vec3 v_normal;
layout (location = 2) in vec2 a_tex_coord;
out vec3 v_position_EC;
out vec3 v_normal_EC;
out vec2 v_tex_coord;
void main(void) {
v_position_EC = vec3(ModelViewMatrix*vec4(v_position, 1.0f));
v_normal_EC = normalize(ModelViewMatrixInvTrans*v_normal);
v_tex_coord = a_tex_coord;
gl_Position = ModelViewProjectionMatrix*vec4(v_position, 1.0f);
}
这是片段着色器
#version 300 es
precision highp float;
struct LIGHT {
int light_on;
vec4 position; // assume point or direction in EC in this example shader
vec4 ambient_color, diffuse_color, specular_color;
vec3 spot_direction;
float spot_exponent;
float spot_cutoff_angle;
vec4 light_attenuation_factors; // compute this effect only if .w != 0.0f
};
struct MATERIAL {
vec4 ambient_color;
vec4 diffuse_color;
vec4 specular_color;
vec4 emissive_color;
float specular_exponent;
};
#define NUMBER_OF_LIGHTS_SUPPORTED 4
uniform vec4 global_ambient_color;
uniform LIGHT light[NUMBER_OF_LIGHTS_SUPPORTED];
uniform MATERIAL material;
uniform int flag_texture_mapping;
uniform sampler2D base_texture;
const float zero_f = 0.0f;
const float one_f = 1.0f;
in vec3 v_position_EC;
in vec3 v_normal_EC;
in vec2 v_tex_coord;
layout (location = 0) out vec4 final_color;
vec4 lighting_equation_textured(in vec3 P_EC, in vec3 N_EC, in vec4 base_color) {
vec4 color_sum;
float local_scale_factor, tmp_float;
vec3 L_EC;
color_sum = material.emissive_color + global_ambient_color * base_color;
for (int i = 0; i < NUMBER_OF_LIGHTS_SUPPORTED; i++) {
if (light[i].light_on == 0) continue;
local_scale_factor = one_f;
if (light[i].position.w != zero_f) { // point light source
L_EC = light[i].position.xyz - P_EC.xyz;
if (light[i].light_attenuation_factors.w != zero_f) {
vec4 tmp_vec4;
tmp_vec4.x = one_f;
tmp_vec4.z = dot(L_EC, L_EC);
tmp_vec4.y = sqrt(tmp_vec4.z);
tmp_vec4.w = zero_f;
local_scale_factor = one_f/dot(tmp_vec4, light[i].light_attenuation_factors);
}
L_EC = normalize(L_EC);
if (light[i].spot_cutoff_angle < 180.0f) { // [0.0f, 90.0f] or 180.0f
float spot_cutoff_angle = clamp(light[i].spot_cutoff_angle, zero_f, 90.0f);
vec3 spot_dir = normalize(light[i].spot_direction);
tmp_float = dot(-L_EC, spot_dir);
if (tmp_float >= cos(radians(spot_cutoff_angle))) {
tmp_float = pow(tmp_float, light[i].spot_exponent);
}
else
tmp_float = zero_f;
local_scale_factor *= tmp_float;
}
}
else { // directional light source
L_EC = normalize(u_light[i].position.xyz);
}
if (local_scale_factor > zero_f) {
vec4 local_color_sum = light[i].ambient_color * material.ambient_color;
tmp_float = dot(N_EC, L_EC);
if (tmp_float > zero_f) {
local_color_sum += light[i].diffuse_color*base_color*tmp_float;
vec3 H_EC = normalize(L_EC - normalize(P_EC));
tmp_float = dot(N_EC, H_EC);
if (tmp_float > zero_f) {
local_color_sum += light[i].specular_color
*material.specular_color*pow(tmp_float, material.specular_exponent);
}
}
color_sum += local_scale_factor*local_color_sum;
}
}
return color_sum;
}
void main(void) {
vec4 base_color;
vec2 tex_coord = v_tex_coord;
if (flag_texture_mapping == 1)
base_color = texture(base_texture, tex_coord);
else
base_color = material.diffuse_color;
vec4 lighting_color = lighting_equation_textured(v_position_EC, normalize(v_normal_EC), base_color);
final_color = vec4(lighting_color.rgb, 1.0f);
//final_color = material.diffuse_color;
}
解决方案
片段着色器代码无法编译,因为您ulight
在该行中使用了未定义的变量:
L_EC = normalize(u_light[i].position.xyz);
使用light
代替u_light
:
L_EC = normalize(light[i].position.xyz);
请注意,您应该检查着色器是否已成功编译glGetShaderiv
GLint status = GL_TRUE;
glGetShaderiv( shaderObj, GL_COMPILE_STATUS, &status );
并且可以通过以下方式检索错误消息glGetShaderInfoLog
推荐阅读
- python - 计算变量改变值的次数
- angular - ng-bootstrap 模态中的组件
- sql - 在 3 个字符后插入空格 (SQL Express)
- php - WooCommerce+WP-All-Import - 在链接的 csv 文本中显示股票价值
- ios - 当重复设置为“是”时,UNUserNotification 不会从待处理通知中删除 - Swift
- mongoose - $and not working in $or 意味着 $or 部分不工作
- java - Hibernate 和 SQL Server - Java 和具有 Java 8 类型的数据库之间的时间不匹配
- php - Centos 7.5 中忽略了内存限制
- reactjs - React Native 中的 this.props undefined: TypeError: Cannot read property 'title' of undefined
- sonarlint-vs - Sonarlint 在 Visual Studio 代码中不起作用