可以用来干啥?

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

开启模板缓冲

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

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

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. mysql设计规范和原则

    DB设计流程: 1,需求分析 2,ER设计 3,物理设计 需求分析的最佳实践是头脑风暴,把需求理解透彻.根据公司的现况和未来的发展,与pm一起来讨论. ER(EntiyRelation)设计阶段要确定 ...

  2. ELK快速入门(一)基本部署

    ELK快速入门一-基本部署 ELK简介 什么是ELK?通俗来讲,ELK是由Elasticsearch.Logstash.Kibana 三个开源软件组成的一个组合体,这三个软件当中,每个软件用于完成不同 ...

  3. nginx.从路人到入门

    nginx 提供各种各样的服务器功能,本文记录 nginx 最基础的操作: 开启.停止.重载配置 静态文件服务器 反向代理 本文操作系统环境为 ubuntu18 安装 官方安装指导 开启.停止.重载配 ...

  4. js清除浏览器的缓存的方法

    许多的项目当中,一旦改动了js的代码,必须在浏览器当中重新加载数据,清理缓存,比较麻烦.网上找了很多的清除浏览器的方法,首先是在 html的头部加上meta的属性,但是发现并没有什么用处,后来看到说在 ...

  5. AtCoder Beginner Contest 136

    AtCoder Beginner Contest 136 题目链接 A - +-x 直接取\(max\)即可. Code #include <bits/stdc++.h> using na ...

  6. Linux-导入已安装的Linux系统

    之前在安装过一个Linux系统,由于重装电脑需要将之前安装的系统重新移动到VMWare中,让Linux系统能够重新运行起来,这样也省去了每次重新安装系统的麻烦. 废话不多说,咱们直接看是如何做? 1) ...

  7. 20180414模拟赛T1——BEAD

    BEAD 源程序名 BEAD.???(PAS,C,CPP) 可执行文件名 BEAD.EXE 输入文件名 BEAD.IN 输出文件名 BEAD.OUT 时间限制 1S 内存限制 128MB 有n颗形状和 ...

  8. python语言(四)关键字参数、内置函数、导入第三方模块、OS模块、时间模块

    一.可变参数 定义函数时,有时候我们不确定调用的时候会传递多少个参数(不传参也可以).此时,可用包裹(packing)位置参数(*args),或者包裹关键字参数(**kwargs),来进行参数传递,会 ...

  9. 20-2 树莓派搭建服务器 Tornado Web服务器

    Drive.google.com/drive/folders/1ahbeoEHkjxoo4NV1wReOmpoRWbl448z- 1.Tornado简介 Tornado一款使用 Python 编写的, ...

  10. re.sub 实现多处替换

    1   | 表示或的意思 将所有字母替换掉 result_content = re.sub('a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z', ...