我有一个带有opengl4csharp库的c#程序,它创建了一个3D立方体,可以用鼠标和键盘在空间中移动。
实际上,我只对一个立方体应用了一个纹理。我的问题是我想为每张脸应用不同的纹理。
我尝试按如下方式启动纹理数组和textureId数组:
diceTextures = new Texture[6];
diceTextures[0] = new Texture("top.jpg");
diceTextures[1] = new Texture("bottom.jpg");
diceTextures[2] = new Texture("left.jpg");
diceTextures[3] = new Texture("right.jpg");
diceTextures[4] = new Texture("front.jpg");
diceTextures[5] = new Texture("back.jpg");
diceUint = new uint[diceTextures.Length];
for (uint ui = 0; ui < diceTextures.Length; ui++)
{
diceUint[ui] = diceTextures[ui].TextureID;
}
然后在OnRenderFrame方法中,将它们绑定到:
Gl.UseProgram(program);
Gl.ActiveTexture(TextureUnit.Texture0);
Gl.BindTextures(0, diceTextures.Length, diceUint);
但是没有任何改变,只有数组的第一个纹理显示在立方体上,就像之前只绑定一个纹理一样。
如何实现纹理应用于面部?
答案 0 :(得分:1)
Gl.BindTextures(0,diceTextures.Length,diceUint);
这将6个纹理绑定到6个单独的纹理单元,0到diceTextures.Length - 1
。实际上,如果您要使用glBindTexture s ,则不需要glActiveTexture
调用。
在任何情况下,如果您的目标是为每个脸部赋予不同的纹理,则首先必须能够从着色器中识别特定的脸部。这意味着每个面需要被赋予每顶点值,该顶点值与其他面的顶点值分开。这也意味着这些面孔不能与其他面孔共享位置,因为它们的一个属性不是面对面共享的。
因此,您需要一个新的vertex attribute,其中包含您希望该面孔使用的纹理的索引。
从那里,您可以使用array textures。这些是包含图像数组的单个纹理。从数组纹理中采样时,您可以指定(作为纹理坐标的一部分)要从中采样的数组中的哪个索引。
当然,这会改变纹理构建代码,因为必须对纹理类型使用GL_TEXTURE_2D_ARRAY
,并为每个mipmap面分配多个数组图层。
总的来说,着色器代码看起来像这样:
#version 330
layout(location = 0) in vec3 position;
layout(location = 2) in vec2 vertTexCoord;
layout(location = 6) in float textureLayer;
out vec2 texCoord;
flat out float layer;
void main()
{
gl_Position = //your usual stuff.
texCoord = vertTexCoord;
layer = textureLayer;
}
片段着色器:
#version 330
in vec2 texCoord;
flat in float layer;
uniform sampler2DArray arrayTexture;
out vec4 outColor;
void main()
{
outColor = texture(arrayTexture, vec3(texCoord, layer));
}