欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

threejs中使用drawbufferss示例詳解

 更新時(shí)間:2022年09月05日 16:31:27   作者:莫石  
這篇文章主要為大家介紹了threejs中使用drawbufferss示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

原因

深度剝離實(shí)現(xiàn)之后,似乎會(huì)使得走樣嚴(yán)重起來(lái)。 我意識(shí)到,這是因?yàn)?剝離這個(gè)過(guò)程,并沒(méi)有什么講究,只要是深度小于等于就剔除了,這樣很可能就導(dǎo)致了,原本平滑的差值過(guò)渡出現(xiàn)了斷層,突變。 簡(jiǎn)單的解決辦法就是增頂點(diǎn)數(shù)。

一番搜尋weight oit算法的demo,但是只找到了用原生webgl寫(xiě)的,傳送門(mén)。在費(fèi)了幾個(gè)日夜之后,終于看懂了,但是,還要把它用three實(shí)現(xiàn)。一般來(lái)說(shuō),沒(méi)有使用編譯的框架,應(yīng)該可以直接使用原生,但是業(yè)務(wù)場(chǎng)景不允許。

我當(dāng)然為此goole了一番,但是只找到一個(gè)教我如何在three里使用原生Texture的方法, 算是解決了一個(gè)困境。

遇到的下一個(gè)困境就是,直接用原生的上下文進(jìn)行一系列緩沖區(qū)和紋理的綁定操作是徒勞的, 因?yàn)閠hree的renderer.render里面會(huì)有他的一套處理。 到這里我就意識(shí)到了,沒(méi)法混用。

比如說(shuō),我要修改融合算法參數(shù),使用gl.blendFunc ,但是只要我使用three的renderer.render ,它就會(huì)以材質(zhì)上的相關(guān)屬性重設(shè)blend,渲染目標(biāo)也是如此。

至于為什么不能不用它的渲染器,直接使用gl.draw方法族,那當(dāng)然是因?yàn)?,拿不到全部的著色器?shù)據(jù)。

所以,結(jié)論就是,必須完全使用threejs的方式實(shí)現(xiàn)。

歷程

原生的使用

先來(lái)看原生的使用 , 用的是webgl2,glsl 3.0。 幸好, three用的也是,為此我還納悶了一番。因?yàn)槲野l(fā)現(xiàn)three 仍然使用的是glsl 1.0的語(yǔ)法。

要知道,glsl 3.0 里面移除了 gl_FragColor 這個(gè)內(nèi)置輸出變量,移除了 attribute varrying 關(guān)鍵字, 直接使用當(dāng)然會(huì)報(bào)錯(cuò)。

因?yàn)椋訖?quán)深度算法用的也是glsl3.0 ,我之前學(xué)的是1.0的語(yǔ)法和api,看的時(shí)候就有些云里霧里,后來(lái)發(fā)覺(jué)原來(lái)版本不對(duì),立即去研究3.0的語(yǔ)法,然后很多問(wèn)題就迎刃而解了。 可見(jiàn),搞清楚自己用的api的版本的重要性

three的處理就是起別名, 對(duì)于fragment的輸出,glsl 3.0,要求至少定義一個(gè) out 修飾的 四維向量, 如果有多個(gè),最好是用layout指定索引。 直接看代碼,以片元著色器為例,頂點(diǎn)著色器不用輸出顏色 。

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

第一行指定版本

第二行定義輸出變量

第三行定義Ocolor的 別名為gl_FragColor

第四行 定義修飾符 in的別名為 varying

知道了3.0的語(yǔ)法特點(diǎn),再來(lái)看oit的代碼。

基本流程

在初次繪制的著色器里 ,聲明輸出變量 顏色和透明度

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

聲明兩個(gè)紋理,并且和顏色緩沖區(qū)綁定,這樣在繪制幀緩沖區(qū)時(shí),會(huì)把顏色緩沖區(qū)的像素繪制到紋理。 color_attachmentN就是對(duì)應(yīng)在片元著色器里聲明的layout (loaction = N) out ve4

 accumBuffer = gl.createFramebuffer();// 幀緩沖區(qū)唯一      
  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 將這兩個(gè)輸出變量和對(duì)應(yīng)的緩沖區(qū)關(guān)聯(lián)起來(lái)。沒(méi)錯(cuò)這個(gè)方法只是關(guān)聯(lián)而已,沒(méi)有真的繪制。

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

原生就是這樣實(shí)現(xiàn),繪制之后顏色和透明度就繪制到對(duì)應(yīng)的紋理了。 透明度是float 類(lèi)型,可直接理解為一維向量。

然后再次繪制的時(shí)候就可以用這兩個(gè)紋理的數(shù)據(jù)去修改alpha 使得最終的合成符合他那個(gè)公式,我也不理解這個(gè)公式,就這樣吧。

靈光乍現(xiàn)

我理解了這個(gè)算法的一套流程,之后就發(fā)現(xiàn)文章開(kāi)頭的問(wèn)題。我發(fā)現(xiàn)blend和 bindframeBuffer的失靈之后,就去搜了一下對(duì)應(yīng)的api ,然后斷點(diǎn)看執(zhí)行時(shí)機(jī)。

不知過(guò)了多久,也許一瞬,也許半天,我突然意識(shí)到,如果threejs實(shí)現(xiàn)了drawBuffers的封裝,那么它必然使用了這個(gè)api,我直接搜 drawBuffers不就行了 。

于是我就發(fā)現(xiàn)了,rendertarget必須設(shè)置為 multipleRendertarget。 所以我轉(zhuǎn)而搜這個(gè),于是乎就發(fā)現(xiàn)了,有現(xiàn)成的example.

使用WebGLMultipleRenderTargets

首先當(dāng)然是實(shí)例化,需要傳入紋理的尺寸和輸出變量的數(shù)目。

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

然后在繪制之前設(shè)置渲染目標(biāo)。

	renderer.setRenderTarget( renderTarget );

沒(méi)了,就這么多。 至于紋理參數(shù)的設(shè)置,小細(xì)節(jié)不拘。

繪制后,就可以把 renderTarget.texture[ N ] 用three的方式傳給著色器。 這里有一個(gè)小點(diǎn)要注意。

renderTarget.texture 沒(méi)有復(fù)數(shù)。

以上就是threejs中使用drawbufferss示例詳解的詳細(xì)內(nèi)容,更多關(guān)于threejs使用drawbufferss的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論