Premultiplied Alpha = false

by Gregg Tavares

HTML

<script src="http://greggman.github.com/webgl-fundamentals/webgl/resources/webgl-utils.js"></script>
<script id="vshader" type="whatever">
    attribute vec4 a_position;
    varying vec2 v_texcoord;
    void main() {
      gl_Position = a_position;
    
      // assuming a unit quad for position we
      // can just use that for texcoords. Flip Y though so we get the top at 0
      v_texcoord = a_position.xy * vec2(0.5, -0.5) + 0.5;
    }    
</script>
<script id="fshader" type="whatever">
precision mediump float;
uniform bool u_premultiply;
varying vec2 v_texcoord;

#define PI 3.14159
    
void main() {
    float alpha = sin(v_texcoord.x * PI) * sin(v_texcoord.y * PI);
    vec4 color = vec4(1, 0, 0, alpha);
    if (u_premultiply) {
      color = vec4(color.rgb * color.a, color.a);
    }
    gl_FragColor = color;
}
</script>
<table>
    <tr>
        <td>canvas: premultipliedAlpha: true<br/>
            data: not premultiplied</td>
        <td>canvas: premultipliedAlpha: false<br/>
            data: not premultiplied</td></tr>
    <tr>
        <td><canvas id="1" width="256" height="256"></canvas></td>
        <td><canvas id="2" width="256" height="256"></canvas></td>
    </tr>
    <tr>
        <td>canvas: premultipliedAlpha: true<br/>
            data: premultiplied</td>
        <td>canvas: premultipliedAlpha: false<br/>
            data: premultiplied</td></tr>
    <tr>
        <td><canvas id="3" width="256" height="256"></canvas></td>
        <td><canvas id="4" width="256" height="256"></canvas></td>
    </tr>
</table>

CSS

body { background-color: green; }
canvas { border: 1px solid black; }

JavaScript

render(document.getElementById("1"));
render(document.getElementById("2"), { premultipliedAlpha: false });
render(document.getElementById("3"), undefined, true);
render(document.getElementById("4"), { premultipliedAlpha: false }, true);

function render(canvas, opt_attribs, premultiplyInShader) {
    var gl = getWebGLContext(canvas, opt_attribs);
    if (!gl) {
        alert("no WebGL");
        return;
    }
    
    // Note: createProgramFromScripts will call bindAttribLocation
    // based on the index of the attibute names we pass to it.
    var program = createProgramFromScripts(
        gl, 
        ["vshader", "fshader"], 
        ["a_position"]);
    gl.useProgram(program);
    
    if (premultiplyInShader) {
        var loc = gl.getUniformLocation(program, "u_premultiply");
        gl.uniform1i(loc, 1);
    }
    
    // Setup a unit quad
    var positions = [
          1,  1,  
         -1,  1,  
         -1, -1,  
          1,  1,  
         -1, -1,  
          1, -1,  
    ];
    var vertBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, vertBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
    gl.enableVertexAttribArray(0);
    gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
    
    gl.drawArrays(gl.TRIANGLES, 0, positions.length / 2);
}