我使用OpenGL创建了一个网格物体查看器,现在我试图在找到here指南后尝试实现一个带有重心坐标的线框着色器。
问题是我的网格有很多黑色三角形,我不明白错误在哪里。它可能在我的重心向量中吗?
我的最终渲染如下所示:
在代码中我以这种方式创建了重心向量:
MatrixXi barycentric(3, faceCount*3);
for(int i=0; i<faceCount*3; i+=9){
barycentric.col(i) << 1,0,0,0,1,0,0,0,1;
}
这是我的顶点着色器:
#version 330
in vec3 vertices;
in vec3 barycentric;
uniform mat4 proj;
uniform mat4 model;
uniform mat4 view;
out vec4 frag_color;
varying vec3 vBC;
void main(void) {
mat4 mvp = proj * view * model;
frag_color = vec4(0.0, 1.0, 0.0, 1.0);
vBC = barycentric;
gl_Position = mvp * vec4(vertices, 1.0);
}
我的片段着色器:
#version 330
varying vec3 vBC;
in vec4 frag_color;
out vec4 color;
float edgeFactor(){
vec3 d = fwidth(vBC);
vec3 a3 = smoothstep(vec3(0.0), d*1.5, vBC);
return min(min(a3.x, a3.y), a3.z);
}
void main(void) {
if(gl_FrontFacing){
gl_FragColor = vec4(0.0, 0.0, 0.0, (1.0-edgeFactor())*0.95);
}
else{
gl_FragColor = vec4(0.0, 0.0, 0.0, (1.0-edgeFactor())*0.7);
}
}
答案 0 :(得分:1)
正如我在问题评论中提到的那样,问题在于网格的某些三角形具有相同的barycentric
属性。据我所知,您使用索引网格,重新排序数据以解决此问题可能会非常棘手,并且很大程度上取决于模型的拓扑结构。然而,有一种防弹的方法,它只是有点不理想:只是摆脱索引(代码是C ++ - ish,但可能需要一些重做):
// Here're buffers with vertices and indices of the mesh.
std::vector<Vertex> vertexBuffer;
std::vector<int> indexBuffer;
std::vector<VertexWithBarycentricCoord> outputVertexBuffer;
const std::array<BarycentricCoord> COORDS({{1, 0, 0}, {0, 1, 0}, {0, 0, 1}});
for (int i : indexBuffer) {
outputVertexBuffer.push_back({vertexBuffer, COORDS[i % 3]});
}
关于glPolygonMode
。你在评论中指出它可能会破坏GUI。但它不必:您只能为您的绘图切换模式GL_LINE
,然后将其切换回GL_FILL
:
glPolygonMode(GL_FRONT_AND_BACK, GL_LINES);
// draw your mesh
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
// draw GUI
你也提到过你可能想要用填充网格“混合”网格的线框,这可能妨碍使用glPolygonMode
,但它不应该。你可以画两次网格:
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
// draw your filled mesh
glDepthFunc(GL_LEQUAL) // to make sure that not all wireframe's fragments are culled in depth test.
glPolygonMode(GL_FRONT_AND_BACK, GL_LINES);
// draw your mesh again