html - WebGL - 使用网格作为倒置蒙版
问题描述
我需要将我的画布完全涂成黑色,除了必须保持透明以显示位于画布下方的页面内容的旋转立方体。画布应作为页面内容的掩码。
我认为我的问题可以归结为这个问题。stancil 解决方案将立方体转换为蒙版,我需要的是一个倒置蒙版。
有没有办法打印立方体外的所有东西并使立方体区域完全透明?
提前致谢。
解决方案
正如@pleup 所说,只需清除不透明的颜色,然后用透明的颜色绘制
网页浏览器
var geoVS = `
attribute vec4 position;
uniform mat4 matrix;
void main() {
gl_Position = matrix * position;
}
`;
var geoFS = `
precision mediump float;
void main() {
gl_FragColor = vec4(0);
}
`;
const m4 = twgl.m4;
const gl = document.querySelector("canvas").getContext("webgl", {
powerPreference: 'low-power',
});
const prgInfo = twgl.createProgramInfo(gl, [geoVS, geoFS]);
const bufferInfo = twgl.primitives.createCubeBufferInfo(gl, 1);
function render(time) {
time *= 0.001;
twgl.resizeCanvasToDisplaySize(gl.canvas);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
var fov = Math.PI * .25;
var aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
var zNear = 0.1;
var zFar = 10;
var mat = m4.perspective(fov, aspect, zNear, zFar);
mat = m4.translate(mat, [0, 0, -2]);
mat = m4.rotateX(mat, time * 0.81);
mat = m4.rotateZ(mat, time * 0.77);
// draw geometry to generate stencil
gl.useProgram(prgInfo.program);
twgl.setBuffersAndAttributes(gl, prgInfo, bufferInfo);
twgl.setUniforms(prgInfo, {
matrix: mat,
});
gl.drawElements(gl.TRIANGLES, bufferInfo.numElements, gl.UNSIGNED_SHORT, 0);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
html, body {
margin: 0;
height: 100%;
font-size: xx-large;
}
canvas {
position: fixed;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
display: block;
pointer-events: none;
}
<script src="https://twgljs.org/dist/3.x/twgl-full.min.js"></script>
<div>
content goes here
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed consequat nec tellus non suscipit. Proin fermentum ante ut justo pharetra placerat. Nullam imperdiet eros lectus, non scelerisque lectus gravida sit amet. Duis in justo consectetur, tincidunt mauris vel, tempus augue. Phasellus venenatis, dui in euismod aliquet, ante lorem efficitur arcu, sed lacinia turpis dui eu metus. Cras ut bibendum velit. Integer lobortis lacus porta odio faucibus, non venenatis arcu pharetra. Praesent fringilla nulla sit amet lectus tempus, id lobortis ligula suscipit. ❤️ Donec sapien erat, sagittis a sem non, vulputate molestie lectus. Etiam id maximus tortor. Pellentesque egestas, ligula sed blandit tristique, est sem facilisis elit, accumsan pellentesque est arcu ac nisl. Sed laoreet nisi sit amet scelerisque convallis.
</div>
<canvas></canvas>
不是立方体,只是为了清楚起见,您应该使用 canvas 2D 轻松完成此操作
const m4 = twgl.m4;
const ctx = document.querySelector("canvas").getContext("2d", {
powerPreference: 'low-power',
});
function render(time) {
time *= 0.001;
twgl.resizeCanvasToDisplaySize(ctx.canvas);
ctx.globalCompositeOperation = "source-over";
ctx.fillStyle = "black";
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.save();
{
ctx.globalCompositeOperation = "destination-out";
ctx.fillStyle = "rgba(0,0,0,1)";
ctx.translate(ctx.canvas.width / 2, ctx.canvas.height / 2);
ctx.rotate(time);
ctx.fillRect(ctx.canvas.width / -4,
ctx.canvas.height / -4,
ctx.canvas.width / 2,
ctx.canvas.height / 2);
}
ctx.restore();
requestAnimationFrame(render);
}
requestAnimationFrame(render);
html, body {
margin: 0;
height: 100%;
font-size: xx-large;
}
canvas {
position: fixed;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
display: block;
pointer-events: none;
}
<script src="https://twgljs.org/dist/3.x/twgl.min.js"></script>
<div>
content goes here
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed consequat nec tellus non suscipit. Proin fermentum ante ut justo pharetra placerat. Nullam imperdiet eros lectus, non scelerisque lectus gravida sit amet. Duis in justo consectetur, tincidunt mauris vel, tempus augue. Phasellus venenatis, dui in euismod aliquet, ante lorem efficitur arcu, sed lacinia turpis dui eu metus. Cras ut bibendum velit. Integer lobortis lacus porta odio faucibus, non venenatis arcu pharetra. Praesent fringilla nulla sit amet lectus tempus, id lobortis ligula suscipit. ❤️ Donec sapien erat, sagittis a sem non, vulputate molestie lectus. Etiam id maximus tortor. Pellentesque egestas, ligula sed blandit tristique, est sem facilisis elit, accumsan pellentesque est arcu ac nisl. Sed laoreet nisi sit amet scelerisque convallis.
</div>
<canvas></canvas>
推荐阅读
- android - 如何在 Expo Client 上打开 React Native 应用程序?
- javascript - 我无法理解为什么我没有被定义?
- python - 类如何在递归函数中工作?
- javascript - JSFiddle、CodePen 上的工作代码,但不在我的电脑上
- javascript - 正则表达式日期 DD/MM/YYYY
- php - PHP多个字符串正则表达式在“if”条件下
- javascript - 使用 Javascript 搜索 Wordpress 媒体
- java - 返回列表中的项目
- r - 用数据框 (R) 中的 NA 替换 X 个连续重复的零值
- android-studio - webview 白名单 url 可能来自外部文件