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

threejs中使用drawbufferss示例詳解

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

原因

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

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

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

遇到的下一個困境就是,直接用原生的上下文進行一系列緩沖區(qū)和紋理的綁定操作是徒勞的, 因為three的renderer.render里面會有他的一套處理。 到這里我就意識到了,沒法混用。

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

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

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

歷程

原生的使用

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

要知道,glsl 3.0 里面移除了 gl_FragColor 這個內(nèi)置輸出變量,移除了 attribute varrying 關鍵字, 直接使用當然會報錯。

因為,加權(quán)深度算法用的也是glsl3.0 ,我之前學的是1.0的語法和api,看的時候就有些云里霧里,后來發(fā)覺原來版本不對,立即去研究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;

聲明兩個紋理,并且和顏色緩沖區(qū)綁定,這樣在繪制幀緩沖區(qū)時,會把顏色緩沖區(qū)的像素繪制到紋理。 color_attachmentN就是對應在片元著色器里聲明的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 將這兩個輸出變量和對應的緩沖區(qū)關聯(lián)起來。沒錯這個方法只是關聯(lián)而已,沒有真的繪制。

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

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

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

靈光乍現(xiàn)

我理解了這個算法的一套流程,之后就發(fā)現(xiàn)文章開頭的問題。我發(fā)現(xiàn)blend和 bindframeBuffer的失靈之后,就去搜了一下對應的api ,然后斷點看執(zhí)行時機。

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

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

使用WebGLMultipleRenderTargets

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

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

然后在繪制之前設置渲染目標。

	renderer.setRenderTarget( renderTarget );

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

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

renderTarget.texture 沒有復數(shù)。

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

相關文章

最新評論