【问题标题】:Can I access not premultiply color from renderer's shader我可以从渲染器的着色器中访问不预乘颜色吗
【发布时间】:2019-03-26 08:48:54
【问题描述】:

我使用的是 pixi.js 版本 4.8.2。 我不想从 pixi.js 应用程序中的渲染器着色器中访问预乘颜色。

我将透明设置为 'notMultiplied' ,但我可以访问预乘 rgb 颜色...

有没有办法访问不相乘的颜色?

我想为 GPGPU 使用纹理,所以我想访问纹理的原始 RGBA。

我把代码和结果放在这里。

// init with not multiply mode
    var app = new PIXI.Application(800, 600, {
      backgroundColor : 0xcccccc,
      transparent: 'notMultiplied'
    });
    document.body.appendChild(app.view);

    // draw circle graphics with red and alpha 0.5 ( drawn at display left )
    var graphic = new PIXI.Graphics();
    graphic.alpha = 0.5;
    graphic.beginFill(0xff0000);
    graphic.drawCircle(100,100,100);
    graphic.endFill();
    app.stage.addChild(graphic);

    // use graphics as a texture ( drawn at display right )
    var mesh = new PIXI.mesh.Mesh( graphic.generateCanvasTexture() );
    mesh.position.set(300,100);
    app.stage.addChild(mesh);

    // replace MeshRenderer shader for test premultiply effect
    app.renderer.plugins.mesh.shader = new PIXI.Shader(
      app.renderer.gl,
      // vertex shader is same as original MeshRender's one
      ` 
          attribute vec2 aVertexPosition;
          attribute vec2 aTextureCoord;

          uniform mat3 projectionMatrix;
          uniform mat3 translationMatrix;
          uniform mat3 uTransform;

          varying vec2 vTextureCoord;

          void main(void) {
              gl_Position = vec4((projectionMatrix * translationMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);
              vTextureCoord = (uTransform * vec3(aTextureCoord, 1.0)).xy;
          }
      `,

      // I changed change fragment shader for test
      `
          varying vec2 vTextureCoord;
          uniform vec4 uColor;
          uniform sampler2D uSampler;

          void main(void) {
              //gl_FragColor = texture2D(uSampler, vTextureCoord) * uColor; <- remove
              gl_FragColor = vec4(texture2D(uSampler, vTextureCoord).rgb, 1.0); 
          }
      `
    );

    // render graphics and mesh.
    app.render();
<html>
    <head>

    </head>
    <body>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.8.2/pixi.js"></script>
    </body>
 </html>

执行结果

理想的结果是这样的

【问题讨论】:

    标签: javascript glsl pixi.js


    【解决方案1】:

    如您所想,您的问题不是由预乘 alpha 引起的。 问题是由您设置的不透明度属性.alpha 引起的。

    graphic.alpha = 0.5;
    

    此属性应用于(相乘)到对象的所有颜色通道和 Alpha 通道。

    如果您不希望此属性影响红绿和蓝色通道,则必须在片段着色器中将 RGB 通道除以不透明度.alpha

    varying vec2 vTextureCoord;
    
    uniform vec4      uColor;
    uniform float     uAlpha;
    uniform sampler2D uSampler;
    
    void main(void) {
        vec4 texColor = texture2D(uSampler, vTextureCoord);
        gl_FragColor  = vec4(texColor.rgb / uAlpha, 1.0); 
    }
    

    看例子:

    var app = new PIXI.Application(800, 600, {
      backgroundColor : 0xcccccc,
      transparent: 'notMultiplied',
    });
    document.body.appendChild(app.view);
    
    var graphic = new PIXI.Graphics();
    graphic.alpha = 0.5;
    graphic.beginFill(0xff0000);
    graphic.drawCircle(100,100,100);
    graphic.endFill();
    app.stage.addChild(graphic);
    
    var mesh = new PIXI.mesh.Mesh( graphic.generateCanvasTexture() );
    mesh.position.set(300,100);
    app.stage.addChild(mesh);
    app.renderer.plugins.mesh.shader = new PIXI.Shader(
      app.renderer.gl,
      ` 
        attribute vec2 aVertexPosition;
        attribute vec2 aTextureCoord;
    
        uniform mat3 projectionMatrix;
        uniform mat3 translationMatrix;
        uniform mat3 uTransform;
    
        varying vec2 vTextureCoord;
    
        void main(void) {
            gl_Position   = vec4((projectionMatrix * translationMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);
            vTextureCoord = (uTransform * vec3(aTextureCoord, 1.0)).xy;
        }
      `,
      `
        varying vec2 vTextureCoord;
        
        uniform vec4      uColor;
        uniform float     uAlpha;
        uniform sampler2D uSampler;
    
        void main(void) {
            vec4 texColor = texture2D(uSampler, vTextureCoord);
            gl_FragColor  = vec4(texColor.rgb / uAlpha, 1.0); 
        }
      `
    );
    app.render();
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.8.2/pixi.min.js"&gt;&lt;/script&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多