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

<!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. 2019年春季学期《C语言程序设计II》助教注意事项

    本学期<C语言程序设计II>课程安排 理论课时24(1-12周),实验课时8(13周),课程设计课时16(14-15周) 理论课教学内容 附:教学进度表 本学期实验课和课程设计参考教材 & ...

  2. dom阻止事件冒泡

    通常有两种事件流模型,一种是冒泡,一种是捕获.顾名思义,冒泡就是从内往外传播,捕获就是从外往里传播. 对于dom事件,就是这样的.比如,有两个父子div. <div id="pdiv& ...

  3. Landen邀请码

    Y2PZ6U8 landen 输入邀请码,注册一年会额外赠送一个月,注册两年会额外赠送三个月.

  4. 大数据入门第十八天——kafka整合flume、storm

    一.实时业务指标分析 1.业务 业务: 订单系统---->MQ---->Kakfa--->Storm 数据:订单编号.订单时间.支付编号.支付时间.商品编号.商家名称.商品价格.优惠 ...

  5. 2017-2018-4 20155203《网络对抗技术》Exp3 免杀原理与实践

    1.基础问题回答 (1)杀软是如何检测出恶意代码的? 分析恶意程序的行为特征,分析其代码流将其性质归类于恶意代码 (2)免杀是做什么? 使恶意代码避免被查杀,也就是要掩盖恶意代码的特征 (3)免杀的基 ...

  6. [agc011C]Squared Graph-[二分图]

    Description 传送门 Solution 我们以下考虑的情况都是原图中非孤立的点. 题目要求新图的连通块个数.这个不好算,我们考虑计算新图的联通块内的特征点(x,y),即无法通过移动找到(t, ...

  7. Kubernetes学习之路目录

    Kubernetes基础篇 环境说明 版本说明 系统环境 Centos 7.2 Kubernetes版本 v1.11.2 Docker版本 v18.09 Kubernetes学习之路(一)之概念和架构 ...

  8. C语言和python的区别

    Python可以说是目前最火的语言之一了,人工智能的兴起让Python一夜之间变得家喻户晓,Python号称目前最最简单易学的语言,现在有不少高校开始将Python作为大一新生的入门语言.本萌新也刚开 ...

  9. PowerBI开发 第三篇:报表设计技巧

    最近做了几个PowerBI报表,对PowerBI的设计有了更深的理解,对数据的塑形(sharp data),不仅可以在Data Source中实现,例如在TSQL查询脚本中,而且可以在PowerBI中 ...

  10. 设计模式 笔记 单例模式 Singleton

    //---------------------------15/04/09---------------------------- //Singleton 单例模式-----对象创建型模式 /* 1: ...