此顶点着色器中的统一浮动不起作用

Posted

技术标签:

【中文标题】此顶点着色器中的统一浮动不起作用【英文标题】:The uniform floats in this vertex shader don't work 【发布时间】:2017-05-17 09:43:43 【问题描述】:

详情: 此着色器绘制行星围绕恒星的轨道路径。我的意图是当路径远离opengl相机时使用统一的浮动“近”和“远”来调暗路径的颜色,以帮助计算颜色亮度。当我尝试使用统一浮点变量时,着色器根本不起作用。我不知道可能出了什么问题。 (我是 openGL 和 C++ 的新手)。

顶点着色器(不使用统一浮点变量时有效)

#version 450

layout(location=0) in vec3 vertex_position;

uniform mat4 proj, view; //view and projection matrix
uniform mat4 matrix;     // model matrix

uniform float near;   //closest orbit distance
uniform float far;    //farthest orbit distance
uniform vec3 dist_orbit_center;
out vec3 colour;

void main()

    vec3 dist_vector = dist_orbit_center + vertex_position;
    float dist = length(dist_vector);

    //Trying out some debugging. Ignoring dist for now
    //float ratio = near / far;  // Not working!
    float ratio = 0.25 / 0.5;  // Working!

    colour = vec3(0.0, 1.0, 0.1) * ratio;

    gl_Position = proj * view * matrix * vec4(vertex_position, 1.0);

片段着色器(不使用统一浮点变量时有效)

#version 450

in vec3 colour;
out vec4 frag_colour;

void main() 

    frag_colour=vec4 (colour, 1.0);

用于绘制行星轨道路径的 C++ 代码(除了 glUniform1f 之外工作?)

 if ((orb.flag))

    double near;
    double far;
    // get nearest and farthest point of orbit
    distance_to_orbit(near, far, cam.pos, sun.pos, plan[orb.body].orbit_radius, plan[orb.body].orbit_axis, Debug);
    GLfloat near_display = (float) (near / DISPLAY_FACTOR);
    GLfloat far_display = (float) (far / DISPLAY_FACTOR);

    glUseProgram(sh_orbit.program);
    glBindVertexArray(sh_orbit.vao);
    glUniformMatrix4fv (sh_orbit.view_mat_location, 1, GL_FALSE, cam.view_mat.m);
    mat4 m = identity_mat4();
    mat4 m2;
    m2 = translate(m, sun.display_pos);
    glUniformMatrix4fv (sh_orbit.matrix_mat_location, 1, GL_FALSE, m2.m);
    // For debugging.  Not working.
    near_display = 0.25;
    glUniform1f(sh_orbit.near_location,  near_display);
    // For debugging.  Not working.
    far_display = 0.5;
    glUniform1f(sh_orbit.far_location,  far_display);
    glUniform3fv(sh_orbit.dist_orbit_center_location, 1, sun.display_pos.v);

    glDrawArrays(GL_LINE_STRIP, 0, 361);
    glBindVertexArray(0);

为顶点着色器创建行星轨道路径的C++代码(工作中)

void Setup_planet_orbit(int index)

    orb.flag = 1;
    orb.body = index;
    vec3d axis = plan[orb.body].orbit_axis;
    vec3d globe = plan[orb.body].origonal_pos;

    for (int lp=0; lp<361; lp++)
    
        globe = Rotate_point((double) lp * TO_RADIANS, axis, 
      plan[orb.body].origonal_pos);
       sh_orbit.points[lp*3] = (float) (globe.v[0] / DISPLAY_FACTOR);
       sh_orbit.points[lp*3+1] = (float) (globe.v[1] / DISPLAY_FACTOR);
       sh_orbit.points[lp*3+2] = (float) (globe.v[2] / DISPLAY_FACTOR);
    
    glUseProgram(sh_orbit.program);
    glBindVertexArray(sh_orbit.vao);
    glBindBuffer(GL_ARRAY_BUFFER, sh_orbit.points_vbo);
    glBufferSubData(GL_ARRAY_BUFFER,  0, 361*3*sizeof(GLfloat), 
   sh_orbit.points);
    glEnableVertexAttribArray(0);
    glBindVertexArray(0);

初始化着色器的C++代码(工作中)

bool Get_orbit_shader()

    float*& point = sh_orbit.points;
    point = (float*)malloc (3 * 361 * sizeof (float));

    string vertshader=readFile("orbit.vert.txt");
    const char* vertex_shader = vertshader.c_str();

    string fragshader=readFile("orbit.frag.txt");
    const char* fragment_shader = fragshader.c_str();
    // Compile vertex shader program
    GLuint vs = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vs, 1, &vertex_shader, NULL);
    glCompileShader(vs);
    int params=-1;
    glGetShaderiv (vs, GL_COMPILE_STATUS, &params);
    if (GL_TRUE != params)
    
        fprintf(stderr, "ERROR: GL shader index %i did not compile\n", vs);
        print_shader_info_log(vs);
        return false;
    
    // Compile fragment shader program
    GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fs, 1, &fragment_shader, NULL);
    glCompileShader(fs);
    glGetShaderiv (fs, GL_COMPILE_STATUS, &params);
    if (GL_TRUE != params)
    
        fprintf(stderr, "ERROR: GL shader index %i did not compile\n", fs);
        print_shader_info_log(fs);
        return false;
    
    // Link vertex and shader program
    sh_orbit.program = glCreateProgram();
    glAttachShader(sh_orbit.program, fs);
    glAttachShader(sh_orbit.program, vs);
    glLinkProgram(sh_orbit.program);
    //Check if linked correctly.
    glGetProgramiv(sh_orbit.program, GL_LINK_STATUS, &params);
    if (GL_TRUE !=params)
   
        fprintf (stderr, "ERROR: could not link shader programme GL index 
        %u\n", 
        sh_orbit.program);
        print_programme_info_log(sh_orbit.program);
        return false;
   
   print_all(sh_orbit.program);
   mat4 matrix = identity_mat4();

   glUseProgram(sh_orbit.program);
   glGenVertexArrays(1, &sh_orbit.vao);
   glBindVertexArray(sh_orbit.vao);

   sh_orbit.view_mat_location = glGetUniformLocation(sh_orbit.program, 
   "view");
   glUniformMatrix4fv (sh_orbit.view_mat_location, 1, GL_FALSE, 
   cam.view_mat.m);

   sh_orbit.proj_mat_location = glGetUniformLocation (sh_orbit.program, 
   "proj");
   glUniformMatrix4fv (sh_orbit.proj_mat_location, 1, GL_FALSE, 
   cam.proj_mat.m);

   sh_orbit.proj_mat_location = glGetUniformLocation (sh_orbit.program, 
   "matrix");
   glUniformMatrix4fv (sh_orbit.matrix_mat_location, 1, GL_FALSE, matrix.m);

   sh_orbit.near_location = glGetUniformLocation(sh_orbit.program, "near");
   glUniform1f (sh_orbit.near_location, 0);

   sh_orbit.far_location = glGetUniformLocation (sh_orbit.program, "far");
   glUniform1f (sh_orbit.far_location, 0);

   vec3 load;
   sh_orbit.dist_orbit_center_location = glGetUniformLocation 
   (sh_orbit.program, "dist_orbit_center");
   glUniform3f (sh_orbit.dist_orbit_center_location, load.v[0], load.v[1], 
   load.v[2]);

   glGenBuffers(1, &sh_orbit.points_vbo);
   glBindBuffer(GL_ARRAY_BUFFER, sh_orbit.points_vbo);
   glBufferData(GL_ARRAY_BUFFER,  361*3*sizeof(GLfloat), sh_orbit.points, 
   GL_DYNAMIC_DRAW);
   glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);

   glEnableVertexAttribArray(0);
   glBindVertexArray(0);

   return true;  

用于在 3D 空间中查找最近和最远轨道点的 C++ 代码(工作中)

/// Find closest and farthest distance to a 3d disk
/// projection of P-C onto plane is Q-C = P-C  -  Dot(N,P-C)*N
void distance_to_orbit(double &near, double &far, vec3d point, vec3d center, 
double radius, vec3d normal, FILE* Debug)

    vec3d PmC;
    vec3d QmC;
    vec3d diff;
    double lengthQmC;
    double sqr_dist;
    double dist;
    double temp;
    vec3d Closest;
    vec3d Farthest;
    vec3d vec_temp;

    PmC = point - center;
    double Dot = dot_d(normal, PmC);
    vec_temp = normal *  Dot;  //Distance to plane that circle is on.
    QmC = PmC - vec_temp;
    lengthQmC = length(QmC);

    vec_temp = QmC * (radius / lengthQmC);
    Closest = center + vec_temp;

    diff = point - Closest;
    sqr_dist = dot_d(diff, diff);
    near = sqrt(sqr_dist);     //distance to nearest point of 3d disc

    vec_temp = center - Closest;
    vec_temp *= 2.0f;
    diff = Closest + vec_temp;
    far = get_distance_d(point, diff);  //distance to farthest point of 3d 
    disc

【问题讨论】:

【参考方案1】:

您不是在glUniform1f (sh_orbit.far_location, 0); 表达式中将far(和near)设置为0 并被零除吗?

【讨论】:

我输入了非零数字,但仍然无法正常工作。不过很好抓。该程序使用了其他四个着色器,因此我将向它们添加统一的浮点数,看看是否会发生同样的问题。 您的代码也缺少任何错误处理。您应该在所有其他 gl 调用之后调用 glGetError 并检查返回的结果。 添加了一些错误检查。似乎来自这行代码。 mat4 m = identity_mat4();垫4平方米; m2 = translate(m, sun.display_pos); glUniformMatrix4fv (sh_orbit.matrix_mat_location, 1, GL_FALSE, m2.m); 好的,发现一个问题。着色器似乎不喜欢统一变量中的下划线。 'dist_orbit_center'。所以它现在可以工作,但是当我添加更多统一变量时,它们就不起作用了。奇怪的!! @VTT

以上是关于此顶点着色器中的统一浮动不起作用的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL First Cube渲染不起作用

OpenGL第一个立方体渲染不起作用

Phong 着色器不起作用

Opengl为啥这个着色器不起作用?

CSS媒体查询更改html选择器中的字体大小不起作用

在顶点和片段着色器中访问同名统一失败