可以用来干啥?

模板缓冲一般用来实现一些地面反射投影和类似镜子的特殊效果,如下:

开启模板缓冲

默认情况下,模板缓冲是关闭的,模板缓冲如果处于关闭状态,运行模板相关的代码不会报错,但是不会出现预期的效果。

使用下面的代码可以开启模板缓冲:

var gl = canvas.getContext("webgl", { stencil: true });

使用流程

模板缓冲可以确定下次渲染时,指定的像素是否要进行剔除,可以理解为每个像素只有 0(丢弃) 和 1(保留) 两个数值。

具体使用模板缓冲大体流程如下:

  1. 启用模板测试;
  2. 设定模板参数;
  3. 渲染物体,同时根据本次渲染出来的内容更新模板缓冲的内容,注意本次渲染会正常更新颜色缓冲和深度缓冲(如果深度缓冲开启);
  4. 设定模板参数;
  5. 渲染(其它)物体,这次根据模板缓冲的内容丢弃特定的片段;
  6. 禁用模板测试;

通过使用模板缓冲,我们可以根据场景中已绘制的其它物体的片段,来决定是否丢弃特定的片段。

当你启用模板测试之后,所有的渲染调用都会以某种方式影响着模板缓冲。

模板相关方法

常规方法

 // 清除模板缓冲,模板缓冲所有像素值都为0。
gl.clear(gl.STENCIL_BUFFER_BIT);
// 开启模板测试
gl.enable(gl.STENCIL_TEST);
// 关闭模板测试
gl.disable(gl.STENCIL_TEST);

gl.stencilMask

glStencilMask允许我们设置一个位掩码(Bitmask),它会与将要写入缓冲的模板值进行与(AND)运算;

gl.stencilMask(0xFF); // 每一位写入模板缓冲时都保持原样
gl.stencilMask(0x00); // 每一位在写入模板缓冲时都会变成0(禁用写入)

gl.stencilFunc

https://developer.mozilla.org/zh-CN/docs/Web/API/WebGLRenderingContext/stencilFunc

确定后续的渲染,和当前模板缓冲中的像素模板值对比之后,是否丢弃掉渲染的结果。

glStencilFunc(GLenum func, GLint ref, GLuint mask)

func可选值如下:

GL_ALWAYS:不和模板缓冲中的值进行对比,所有渲染出的像素值都进行正常绘制;

GL_NEVER:不和模板缓冲中的值进行对比,所有渲染出的像素值都丢弃;

GL_LESS、GL_LEQUAL、GL_GREATER、GL_GEQUAL、GL_EQUAL、GL_NOTEQUAL:按照规则对比模板缓冲中的值和渲染出来的值进行释放丢弃渲染结果的判定。

ref 和 mask:

配合func参数使用,具体规则请看MDN。

gl.stencilOp

https://developer.mozilla.org/zh-CN/docs/Web/API/WebGLRenderingContext/stencilOp

设定如何根据下一次渲染的结果来更新模板缓冲中的值。

glStencilOp(GLenum sfail, GLenum dpfail, GLenum dppass)
  1. sfail:模板测试失败时采取的行为。
  2. dpfail:模板测试通过,但深度测试失败时采取的行为。
  3. dppass:模板测试和深度测试都通过时采取的行为。

具体可以传递的参数如下:

  • KEEP(不改变,这也是默认值)
  • ZERO(回零)
  • REPLACE(使用测试条件中的设定值来代替当前模板值,stencilFunc方法中的ref参数)
  • INCR(增加1,但如果已经是最大值,则保持不变)
  • INCR_WRAP(增加1,但如果已经是最大值,则从零重新开始)
  • DECR(减少1,但如果已经是零,则保持不变)
  • DECR_WRAP(减少1,但如果已经是零,则重新设置为最大值)
  • INVERT(按位取反)

示例

https://hammerc.github.io/dou3d-ts/learning/learningNotes/lesson_15/index.html

上下箭头控制小方块的移动。

WebGL学习笔记(十五):模板缓冲的更多相关文章

  1. python3.4学习笔记(十五) 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)

    python3.4学习笔记(十五) 字符串操作(string替换.删除.截取.复制.连接.比较.查找.包含.大小写转换.分割等) python print 不换行(在后面加上,end=''),prin ...

  2. (转载)西门子PLC学习笔记十五-(数据块及数据访问方式)

    一.数据块 数据块是在S7 CPU的存储器中定义的,用户可以定义多了数据块,但是CPU对数据块数量及数据总量是有限制的. 数据块与临时数据不同,当逻辑块执行结束或数据块关闭,数据块中的数据是会保留住的 ...

  3. (C/C++学习笔记) 十九. 模板

    十九. 模板 ● 模板的基本概念 模板(template) 函数模板:可以用来创建一个通用功能的函数,以支持多种不同形参,进一步简化重载函数的函数体设计. 语法: template <<模 ...

  4. (C/C++学习笔记) 十五. 构造数据类型

    十五. 构造数据类型 ● 构造数据类型概念 Structured data types 构造数据类型 结构体(structure), 联合体/共用体 (union), 枚举类型(enumeration ...

  5. MySQL学习笔记十五:优化(2)

    一.数据库性能评测关键指标 1.IOPS:每秒处理的IO请求次数,这跟磁盘硬件相关,DBA不能左右,但推荐使用SSD. 2.QPS:每秒查询次数,可以使用show status或mysqladmin ...

  6. python 学习笔记十五 web框架

    python Web程序 众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. Python的WEB框架分为两类: 自己写socket,自 ...

  7. python 学习笔记十五 django基础

    Python的WEB框架有Django.Tornado.Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM.模型绑定.模板引擎.缓存.Session等诸多功能. ...

  8. Java基础学习笔记十五 集合、迭代器、泛型

    Collection 集合,集合是java中提供的一种容器,可以用来存储多个数据. 在前面的学习中,我们知道数据多了,可以使用数组存放或者使用ArrayList集合进行存放数据.那么,集合和数组既然都 ...

  9. angular学习笔记(十五)-module里的'服务'

    本篇介绍angular中的模块:module 在笔记(二)http://www.cnblogs.com/liulangmao/p/3711047.html里已经讲到过模块,这篇主要讲模块的 '服务' ...

  10. Java学习笔记十五:Java中的成员变量和局部变量

    Java中的成员变量和局部变量 一:成员变量: 成员变量在类中定义,用来描述对象将要有什么 成员变量可以被本类的方法使用,也可以被其他类的方法使用,成员变量的作用域在整个类内部都是可见的 二:局部变量 ...

随机推荐

  1. Httpd服务进阶知识-LAMP源码编译安装

    Httpd服务进阶知识-LAMP源码编译安装 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 想必大家都知道,动态资源交给fastcgi程序处理,静态资源依旧由httpd服务器处理  ...

  2. 4.LVS的三种工作模式_DR模式

    1.DR模式(直接路由模式:Virtual Server via Direct Routing) DR模式是通过改写请求报文的目标MAC地址,将请求发给真实服务器的,而真实服务器响应后的处理结果直接返 ...

  3. js--动画

    运动框架实现思想1.速度(改变值left,right,width,height,opacity)2.缓冲运动3.多物体运动4.任意值变化5.链式运动6.同时运动 我们先来介绍第一章改变left值来使物 ...

  4. 牛客NOIP暑期七天营-普及组2D

    链接:https://ac.nowcoder.com/acm/contest/926/D来源:牛客网 在一维坐标系中,给定 n条有颜色的线段,第 i条线段的左右端点分别为 li​和 ri​,此外它的颜 ...

  5. 30、Python程序中的线程操作(oncurrent模块)

    进程是cpu资源分配的最小单元,一个进程中可以有多个线程. 线程是cpu计算的最小单元. 对于Python来说他的进程和线程和其他语言有差异,是有GIL锁. GIL锁 GIL锁保证一个进程中同一时刻只 ...

  6. 通信、端点、IO、文件

    什么是网络套接字(Socket)?一时还真不好回答,而且网络上也有各种解释,莫衷一是.下文将以本人所查阅到的资料来说明一下什么是Socket. Socket定义 Socket在维基百科的定义: A n ...

  7. Let Start

      A free timing software with very small memory occupation. This tool is a pure green convenient off ...

  8. Install Python3.6 on Amazon Linux/EC2 在Amazon Linux实例中安装使用Python3.6

    本文转载自 https://gist.github.com/niranjv/f80fc1f488afc49845e2ff3d5df7f83b 由于Amazon Linux中预装的Python版本为2. ...

  9. 全部文章> Maven

    Maven     原 Maven中<resources>标签详解 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;& ...

  10. 修改 oracle xe 默认中文字符集成为:SIMPLIFIED CHINESE_CHINA.ZHS16GBK

    修改 oracle xe 默认中文字符集成为:SIMPLIFIED CHINESE_CHINA.ZHS16GBK Oracle XE 执行安装程序后,很简单的默认为  SIMPLIFIED CHINE ...