我在使用Stage3D时遇到了意想不到的事情。我为我的对象制作了两个不同的着色器程序。其中一个程序是使用纹理位图和uv数据。另一个只使用颜色数据。这两个对象是非常不同的,因为最终,我将使用纯色和简单的渲染逻辑显示一些东西(如方向线,高光等),而其他东西(如实际对象,背景等)将使用mipmap呈现,所以向前。问题是当我使用这两个非常不同的着色器程序时,只有一个或另一个工作。因此,要么显示所有仅颜色对象,要么显示所有仅纹理对象。显然,我希望两者都出现。
这是纹理对象的agal代码:
顶点着色器:
//4x4 matrix multiply to get camera angle
"m44 op, va0, vc0\n" +
//tell fragment shader about xyz
"mov v0, va0\n" +
//tell frament shader about uv
"mov v1, va1\n" +
//tell fragment shader about RGBA
"mov v2, va2\n"
片段着色器:
//grab the texture color from texture 0 and
//the uv coordinates from varying register 1 and
//store the interpolated value in ft0
"tex ft0, v1, fs0 <2d,linear,repeat,miplinear>\n" +
//move this value to the output color
"mov oc, ft0\n"
这些对象的呈现代码如下所示:
context3D.setProgram(_renderProgram);
context3D.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, renderMatrix, true);
context3D.setTextureAt(0, texture);
// vertex position to attribute register 0
context3D.setVertexBufferAt(0, vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
context3D.setVertexBufferAt(1, uvBuffer, 0, Context3DVertexBufferFormat.FLOAT_2);
context3D.setVertexBufferAt(2, colorsBuffer, 0, Context3DVertexBufferFormat.FLOAT_4);
这是我用于明显彩色物体的agal代码(即没有纹理):
顶点着色器:
"m44 op, va0, vc0\n" + // pos to clipspace
"mov v0, va1" // copy color
片段着色器:
"mov oc, v0 "
这些对象的呈现代码如下所示:
context3D.setProgram(_renderProgram);
context3D.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, renderMatrix, true);
// vertex position to attribute register 0
context3D.setVertexBufferAt(0, vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
// color to attribute register 1
context3D.setVertexBufferAt(1, vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_3);
由于某些我无法弄清楚的原因,我将不同的数据分配给不同的不同寄存器索引(va)这一事实导致其中一个渲染过程失败。如果我在纹理循环中首先渲染纹理对象,则所有彩色对象都会消失,反之亦然。对象将在第一帧正确显示。但是只要渲染循环第二次播放,就会发生这种意外行为。
我发现如果通过添加以下内容来修改颜色对象的渲染代码:
context3D.setTextureAt(0, null);
context3D.setVertexBufferAt(2, null);
有效。但这确实不是一个好的解决方案。我不想知道在我的程序中的某个地方另一个对象是使用n个不同的寄存器进行渲染,所以如果另一个program3D实例需要少于n,我必须将所有那些未使用的va设置为null。此外,如果我为某个对象(例如发光对象)创建一个新的着色器程序,现在需要第4个va,现在我必须返回并修改所有其他着色器程序以将va4设置为null,以便所有内容都将呈现。这是真的吗?当然,我在这里遗漏了一些东西。设置所有纹理寄存器(ft)同样如此。
我可以提供更多信息......
答案 0 :(得分:0)
在这里挖一个旧帖子。我注意到你的意见和想法我提到(主要是为了未来读者的利益),你偶然发现的是纠正解决方案。准备将3D对象绘制到屏幕时,典型过程如下所示:
答案 1 :(得分:0)
不幸的是,看起来你是对的 - 至少这是我找到并实施的解决方案。之前传递的纹理必须“清除”......
context3D.setTextureAt(<n>, null);
...否则你的无纹理着色器仍会指望纹理并且不会渲染。