簡體   English   中英

原語的Regl顏色和alpha混合

[英]Regl color and alpha blending of primitives

我試圖弄清楚如何使用Regl實現基元之間的顏色和alpha混合。

我知道Regl命令具有blend屬性,並且我嘗試過復制以下實現該技巧的webgl設置:

gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);

在Regl中使用以下blend設置:

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代碼所產生的混合呢? 謝謝!

多虧了這個好答案,我才知道:

簡而言之,需要調整混合功能,並且需要禁用深度測試。 (但是我仍然不知道為什么在普通WebGL示例中可用的blend函數在Regl中不起作用)

  1. 使用以下混合模式

     blend: { enable: true, func: { srcRGB: 'src alpha', srcAlpha: 'src alpha', dstRGB: 'one minus src alpha', dstAlpha: 'one minus src alpha', }, }, 
  2. 禁用深度測試

     depth: { enable: false }, 

這是我問題的固定示例: http : //jsfiddle.net/8gyf7pek/22/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM