Martin K
Martin K

Reputation: 825

AS3 Stage3D Fragment Shader?

Can someone tell me whats the difference between these 2 fragment shaders:

// Adobe's GPUSprite Fragment Shader 
"tex ft0, v0, fs0 <2d,clamp,linear,mipnearest> \n" + 
"mul ft0, ft0, v0.zzzz\n" +  // multiply with alpha?? 
"mov oc, ft0 \n"

// Node2D Fragment Shader 
"tex ft0, v0, fs0 <2d,clamp,linear,mipnearest> \n" + 
"mul ft0, ft0, fc0\n" + // this line is different
"mov oc, ft0 \n" 

Only the second line is different, where we multiply it with alpha. As a result, the second shader(Node2D) allows you to pass in a master alpha value via a setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, [1,1,1,1]); call, which will result in all triangles to be drawn with that alpha.

1) Can someone tell me whats happening in that 2nd line?

2) What the above does in practice, is that it Overrides the individual alpha settings of each triange. What I would like instead is to Multiply its own alpha with the shader's, so that the final alpha value would be = Triangle_alpha * Shader_alpha.

(as it is now I cannot set a separate alpha value for specific triangles with the second shader. What I would like is to be able to set an alpha value for each triangle separately and also another for the entire drawTriangles call )

Upvotes: 1

Views: 933

Answers (1)

bwroga
bwroga

Reputation: 5449

I would like to revise my answer, because the original was not correct.

"mul ft0, ft0, v0.zzzz\n"

is multiplying the fragment RGBA by the third component of the value stored in Varying Register 0. This is probably the vertex coordinates, passed to the Fragment Shader from the Vertex Shader. This line should cause the the color to lighten, the farther away it is from the camera.

"mul ft0, ft0, fc0\n"

is multiplying the fragment RGBA by a RGBA value uploaded into the Fragment Constant 0. The lighter/more transparent the color in the constant is, the lighter/more transparent your final value will be.

If you only want to change the alpha, you could try:

"mul ft0.a, ft0.a, fc0.a\n"

If you want to just combine the alphas you could try adding instead of multiplying.

"add ft0.a, ft0.a, fc0.a\n"

You can specify separate alpha values for each triangle by putting an alpha component in each vertex. You could combine these values with the "global" alpha which you could store in a constant, before combining them with the Fragment Alpha. The only problem, is that you will have to duplicate vertices, if they have different alpha values.

So your vertices for an example triangle would go from:

var vertices:Vector.<Number> = Vector.<Number>([
    //x, y, z, w,
    0, 0, 0, 0,
    1, 0, 0, 0,
    0, 1, 0, 0,
]);

vertexBuffer:VertexBuffer3D = context3D.createVertexBuffer(3, 4);
vertexBuffer.uploadFromVector(vertices, 0, 3);

to:

var vertices:Vector.<Number> = Vector.<Number>([
    //x, y, z, w, a
    0, 0, 0, 0, 0.5,
    1, 0, 0, 0, 0.5,
    0, 1, 0, 0, 0.5,
]);

vertexBuffer:VertexBuffer3D = context3D.createVertexBuffer(3, 5);
vertexBuffer.uploadFromVector(vertices, 0, 3);

Then you would pass the alpha value from your Vertex Shader to your Fragment Shader through a Varying Register, where you can make use of it.

Upvotes: 1

Related Questions