1

我已经尝试了几个小时来用 GL_OBJECT_LINEAR 实现 glTexGen 的 GLSL 替换。对于 OpenGL ES 2.0。在 Ogl GLSL 中有 gl_TextureMatrix 使这更容易,但这在 OpenGL ES 2.0 / OpenGL ES Shader Language 1.0 上不可用

一些网站已经提到这在 GLSL 垂直着色器中应该很“容易”。但我就是无法让它工作。

我的预感是我没有正确设置飞机,或者我的理解中遗漏了一些东西。

我已经仔细研究了网络。但是大多数网站都在谈论投影纹理,我只是想根据平面投影创建 UV。模型在 Maya 中构建,有 50k 多边形,建模器使用平面贴图,但 Maya 不会导出 UV。所以我试图弄清楚这一点。

我查看了 glTexGen 联机帮助页信息:

g = p1xo + p2yo + p3zo + p4wo

什么是克?g 是 texture2d 调用中 s 的值吗?

我看过网站:

http://www.opengl.org/wiki/Mathematics_of_glTexGen

另一个尺寸解释了相同的功能:

坐标 = P1*X + P2*Y + P3*Z + P4*W

我不明白坐标(我心中的 UV vec2)与点积(标量值)有多相等?我以前用“g”遇到过同样的问题。

我将飞机设置为什么?在我的 opengl c++ 3.0 代码中,我将其设置为 [0, 0, 1, 0] (基本上是单位 z)并且 glTexGen 效果很好。

我仍然缺少一些东西。

我的垂直着色器看起来基本上是这样的:WVPMatrix = World View Project Matrix。POSITION 是模型顶点位置。

改变 vec4 kOutBaseTCoord;
无效的主要()
{
    gl_Position = WVPMatrix * vec4(POSITION, 1.0);

    vec4 平面 = vec4(1.0, 0.0, 0.0, 0.0);
    vec4 tPlane = vec4(0.0, 1.0, 0.0, 0.0);
    vec4 rPlane = vec4(0.0, 0.0, 0.0, 0.0);
    vec4 qPlane = vec4(0.0, 0.0, 0.0, 0.0);

    kOutBaseTCoord.s = dot(vec4(POSITION, 1.0), sPlane);
    kOutBaseTCoord.t = dot(vec4(POSITION, 1.0), tPlane);
    //kOutBaseTCoord.r = dot(vec4(POSITION, 1.0), rPlane);
    //kOutBaseTCoord.q = dot(vec4(POSITION, 1.0), qPlane);

}

碎片着色器

精度 mediump 浮点数;
统一采样器2D BaseSampler;
不同的mediump vec4 kOutBaseTCoord;
无效的主要()
{

    //gl_FragColor = vec4(kOutBaseTCoord.st, 0.0, 1.0);
    gl_FragColor = texture2D(BaseSampler, kOutBaseTCoord.st);
}

我在片段着色器中尝试过 texture2DProj

这是我查找的其他一些链接

http://www.gamedev.net/topic/407961-texgen-not-working-with-glsl-with-fixed-pipeline-is-ok/

先感谢您。

4

1 回答 1

3

来自 glTexGen 文档::

void glTexGenfv ( GLenum coord , GLenum pname , const GLfloat *params );

  • coord - 指定纹理坐标。必须是 GL_S、GL_T、GL_R 或 GL_Q 之一。
  • pname - 如果纹理生成函数是 GL_OBJECT_LINEAR,则函数

g = p1 xo + p2 哟 + p3 zo + p4 wo

使用,其中g是为coord中命名的坐标计算的值,...

所以g确实是一个标量值,它可以是 vec2 uv 值的st分量,具体取决于coord的值(GL_S 或 GL_T)。

更明确地说,调用

glTexGen(GL_S, GL_OBJECT_LINEAR, {ps0,ps1,ps2,ps3})
glTexGen(GL_T, GL_OBJECT_LINEAR, {pt0,pt1,pt2,pt3})

类似于

vec4 sPlane = vec4(ps0,ps1,ps2,ps3);
vec4 tPlane = vec4(pt0,pt1,pt2,pt3);
kOutBaseTCoord.s = dot(vec4(POSITION, 1.0), sPlane);
kOutBaseTCoord.t = dot(vec4(POSITION, 1.0), tPlane);

根据您的 POSITION 值的比例,输出st坐标可能在 (0,1) 范围之外。使用您的价值观:

vec4 sPlane = vec4(1.0, 0.0, 0.0, 0.0);
vec4 tPlane = vec4(0.0, 1.0, 0.0, 0.0);

将直接将模型顶点的x坐标映射到纹理坐标的s值,与yt相同。因此,如果您的模型的坐标范围在 (0,1) 之外,UV 值将随之而来。

为了使纹理适合您的模型,您必须使投影的比例适应模型的大小。对于 100.0 的示例模型大小,这将给出以下代码:

float MODEL_SIZE = 100.0;
vec4 sPlane = vec4(1.0/MODEL_SIZE, 0.0, 0.0, 0.0);
vec4 tPlane = vec4(0.0, 1.0/MODEL_SIZE, 0.0, 0.0);

如果您的模型以 (0,0,0) 为中心,此解决方案仍然可以为您提供 < 0 的值。要对此进行调整,您可以为生成的 UV 值添加偏移量。如 :

kOutBaseTCoord.st += vec(0.5);

请注意,所有这些都很大程度上取决于您的应用程序,以及您尝试通过纹理投影实现的目标。不要犹豫,调整您的公式以满足您的需求,这就是着色器的用途!

于 2011-02-21T07:40:21.857 回答