webgl 模板缓冲
先思考个问题, 想实现遮罩怎么办?
<!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 模板缓冲的更多相关文章
- WebGL学习笔记(十五):模板缓冲
可以用来干啥? 模板缓冲一般用来实现一些地面反射投影和类似镜子的特殊效果,如下: 开启模板缓冲 默认情况下,模板缓冲是关闭的,模板缓冲如果处于关闭状态,运行模板相关的代码不会报错,但是不会出现预期的效 ...
- Shader 模板缓冲和模板测试
http://blog.sina.com.cn/s/blog_6e159df70102xa67.html 模板缓冲的概念 Unity官方的Shader文档根本没有提到这个玩意,这个概念也是看到了UGU ...
- 进一步使用 模板缓冲(stencil)
最近做课题的时候需要计算一个 view(就是一次渲染得到的帧) 下的重叠像素个数(两个物体或更多的物体重叠). 最开始我的想法是渲染一个物体输出一张纹理,这样对比物体之间的纹理就知道重叠了.但是这样当 ...
- windows API下的模板缓冲(stencil buffer)
在windows API搭建的OpenGL窗口中使用模板缓冲,需要在像素格式描述表中设置stencil buffer位宽为8,这样窗口会自动生成stencil buffer,然后可以在opengl环境 ...
- webgl 深度缓冲
传统的画2d画布就是后画的会盖在先画的上面,但是在画一些三维图形时,这很难控制 深度缓冲区的作用就是区分颜色所在的层次,防止把被遮挡住的颜色显示出来. 深度缓冲很强大,用起来很简单 开启深度缓冲(测试 ...
- WebGL学习笔记(十六):遮罩
这里总结下几种WebGL中实现遮罩的方法. 模板缓冲 模板缓冲可以实现渲染剔除,但是我们之前的学习里,剔除范围是基于上一次渲染的结果,且上一次的渲染也会进行显示,这样的话并不适合用来实现遮罩. 我们想 ...
- OpenGL ES 中的模板测试
模板测试的主要功能是丢弃一部分片元,相对于深度检测来说,模板测试提出的片元数量相对较少.模板测试发生在剪裁测试之后,深度测试之前. 使用模板测试时很重要的代码提示: 1.glClear( GL_STE ...
- WebGL自学教程——WebGL演示样本:开始
最终开始WebGL样品演示,...... 开始 使用WebGL步骤,非常easy: 1. 获得WebGL的渲染环境(也叫渲染上下文). 2. 发挥你的想象力,利用<WebGL參考手冊>中的 ...
- WebGL自学教程——WebGL演示样例:開始
最终開始WebGL的演示样例了,...... 開始 使用WebGL的步骤,非常easy: 1. 获得WebGL的渲染环境(也叫渲染上下文). 2. 发挥你的想象力,利用<WebGL參考手冊> ...
随机推荐
- pycham database查看db.sqlites文件 无内容解决方法
初学django,使用pycharm IDE的时候,通过使用默认的sqlites数据库,执行问makemigration 和migrate操作之后,控制台正常输出类似如下结果,按照道理应该生成了数据表 ...
- WorldWind源码剖析系列:可渲染对象列表类RenderableObjectList
可渲染对象列表类RenderableObjectList用来存储与一个星球体相关联的全部的可渲染对象,继承自可渲染对象类RenderableObject.RenderableObjectList的类图 ...
- 使用Android绘图技术绘制一个椭圆形,然后通过触摸事件让该椭圆形跟着手指移动
引言:在图形绘制中,控制一个图形(圆形,椭圆形,矩形,三角形)移动时,其实计算的都是该图形的中心点移动.在绘制过程中,首先计算出中心点,然后根据中心点的位置计算重图形的上下左右位置.我们假设图形左边为 ...
- DC-DC Controllers Use Average-Current-Mode Control for Infotainment Applications-3939
DC-DC Controllers Use Average-Current-Mode Control for Infotainment Applications Abstract: Auto info ...
- gdb中信号
信号(Signals) 信号是一种软中断,是一种处理异步事件的方法.一般来说,操作系统都支持许多信号.尤其是UNIX,比较重要应用程序一般都会处理信号.UNIX定义了许 多信号,比如SIGINT表示中 ...
- 关于NLB的群集操作模式知识 (转载)
单播:单播模式是指各节点的网络适配器被重新指定了一个虚拟MAC(由02-bf和群集IP地址组成确保此MAC的唯一性).由于所有绑定群集的网络适配器的MAC都相同,所以在单网卡的情况下,各节点之间是不能 ...
- ASP.NET Core MVC 模型绑定 (转载)
ASP.NET Core MVC的Model Binding会将HTTP Request数据,以映射的方式对应到参数中.基本上跟ASP.NET MVC差不多,但能Binding的来源更多了一些.本篇将 ...
- MySQL 数据库赋予用户权限操作表
MySQL清空数据库的操作:truncate table tablename; MySQL 赋予用户权限命令的简单格式可概括为:grant 权限 on 数据库对象 to 用户 一.grant 普通数 ...
- 20155325 Exp6 信息搜集与漏洞扫描
实践目标 掌握信息搜集的最基础技能与常用工具的使用方法. 实践内容 (1)各种搜索技巧的应用 (2)DNS IP注册信息的查询 (3)基本的扫描技术:主机发现.端口扫描.OS及服务版本探测.具体服务的 ...
- Walle 2.0 发布系统
目录 walle 2.0 1.walle原理 1.1.walle原理图 1.2.权限设计模型 2.部署walle 2.1.依赖检查安装 2.2.walle部署 3.Walle使用 3.1.用户配置 3 ...