Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/flash/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flash 混合使用不同的程序会导致某些对象无法渲染_Flash_Fragment Shader_Vertex Shader_Stage3d_Molehill - Fatal编程技术网

Flash 混合使用不同的程序会导致某些对象无法渲染

Flash 混合使用不同的程序会导致某些对象无法渲染,flash,fragment-shader,vertex-shader,stage3d,molehill,Flash,Fragment Shader,Vertex Shader,Stage3d,Molehill,我在使用Stage3D时遇到了一些意想不到的问题。我为我的对象制作了两个不同的着色器程序。其中一个程序用于使用纹理位图和uv数据。另一个只是使用颜色数据。这两个对象非常不同,因为最终,我将使用纯色和简单的渲染逻辑显示一些东西(如定向线、高光等),而其他东西(如实际对象、背景等)将使用mipmap等进行渲染。问题是,当我使用这两个非常不同的着色器程序时,只有一个或另一个可以工作。因此,要么显示所有仅使用颜色的对象,要么显示所有仅使用纹理的对象。很明显,我想两者都出现 以下是我对纹理对象的agal代

我在使用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"
"m44 op, va0, vc0\n" + // pos to clipspace
"mov v0, va1" // copy color
片段着色器:

//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"
"mov oc, v0 "
以下是我对浅色对象(即无纹理)的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"
"m44 op, va0, vc0\n" + // pos to clipspace
"mov v0, va1" // copy color
片段着色器:

//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"
"mov oc, v0 "
这些对象的渲染代码如下所示:

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);
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。此外,如果我为现在需要第四个va的某个对象(例如发光对象)创建了一个新的着色器程序,那么现在我必须返回并修改所有其他着色器程序,将va4设置为null,以便所有内容都将渲染。这是真的吗?我肯定错过了什么。设置我的所有纹理寄存器(ft)也是如此


我可以提供更多信息…

在这里挖掘一篇旧帖子。我注意到了你的评论,我想我应该提到(主要是为了未来读者的利益),事实上,你偶然发现的是正确的解决方案。准备在屏幕上绘制3D对象时,典型的过程如下所示:

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);
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);
  • 定义/编译/上传程序
  • 上载顶点和纹理
  • 开始渲染循环
    • 开始对象循环
      • 设置程序
      • 设置常数
      • 设置输入缓冲区和纹理
      • 调用drawTriangles()
      • 将输入缓冲区和纹理设置为空
    • 结束对象循环
    • 呼叫当前()
  • 结束渲染循环

不幸的是,您似乎是对的-至少这是我找到并实施的解决方案。以前传递的纹理必须“清除”

context3D.setTextureAt(<n>, null);
context3D.setTextureAt(,null);

…否则,您的无纹理着色器仍将使用纹理,并且不会进行渲染。

现在还不打算添加此作为答案,但我在以下链接中发现了一些有趣的内容::“问题是,在drawTriangles()之后,此顶点缓冲区将保留在内存中。”调用,当你绘制下一个对象时,GPU会期望着色器使用它,如果不使用,则会崩溃。因此,在渲染任何对象之前,明智的做法是实现3步渲染逻辑。”他接着说,每次调用drawTriangles()后,他都会取消分配GPU的资源。例如:context.setVertexBufferAt(0,null);//->va0=零;context.setVertexBufferAt(1,null);//->va1=null;context.setTextureAt(0,null);//->fs0=Null您是否收到任何实际错误,或者您的代码是否无法正常工作?你能提供更多的源代码吗?很高兴看到您设置程序和drawTriangles()的顺序。