Phong 着色器不起作用

Posted

技术标签:

【中文标题】Phong 着色器不起作用【英文标题】:Phong shader didn't work 【发布时间】:2018-06-27 05:00:07 【问题描述】:

我想使用 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;

【问题讨论】:

对不起。我要渲染的对象没有出现在窗口中。当我通过 gouraud 着色渲染对象时,对象出现了。 【参考方案1】:

片段着色器代码无法编译,因为您在该行中使用了未定义的变量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检索

【讨论】:

谢谢!你救了我的命

以上是关于Phong 着色器不起作用的主要内容,如果未能解决你的问题,请参考以下文章

简单的 OpenTK 着色器不起作用

CAD2014安全系统软件锁许可管理器不起作用或未正确安装

引导日期选择器不起作用

为啥 AVPlayer 边界时间观察器不起作用?

Jquery $('class', this) 选择器不起作用

Weka 分类器不起作用