需要从三个颜色顶点创建平滑的 Alpha 过渡,而不会中断。我做错了什么。
https://jsfiddle.net/Lm208gjq/
var vertexShaderText =
[
'precision mediump float;',
'',
'attribute vec2 vertPosition;',
'attribute vec4 vertColor;',
'varying vec4 fragColor;',
'',
'void main()',
'{',
' fragColor = vertColor;',
' gl_Position = vec4(vertPosition, 0.0, 1.0);',
'}'
].join('\n');
var fragmentShaderText =
[
'precision mediump float;',
'',
'varying vec4 fragColor;',
'void main()',
'{',
' gl_FragColor = fragColor;',
'}'
].join('\n');
var InitDemo = function () {
console.log('This is working');
var canvas = document.getElementById('opengl_output');
var gl = canvas.getContext('webgl');
if (!gl) {
console.log('WebGL not supported, falling back on experimental-webgl');
gl = canvas.getContext('experimental-webgl');
}
if (!gl) {
alert('Your browser does not support WebGL');
}
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
//
// Create shaders
//
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(vertexShader, vertexShaderText);
gl.shaderSource(fragmentShader, fragmentShaderText);
gl.compileShader(vertexShader);
if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
console.error('ERROR compiling vertex shader!', gl.getShaderInfoLog(vertexShader));
return;
}
gl.compileShader(fragmentShader);
if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
console.error('ERROR compiling fragment shader!', gl.getShaderInfoLog(fragmentShader));
return;
}
var program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
console.error('ERROR linking program!', gl.getProgramInfoLog(program));
return;
}
gl.validateProgram(program);
if (!gl.getProgramParameter(program, gl.VALIDATE_STATUS)) {
console.error('ERROR validating program!', gl.getProgramInfoLog(program));
return;
}
//
// Create buffer
//
var triangleVertices =
[ // X, Y, R, G, B, A
0.0, 0.5, 1.0, 0.0, 0.0, 1.0,
-0.5, -0.5, 0.0, 1.0, 0.0, 0.0001,
0.5, -0.5, 0.0, 0.0, 1.0, 1.0
];
var triangleVertexBufferObject = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexBufferObject);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(triangleVertices), gl.STATIC_DRAW);
var positionAttribLocation = gl.getAttribLocation(program, 'vertPosition');
var colorAttribLocation = gl.getAttribLocation(program, 'vertColor');
gl.vertexAttribPointer(
positionAttribLocation, // Attribute location
2, // Number of elements per attribute
gl.FLOAT, // Type of elements
gl.FALSE,
6 * Float32Array.BYTES_PER_ELEMENT, // Size of an individual vertex
0 // Offset from the beginning of a single vertex to this attribute
);
gl.vertexAttribPointer(
colorAttribLocation, // Attribute location
4, // Number of elements per attribute
gl.FLOAT, // Type of elements
gl.FALSE,
6 * Float32Array.BYTES_PER_ELEMENT, // Size of an individual vertex
2 * Float32Array.BYTES_PER_ELEMENT // Offset from the beginning of a single vertex to this attribute
);
gl.enable(gl.BLEND);
gl.blendFunc(gl.ONE, gl.ZERO);
gl.enableVertexAttribArray(positionAttribLocation);
gl.enableVertexAttribArray(colorAttribLocation);
//
// Main render loop
//
gl.useProgram(program);
gl.drawArrays(gl.TRIANGLES, 0, 3);
};
InitDemo();
<canvas id="opengl_output" width="640" height="480"></canvas>
为什么这段代码会产生另一个三 Angular 形?
我是 webgl 编程的新手,这可能是一些简单的事情,我尝试更改属性缓冲区但没有成功。
最佳答案
默认的 Alpha 合成是 premultiplied alpha 。
您必须禁用premultipliedAlpha
,
var gl = canvas.getContext('webgl', { premultipliedAlpha: false });
或者您必须在片段着色器中将 RGB 颜色 channel 乘以 ALPHA channel :
gl_FragColor = vec4(fragColor.rgb * fragColor.a, fragColor.a);
参见WebGLFundamentals - WebGL and Alpha
var vertexShaderText =
[
'precision mediump float;',
'',
'attribute vec2 vertPosition;',
'attribute vec4 vertColor;',
'varying vec4 fragColor;',
'',
'void main()',
'{',
' fragColor = vertColor;',
' gl_Position = vec4(vertPosition, 0.0, 1.0);',
'}'
].join('\n');
var fragmentShaderText =
[
'precision mediump float;',
'',
'varying vec4 fragColor;',
'void main()',
'{',
' gl_FragColor = vec4(fragColor.rgb * fragColor.a, fragColor.a);',
'}'
].join('\n');
var InitDemo = function () {
console.log('This is working');
var canvas = document.getElementById('opengl_output');
var gl = canvas.getContext('webgl' /*, { premultipliedAlpha: false }*/);
if (!gl) {
console.log('WebGL not supported, falling back on experimental-webgl');
gl = canvas.getContext('experimental-webgl' /*, { premultipliedAlpha: false }*/);
}
if (!gl) {
alert('Your browser does not support WebGL');
}
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
//
// Create shaders
//
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(vertexShader, vertexShaderText);
gl.shaderSource(fragmentShader, fragmentShaderText);
gl.compileShader(vertexShader);
if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
console.error('ERROR compiling vertex shader!', gl.getShaderInfoLog(vertexShader));
return;
}
gl.compileShader(fragmentShader);
if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
console.error('ERROR compiling fragment shader!', gl.getShaderInfoLog(fragmentShader));
return;
}
var program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
console.error('ERROR linking program!', gl.getProgramInfoLog(program));
return;
}
gl.validateProgram(program);
if (!gl.getProgramParameter(program, gl.VALIDATE_STATUS)) {
console.error('ERROR validating program!', gl.getProgramInfoLog(program));
return;
}
//
// Create buffer
//
var triangleVertices =
[ // X, Y, R, G, B, A
0.0, 0.5, 1.0, 0.0, 0.0, 1.0,
-0.5, -0.5, 0.0, 1.0, 0.0, 0.0001,
0.5, -0.5, 0.0, 0.0, 1.0, 1.0
];
var triangleVertexBufferObject = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexBufferObject);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(triangleVertices), gl.STATIC_DRAW);
var positionAttribLocation = gl.getAttribLocation(program, 'vertPosition');
var colorAttribLocation = gl.getAttribLocation(program, 'vertColor');
gl.vertexAttribPointer(
positionAttribLocation, // Attribute location
2, // Number of elements per attribute
gl.FLOAT, // Type of elements
gl.FALSE,
6 * Float32Array.BYTES_PER_ELEMENT, // Size of an individual vertex
0 // Offset from the beginning of a single vertex to this attribute
);
gl.vertexAttribPointer(
colorAttribLocation, // Attribute location
4, // Number of elements per attribute
gl.FLOAT, // Type of elements
gl.FALSE,
6 * Float32Array.BYTES_PER_ELEMENT, // Size of an individual vertex
2 * Float32Array.BYTES_PER_ELEMENT // Offset from the beginning of a single vertex to this attribute
);
gl.enable(gl.BLEND);
gl.blendFunc(gl.ONE, gl.ZERO);
gl.enableVertexAttribArray(positionAttribLocation);
gl.enableVertexAttribArray(colorAttribLocation);
//
// Main render loop
//
gl.useProgram(program);
gl.drawArrays(gl.TRIANGLES, 0, 3);
};
InitDemo();
<canvas id="opengl_output" width="640" height="480"></canvas>
关于javascript - 我需要在 webgl 中创建平滑的 alpha 过渡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58843463/