我的编程空间,编程开发者的网络收藏夹
学习永远不晚

threejs中使用drawbufferss示例详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

threejs中使用drawbufferss示例详解

原因

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

一番搜寻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的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

threejs中使用drawbufferss示例详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Android中ExpandableListView使用示例详解

本文实例为大家分享了ExpandableListView使用示例,供大家参考,具体内容如下MainActivity:public class Expandable_test extends Activity { private Expan
2023-05-30

MySQL 中 LIMIT 使用示例详解

mysql是一种常用的关系型数据库管理系统,它提供了许多用于查询和操作数据的功能。其中,LIMIT是一个非常有用的关键字,用于在查询结果中限制返回的行数。操作数据库时,经常会遇到需要查询前几条或者后几条数据的javascript情况,尤
MySQL 中 LIMIT 使用示例详解
2024-08-12

iOS中NSThread使用示例详解

这篇文章主要为大家介绍了iOS中NSThread使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-11-13

godoudou应用中使用注解示例详解

这篇文章主要为大家介绍了godoudou应用中使用注解示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-12-08

.NET中的Swagger使用示例详解

本文章详细介绍了.NET中Swagger的使用示例。通过安装Swashbuckle.AspNetCoreNuGet包,可以生成交互式API文档。使用特性可以为控制器和操作添加Swagger文档信息,包括状态码、响应类型和摘要描述。配置文件中的代码负责配置Swagger设置,启用Swagger中间件并指定文档路径。最终,可以通过SwaggerUI浏览和测试API,从而自动生成文档,简化开发和测试,提高代码可维护性,促进API可发现性和集成。
.NET中的Swagger使用示例详解
2024-04-02

Python中Merge使用的示例详解

Python里的merger函数是数据分析工作中最常见的函数之一,类似于MySQL中的join函数和Excel中的vlookup函数。本文将通过一些简单的实力和大家聊聊Merge的使用,需要的可以了解一下
2023-02-21

requestAnimationFrame使用示例详解

这篇文章主要为大家介绍了requestAnimationFrame使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-02-21

Collectionstream使用示例详解

这篇文章主要介绍了Collectionstream使用示例,stream流几乎可以完成对集合的任意操作,映射、去重、分组、排序、过滤等
2022-12-19

GoJs中的动画使用示例详解

这篇文章主要为大家介绍了GoJs中的动画使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-05-18

react中使用antd及immutable示例详解

这篇文章主要为大家介绍了react中使用antd及immutable示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-11-13

vue中使用window.open()参数示例详解

这篇文章主要介绍了vue中使用window.open()参数详解,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
2023-05-17

ESLint和Jest中使用esm示例详解

这篇文章主要为大家介绍了ESLint和Jest中使用esm示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-03-03

TreeSet详解和使用示例

TreeSet是Java集合框架中的一个类,它实现了SortedSet接口,底层使用红黑树实现,可以实现有序的插入和遍历。TreeSet的特点:1. TreeSet中的元素是有序的,默认按照升序排序,也可以通过Comparator自定义排序
2023-08-08

编程热搜

目录