threejs中使用drawbufferss示例详解

目录
  • 原因
  • 历程
    • 原生的使用
    • 基本流程
    • 灵光乍现
    • 使用WebGLMultipleRenderTargets

原因

深度剥离实现之后,似乎会使得走样严重起来。 我意识到,这是因为 剥离这个过程,并没有什么讲究,只要是深度小于等于就剔除了,这样很可能就导致了,原本平滑的差值过渡出现了断层,突变。 简单的解决办法就是增顶点数。

一番搜寻weight oit算法的demo,但是只找到了用原生webgl写的,传送门。在费了几个日夜之后,终于看懂了,但是,还要把它用three实现。一般来说,没有使用编译的框架,应该可以直接使用原生,但是业务场景不允许。

我当然为此goole了一番,但是只找到一个教我如何在three里使用原生Texture的方法, 算是解决了一个困境。

遇到的下一个困境就是,直接用原生的上下文进行一系列缓冲区和纹理的绑定操作是徒劳的, 因为three的renderer.render里面会有他的一套处理。 到这里我就意识到了,没法混用。

比如说,我要修改融合算法参数,使用gl.blendFunc ,但是只要我使用three的renderer.render ,它就会以材质上的相关属性重设blend,渲染目标也是如此。

至于为什么不能不用它的渲染器,直接使用gl.draw方法族,那当然是因为,拿不到全部的着色器数据。

所以,结论就是,必须完全使用threejs的方式实现。

历程

原生的使用

先来看原生的使用 , 用的是webgl2,glsl 3.0。 幸好, three用的也是,为此我还纳闷了一番。因为我发现three 仍然使用的是glsl 1.0的语法。

要知道,glsl 3.0 里面移除了 gl_FragColor 这个内置输出变量,移除了 attribute varrying 关键字, 直接使用当然会报错。

因为,加权深度算法用的也是glsl3.0 ,我之前学的是1.0的语法和api,看的时候就有些云里雾里,后来发觉原来版本不对,立即去研究3.0的语法,然后很多问题就迎刃而解了。 可见,搞清楚自己用的api的版本的重要性

three的处理就是起别名, 对于fragment的输出,glsl 3.0,要求至少定义一个 out 修饰的 四维向量, 如果有多个,最好是用layout指定索引。 直接看代码,以片元着色器为例,顶点着色器不用输出颜色 。

#version 300 es
out highp vec4 Ocolor;
#define gl_FragColor Ocolor
#define varying in

第一行指定版本

第二行定义输出变量

第三行定义Ocolor的 别名为gl_FragColor

第四行 定义修饰符 in的别名为 varying

知道了3.0的语法特点,再来看oit的代码。

基本流程

在初次绘制的着色器里 ,声明输出变量 颜色和透明度

 layout(location=0) out vec4 accumColor;
 layout(location=1) out float accumAlpha;

声明两个纹理,并且和颜色缓冲区绑定,这样在绘制帧缓冲区时,会把颜色缓冲区的像素绘制到纹理。 color_attachmentN就是对应在片元着色器里声明的layout (loaction = N) out ve4

 accumBuffer = gl.createFramebuffer();// 帧缓冲区唯一
  gl.bindFramebuffer(gl.FRAMEBUFFER, accumBuffer);
 ......
 var accumTarget = gl.createTexture();
 ......
 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, accumTarget, 0);
var accumAlphaTarget = gl.createTexture();
......
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.TEXTURE_2D, accumAlphaTarget, 0);

在js里使用drawbuffer 将这两个输出变量和对应的缓冲区关联起来。没错这个方法只是关联而已,没有真的绘制。

gl.drawBuffers([ gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1 ]);
还原
gl.bindFramebuffer(gl.FRAMEBUFFER, null);

原生就是这样实现,绘制之后颜色和透明度就绘制到对应的纹理了。 透明度是float 类型,可直接理解为一维向量。

然后再次绘制的时候就可以用这两个纹理的数据去修改alpha 使得最终的合成符合他那个公式,我也不理解这个公式,就这样吧。

灵光乍现

我理解了这个算法的一套流程,之后就发现文章开头的问题。我发现blend和 bindframeBuffer的失灵之后,就去搜了一下对应的api ,然后断点看执行时机。

不知过了多久,也许一瞬,也许半天,我突然意识到,如果threejs实现了drawBuffers的封装,那么它必然使用了这个api,我直接搜 drawBuffers不就行了 。

于是我就发现了,rendertarget必须设置为 multipleRendertarget。 所以我转而搜这个,于是乎就发现了,有现成的example.

使用WebGLMultipleRenderTargets

首先当然是实例化,需要传入纹理的尺寸和输出变量的数目。

renderTarget = new THREE.WebGLMultipleRenderTargets(
		window.innerWidth * window.devicePixelRatio,
		window.innerHeight * window.devicePixelRatio,
	2
	);

然后在绘制之前设置渲染目标。

	renderer.setRenderTarget( renderTarget );

没了,就这么多。 至于纹理参数的设置,小细节不拘。

绘制后,就可以把 renderTarget.texture[ N ] 用three的方式传给着色器。 这里有一个小点要注意。

renderTarget.texture 没有复数。

以上就是threejs中使用drawbufferss示例详解的详细内容,更多关于threejs使用drawbufferss的资料请关注我们其它相关文章!

(0)

相关推荐

  • 使用threejs实现第一人称视角的移动的问题(示例代码)

    在数据可视化领域利用webgl来创建三维场景或VR已经越来越普遍,各种开发框架也应运而生.今天我们就通过最基本的threejs来完成第一人称视角的场景巡检功能.如果你是一位threejs的初学者或正打算入门,我强烈推荐你仔细阅读本文并在我的代码基础之上继续深入学习.因为它将是你能够在网上找到的最好的免费中文教程,通过本文你可以学习到一些基本的三维理论,threejs的api接口以及你应该掌握的数学知识.当然要想完全掌握threejs可能还有很长的路需要走,但至少今天我将带你入门并传授一些独特的学

  • 解决threeJS加载obj gltf模型后颜色太暗的方法

    目录 网上找到的部分解决方法 效果对比 总结 网上找到的部分解决方法 其实通过查找后不难发现网上给出了很多解决方法,但是大部分都无法从根本上解决问题.我之前看到有一篇文章对gltf的解决方法是让gltf增加自发光,相关的设置如下: 使用threeJS的过程中,刚开始总是会遇到些问题,就比如加载obj/gltf等带材质的模型时老是会出现显示效果较暗的问题. object.traverse((child) => { if(child.isMesh) { child.material.emissive

  • threejs太阳光与阴影效果实例代码

    目录 前言 灯光与材质基础篇 太阳光 整体调用代码 太阳光类 初始化 设置平行光信息 Tween 总结 前言 这篇文章实现智慧城市中模拟太阳光随时间变化产生对应场景效果.为了场景能够更逼真,我们一般会通过对接天气以及阳光等各种环境因素同步到场景中,使得场景能够更贴近现实.比如一些常见的天气系统,下雨.下雪.阴天.雾霾等,我之后会独立一篇文章中提现.这边文章主要介绍一系列灯光,主要是平行光对于太阳的模仿,以及一些材质的问题~ 灯光与材质基础篇 常见的灯光: - 点光源 (点光源可以理解为一个同时向

  • threejs全景图和锚点编辑的实现方案

    目录 全景图和锚点编辑 全景图 全景图拆解 场景编辑方案 transformControls 初始化控制器 添加可移动对象 平移.缩放.旋转 保存对象 结语 全景图和锚点编辑 今天来简单聊聊threejs全景图和锚点编辑的方案. 全景图也就是所谓的天空盒子,所应用到的场景例如:场景模型的天空背景.夜晚的星空背景.VR看房等~ 锚点编辑这篇重点讲一讲锚点编辑,也就是所谓场景编辑的方案.其中思想无限接近于Low Code,说到Low Code!我拖更了四篇文章,由于过年那段时间太忙了,实在是没时间更

  • vue3中如何用threejs画一些简单的几何体

    目录 前言 threejs简述 依赖包版本 vue3操作DOM 创建场景,相机,渲染器本节及后续都在initThree方法中写 立方体 球体 圆柱体 坐标系 点光源 鼠标操作旋转,缩放 球体,立方体自动旋转 initThree完整代码 总结 前言 在vue3中使用threejs画了几个最简单的几何体,自动旋转的立方体,圆柱体,球体,并且加入了光照,几何体影阴部分即光没照到的地方,成果如下,感兴趣的可以看看具体实现过程~ threejs简述 Three.js是基于原生WebGL封装运行的三维引擎

  • threejs后期处理的基本使用方法之加特效

    目录 前言 基本代码 基本流程 核心函数介绍 EffectComposer 效果组合器 构造函数 重要方法: RenderPass 渲染通道 构造函数 重要属性: ShaderPass 着色器通道 官方案例 链接 通道相关代码位置 案例演示 电脉冲故障风效果 代码 描边效果 代码 泛光效果 BloomPass的参数 代码 总结 前言 后期处理:简单的说就是先渲染一张图存起来,在这张图上面"添油加醋",处理完后再渲染到屏幕上.这一过程three进行了封装,使用现成的可以更快实现需求 基本

  • threejs中使用drawbufferss示例详解

    目录 原因 历程 原生的使用 基本流程 灵光乍现 使用WebGLMultipleRenderTargets 原因 深度剥离实现之后,似乎会使得走样严重起来. 我意识到,这是因为 剥离这个过程,并没有什么讲究,只要是深度小于等于就剔除了,这样很可能就导致了,原本平滑的差值过渡出现了断层,突变. 简单的解决办法就是增顶点数. 一番搜寻weight oit算法的demo,但是只找到了用原生webgl写的,传送门.在费了几个日夜之后,终于看懂了,但是,还要把它用three实现.一般来说,没有使用编译的框

  • ThinkPHP Where 条件中常用表达式示例(详解)

    Where 条件表达式格式为: $map['字段名'] = array('表达式', '操作条件'); 其中 $map 是一个普通的数组变量,可以根据自己需求而命名.上述格式中的表达式实际是运算符的意义: ThinkPHP运算符 与 SQL运算符 对照表 TP运算符 SQL运算符 例子 实际查询条件 eq = $map['id'] = array('eq',100); 等效于:$map['id'] = 100; neq != $map['id'] = array('neq',100); id !

  • Vue中的vue-resource示例详解

    vue-resource特点 vue-resource插件具有以下特点: 1. 体积小 vue-resource非常小巧,在压缩以后只有大约12KB,服务端启用gzip压缩后只有4.5KB大小,这远比jQuery的体积要小得多. 2. 支持主流的浏览器 和Vue.js一样,vue-resource除了不支持IE 9以下的浏览器,其他主流的浏览器都支持. 3. 支持Promise API和URI Templates Promise是ES6的特性,Promise的中文含义为"先知",Pro

  • django中使用memcached示例详解

    目录 什么是memcached: 安装和启动memcached: windows linux(ubuntu) 启动memcached: telnet操作memcached: 添加数据: 获取数据: 删除数据: 通过python操作memcached: memcached的安全性: 在Django中使用memcached: 什么是memcached: memcached之前是danga的一个项目,最早是为LiveJournal服务的,当初设计师为了加速LiveJournal访问速度而开发的,后来被

  • Go Java算法之从英文中重建数字示例详解

    目录 从英文中重建数字 Java实现 Go实现 从英文中重建数字 给你一个字符串 s ,其中包含字母顺序打乱的用英文单词表示的若干数字(0-9).按 升序 返回原始的数字. 示例 1: 输入:s = "owoztneoer" 输出:"012" 示例 2: 输入:s = "fviefuro" 输出:"45" 提示: 1 <= s.length <= 105 s[i] 为 ["e","g&

  • Java结构型设计模式中代理模式示例详解

    目录 代理模式 分类 主要角色 作用 静态代理与动态代理的区别 静态代理的基本使用 创建抽象主题 创建真实主题 创建代理主题 客户端调用 JDK动态代理的基本使用 创建抽象主题 创建真实主题 创建代理主题 客户端调用 小优化 CGLIB动态代理的基本使用 创建抽象主题 创建真实主题 创建代理主题 客户端调用 小优化 CGLIB与JDK动态代理区别 1.执行条件 2.实现机制 3.性能 代理模式 代理模式(Proxy Pattern)属于结构型模式. 它是指为其他对象提供一种代理以控制对这个对象的

  • Java结构型设计模式中建造者模式示例详解

    目录 建造者模式 概述 角色 优缺点 应用场景 基本使用 创建产品类 创建建造者类 使用 链式写法 创建产品类与建造者类 使用 建造者模式 概述 建造者模式(Builder Pattern)属于创建型模式. 它是将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示. 简而言之:建造者模式就是使用多个简单的对象一步一步构建成一个复杂的对象. 建造者模式适用于创建对象需要很多步骤,但是步骤的顺序不一定固定.如果一个对象有非常复杂的内部结构(很多属性),可以将复杂对象的创建和使用进行分

  • C C++ LeetCode题解在二叉树中增加一行示例详解

    目录 题目描述 整理题意 解题思路分析 层序遍历(广度优先搜索) 递归(深度优先搜索) 具体实现 复杂度分析 代码实现 层序遍历(广度优先搜索) 递归(深度优先搜索) 总结 题目描述 题目链接:623. 在二叉树中增加一行 给定一个二叉树的根 root 和两个整数 val 和 depth ,在给定的深度 depth 处添加一个值为 val 的节点行. 注意,根节点 root 位于深度 1 . 加法规则如下: 给定整数 depth,对于深度为 depth - 1 的每个非空树节点 cur ,创建两

  • React.memo函数中的参数示例详解

    目录 React.memo?这是个啥? React.memo的第一个参数 父组件 子组件 React.memo优化 React.memo的第二个参数 父组件 子组件 React.memo优化 父组件 子组件 小结 React.memo?这是个啥? 按照官方文档的解释: 如果你的函数组件在给定相同 props 的情况下渲染相同的结果,那么你可以通过将其包装在 React.memo 中调用,以此通过记忆组件渲染结果的方式来提高组件的性能表现.这意味着在这种情况下,React 将跳过渲染组件的操作并直

  • GraphQL在react中的应用示例详解

    目录 什么是 GraphQL GraphQL出现的意义 传统API存在的主要问题: GraphQL 如何解决问题 GraphQL基本语法 标量类型 对象类型 枚举类型 GraphQL 内置指令 什么是 Apollo apollo-server 处理流程 1.解析阶段 2.校验阶段 3.执行阶段 Schema 给server端带来的便利性 创建client 将client注入到react 数据请求 数据缓存 apollo-client 总结 GraphQL 的优缺点 优点 缺点 什么是 Graph

随机推荐