【问题标题】:Stage3D Error #3632: AGAL linkage: Varying 1 is read in the fragment shader but not written to by the vertex shaderStage3D 错误 #3632:AGAL 链接:在片段着色器中读取可变 1,但未由顶点着色器写入
【发布时间】:2016-05-11 15:04:41
【问题描述】:

我是 AGAL 的初学者,我相信这并不复杂。

我有一个顶点和片段着色器,用于简单地绘制一个没有光效的带有纹理的盒子,代码如下:

            vertexAssembly.assemble( Context3DProgramType.VERTEX,
            "m44 op, va0, vc0\n" + // pos to clipspace
            "mov v0, va1"  // copy uv
        );
        fragmentAssembly.assemble(Context3DProgramType.FRAGMENT,
            "tex ft1, v0, fs0 <2d,linear,nomip>\n" +
            "mov oc, ft1"
        );

我还有一个没有纹理、只有颜色和灯光效果的盒子的 AGAL 代码,这里是着色器的代码:

        private const VERTEX_SHADER_LIGHT:String = 
        "mov vt0, va0\n"+
        "m44 op, vt0, vc0\n"+
        "nrm vt1.xyz, va0.xyz\n"+
        "mov vt1.w, va0.w\n"+   
        "mov v1, vt1\n" +
        "mov v2, va1"

    private const FRAGMENT_SHADER_LIGHT:String = 
        "dp3 ft1, fc2, v1 \n"+
        "neg ft1, ft1 \n"+
        "max ft1, ft1, fc0 \n"+
        "mul ft2, fc4, ft1 \n"+
        "mul ft2, ft2, fc3 \n"+
        "add oc, ft2, fc1";

问题是,如何结合这两个代码,我想要一个带有纹理贴图的盒子模型,以显示灯光效果。

我这样做了:

        private const VERTEX_SHADER_LIGHT:String = 
        "m44 op, va0, vc0\n" + // pos to clipspace
        "mov v0, va1"  // copy uv
        //"mov vt0, va0\n"+
        //"m44 op, vt0, vc0\n"+
        "nrm vt1.xyz, va0.xyz\n"+
        "mov vt1.w, va0.w\n"+   
        "mov v1, vt1\n" +
        "mov v2, va1"

    private const FRAGMENT_SHADER_LIGHT:String = 
        "tex ft1, v0, fs0 <2d,linear,nomip>\n" +
        "mov oc, ft1 \n" + 
        "dp3 ft1, fc2, v1 \n"+
        "neg ft1, ft1 \n"+
        "max ft1, ft1, fc0 \n"+
        "mul ft2, fc4, ft1 \n"+
        "mul ft2, ft2, fc3 \n"+
        "add oc, ft2, fc1";

但它给了我一个错误: “错误:错误 #3632:AGAL 链接:可变 1 在片段着色器中被读取,但未被顶点着色器写入。 在 flash.display3D::Program3D/upload() 在 Context3DExample/setupScene() 在 Context3DExample/contextCreated()"

我相信有经验的人可以在 5 分钟内解决这个问题。 谢谢

【问题讨论】:

    标签: stage3d


    【解决方案1】:

    看起来你忘了连接一个字符串,即

    "mov v0, va1"  // copy uv
    "nrm vt1.xyz, va0.xyz\n"
    

    应该是

    "mov v0, va1\n" +  // copy uv
    "nrm vt1.xyz, va0.xyz\n"
    

    注意第一行有额外的\n+

    【讨论】:

    • 谢谢,现在我没有收到错误消息并且它可以工作,我看到了灯光效果,但我没有获得纹理贴图,不知何故颜色覆盖了纹理。如果我取出一些代码,只留下代码的前 2 行:"tex ft1, v0, fs0 \n" + "mov oc, ft1";又看到贴图了,但是光效没了,怎么办?
    • 我已经很久没有在闪存中编程了,所以我没有 100% 记得。试试这个private const FRAGMENT_SHADER_LIGHT:String = "tex ft0, v0, fs0 &lt;2d,linear,nomip&gt;\n" + "dp3 ft1, fc2, v1 \n"+ "neg ft1, ft1 \n"+ "max ft1, ft1, fc0 \n"+ "mul ft2, fc4, ft1 \n"+ "mul ft2, ft2, fc3 \n"+ "add ft3, ft2, fc1 \n" + "mul oc, ft0, ft3"; 但我看到了其他问题,例如法线应该在像素着色器中重新规范化。
    • 我使用了你的代码,但结果是一样的,可能是因为法线问题吗?因为如果我只使用两行代码 "tex ft1, v0, fs0 \n" + "mov oc, ft1";我确实看到了纹理,我认为法线是另一个问题,它们决定了模型是否看起来平滑。
    • 不,我不这么认为。你能告诉我你的片段常量是什么(fc 寄存器)吗?
    • renderContext.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, Vector.([0,0,0,0])); renderContext.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 1, Vector.([0,0,0,0])); renderContext.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 2, Vector.([p.x,p.y,p.z,1])); renderContext.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 3, Vector.([1, 1, 1, 1])); renderContext.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 4, Vector.([0.6, 0.6, 0.6, 1]) );
    【解决方案2】:

    在这里找到答案是代码(基于下面的nikitablack答案):

            private const VERTEX_SHADER_LIGHT:String = "" +
    
            "m44 op, va0, vc0\n" +// pos to clipspace
            "mov v0, va1\n" +// pass uv
            "mov v1, va0"; // pas normal for vertex shader. 
    
    
        private const FRAGMENT_SHADER_LIGHT:String = "" +
    
        "tex ft0, v0, fs0 <2d,linear,nomip>\n" + // read from texture
        "nrm ft1.xyz, v1.xyz\n" + // renormalize normal
        "dp3 ft1, fc2.xyz, ft1.xyz \n" + // directional light contribution
        //"neg ft1, ft1 \n" + // negation because we have a vector "from" light 
        "max ft1, ft1, fc0 \n"+ // clamp to [0, dot]
        "mul ft1, ft1, fc3 \n"+ // contribution from light
        "mul ft1, ft1, ft0 \n"+ // contribution from light + texture
        //"add oc, ft1, fc1"; // final color as surface + ambient
        "add oc, ft1, ft0"; // final color as surface + texture
    

    我取出了“ft1 的否定”,无需在我的代码中否定这个 verctor,它是可以的。最后我没有添加环境色,只是再次添加纹理,因此它会变得明亮清晰,只有一点阴影。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-24
      相关资源
      最近更新 更多