Phaser 2 - Opacity

Discuss issues pertaining to the various game/web runtimes of Creature here.
Post Reply
anjey
Posts: 5
Joined: Tue Apr 23, 2019 1:35 pm

Phaser 2 - Opacity

Post by anjey » Fri Apr 26, 2019 5:35 am

Hello again,
first of all I wanted to thank you for the help on adding overlapping animations.

We are implementing creature into our framework(based on phaser 2) and noticed one further regression we would like fix.
Currently region opacity is not running properly. I have searched a lot and actually found a thread that is a few years old, but onfortunately I was not able to fix it yet. That's why I open this thread. Hopefully you can guide me a bit.

The main problem I see is currently, that the alpha is not properly send to the vertex shader.

Here is how the relevant parts currently look like in the phaser source code:


This is the update Render method. At the bottom the alpha calculated and stored in colors. But this colors is not properly send to the vertex shader.

Code: Select all

Phaser.Creature.prototype.updateRenderData = function (verts, uvs)
{

   ... UV and VERT calculation not displayed here ...
	
	// Update colour/opacity region values
	var render_composition =
    	target.render_composition;
	var regions_map =
	    render_composition.getRegionsMap();
	for(region_name in regions_map)
	{
		var cur_region = regions_map[region_name];
		var start_pt_idx = cur_region.getStartPtIndex();
		var end_pt_idx = cur_region.getEndPtIndex();
		var cur_opacity = cur_region.opacity * 0.01;
				
		for(var i = (start_pt_idx * 3); i <= (end_pt_idx * 3); i++)
		{
			this.colors[i] = cur_opacity;
		}
	}

};
The framgment and vertex shader looks like this. When overriding the alpha in the vertexSrc, the alpha is set. But for all regions. So general shader seems to function. The alpha is not send properly from the updateRenderData. Or something is not hooked up correctly.

Code: Select all

    this.fragmentSrc = [
        '//CreatureShader Fragment Shader.',
        'precision mediump float;',
        'varying vec2 vTextureCoord;',
        'varying float vTextureIndex;',
        'varying vec4 vColor;',

        // 'uniform float alpha;',
        // 'uniform vec3 tint;',
        'uniform sampler2D uSampler;',
        'void main(void) {',
        '   gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;',
        '}'
    ];

Code: Select all

    this.vertexSrc = [
        '//CreatureShader Vertex Shader.',
        'attribute vec2 aVertexPosition;',
        'attribute vec2 aTextureCoord;',
        'attribute float aTextureIndex;',
        'uniform mat3 translationMatrix;',
        'uniform vec2 projectionVector;',
        'uniform vec2 offsetVector;',
        'uniform float alpha;',
        'uniform vec3 tint;',
        'varying vec2 vTextureCoord;',
        'varying float vTextureIndex;',
        'varying vec4 vColor;',

        'void main(void) {',
        '   vec3 v = translationMatrix * vec3(aVertexPosition , 1.0);',
        '   v -= offsetVector.xyx;',
        '   gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);',
        '   vTextureCoord = aTextureCoord;',
        '   vTextureIndex = aTextureIndex;',
        '   vColor = vec4(tint[0], tint[1], tint[2], 1.0) * alpha;',
        '}'
    ];
And here is the CreatureShader init function.

Code: Select all

PIXI.CreatureShader.prototype.init = function ()
{
    var gl = this.gl;
    var program = PIXI.compileProgram(gl, this.vertexSrc, this.fragmentSrc);
    gl.useProgram(program);

    // get and store the uniforms for the shader
    this.uSampler = PIXI._enableMultiTextureToggle ?
        gl.getUniformLocation(program, 'uSamplerArray[0]') :
        gl.getUniformLocation(program, 'uSampler');


    this.projectionVector = gl.getUniformLocation(program, 'projectionVector');
    this.offsetVector = gl.getUniformLocation(program, 'offsetVector');
    this.colorAttribute = gl.getAttribLocation(program, 'aColor');
    this.aTextureIndex = gl.getAttribLocation(program, 'aTextureIndex');

    // this.dimensions = gl.getUniformLocation(this.program, 'dimensions');

    // get and store the attributes
    this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition');
    this.aTextureCoord = gl.getAttribLocation(program, 'aTextureCoord');

    this.attributes = [ this.aVertexPosition, this.aTextureCoord, this.aTextureIndex ];

    this.translationMatrix = gl.getUniformLocation(program, 'translationMatrix');
    this.alpha = gl.getUniformLocation(program, 'alpha');
    this.tintColor = gl.getUniformLocation(program, 'tint');

    this.program = program;
};

Code: Select all

Phaser.Creature.prototype._initWebGL = function (renderSession)
{

    // build the strip!
    var gl = renderSession.gl;

    this._vertexBuffer = gl.createBuffer();
    this._indexBuffer = gl.createBuffer();
    this._uvBuffer = gl.createBuffer();
    this._colorBuffer = gl.createBuffer();

    gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, this.vertices, gl.DYNAMIC_DRAW);

    gl.bindBuffer(gl.ARRAY_BUFFER, this._uvBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, this.uvs, gl.DYNAMIC_DRAW);

    gl.bindBuffer(gl.ARRAY_BUFFER, this._colorBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, this.colors, gl.STATIC_DRAW);

    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indexBuffer);
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW);

};

I would really appreciate if you may have a look. Maybe you spot the problem. I am not very familiar with writing shader. Especially hooking everything up.

chong
Posts: 1006
Joined: Thu Feb 19, 2015 2:21 am

Re: Phaser 2 - Opacity

Post by chong » Fri Apr 26, 2019 6:28 am

Hello,

I took a quick look at the code you posted.
The issue seems to be that in their vertex shader code, the per vertex colour is actually not properly passed in.

In the vertex shader code, the final vertex colour is computed as:
vColor = vec4(tint[0], tint[1], tint[2], 1.0) * alpha;',

This is incorrect as it does not take into account of the actual per vertex colour for every vertex of the Creature mesh.
The vertex shader they declared ( I did not write this part, it was provided by the Phaser team ) is such:

'attribute vec2 aVertexPosition;',
'attribute vec2 aTextureCoord;',
'attribute float aTextureIndex;',

Notice it does not have an input attribute for any per vertex colours coming in, only the vertex position, texture coordinate and texture index are considered.
Hence, it will seem like you will need to add in a line to also take in a per vertex colour attribute input just like what they are doing for the vertex position. After that, the vColor should be computed based on the input colour instead of the tint and alpha like what it is doing right now. You will get the correct alpha directly from the input per vertex colour attribute if it is correctly declared and the data flows through.
Hope my analysis helps and sends you on the right path.

Thanks

anjey
Posts: 5
Joined: Tue Apr 23, 2019 1:35 pm

Re: Phaser 2 - Opacity

Post by anjey » Tue Apr 30, 2019 9:10 am

Hi Chong,
thanks for your help.

I was able to fix the issue for our case. I also submitted a pull request to the phaser ce github repo. It has been merged now and will be available in future phaser ce releases.

chong
Posts: 1006
Joined: Thu Feb 19, 2015 2:21 am

Re: Phaser 2 - Opacity

Post by chong » Tue Apr 30, 2019 3:52 pm

Wow fantastic job! This is amazing news and thank you for your hard work!

Cheers

Post Reply