three.js 中的官方例子 webgl_clipping_stencil 着实费解,我在不同的时间 看了有三次以上, 才逐渐理解。

概括的讲:这个例子是在说 如何使用webgl stencil 模板缓存来对 几何网格进行裁切。对几何网格进行裁切有三种方式了:

  1. 自己开发切割工具,对网格进行切割,对网格的顶点进行分割,在切割边缘处新增顶点 和三角面
  2. shader 中的片元着色器绘制几何体,在片元着色器中进行裁切,csg技术(Constructive Solid Geometry)
  3. 使用模板缓存,就是例子中的方法
    第三种是最取巧的一种办法,没有像第一种 实实在在的修改了几何网格,也没有像第二种 涉及到 片元着色器的编写。

这个例子中,有意思的一点是,隐藏网格还可以这样做:

baseMat.colorWrite = false;

就是修改材质,不让材质写入颜色缓存。

模板缓存位于屏幕空间,createPlaneStencilGroup 方法 使用纽结几何网格对模板缓存进行写入,朝向相机的像素 减去1, 被向相机的像素 加上1;

createPlaneStencilGroup 中的代码

mat0.clippingPlanes = [ plane ];

用平面切割 纽结几何网格 后,会有这样的像素,只背向当前相机,没有朝向相机,这时该像素对应的模板缓存的值为 1;另外,还有很多这样的像素,既朝向相机,又背对着相机,这时该像素对应的模板缓存是0;
想象一下,有很多光线,从相机位置发出,射向屏幕的各个像素,对于这些射线,有点穿过 纽结几何网格 两次,有的没有穿过 纽结几何网格 零次,有点正好只穿过 纽结几何网格 一次,只穿过一次这种,对应的屏幕像素 的模板值就是 1 或者 -1

init方法中调用了 createPlaneStencilGroup() 之后,紧接着创建了平面网格,也是对模板缓存进行修改

const planeMat =new THREE.MeshStandardMaterial( {color: '#E91E63',metalness: 0.1,roughness: 0.75,clippingPlanes: planes.filter( p => p !== plane ),stencilWrite: true,stencilRef: 0,stencilFunc: THREE.NotEqualStencilFunc,stencilFail: THREE.ReplaceStencilOp,stencilZFail: THREE.ReplaceStencilOp,stencilZPass: THREE.ReplaceStencilOp,} );

stencilRef 和 stencilFunc 两个属性很重要,表示模板值不为0的通过测试,渲染到屏幕;平面网格如果始终把 1 写入模板,那么通常情况下,屏幕上显示出一个四边形(矩形投影到地面一般也是四边形)

渲染顺序在这里 非常非常重要,一定要保证 纽结几何网格 先 绘制,先修改模板缓存,平面网格 后 绘制,后修改模板缓存,这样相机始终可以看到 纽结几何网格 的截断面

如果,把代码中的

createPlaneStencilGroup( geometry, plane, i + 1 )

修改为

createPlaneStencilGroup( geometry, plane, i + 2 )

po.renderOrder = i + 1.1;

保持不变。
这样平面网格 先修改模板缓存,纽结几何网格 后修改模板缓存,显示的画面就完全乱套了

const clippedColorFront = new THREE.Mesh( geometry, material );clippedColorFront.castShadow = true;clippedColorFront.renderOrder = 6;object.add( clippedColorFront );

以上代码,注释掉后,只显示 三个截断面

对 three.js webgl_clipping_stencil 例子的理解相关推荐

  1. js回调函数的理解(轉)

    js回调函数(callback)理解Mark!讲之前说一句function say(){alert(,,,,,,,,)}var say=function (){alert(,,,,,,,)}var s ...

  2. Js面向对象的程序设计——理解对象

    Js面向对象的程序设计 Js面向对象的程序设计 理解对象 属性类型 Js面向对象的程序设计 理解对象 示例 : var person=new Object(); person.name="N ...

  3. Js模块化开发的理解

    Js模块化开发的理解 模块化是一个语言发展的必经之路,其能够帮助开发者拆分和组织代码,随着前端技术的发展,前端编写的代码量也越来越大,就需要对代码有很好的管理,而模块化能够帮助开发者解决命名冲突.管理 ...

  4. 西门子for循环例子_理解JavaScript中的循环缺陷和迭代协议

    如果您已经用JavaScript或任何语言编程了一段时间,for-循环对你来说不应该陌生.您没有注意到许多编程语言,包括JavaScript,已经从使用for-循环使用迭代器-返回给定集合的下一项的对 ...

  5. 理解Babel是如何编译JS代码的及理解抽象语法树(AST)

    Babel是如何编译JS代码的及理解抽象语法树(AST) 1. Babel的作用是?    很多浏览器目前还不支持ES6的代码,但是我们可以通过Babel将ES6的代码转译成ES5代码,让所有的浏览器 ...

  6. JS中setter/getter理解

    JS中setter/getter理解 JS对象属性 get/set和getter/setter 数据属性 Object.defineProperty() 访问器属性 getter/setter创建及删 ...

  7. php正则换成js正则,php正则替换_php使用正则替换过滤掉js脚本例子

    摘要 腾兴网为您分享:php使用正则替换过滤掉js脚本例子,榛果民宿,掌上书院,夜读小说,学堂里等软件知识,以及中辉期货,车易行违章,孢子,必应壁纸app,鲁证期货,dota26.88,ip摄像头ap ...

  8. Js函数function基础理解

    正文:我们知道,在js中,函数实际上是一个对象,每个函数都是Function类型的实例,并且都与其他引用类型一样具有属性和方法.因此,函数名实际上是指向函数对象的指针,不与某个函数绑定.在常见的两种定 ...

  9. three.js webgl_tiled_forward 例子分析

    three.js 中 webgl_tiled_forward 是比较难理解的一个官方样例,我第一次看时,看得一头雾水,看得快睡着了,比较枯燥... 这个例子,就是展示场景中 有多个光源时,如何提升渲染 ...

最新文章

  1. Effective STL 50条有效使用STL的经验笔记
  2. 人体姿态fast-human-pose-estimation.pytorch
  3. mongodb学习笔记(1)
  4. 【简单易懂】getBean(id)和getBean(Class)使用的区别
  5. Redis运维和开发学习笔记(2) redis持久化
  6. UE3 内存使用和分析
  7. STM32工作笔记0069---汉字显示实验
  8. Kaldi的英文缩写
  9. C++之编写dll库
  10. 云中树莓派(3):通过 AWS IoT 控制树莓派上的 Led
  11. 【C++】将(数组)数据写入csv文件
  12. 使用post访问不到接口_Postman调试依赖登录接口的3种方法
  13. /proc/sysrq-trigger的使用
  14. 仿真技术在控制系统中的应用 ---飞机姿态控制仿真( 俯仰角)
  15. Windows 10 (64位)下 VMware 15虚拟机下载及安装教程(内附安装包)
  16. 幸运数字c语言编程软件,幸运数 (C++代码)
  17. 生成对抗网络——原理解释和数学推导
  18. 苹果怎么关闭自动更新系统_iPhone系统关闭自动更新教程
  19. java实现FTP协议:wireshark抓包解析
  20. 【基础入门题022】一元钱换成分币

热门文章

  1. JUCE 0基础小白学习day2---Timer
  2. Linux下源码安装python3、配置pip国内源、生成requirements.txt总结
  3. java基础——求数组长度、遍历数组、求最值和数组元素反转
  4. 内网窄带宽环境下的设备集成,如何有效运用流媒体服务器搭建云端视频监控管理平台
  5. 2022-2028全球嵌入式工业个人电脑行业发展现状调研及投资前景分析报告
  6. 华为p10plus开机动画路径
  7. Vue2.x 源码 - render 函数生成 VNode
  8. LaTeX - 笛卡尔叶形线
  9. 获取url地址的方法
  10. 视频URL地址获取神器:疯狂URL 视频及直播源地址获取