可以用来干啥?

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

开启模板缓冲

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

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

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. idea 端口被占用

    打开你的DOS命令首先输入 netstat  -ano|findstr  8088   (8088即为被占用的端口号) 再输入taskkill  /pid  7348  /f     (7348即为上 ...

  2. Linux必知必会--vmstat

    视野.格局.胸怀.魄力 ---无 参考资料:https://man.linuxde.net/vmstat http://www.ha97.com/4512.html vmstat命令的含义为显示虚拟内 ...

  3. Xorequ(BZOJ3329+数位DP+斐波那契数列)

    题目链接 传送门 思路 由\(a\bigoplus b=c\rightarrow a=c\bigoplus b\)得原式可化为\(x\bigoplus 2x=3x\). 又异或是不进位加法,且\(2x ...

  4. JUnit 5.x 知识点

    出处:https://blinkfox.github.io/2018/11/15/hou-duan/java/dan-yuan-ce-shi-zhi-nan/#toc-heading-14 表面上来看 ...

  5. try catch 小结 , node的回调callback里不能捕获异常 , 不能被v8优化(现在能了),

    <深入浅出Nodejs>时,在第四章 - 异步编程中作者朴灵曾提到,异步编程的难点之一是异常处理,书中描述"尝试对异步方法进行try/catch操作只能捕获当次事件循环内的异常, ...

  6. C++传递不定参函数

    定义不定参数函数,要用到下面这些宏: va_start(ap, farg): 初始化一个va_list变量ap,farg是第一个形参 va_arg(ap, type): 获取(下)一个type类型的参 ...

  7. 第8章 动态SQL

    8.1动态SQL中的元素 8.2<if>元素 举例,在映射文件中: <select id="findCustomerByNameAndJobs" paramete ...

  8. Educational Codeforces Round 47 (Rated for Div. 2) G. Allowed Letters

    把原字符看成 $X$,每个位置看成 $Y$,每种字符向每个能去的位置连边,就成了一个二分图完美匹配的问题.现要得到字典序最小,那么就枚举每一位要放什么,然后看放完这种字符,剩下的字符的个数和后面能不能 ...

  9. ent 基本使用十三 debug 模式

    ent 生成的代码client 包中包含了一个方便的方法Debug(), 记得昨天我为了查看生成的sql 查询通过配置mysql 启用慢查询,同时设置记录慢查询为0,实际上client Debug 方 ...

  10. 2019.10.1 qbxt模拟题

    第一题 考虑树上\(DP\),f[i][j][0/1]表示以\(i\)为根的子树,入读为零点的个数为\(j\),点\(i\)的入度为\(0\)/不为\(0\)时的方案数 转移的时候考虑\(u\)的一个 ...