先思考个问题, 想实现遮罩怎么办?

<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Stencil Buffer</title>
<script id="shader-vs" type="x-shader/x-vertex">
precision highp float;
attribute vec3 aPos;
attribute vec4 aColor;
varying vec4 vColor;
void main(void){
gl_Position = vec4(aPos, 1);
vColor = aColor;
}
</script>
<script id="shader-fs" type="x-shader/x-fragment">
precision highp float;
varying vec4 vColor;
void main(void) {
gl_FragColor = vColor;
}
</script>
<script id="shader-vs-2" type="x-shader/x-vertex">
precision highp float;
attribute vec3 aPos;
attribute vec2 aTextureCoords;
varying vec2 vTextureCoord;
void main(void){
gl_Position = vec4(aPos, 1.0);
vTextureCoord = aTextureCoords;
}
</script>
<script id="shader-fs-2" type="x-shader/x-fragment">
precision highp float;
varying vec2 vTextureCoord;
uniform sampler2D uSampler;
void main(void) {
gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
if (gl_FragColor.a == 0.0) {
discard;
}
}
</script>
</head>
<body>
<canvas id="canvas" width="400" height="400" ></canvas>
<script>
var gl;
var canvas = document.getElementById('canvas');
var glProgram = null;
var glProgram2 = null;
var samplerUniform = null;
var maskTexture; function getGLContext() {
var glContextNames = ['webgl', 'experimental-webgl'];
for (var i = 0; i < glContextNames.length; i ++) {
try {
gl = canvas.getContext(glContextNames[i], {
stencil: true
});
} catch (e) {}
if (gl) {
gl.clearColor(74 / 255, 115 / 255, 94 / 255, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
gl.viewport(0, 0, canvas.width, canvas.height);
gl.enable(gl.STENCIL_TEST);
break;
}
}
} function initShaders(vsShaderId, fsShaderId) {
//get shader source
var vs_source = document.getElementById(vsShaderId).innerHTML;
var fs_source = document.getElementById(fsShaderId).innerHTML; //compile shaders
var vertexShader = makeShader(vs_source, gl.VERTEX_SHADER);
var fragmentShader = makeShader(fs_source, gl.FRAGMENT_SHADER); //create program
var glProgram = gl.createProgram(); //attach and link shaders to the program
gl.attachShader(glProgram, vertexShader);
gl.attachShader(glProgram, fragmentShader);
gl.linkProgram(glProgram); if (!gl.getProgramParameter(glProgram, gl.LINK_STATUS)) {
alert("Unable to initialize the shader program.");
} //use program
// gl.useProgram(glProgram);
return glProgram;
} function makeShader(src, type) {
//compile the vertex shader
var shader = gl.createShader(type);
gl.shaderSource(shader, src);
gl.compileShader(shader); if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert("Error compiling shader: " + gl.getShaderInfoLog(shader));
}
return shader;
}
// vertex representing the triangle
var vertex = [
-.5, -.2, 0,
.5, -.2, 0,
0, .6, 0
];
var stencilVertex = [
-.2, -.5, 0,
.4, -.5, 0,
.3, .6, 0
];
function setupBufferAndDraw(){
// draw the mask image as stencil
gl.useProgram(program2);
var maskVertex = [
-1, -1, 0,
1, -1, 0,
1, 1, 0,
-1, -1, 0,
1, 1, 0,
-1, 1, 0
];
var maskTexCoords = [
0, 0,
1, 0,
1, 1,
0, 0,
1, 1,
0, 1
];
var maskBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, maskBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(maskVertex), gl.STATIC_DRAW); var aMaskVertexPosition = gl.getAttribLocation(program2, 'aPos');
gl.vertexAttribPointer(aMaskVertexPosition, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(aMaskVertexPosition); // texture coordinate data
var maskTexCoordBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, maskTexCoordBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(maskTexCoords), gl.STATIC_DRAW); var vertexTexCoordAttribute = gl.getAttribLocation(program2, "aTextureCoords");
gl.enableVertexAttribArray(vertexTexCoordAttribute);
gl.vertexAttribPointer(vertexTexCoordAttribute, 2, gl.FLOAT, false, 0, 0); // Always pass test
gl.stencilFunc(gl.ALWAYS, 1, 0xff);
gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
gl.stencilMask(0xff);
gl.clear(gl.STENCIL_BUFFER_BIT);
// No need to display the triangle
gl.colorMask(0, 0, 0, 0); gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, maskTexture);
gl.uniform1i(samplerUniform, 0); gl.drawArrays(gl.TRIANGLES, 0, maskVertex.length / 3);
// return;
gl.useProgram(program);
// Pass test if stencil value is 1
gl.stencilFunc(gl.EQUAL, 1, 0xFF);
gl.stencilMask(0x00);
gl.colorMask(1, 1, 1, 1);
// draw the clipped triangle
var color = [
1, 0, 0, 1,
0, 1, 0, 1,
0, 0, 1, 1
];
var colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(color), gl.STATIC_DRAW); var aColorPosition = gl.getAttribLocation(program, 'aColor');
gl.vertexAttribPointer(aColorPosition, 4, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(aColorPosition); var vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertex), gl.STATIC_DRAW); var aVertexPosition = gl.getAttribLocation(program, 'aPos');
gl.vertexAttribPointer(aVertexPosition, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(aVertexPosition);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, vertex.length / 3);
} function createTexture(source) {
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.bindTexture(gl.TEXTURE_2D, null);
return texture;
} window.onload = function () {
getGLContext();
program = initShaders('shader-vs', 'shader-fs');
program2 = initShaders('shader-vs-2', 'shader-fs-2');
samplerUniform = gl.getUniformLocation(program2, 'uSampler');
var img = new Image();
img.onload = function () {
maskTexture = createTexture(this);
setupBufferAndDraw();
};
img.src = '../images/mask-png8.png';
}
</script>
</body>
</html>

  

webgl 模板缓冲的更多相关文章

  1. WebGL学习笔记(十五):模板缓冲

    可以用来干啥? 模板缓冲一般用来实现一些地面反射投影和类似镜子的特殊效果,如下: 开启模板缓冲 默认情况下,模板缓冲是关闭的,模板缓冲如果处于关闭状态,运行模板相关的代码不会报错,但是不会出现预期的效 ...

  2. Shader 模板缓冲和模板测试

    http://blog.sina.com.cn/s/blog_6e159df70102xa67.html 模板缓冲的概念 Unity官方的Shader文档根本没有提到这个玩意,这个概念也是看到了UGU ...

  3. 进一步使用 模板缓冲(stencil)

    最近做课题的时候需要计算一个 view(就是一次渲染得到的帧) 下的重叠像素个数(两个物体或更多的物体重叠). 最开始我的想法是渲染一个物体输出一张纹理,这样对比物体之间的纹理就知道重叠了.但是这样当 ...

  4. windows API下的模板缓冲(stencil buffer)

    在windows API搭建的OpenGL窗口中使用模板缓冲,需要在像素格式描述表中设置stencil buffer位宽为8,这样窗口会自动生成stencil buffer,然后可以在opengl环境 ...

  5. webgl 深度缓冲

    传统的画2d画布就是后画的会盖在先画的上面,但是在画一些三维图形时,这很难控制 深度缓冲区的作用就是区分颜色所在的层次,防止把被遮挡住的颜色显示出来. 深度缓冲很强大,用起来很简单 开启深度缓冲(测试 ...

  6. WebGL学习笔记(十六):遮罩

    这里总结下几种WebGL中实现遮罩的方法. 模板缓冲 模板缓冲可以实现渲染剔除,但是我们之前的学习里,剔除范围是基于上一次渲染的结果,且上一次的渲染也会进行显示,这样的话并不适合用来实现遮罩. 我们想 ...

  7. OpenGL ES 中的模板测试

    模板测试的主要功能是丢弃一部分片元,相对于深度检测来说,模板测试提出的片元数量相对较少.模板测试发生在剪裁测试之后,深度测试之前. 使用模板测试时很重要的代码提示: 1.glClear( GL_STE ...

  8. WebGL自学教程——WebGL演示样本:开始

    最终开始WebGL样品演示,...... 开始 使用WebGL步骤,非常easy: 1. 获得WebGL的渲染环境(也叫渲染上下文). 2. 发挥你的想象力,利用<WebGL參考手冊>中的 ...

  9. WebGL自学教程——WebGL演示样例:開始

    最终開始WebGL的演示样例了,...... 開始 使用WebGL的步骤,非常easy: 1. 获得WebGL的渲染环境(也叫渲染上下文). 2. 发挥你的想象力,利用<WebGL參考手冊> ...

随机推荐

  1. 开源http协议库curl和wget的区别和使用

    curl和wget基础功能有诸多重叠,如下载等. 在高级用途上的curl由于可自定义各种请求参数所以长于模拟web请求,用于测试网页交互(浏览器):wget由于支持ftp和Recursive所以长于下 ...

  2. OpenCV——图像的深度与通道数讲解

    矩阵数据类型: – CV_(S|U|F)C S = 符号整型 U = 无符号整型 F = 浮点型 E.g.: CV_8UC1 是指一个8位无符号整型单通道矩阵, CV_32FC2是指一个32位浮点型双 ...

  3. HTML5 <iframe> 标签

    iframe 元素会创建包含另外一个文档的内联框架(即行内框架). 即页面中嵌入另外一个独立的页面使用iframe,熟悉src是嵌套的页面的路径地址,scrolling属性可以设置iframe的滚动条 ...

  4. (转)LVS+Keepalived使用总结 vip丢失

    /sbin/ifconfig lo: $vip broadcast $vip netmask 255.255.255.255 up /sbin/ifconfig lo: 172.16.254.63 b ...

  5. [Lydsy1805月赛]quailty 算法 BZOJ5362

    分析: 题目中描述了一个二分图,让我们求最小权最大匹配,实际上其实是求n个点,在n*(n-1)/2中选n条边的权值和最小,形成一个每个点都有出边的体系,也就是基环树,(证明:因为我们需要二分图最大匹配 ...

  6. 网络对抗技术 2017-2018-2 20152515 Exp5 MSF基础应用

    1.实践内容(3.5分) 本实践目标是掌握metasploit的基本应用方式,重点常用的三种攻击方式的思路. 1.1一个主动攻击实践,如ms08_067; (1分) MS08-067漏洞攻击 这次使用 ...

  7. 20155321 《网络攻防》 Exp7 网络欺诈防范

    20155321 <网络攻防> Exp7 网络欺诈防范 实验内容 简单应用SET工具建立冒名网站 因为钓鱼网站是在本机的http服务下使用,因此需要将SET工具的访问端口改为http默认的 ...

  8. OpenCV学习C++接口 Mat像素遍历详解

    OpenCV学习C++接口 Mat像素遍历详解

  9. Linux部署DotNetCore记录

    一.背景 最近半年或最近三个月来,公司在计划大刀阔斧的规划重构新的产品.按目前的计划和宣传还是很令人期待的.前端预计应用现在很流行的前端框架,有Vue.ElementUI等,后端宣传了很多微服务.持续 ...

  10. 使用python处理百万条数据分享(适用于java新手)

    1.前言 因为负责基础服务,经常需要处理一些数据,但是大多时候采用awk以及java程序即可,但是这次突然有百万级数据需要处理,通过awk无法进行匹配,然后我又采用java来处理,文件一分为8同时开启 ...