日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

如何用threejs實(shí)現(xiàn)實(shí)時(shí)多邊形折射

瀏覽:221日期:2024-03-27 13:53:48
前言

在本教程中,您將學(xué)習(xí)如何使用Three.js在三個步驟中使對象看起來像玻璃。

渲染3D對象時(shí),無論使用某種3D軟件還是使用WebGL進(jìn)行實(shí)時(shí)顯示,始終都必須為其分配材料以使其可見并具有所需的外觀。

可以使用Three.js之類的庫中的現(xiàn)成程序來模仿許多類型的材料,但是在本教程中,我將向您展示如何使用三個對象(三個步驟)使對象看起來像玻璃一樣。

步驟1:設(shè)定和正面折射

在本演示中,我將使用菱形幾何圖形,但是您可以跟隨一個簡單的盒子或任何其他幾何圖形。

讓我們建立我們的項(xiàng)目。我們需要一個渲染器,一個場景,一個透視相機(jī)和我們的幾何圖形。為了渲染我們的幾何圖形,我們需要為其分配材質(zhì)。創(chuàng)建此材料將是本教程的主要重點(diǎn)。因此,繼續(xù)創(chuàng)建具有基本頂點(diǎn)和片段著色器的新ShaderMaterial。

與您期望的相反,我們的材料將不是透明的,實(shí)際上,我們將對鉆石后面的任何東西進(jìn)行采樣和變形。為此,我們需要將場景(沒有菱形)渲染為紋理。我只是使用正交攝影機(jī)渲染全屏平面,但這也可能是充滿其他對象的場景。在Three.js中從菱形分割背景幾何圖形的最簡單方法是使用“圖層”。

this.orthoCamera = new THREE.OrthographicCamera( width / - 2,width / 2, height / 2, height / - 2, 1, 1000 );// assign the camera to layer 1 (layer 0 is default)this.orthoCamera.layers.set(1);const tex = await loadTexture(’texture.jpg’);this.quad = new THREE.Mesh(new THREE.PlaneBufferGeometry(), new THREE.MeshBasicMaterial({map: tex}));this.quad.scale.set(width, height, 1);// also move the plane to layer 1this.quad.layers.set(1);this.scene.add(this.quad);

我們的渲染循環(huán)如下所示:

this.envFBO = new THREE.WebGLRenderTarget(width, height);this.renderer.autoClear = false;render() { requestAnimationFrame( this.render ); this.renderer.clear(); // render background to fbo this.renderer.setRenderTarget(this.envFbo); this.renderer.render( this.scene, this.orthoCamera ); // render background to screen this.renderer.setRenderTarget(null); this.renderer.render( this.scene, this.orthoCamera ); this.renderer.clearDepth(); // render geometry to screen this.renderer.render( this.scene, this.camera );};

好吧,現(xiàn)在該花一點(diǎn)點(diǎn)理論了。透明材料(如玻璃)可以彎曲,因此可見。那是因?yàn)楣庠诓Aе械膫鞑ヒ瓤諝庵械膫鞑ヂ虼水?dāng)光波以一定角度撞擊玻璃物體時(shí),這種速度變化會導(dǎo)致光波改變方向。波浪方向的這種變化描述了折射現(xiàn)象。

如何用threejs實(shí)現(xiàn)實(shí)時(shí)多邊形折射

為了在代碼中復(fù)制這一點(diǎn),我們將需要知道我們的眼睛向量與世界空間中鉆石表面(法線)向量之間的角度。讓我們更新頂點(diǎn)著色器以計(jì)算這些向量。

varying vec3 eyeVector;varying vec3 worldNormal;void main() { vec4 worldPosition = modelMatrix * vec4( position, 1.0); eyeVector = normalize(worldPos.xyz - cameraPosition); worldNormal = normalize( modelViewMatrix * vec4(normal, 0.0)).xyz; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);}

在片段著色器中,我們現(xiàn)在可以將eyeVector和worldNormal用作glsl內(nèi)置折射函數(shù)的前兩個參數(shù)。第三個參數(shù)是折射率的比率,即我們的快速介質(zhì)(空氣)的折射率(IOR)除以我們的慢速介質(zhì)(玻璃)的IOR。在這種情況下,該值為1.0 / 1.5,但是您可以調(diào)整該值以獲得所需的結(jié)果。例如,水的IOR為1.33,鉆石的IOR為2.42。

uniform sampler2D envMap;uniform vec2 resolution;varying vec3 worldNormal;varying vec3 viewDirection;void main() { // get screen coordinates vec2 uv = gl_FragCoord.xy / resolution; vec3 normal = worldNormal; // calculate refraction and add to the screen coordinates vec3 refracted = refract(eyeVector, normal, 1.0/ior); uv += refracted.xy;// sample the background texture vec4 tex = texture2D(envMap, uv); vec4 output = tex; gl_FragColor = vec4(output.rgb, 1.0);}

如何用threejs實(shí)現(xiàn)實(shí)時(shí)多邊形折射

真好!我們成功編寫了折射著色器。但是我們的鉆石幾乎看不見……部分原因是我們只處理了玻璃的一種視覺特性。并非所有的光都會穿過要折射的材料,實(shí)際上,一部分光會被反射。讓我們看看如何實(shí)現(xiàn)它!

步驟2:反射和菲涅耳方程

為了簡單起見,在本教程中,我們將不計(jì)算適當(dāng)?shù)姆瓷洌鴥H將白色用作反射光。現(xiàn)在,我們怎么知道什么時(shí)候該反思,什么時(shí)候該折射?理論上,這取決于材料的折射率,當(dāng)入射矢量和表面法線之間的角度大于臨界角時(shí),光波將被反射。

如何用threejs實(shí)現(xiàn)實(shí)時(shí)多邊形折射

在片段著色器中,我們將使用菲涅耳方程來計(jì)算反射光線與折射光線之間的比率。不幸的是,glsl也沒有內(nèi)置此方程式,但是您可以從這里復(fù)制它:

float Fresnel(vec3 eyeVector, vec3 worldNormal) { return pow( 1.0 + dot( eyeVector, worldNormal), 3.0 );}

現(xiàn)在,我們可以根據(jù)剛計(jì)算出的菲涅耳比,簡單地將折射紋理顏色與白色反射顏色混合。

uniform sampler2D envMap;uniform vec2 resolution;varying vec3 worldNormal;varying vec3 viewDirection;float Fresnel(vec3 eyeVector, vec3 worldNormal) { return pow( 1.0 + dot( eyeVector, worldNormal), 3.0 );}void main() { // get screen coordinates vec2 uv = gl_FragCoord.xy / resolution; vec3 normal = worldNormal; // calculate refraction and add to the screen coordinates vec3 refracted = refract(eyeVector, normal, 1.0/ior); uv += refracted.xy; // sample the background texture vec4 tex = texture2D(envMap, uv); vec4 output = tex; // calculate the Fresnel ratio float f = Fresnel(eyeVector, normal); // mix the refraction color and reflection color output.rgb = mix(output.rgb, vec3(1.0), f); gl_FragColor = vec4(output.rgb, 1.0);}

如何用threejs實(shí)現(xiàn)實(shí)時(shí)多邊形折射

看起來已經(jīng)好多了,但是還有一些不足之處……嗯,我們看不到透明對象的另一面。讓我們解決這個問題!

步驟3:多邊折射

到目前為止,我們已經(jīng)了解了有關(guān)反射和折射的知識,我們可以理解,光在離開對象之前可以在對象內(nèi)部來回反彈幾次。

為了獲得物理上正確的結(jié)果,我們將必須跟蹤每條光線,但是不幸的是,這種計(jì)算量太大,無法實(shí)時(shí)渲染。因此,我將向您展示一個簡單的近似值,至少可以直觀地看到我們鉆石的背面。

在一個片段著色器中,我們需要幾何圖形的正面和背面的世界法線。由于我們不能同時(shí)渲染兩側(cè),因此需要首先將背面法線渲染為紋理。

如何用threejs實(shí)現(xiàn)實(shí)時(shí)多邊形折射

讓我們像在步驟1中一樣制作一個新的ShaderMaterial,但是這次我們將世界法線渲染為gl_FragColor。

varying vec3 worldNormal;void main() { gl_FragColor = vec4(worldNormal, 1.0);}

接下來,我們將更新渲染循環(huán)以包括背面通道。

this.backfaceFbo = new THREE.WebGLRenderTarget(width, height);...render() { requestAnimationFrame( this.render ); this.renderer.clear(); // render background to fbo this.renderer.setRenderTarget(this.envFbo); this.renderer.render( this.scene, this.orthoCamera ); // render diamond back faces to fbo this.mesh.material = this.backfaceMaterial; this.renderer.setRenderTarget(this.backfaceFbo); this.renderer.clearDepth(); this.renderer.render( this.scene, this.camera ); // render background to screen this.renderer.setRenderTarget(null); this.renderer.render( this.scene, this.orthoCamera ); this.renderer.clearDepth(); // render diamond with refraction material to screen this.mesh.material = this.refractionMaterial; this.renderer.render( this.scene, this.camera );};

現(xiàn)在,我們在折射材料中采樣背面法線紋理。

vec3 backfaceNormal = texture2D(backfaceMap, uv).rgb;

最后,我們結(jié)合了正面和背面法線。

float a = 0.33;vec3 normal = worldNormal * (1.0 - a) - backfaceNormal * a;

在此等式中,a只是一個標(biāo)量值,指示應(yīng)應(yīng)用背面法線的數(shù)量。

如何用threejs實(shí)現(xiàn)實(shí)時(shí)多邊形折射

我們做到了!我們可以看到鉆石的所有側(cè)面,僅是因?yàn)槲覀儗︺@石的材質(zhì)進(jìn)行了折射和反射。

局限性

正如我已經(jīng)解釋的那樣,用這種方法實(shí)時(shí)渲染物理上正確的透明材料是不可能的。當(dāng)在彼此前面渲染多個玻璃對象時(shí)會發(fā)生另一個問題。由于我們僅對環(huán)境采樣一次,因此無法看透一連串的對象。最后,我在這里演示的屏幕空間折射在畫布的邊緣附近效果不佳,因?yàn)楣饩€可能會折射到其邊界之外的值,并且在將背景場景渲染到渲染目標(biāo)時(shí)我們沒有捕獲到該數(shù)據(jù)。

當(dāng)然,有多種方法可以克服這些限制,但是對于您在WebGL中進(jìn)行實(shí)時(shí)渲染,它們可能并不是全部很好的解決方案。

以上就是如何用threejs實(shí)現(xiàn)實(shí)時(shí)多邊形折射的詳細(xì)內(nèi)容,更多關(guān)于JS庫的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: JavaScript
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
亚洲免费黄色| 日韩一级网站| 日韩精品亚洲一区二区三区免费| 午夜国产精品视频免费体验区| 亚洲成人不卡| 在线观看精品| 欧美中文一区二区| 五月天久久777| 亚洲精品1区| 99国产成+人+综合+亚洲欧美| 中日韩男男gay无套| 欧美一区二区性| av不卡免费看| 日韩欧美三区| 国产精品密蕾丝视频下载| 国产激情欧美| 中文字幕高清在线播放| 日本欧美不卡| 国产视频一区三区| 日韩免费精品| 麻豆视频一区| 欧美日韩视频免费观看| 欧美日韩视频| 日韩精品中文字幕吗一区二区 | 成人在线黄色| 欧美一区久久久| 狠狠爱成人网| 日本免费在线视频不卡一不卡二| 免费亚洲一区| 亚洲高清激情| 天堂av一区| 韩国一区二区三区视频| 欧美亚洲精品在线| 日韩欧美在线精品| 岛国av免费在线观看| 青青伊人久久| 不卡专区在线| 欧美专区18| 国产精品久久免费视频| av中文字幕在线观看第一页 | 久久精品主播| 亚洲一二av| 精品视频99| 99国产精品| 欧美a级一区二区| 欧美日韩在线二区| 亚洲精品成人一区| 首页国产精品| 免费人成在线不卡| 精品国产a一区二区三区v免费| 国产99精品一区| 亚洲久久一区| 国产传媒在线| 中文不卡在线| 91免费精品| 蜜臀av亚洲一区中文字幕| 欧美xxxx性| 美女被久久久| 久久uomeier| 日韩精品导航| 亚洲天堂成人| 麻豆精品视频在线观看免费| 久久xxxx精品视频| 国产拍在线视频| 日本成人精品| 在线一区电影| 欧美国产极品| 一区二区三区四区在线观看国产日韩 | 91精品观看| 国产精品magnet| 欧美日韩国产亚洲一区| 水蜜桃精品av一区二区| 日韩成人午夜精品| 亚洲精品一区二区妖精| 精品入口麻豆88视频| 中文字幕日韩高清在线| 午夜精品成人av| 国产精品入口久久| 国产亚洲福利| 一区二区三区四区日本视频| 日韩精品福利一区二区三区| 在线国产一区| 人人草在线视频| 国产美女久久| 在线观看亚洲精品福利片| 欧美jjzz| 亚洲涩涩在线| 国产一区二区三区天码| 日本va欧美va欧美va精品| 亚洲激情欧美| 欧美 日韩 国产一区二区在线视频 | 久久精品理论片| 日韩毛片一区| 亚洲欧美高清| 色爱av综合网| 精品三区视频| 国产精品亚洲一区二区在线观看| 蜜臀av性久久久久蜜臀aⅴ四虎 | 免费欧美在线视频| 免费视频亚洲| 丝袜诱惑一区二区| 精品国产99| 老牛国内精品亚洲成av人片| 88久久精品| 偷拍亚洲精品| 亚洲最新av| 视频精品一区二区| 中日韩男男gay无套| 国精品一区二区| 久久精品国产大片免费观看| 美女一区网站| 欧美日韩免费看片| 午夜欧美巨大性欧美巨大| 久久不见久久见国语| 欧美色综合网| 日韩不卡一二三区| 美女网站一区| 欧美福利专区| 午夜日韩福利| 在线亚洲国产精品网站| 亚洲欧美一区在线| 精品在线91| 欧美粗暴jizz性欧美20| 蜜桃国内精品久久久久软件9| 欧美国产91| 99视频一区| 免费黄网站欧美| 亚洲美女91| 天堂av一区| 国产午夜一区| 久久av网址| 岛国精品一区| 日韩精品一区二区三区免费观影| 欧美sm一区| 午夜久久久久| 狠狠干成人综合网| 亚洲精品韩国| 久久精品99国产国产精| 国产精品久久久亚洲一区| 国产精品tv| 日本а中文在线天堂| 国产精品字幕| 欧美精品激情| 免费在线视频一区| 日韩av中文字幕一区| 国产精品白丝一区二区三区| 精品视频在线一区二区在线| 国产白浆在线免费观看| 亚洲a一区二区三区| 日韩亚洲国产欧美| 日韩精品久久久久久久软件91| 国产精品啊v在线| 福利欧美精品在线| 国产专区一区| 亚洲精品大片| 精品视频网站| 欧美日韩中文一区二区| 噜噜噜躁狠狠躁狠狠精品视频 | 午夜电影亚洲| 91大神在线观看线路一区| 国产精品久久久久蜜臀| 亚州av乱码久久精品蜜桃| 日本国产欧美| 国产成人久久| 日韩午夜av| 国产精品一区二区精品视频观看| 成人片免费看| 亚洲精品一区二区在线播放∴| 国产探花在线精品| 日韩大片在线观看| 亚洲综合福利| 97精品视频在线看| 黄色精品网站| 国产精品伊人| 蜜桃成人av| 国产精品久久亚洲不卡| 激情久久久久久| 日韩高清电影一区| 亚洲涩涩在线| 日本精品久久| 久久蜜桃精品| 69精品国产久热在线观看| 免费看av不卡| 日欧美一区二区| 日韩一区二区在线免费| 日韩影院精彩在线| 国产一区二区三区四区五区传媒| 亚洲午夜av| 国产精品一区二区美女视频免费看| 亚洲a一区二区三区| 国产欧美日韩亚洲一区二区三区| 亚洲不卡系列| 国产欧美自拍一区| 婷婷丁香综合| 国产精久久久| 综合一区二区三区| 久久天堂av| 国产精品三级| 水蜜桃久久夜色精品一区的特点 | 国产精品18|