1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
| function drawIntersection(meshA, meshB) {
// write A in depth buffer
gl.colorMask(false, false, false, false);
meshA.draw(gl);
// increment stencil each fragment where B is in front of A
gl.depthMask(false);
gl.disable(gl.CULL_FACE);
gl.stencilOp(gl.KEEP, gl.KEEP, gl.INCR);
meshB.draw(gl);
// draw A where B hides it once
gl.colorMask(true, true, true, true);
gl.enable(gl.CULL_FACE);
gl.depthFunc(gl.ALWAYS);
gl.stencilFunc(gl.EQUAL, 1, 1);
gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
meshA.draw(gl);
// reset buffer behavior
gl.stencilFunc(gl.ALWAYS, 0, 0);
gl.depthMask(true);
gl.depthFunc(gl.LESS);
};
function drawSubtraction(meshA, meshB) {
// write back of A in depth and stencil
gl.colorMask(false, false, false, false);
gl.cullFace(gl.FRONT);
gl.stencilOp(gl.KEEP, gl.KEEP, gl.INCR);
meshA.draw(gl);
// draw back of B where it hides backside of A
gl.colorMask(true, true, true, true);
gl.uniform1f(shader.normalDirectionUniform, -1.0);
gl.stencilFunc(gl.EQUAL, 1, 1);
meshB.draw(gl);
// draw front of A where it is falsly hiden by back of B
gl.cullFace(gl.BACK);
gl.uniform1f(shader.normalDirectionUniform, 1.0);
gl.stencilFunc(gl.EQUAL, 2, 2);
gl.depthFunc(gl.GREATER);
meshA.draw(gl);
gl.clear(gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
// write front of B in depth
gl.stencilFunc(gl.ALWAYS, 0, 0);
gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
gl.depthFunc(gl.LESS);
gl.colorMask(false, false, false, false);
meshB.draw(gl);
// draw front of A
gl.colorMask(true, true, true, true);
meshA.draw(gl);
}; |
Partager