Ошибка Stage3D № 3632: связь AGAL: вариант 1 считывается во фрагментном шейдере, но не записывается вершинным шейдером

Я новичок в АГАЛе, уверен это не сложно.

У меня есть вершинный и фрагментный шейдер, для простого рисования коробки с текстурой без светового эффекта, вот код:

            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";

Вопрос в том, как мне объединить 2 кода, я хочу модель коробки с текстурной картой, чтобы показать световой эффект.

Я сделал это:

        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 минут. Спасибо


person Shai Quantz    schedule 11.05.2016    source источник


Ответы (2)


Похоже, вы забыли объединить строку, т.е.

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

должно быть

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

Обратите внимание на дополнительные \n и + в первой строке.

person nikitablack    schedule 12.05.2016
comment
Спасибо, теперь я не получаю сообщения об ошибке, и это работает, я вижу световой эффект, но я не получаю текстурную карту, каким-то образом цвет перезаписывает текстуру. Если я уберу часть кода и оставлю только первые 2 строки кода: tex ft1, v0, fs0 ‹2d,linear,nomip›\n + mov oc, ft1; Я снова вижу текстуру, но световой эффект пропал, что мне делать? - person Shai Quantz; 12.05.2016
comment
Я давно не программировал во flash, поэтому на 100% не помню. Попробуйте это private const FRAGMENT_SHADER_LIGHT:String = "tex ft0, v0, fs0 <2d,linear,nomip>\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"; Но я вижу другие проблемы, например нормали должны быть перенормированы в пиксельных шейдерах. - person nikitablack; 12.05.2016
comment
Я использовал ваш код, но результат тот же, может ли это быть из-за проблемы с нормалями? потому что если я использую только 2 строки кода tex ft1, v0, fs0 ‹2d,linear,nomip›\n + mov oc, ft1; Я вижу текстуру, я думаю, что нормали - это еще одна проблема, они определяют, будет ли модель выглядеть гладкой или нет. - person Shai Quantz; 12.05.2016
comment
Нет, я так не думаю. Можете ли вы сказать мне, каковы ваши константы фрагмента (регистр fc)? - person nikitablack; 12.05.2016
comment
renderContext.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, Vector.‹Number›([0,0,0,0])); renderContext.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 1, Vector.‹Number›([0,0,0,0])); renderContext.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 2, Vector.‹Number›([px,py,pz,1])); renderContext.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 3, Vector.‹Number›([1, 1, 1, 1])); renderContext.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 4, Vector.‹Number›([0.6, 0.6, 0.6, 1]) ); - person Shai Quantz; 13.05.2016
comment
Попробуйте этот 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 для вершинного шейдера. - person nikitablack; 13.05.2016
comment
И это и и 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 для фрагментных шейдеров. Я добавил комментарии sj, вы должны понять, если это не работает. - person nikitablack; 13.05.2016
comment
Спасибо за код, я попробовал, но результат остался прежним, я могу выслать вам весь код, если у вас есть время посмотреть его, можно ли загрузить весь код? это немного долго. - person Shai Quantz; 14.05.2016
comment
вот ссылка на код, если кому интересно посмотреть: drive.google.com/file/d/0Bw_t4cDR6CFBRmpmaGd1cmdRWc/ - person Shai Quantz; 15.05.2016
comment
Я вынул одну строчку: neg ft1, ft1\n+ и теперь я вижу текстуру и видно эффект нормлов, но темно. - person Shai Quantz; 18.05.2016

Найденный здесь ответ - это код (на основе ответа 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», нет необходимости отрицать этот вектор в моем коде, все в порядке. и я не добавляла окружающий цвет в конце, только еще раз текстуру, чтобы она стала яркой и четкой, с небольшим затенением.

person Shai Quantz    schedule 19.05.2016