GLKit混合两个纹理。

3
我正在尝试将OGL ES 1.1代码转换为GLKit。 GLKit提供了一对纹理槽:
  1. texture2d0
  2. texture2d1
每个纹理都有一个环境模式:
  1. GLKTextureEnvModeReplace,
  2. GLKTextureEnvModeModulate,
  3. GLKTextureEnvModeDecal
通常,您会留下texture2d1为空,只设置texture2d0。我假设(从阅读Apple的文档中得出)2d1用于混合/组合/修改纹理。由于GLKit“仅仅”坐在着色器之上,每个着色器标准配备一对纹理插槽 - “传入”插槽代表已经在材料上的内容,“修改”插槽代表着色器将使用的参数来修改材料。
但是这似乎行不通。
我尝试过:
self.baseEffect.texture2d0.envMode = GLKTextureEnvModeReplace;
self.baseEffect.texture2d0.target = GLKTextureTarget2D;
self.baseEffect.texture2d0.name = [earthTextureDefault name];

self.baseEffect.texture2d1.envMode =  GLKTextureEnvModeModulate;
self.baseEffect.texture2d1.target = GLKTextureTarget2D;
self.baseEffect.texture2d1.enabled = TRUE;
self.baseEffect.texture2d1.name = [textureClouds name];

我所得到的只有一个黑色的非纹理。无论是什么纹理,放置在0(1中没有任何东西)中都可以正常工作。第二个纹理是阴影的 alpha-to-white,而第一个纹理则是全部不透明,但调色板相当丰富。

我真正想做的是高效地应用动态生成/更新的混合。例如:

  1. 加载基础纹理
  2. 加载第二个纹理
  3. 加载混合蒙版,使它们混合
  4. 逐帧更新混合蒙版。无需重新上传前两个纹理

注:我不想放弃 GLKit 并编写自定义着色器来代替它。我想了解 GLKit 的工作原理——从事简单事情时,维护起来应该比我四处编写一堆着色器要容易得多。


你是否愿意尝试一些能够为你处理混合模式着色器的东西?https://github.com/BradLarson/GPUImage 如果你仍然希望在GLKView场景中使用它,你可以在最后提取出一个纹理。 - Brad Larson
看起来很不错,但并没有回答核心问题:我们如何使用GLKit的内置功能? - Adam
当然,我也很好奇这是如何工作的,因为我只是通过OpenGL ES直接处理着色器和纹理。我几乎没有花太多时间来了解GLKit的抽象层。只是想提一下,以防你对此感到沮丧,并需要在短期内得到一些东西。 - Brad Larson
不,如果我放弃GLKit,我会写着色器。 - Adam
似乎没有人知道,而且苹果公司(作为我的错误报告回应)拒绝进一步记录GLKit,即使文档明显缺失。因此,我放弃了,并将所有内容移植到着色器中... - Adam
1个回答

0

正如文档中所述, GLKTextureEnvModeModulate 将纹理的颜色值相乘,这可能是你看到黑色的原因。如果你想在没有 alpha 的纹理上叠加带有 alpha 的纹理,请改用 GLKTextureEnvAttribDecal

我没有看到只使用 GLKit API 实现动态混合掩码的方法,但你不必完全放弃它。尝试像这样做:

  1. 加载三个纹理对象:基础纹理、第二个纹理和混合蒙版。
  2. 创建一个帧缓冲对象,其颜色附件是第四个纹理。
  3. 使用一个着色器将第二个纹理的RGB值和混合蒙版的alpha值填充到纹理FBO中。
  4. 使用基础纹理作为texture0,使用FBO纹理作为texture1,并使用GLKBaseEffect将主场景渲染到屏幕上。
  5. 更新混合蒙版时,请重复步骤3-4。

这种方法可能不如在一个渲染通道中完成所有操作的片段着色器高效,但它应该可以工作。


苹果不再允许我们为没有GL ES 2的设备编写应用程序,因此我认为人们使用ES 1没有意义。正如问题中所指出的,我已经切换到ES 2 - 只有在苹果很好地记录了ES 1管道时才值得使用ES 1。但是你的答案听起来对我来说是正确的,所以标记为已回答。 - Adam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接