使用WebGL2使用alpha混合渲染到帧缓冲区时的人工制品

使用WebGL2使用alpha混合渲染到帧缓冲区时的人工制品,webgl,webgl2,Webgl,Webgl2,我正在尝试使用WebGL2绘制2D元球。我使用透明的径向渐变和gl.blendFunc(gl.SRC_ALPHA,gl.ONE_减去2.5?2.5:devicePixelRatio 如果(!gl){ showWebGL2NotSupported() } 常量lineVertexArrayObject=gl.createVertexArray() 常量quadVertexArrayObject=gl.createVertexArray() 常量ballsVertexArrayObject=gl.c

我正在尝试使用WebGL2绘制2D元球。我使用透明的径向渐变和
gl.blendFunc(gl.SRC_ALPHA,gl.ONE_减去
将一组四边形渲染到一个单独的帧缓冲区。然后,我在全屏四边形中使用生成的纹理,在这里我根据像素的alpha值决定是否渲染像素,如下所示:

vec4 inputColor=纹理(u_纹理,v_uv);
浮动截止阈值=0.14;
浮点截止=步长(截止阈值,inputColor.a);
浮动阈值=0.005;
outputColor=mix(
vec4(1,0,0,1),
vec4(0,0,1,1),
切断
);
虽然这种方法可行,但它在边缘产生了非常明显的人工制品:

我认为问题在于我的混合操作。我尝试仅在绘制到帧缓冲区时启用混合,而在渲染主四边形时禁用混合,但没有取得多大成功

这是我的节目:

const-CONFIG={
鲍尔斯坎特:10,
ballRadius:isMobileBrowser()?75:200,
重力:0.1,
线宽:innerWidth/2,
startVelocityX:{min:0,max:0.1},
startVelocityY:{min:1,max:3},
}
const contentWrapper=document.querySelector(“.content”)
const canvas=document.createElement('canvas')
const gl=canvas.getContext('webgl2')
const dpr=设备固定比率>2.5?2.5:devicePixelRatio
如果(!gl){
showWebGL2NotSupported()
}
常量lineVertexArrayObject=gl.createVertexArray()
常量quadVertexArrayObject=gl.createVertexArray()
常量ballsVertexArrayObject=gl.createVertexArray()
常量ballsofsetsbuffer=gl.createBuffer()
设oldTime=0
设lineAngle=0
//WebGL程序
让我们来看看这个程序
让我们来看看这个程序
让我们来看看程序
让我们来讨论一下
让lineAngleUniformLoc
让lineVertexArray
让Ballsofsetsarray
//不用于渲染,只存储球的速度
让巴尔斯韦洛西蒂去吧
/*------创建水平线WebGL程序------*/
{
const vertexShader=makeWebglShader(gl{
着色器类型:gl.VERTEX\u着色器,
shaderSource:`#版本300 es
均匀mat4u_投影矩阵;
均匀vec2u_分辨率;
均匀浮动u_角;
在vec4 a_位置;
mat4旋转Z(以浮动角度){
返回mat4(
cos(角度),sin(角度),0.0,0.0,
sin(角度)、cos(角度)、0.0、0.0、,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0
);
}
空干管(){
gl_位置=u_投影矩阵*(旋转Z(u_角度)*a_位置+vec4(u_分辨率.xy/2.0,0.0,1.0));
}
`,
})
常量fragmentShader=makeWebglShader(gl{
着色器类型:gl.FRAGMENT\u着色器,
shaderSource:`#版本300 es
高精度浮点;
输出vec4输出颜色;
空干管(){
outputColor=vec4(0,0,1,1);
}
`,
})
lineWebGLProgram=makeWebglProram(gl{
顶点着色器,
碎片着色器,
})
}
/*------创建并指定水平线WebGL属性------*/
{
lineVertexArray=newfloat32array([-CONFIG.lineWidth/2,0,CONFIG.lineWidth/2,0])
const vertexBuffer=gl.createBuffer()
常量a_position=gl.getAttriblLocation(lineWebGLProgram,“a_position”)
总账bindVertexArray(lineVertexArrayObject)
gl.bindBuffer(gl.ARRAY\u BUFFER,vertexBuffer)
总账缓冲数据(总账数组缓冲区、lineVertexArray、总账静态绘图)
gl.EnableVertexAttributeArray(a_位置)
gl.VertexAttribute指针(a_位置,2,gl.FLOAT,false,0,0)
总账bindVertexArray(空)
}
/*------创建metaballs WebGL程序------*/
{
const vertexShader=makeWebglShader(gl{
着色器类型:gl.VERTEX\u着色器,
shaderSource:`#版本300 es
均匀mat4u_投影矩阵;
在vec4 a_位置;
在vec4 a_偏置位置;
在vec2a_-uv中;
输出vec2v_-uv;
空干管(){
vec4校正偏移位置=a_偏移位置+a_位置;
gl_位置=u_投影矩阵*校正偏移检测位置;
v_uv=a_uv;
}
`
})
常量fragmentShader=makeWebglShader(gl{
着色器类型:gl.FRAGMENT\u着色器,
shaderSource:`#版本300 es
高精度浮点;
在vec2v_-uv中;
输出vec4输出颜色;
空干管(){
浮动距离=距离(v_uv,vec2(0.5));
浮点数c=0.5-距离;
outputColor=vec4(vec3(1.0),c);
}
`
})
ballsWebGLProgram=MAKEWEBGGLPRORAM(总帐{
顶点着色器,
碎片着色器,
})
}
/*------创建并分配metaballs WebGL属性------*/
{
const vertexArray=新的浮点数组([
-CONFIG.ballRadius/2,CONFIG.ballRadius/2,
CONFIG.ballRadius/2,CONFIG.ballRadius/2,
CONFIG.ballRadius/2,-CONFIG.ballRadius/2,
-CONFIG.ballRadius/2,CONFIG.ballRadius/2,
CONFIG.ballRadius/2,-CONFIG.ballRadius/2,
-CONFIG.ballRadius/2,-CONFIG.ballRadius/2
])
常量uvsArray=makeQuadUVs()
ballsofsetsarray=新Float32Array(CONFIG.ballscont*2)
ballsVelocitiesArray=新Float32Array(CONFIG.ballscont*2)
for(设i=0;i    float dist = distance(v_uv, vec2(0.5));
    float c = 0.5 - dist;
    float dist = distance(v_uv, vec2(0.5)) * 2.0;
    float c = 1.0 - dist;