我试图弄清楚如何使用Regl实现基元之间的颜色和 alpha 混合。
我知道 Regl 命令有一个blend
属性,并且我尝试复制以下 webgl 设置来解决问题:
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
blend
在 Regl 中使用以下设置:
blend: {
enable: true,
func: { src: 'src alpha', dst:'one minus src alpha' }
},
但是混合似乎只对背景颜色起作用,而不是在点之间。(请参见下面的示例。)
示例:http: //jsfiddle.net/8gyf7pek/13/
const canvas1 = document.querySelector('#c1');
const canvas2 = document.querySelector('#c2');
//////////////////////////////////////////////
// PURE WEBGL
//////////////////////////////////////////////
const gl = canvas1.getContext('webgl');
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
const vertexShaderSource = `
attribute vec2 position;
attribute vec4 color;
varying vec4 v_color;
void main() {
gl_PointSize = 50.0;
gl_Position = vec4(position, 0, 1);
v_color = color;
}
`;
const fragmentShaderSource = `
precision mediump float;
varying vec4 v_color;
void main() {
gl_FragColor = v_color;
}
`;
const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
const program = createProgram(gl, vertexShader, fragmentShader);
gl.useProgram(program);
const positionAttributeLocation = gl.getAttribLocation(program, 'position');
const colorAttributeLocation = gl.getAttribLocation(program, 'color');
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.enableVertexAttribArray(positionAttributeLocation);
gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
const colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.enableVertexAttribArray(colorAttributeLocation);
gl.vertexAttribPointer(colorAttributeLocation, 4, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
-0.05, -0.05, -0.05, 0.05, 0.05, 0.05, 0.05, -0.05,
]), gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
const red = [1, 0, 0, 0.5];
const blue = [0, 0, 1, 0.5];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
...red, ...red,
...blue, ...blue,
]), gl.STATIC_DRAW);
gl.drawArrays(gl.POINTS, 0, 4);
function createShader(gl, type, shaderSource) {
const shader = gl.createShader(type);
gl.shaderSource(shader, shaderSource);
gl.compileShader(shader);
const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
if(!success) {
console.warn(gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
}
return shader;
}
function createProgram(gl, vertexShader, fragmentShader) {
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
const success = gl.getProgramParameter(program, gl.LINK_STATUS);
if(!success) {
console.log(gl.getProgramInfoLog(program));
gl.deleteProgram(program);
}
return program;
}
//////////////////////////////////////////////
// REGL
//////////////////////////////////////////////
const regl = createREGL(canvas2);
regl.clear({ color: [0, 0, 0, 0], depth: 1 });
regl({
frag: `
precision mediump float;
varying vec4 fragColor;
void main () {
gl_FragColor = fragColor;
}`,
vert: `
precision mediump float;
attribute vec2 position;
attribute vec4 color;
varying vec4 fragColor;
uniform float pointWidth;
void main () {
fragColor = color;
gl_PointSize = pointWidth;
gl_Position = vec4(position, 0, 1);
}`,
attributes: {
position: [
[-0.05, -0.05],
[-0.05, 0.05],
[0.05, -0.05],
[0.05, 0.05],
],
color: [
[1, 0, 0, 0.5],
[1, 0, 0, 0.5],
[0, 0, 1, 0.5],
[0, 0, 1, 0.5]
],
},
uniforms: {
pointWidth: 50,
},
blend: {
enable: true,
func: { src: 'src alpha', dst:'one minus src alpha' }
},
count: 4,
primitive: 'points',
})();
#bg {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
color: #808080;
background: black;
}
#c1, #c2 {
width: 240px;
height: 240px;
border: 1px solid white;
}
em {
display: block;
}
<div id="bg">
<canvas id="c1"></canvas>
<canvas id="c2"></canvas>
<em>Left is pure WebGL. Right is Regl.</em>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/regl/1.3.7/regl.min.js"></script>
难道我做错了什么?我怎样才能实现与纯 webgl 代码产生的相同类型的混合?谢谢!