【问题标题】:glTexGen in OpenGL ES 2.0OpenGL ES 2.0 中的 glTexGen
【发布时间】:2011-07-01 01:02:23
【问题描述】:

我已经尝试了几个小时来用 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? g是texture2d调用中s的值吗?

我看过网站:

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

另一个尺寸说明相同的功能:

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

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

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

我仍然缺少一些东西。

我的垂直着色器看起来基本上是这样的: WVPMatrix = 世界观项目矩阵。 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/

提前谢谢你。

【问题讨论】:

  • 我不确定你的问题是什么......你的着色器代码工作正常吗?
  • 不,在垂直着色器中获取点会返回 1 之外的值。

标签: opengl-es opengl-es-2.0 opengl-to-opengles


【解决方案1】:

来自 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 yo + 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 值,y 相同t。因此,如果您的模型的坐标范围在 (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) 为中心,此解决方案仍然可以为您提供

kOutBaseTCoord.st += vec(0.5);

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

【讨论】:

  • 谢谢,但是值应该是什么或 ps0...3 和 pt0...3?以上还是不行。我正在尝试在 C++ 中移动代码,以便可以查看调试器中的值 - 显示颜色表明 s & t 始终 = 1。
  • 感谢 rotoglup,您的帖子帮助很大。您对模型大小所做的最后一次编辑正是我最终实现的。我开始意识到这是关于在每个方向上获取模型的边界并使顶点落在 [0-1] UV 线的范围内。所以我写了一个方法来找到 AABB 或每个模型,然后创建正确的缩放和平移矩阵,当一个顶点乘以矩阵时,每个平面上的值落在 0-1 之间。将矩阵作为制服向下传递,并映射纹理。再次感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-08
  • 1970-01-01
  • 2011-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多