OpenGL问题列表

✔️ OpenGL没有做任何MVP变换那默认视觉空间的范围多大?

默认的视觉空间为从-z方向看 [ − 1 , 1 ] 3 [-1,1]^3 [1,1]3标准立方体内没有depth_test的正交投影。也就是只能看见x,y这个平面。

  

✔️view变换应是先将摄像机平移到原点,之后进行摄像机坐标与世界坐标的对齐,也就是先TRglm::lookAt的实现把TR操作放到一个变换矩阵中,岂不是先RT了?

问题本质源于games101图形学理论与OpenGL中具体实现的区别,即理论支撑和落地实践的区别。

games101:先确定相机位置,将相机移动到原点位置,同时所有物体随之做相对运动,最后对齐相机坐标和世界坐标,所有物体依旧做相对运动。

OpenGL:相机(视点)永远在原点位置,根据定义的摄像机坐标先与世界坐标对齐,最后物体再平移。可以说没有相对运动一说,因为相机永远不动,只有物体去找自己应该站的位置。

template <typename T> 
	GLM_FUNC_QUALIFIER detail::tmat4x4<T> lookAt
	(
		detail::tvec3<T> const & eye,
		detail::tvec3<T> const & center,
		detail::tvec3<T> const & up
	)
	{
		detail::tvec3<T> f = normalize(center - eye);
		detail::tvec3<T> u = normalize(up);
		detail::tvec3<T> s = normalize(cross(f, u));
		u = cross(s, f);

		detail::tmat4x4<T> Result(1);
		Result[0][0] = s.x;
		Result[1][0] = s.y;
		Result[2][0] = s.z;
		Result[0][1] = u.x;
		Result[1][1] = u.y;
		Result[2][1] = u.z;
		Result[0][2] =-f.x;
		Result[1][2] =-f.y;
		Result[2][2] =-f.z;
		Result[3][0] =-dot(s, eye);
		Result[3][1] =-dot(u, eye);
		Result[3][2] = dot(f, eye);
		return Result;
	}

  

✔️glm::lookAt的上向量参数设置成不同的参数值,呈现效果却一样?

此方法的上向量参数,并不是严格意义上的上向量(up)。具体看源码,他是根据此向量和lookat向量生成right向量,然后由right和lookat重新生成真正意义上的up向量。并且无需传进一个单位向量,方法内部会自动进行标准化。

  

✔️ 归一化的意义是什么?

为了适配不同大小的视口

  

✔️ 关于深度测试Z值越大离视点近,还是越小离视点近的问题。

正常按标准来说视点在原点位置,看向-z方向,那应该z的值越小离视点越远啊!实际上并不是这样,这里的z说的是世界坐标,而深度测试时所用的z其实是归一化之后的坐标,区间为[0,1],所以应该是z越小离视点越近

  

✔️ GS的输入类型与DrawArray()设置的类型有关联吗?

强关联

在使法线可视化实验中,以下两种参数配置所呈现出的效果等价。

versionⅠ:

// main 中 `glDrawArrays(GL_POINTS, 0, 36);`
#version 330 core
layout (points) in;
layout (line_strip, max_vertices = 2) out;

in VS_OUT {
    vec3 normal;
} gs_in[];

const float MAGNITUDE = 0.3;

uniform mat4 projection;

void GenerateLine(int index) {
    gl_Position = projection * gl_in[index].gl_Position;
    EmitVertex();
    gl_Position = projection * (gl_in[index].gl_Position + vec4(gs_in[index].normal, 0.0) * MAGNITUDE);
    EmitVertex();
    EndPrimitive();
}

void main() {
    GenerateLine(0); 
}

versionⅡ:

// main 中 `glDrawArrays(GL_TRIANGLES, 0, 36);`
#version 330 core
layout (triangles) in;
layout (line_strip, max_vertices = 6) out;

in VS_OUT {
    vec3 normal;
} gs_in[];

const float MAGNITUDE = 0.3;

uniform mat4 projection;

void GenerateLine(int index) {
    gl_Position = projection * gl_in[index].gl_Position;
    EmitVertex();
    gl_Position = projection * (gl_in[index].gl_Position + vec4(gs_in[index].normal, 0.0) * MAGNITUDE);
    EmitVertex();
    EndPrimitive();
}

void main() {
    GenerateLine(0); 
    GenerateLine(1); 
    GenerateLine(2); 
}

  

✔️ Emitvertex()会把GS中out对象当前数据也存储一份吗?

是的,Emitvertex()负责产生一个新的顶点作为几何着色器的输出。既然是shader的输出,那必然包括out对象。

#version 330 core
layout (triangles) in;
layout (line_strip, max_vertices = 6) out;

in VS_OUT {
    vec3 normal;
} gs_in[];

const float MAGNITUDE = 0.3;

uniform mat4 projection;

void GenerateLine(int index) {
    gl_Position = projection * gl_in[index].gl_Position;
    EmitVertex();
    gl_Position = projection * (gl_in[index].gl_Position + vec4(gs_in[index].normal, 0.0) * MAGNITUDE);
    EmitVertex();
    EndPrimitive();
}

void main() {
    GenerateLine(0); 
    GenerateLine(1); 
    GenerateLine(2); 
}