【发布时间】:2018-02-11 13:40:58
【问题描述】:
假设我有我的几何图形并创建了一个包含三角形邻接信息的索引缓冲区。然后,将绘图模式从GL_TRIANGLES 更改为GL_TRIANGLE_ADJACENCY。
问题是,我可以使用几何着色器将几何从三角形邻接转换为三角形带吗?
类似这样的:
layout(triangles_adjacency) in;
layout(triangle_strip, max_vertices = 3) out;
in Vertex
{
vec3 normal;
} vertex[];
out FragmentVertexData
{
vec3 normal;
vec3 fragpos;
} VertexOut;
void main()
{
for(int i = 0 ; i < gl_in.length(); i+=2)
{
gl_Position = ProjectionMatrix * ViewMatrix * ModelMatrix * gl_in[i].gl_Position;
VertexOut.normal = vertex[i].normal;
VertexOut.fragpos = vec3(ModelMatrix * gl_in[i].gl_Position);
VertexOut.fragpos = gl_Position;
EmitVertex();
}
EndPrimitive();
}
我已经尝试过,实际上它会绘制几何图形,但法线有问题。我也必须索引它们吗?我错过了一步吗?
这就是我在片段着色器中使用 fragpos 和 normal 的方式
vec3 normal = normalize(VertexOut.normal);
vec3 lightDir = normalize(light.position - VertexOut.fragpos);
这是我编写三角形邻接索引缓冲区的算法:
void Loader::FindAdjacencies(const aiMesh * paiMesh, vector<int>& indices)
{
// Step 1 - find the two triangles that share every edge
for (uint i = 0; i < paiMesh->mNumFaces; i++)
{
const aiFace& face = paiMesh->mFaces[i];
Face Unique;
// If a position vector is duplicated in the VB we fetch the
// index of the first occurrence.
for (uint j = 0; j < 3; j++)
{
uint Index = face.mIndices[j];
aiVector3D& v = paiMesh->mVertices[Index];
if (m_posMap.find(v) == m_posMap.end())
{
m_posMap[v] = Index;
}
else
{
Index = m_posMap[v];
}
Unique.Indices[j] = Index;
}
m_uniqueFaces.push_back(Unique);
Edge e1(Unique.Indices[0], Unique.Indices[1]);
Edge e2(Unique.Indices[1], Unique.Indices[2]);
Edge e3(Unique.Indices[2], Unique.Indices[0]);
m_indexMap[e1].AddNeigbor(i);
m_indexMap[e2].AddNeigbor(i);
m_indexMap[e3].AddNeigbor(i);
}
// Step 2 - build the index buffer with the adjacency info
for (uint i = 0; i < paiMesh->mNumFaces; i++)
{
const Face& face = m_uniqueFaces[i];
for (uint j = 0; j < 3; j++)
{
Edge e(face.Indices[j], face.Indices[(j + 1) % 3]);
assert(m_indexMap.find(e) != m_indexMap.end());
Neighbors n = m_indexMap[e];
uint OtherTri = n.GetOther(i);
uint minus1 = (uint)-1;
bool comp = (OtherTri != minus1);
assert(comp);
const Face& OtherFace = m_uniqueFaces[OtherTri];
uint OppositeIndex = OtherFace.GetOppositeIndex(e);
indices.push_back(face.Indices[j]);
indices.push_back(OppositeIndex);
}
}
}
不幸的是,仅适用于接近的几何形状。这就是我用立方体测试它的原因。我尝试使用 bunny.ply,但模型的一部分有孔,我必须在搅拌机中对其进行编辑。
这是 obj 文件:
# Blender v2.76 (sub 0) OBJ File: ''
# www.blender.org
v 1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 -1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -0.999999
v 0.999999 1.000000 1.000001
v -1.000000 1.000000 1.000000
v -1.000000 1.000000 -1.000000
vt 0.333333 0.666667
vt 0.333333 1.000000
vt 0.000000 1.000000
vt 0.000000 0.666667
vt 0.000000 0.333333
vt 0.333333 0.333333
vt 0.333333 0.000000
vt 0.666667 0.000000
vt 0.000000 0.000000
vt 1.000000 0.333333
vt 0.666667 0.333333
vt 0.666667 0.666667
vt 1.000000 0.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 1.000000 0.000000 0.000000
vn -0.000000 0.000000 1.000000
vn -1.000000 -0.000000 -0.000000
vn 0.000000 0.000000 -1.000000
f 2/1/1 3/2/1 4/3/1
f 8/1/2 7/4/2 6/5/2
f 5/6/3 6/7/3 2/8/3
f 6/9/4 7/7/4 3/6/4
f 3/10/5 7/11/5 8/8/5
f 1/11/6 4/12/6 8/1/6
f 1/4/1 2/1/1 4/3/1
f 5/6/2 8/1/2 6/5/2
f 1/11/3 5/6/3 2/8/3
f 2/5/4 6/9/4 3/6/4
f 4/13/5 3/10/5 8/8/5
f 5/6/6 1/11/6 8/1/6
非常感谢!
这是我的顶点着色器:
#version 430 core
layout(location = 0) in vec3 vertexPosition;
layout(location = 1) in vec2 texCoord;
layout(location = 2) in vec3 normal;
out VertexData
{
vec3 normal;
vec2 textCoord;
} vertex;
// Values that stay constant for the whole mesh.
void main(){
gl_Position = vec4(vertexPosition,1.0f);
vertex.textCoord = texCoord;
vertex.normal = normal;
}
还有我的片段着色器:
#version 430 core
struct Material {
vec3 ambient;
vec3 diffuse;
vec3 specular;
float shininess;
};
struct Light {
vec3 position;
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
uniform Material material;
uniform Light light;
out vec4 color;
uniform float LightIntensity;
uniform vec3 LightPos;
uniform vec3 ViewPos;
in FragmentVertexData
{
vec3 normal;
vec3 fragpos;
vec2 texCoord;
} VertexOut;
void main(){
// color of the object
vec3 objectColor = vec3(1.0f, 0.5f, 0.31f);
// Ambient
vec3 ambient = light.ambient * material.ambient ;
vec3 normal = normalize(VertexOut.normal);
vec3 lightDir = normalize(light.position - VertexOut.fragpos);
float diff = max(dot(lightDir,normal), 0.0);
vec3 diffuse = light.diffuse * diff * material.diffuse ;
vec3 viewDir = normalize(ViewPos - VertexOut.fragpos);
vec3 reflectDir = reflect(-lightDir, normal);
vec3 halfwayDir = normalize(lightDir + viewDir );
float spec = pow(max(dot(normal, halfwayDir), 0.0), material.shininess);
vec3 specular = light.specular * spec * material.specular ;
color = vec4((ambient + diffuse + specular) * objectColor, 1);
}
【问题讨论】: