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參考手冊> ...
随机推荐
- Python2.7-codecs
codecs 自然语言编码转换模块 模块内的主要方法如下: codecs.encode(obj[, encoding[, errors]]):对obj用encoding编码codecs.decode( ...
- (转)win7批量创建用户
@echo off::zhangsan 改为你需要建立的用户名,123456改为你的密码,后面的两个参数的意思是“用户::不可以更改密码”和“密码永不过期”net user xiaowei 12345 ...
- 基于树莓派3的CAN总线编程
基于树莓派3的CAN总线编程 原创 2016年09月08日 10:16:13 标签: 树莓派3 / MCP2515 / CAN总线 / python / 命令行 5254 简介 树莓派3使用Pytho ...
- OpenShift-OKD3.10基础环境部署
单master + 双node 1.主机角色划分 #采用双网段部署 0 网段是opesnshift内部通信IP,1 网段是连接外网通信地址 #master master.example.com 192 ...
- Hive JDBC:Permission denied: user=anonymous, access=EXECUTE, inode=”/tmp”
今天使用JDBC来操作Hive时,首先启动了hive远程服务模式:hiveserver2 &(表示后台运行),然后到eclipse中运行程序时出现错误: Permission denied: ...
- 20155232《网络对抗》Exp5 MSF基础应用
20155232<网络对抗>Exp5 MSF基础应用 基础问题回答 用自己的话解释什么是exploit,payload,encode. exploit:就是利用可能存在的漏洞对目标进行攻击 ...
- 20155238 2016-2017-2《Java程序设计》课程总结
每周作业链接汇总(按顺序) 预备作业1 预备作业2 预备作业3 第一周作业 第二周作业 第三周作业 第四周作业 第五周作业 第六周作业 第七周作业 第八周作业 第九周作业 第十周作业 自认为写得最好一 ...
- 20155323刘威良《网络对抗》Exp3 免杀原理与实践
20155323刘威良<网络对抗>Exp3 免杀原理与实践 实践内容 1 正确使用msf编码器,msfvenom生成如jar之类的其他文件,veil-evasion,自己利用shellco ...
- Javascript 地图库收集
ArcGis leafletjs openlayers jvectormap
- 分布式事务的CAP理论 与BASE理论
CAP理论 一个经典的分布式系统理论.CAP理论告诉我们:一个分布式系统不可能同时满足一致性(C:Consistency).可用性(A:Availability)和分区容错性(P:Partition ...