【问题标题】:Accurately passing the player's relative position into AGAL准确地将玩家的相对位置传递给 AGAL
【发布时间】:2013-11-25 22:20:32
【问题描述】:

我正在尝试开发一个片段着色器,它会在面部法线垂直于玩家“相机”的方向时淡化为 0。 (这是针对球形行星大气;我希望它们在外部范围内消失)。

我将游戏设置为让玩家始终处于“宇宙位置”0、0、0 处,并且所有对象的 transform.matrix3D 在玩家移动时都围绕玩家进行平移。

我应该指出,我有多个着色器工作正常,其中一些包括混合纹理、在 2 个模型之间插值和镜面着色;不过,这个问题让我成功了。

我一直认为片段着色器需要知道玩家的方向(以便它可以在当前面法线和玩家方向之间进行点积)。但是,它还需要将模型的“当前”顶点位置(即着色器当前正在绘制的顶点输出位置)添加到反向玩家相机方向上;这样,从该模型表面位置到相机的方向将是正确的。

嗯,显然不是。 (我可以解释我一直在做什么,但我可以感觉到人们已经忽略了这个问题......)。鉴于我还需要包括(我认为)模型的顶点位置与模型的中心位置“偏移”的事实,谁能告诉我如何正确计算玩家的方向?这一直让我头疼!

谢谢。

编辑

下面是相关的 AS3 代码,后面是 AGAL:

// invMatrix is a cloned and inverted copy of the Planet object's transform.matrix3D...
// .deltaTransformVector ONLY uses the matrix3D's rotation to rotate a vector3D...
var tempVector:Vector3D = invMatrix.deltaTransformVector(transform.matrix3D.position);
tempVector.normalize();
context3D.setProgramConstantsFromVector(Context3DProgramType.VERTEX, 5, Vector.<Number>([-tempVector.x, -tempVector.y, -tempVector.z, 0]));
context3D.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 7, rotMatrix, true);
... other constants set here ...
context3D.setVertexBufferAt(3, mesh.normalsBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);

在顶点着色器中:

"m44 v3, va3, vc7 \n" + // passed rotMatrix is used to rotate the face normals
"dp3 v4, vc5, va3 \n" + // put the dot product of the normalised, rotated camera position and the rotated normal in v4

然后,在片段着色器中:

"mul ft0, ft0, v4 \n" + // multiply the sampled texture in ft0 by the passed dot product in v4

但这一切都导致了一些奇怪的渲染行为,其中一半的大气似乎被绘制,这取决于你相对于地球的位置。莫名其妙。非常感谢任何帮助。

【问题讨论】:

    标签: 3d fragment-shader stage3d 3dcamera


    【解决方案1】:

    你需要找到从顶点到空间中某个点的向量吗?如果是这样,您只需要在一个框架中工作,例如在世界框架中。为此,您需要知道世界空间中的所需位置,并且需要将顶点转换为世界空间(只需乘以模型矩阵)。

    【讨论】:

    • 感谢您的回复。我没有在上面介绍太多细节,对不起,但你描述的是我正在做的事情。我将对象的反向位置传递给片段着色器。我还传入了对象的旋转矩阵并用它来旋转顶点位置。然后我将旋转的顶点位置添加到反向对象位置。这应该给我从着色器计算的片段到相机的方向,但是我所看到的渲染并不像我期望的那样。看起来更多的气氛正在模型的顶部和底部被“绘制”。有什么想法吗?
    • 这似乎是正确的。但让我澄清一些步骤。 1. 你需要在顶点着色器中进行这样的计算。为什么将对象的反向位置传递给片段着色器?为什么要逆向? 2.你提到你传递了旋转矩阵。在片段着色器中也是如此?您的对象没有翻译?
    • 我将模型视图矩阵(它的平移、缩放和旋转组合)传递给注册 vc0。我尝试通过该寄存器转换模型的顶点缓冲区(如您所说,这是在顶点着色器中完成的),然后将结果传递给片段着色器,但这似乎也不起作用。我会再试一次,看看我的进展如何。我正在片段着色器中进行点积计算,因为我正在使用它来确定在该像素处绘制了多少采样纹理。
    • 所以,您知道相机在世界空间中的方向。你需要在这个方向上取法线的点积。您可以在顶点着色器中通过将法线转换为世界空间来完成此操作,但这有点复杂,因为您有平移和缩放。更好的方法是在应用程序中将相机方向转换为对象空间,并使用该值与法线进行点积。结果应该传递给片段着色器。
    • 但是如果我在应用程序中计算点积,我只会使用一个普通的。为了实现我想要的褪色,当然我需要在片段着色器中计算点积,使用每个面的法线,以便产生不同的点积......
    【解决方案2】:

    好的 - 感谢 Volgogradetzzz,您的回复;你绝对让我放心,我在思考正确的“方向”。它最终成为同时纠正许多事情的问题。我结束了:
    1) 将相对的、未旋转的摄像机位置传递给着色器。
    2) 通过对象的旋转矩阵(包括比例,但不包括位置平移)在顶点着色器中旋转顶点和法线缓冲区
    3) 最后,关键是从片段着色器中的相机位置减去旋转的顶点位置
    所以 - 它终于奏效了! (好吧,那是我生命中的一周,我永远不会回来了)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-13
      • 2021-09-13
      • 1970-01-01
      • 2018-06-05
      • 1970-01-01
      • 2016-09-12
      • 2020-12-16
      • 2013-02-03
      相关资源
      最近更新 更多