此顶点着色器中的统一浮动不起作用
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, ¶ms);
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, ¶ms);
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, ¶ms);
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以上是关于此顶点着色器中的统一浮动不起作用的主要内容,如果未能解决你的问题,请参考以下文章