我可以不从渲染器的着色器访问预乘颜色吗
Can I access not premultiply color from renderer's shader
我正在使用 pixi.js 版本 4.8.2。
我希望在 pixi.js 应用程序中访问渲染器的着色器而不是预乘颜色。
我设置的透明是'notMultiplied',但是我可以olny访问premultiplied 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>
执行结果
理想的结果是这样的
您的问题并非如您所想的那样是由预乘 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();
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.8.2/pixi.min.js"></script>
我正在使用 pixi.js 版本 4.8.2。 我希望在 pixi.js 应用程序中访问渲染器的着色器而不是预乘颜色。
我设置的透明是'notMultiplied',但是我可以olny访问premultiplied 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>
执行结果
理想的结果是这样的
您的问题并非如您所想的那样是由预乘 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();
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.8.2/pixi.min.js"></script>