电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

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

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

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

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

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

步驟1:設定和正面折射

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

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

與您期望的相反,我們的材料將不是透明的,實際上,我們將對鉆石后面的任何東西進行采樣和變形。為此,我們需要將場景(沒有菱形)渲染為紋理。我只是使用正交攝影機渲染全屏平面,但這也可能是充滿其他對象的場景。在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)在該花一點點理論了。透明材料(如玻璃)可以彎曲,因此可見。那是因為光在玻璃中的傳播要比空氣中的傳播慢,因此當光波以一定角度撞擊玻璃物體時,這種速度變化會導致光波改變方向。波浪方向的這種變化描述了折射現(xiàn)象。

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

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

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內置折射函數(shù)的前兩個參數(shù)。第三個參數(shù)是折射率的比率,即我們的快速介質(空氣)的折射率(IOR)除以我們的慢速介質(玻璃)的IOR。在這種情況下,該值為1.0 / 1.5,但是您可以調整該值以獲得所需的結果。例如,水的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實現(xiàn)實時多邊形折射

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

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

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

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

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

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

現(xiàn)在,我們可以根據(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實現(xiàn)實時多邊形折射

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

步驟3:多邊折射

到目前為止,我們已經了解了有關反射和折射的知識,我們可以理解,光在離開對象之前可以在對象內部來回反彈幾次。

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

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

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

讓我們像在步驟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;

最后,我們結合了正面和背面法線。

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

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

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

我們做到了!我們可以看到鉆石的所有側面,僅是因為我們對鉆石的材質進行了折射和反射。

局限性

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

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

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

標簽: JavaScript
相關文章:
主站蜘蛛池模板: 污泥烘干机-低温干化机-工业污泥烘干设备厂家-焦作市真节能环保设备科技有限公司 | 无轨电动平车_轨道平车_蓄电池电动平车★尽在新乡百特智能转运设备有限公司 | 北京成考网-北京成人高考网| 进口试验机价格-进口生物材料试验机-西安卡夫曼测控技术有限公司 | 火锅底料批发-串串香技术培训[川禾川调官网] | 电缆故障测试仪_电缆故障定位仪_探测仪_检测仪器_陕西意联电气厂家 | Brotu | 关注AI,Web3.0,VR/AR,GPT,元宇宙区块链数字产业 | 游泳池设计|设备|配件|药品|吸污机-东莞市太平洋康体设施有限公司 | 民用音响-拉杆音响-家用音响-ktv专用音响-万昌科技 | 云阳人才网_云阳招聘网_云阳人才市场_云阳人事人才网_云阳人家招聘网_云阳最新招聘信息 | 学习虾-免费的学习资料下载平台| 船用锚链|专业锚链生产厂家|安徽亚太锚链制造有限公司 | 工业机械三维动画制作 环保设备原理三维演示动画 自动化装配产线三维动画制作公司-南京燃动数字 聚合氯化铝_喷雾聚氯化铝_聚合氯化铝铁厂家_郑州亿升化工有限公司 | 宁夏活性炭_防护活性炭_催化剂载体炭-宁夏恒辉活性炭有限公司 | 【灵硕展览集团】展台展会设计_展览会展台搭建_展览展示设计一站式服务公司 | 番茄畅听邀请码怎么输入 - Dianw8.com| 成都装修公司-成都装修设计公司推荐-成都朗煜装饰公司 | 重庆中专|职高|技校招生-重庆中专招生网 | 沈阳庭院景观设计_私家花园_别墅庭院设计_阳台楼顶花园设计施工公司-【沈阳现代时园艺景观工程有限公司】 | 西安展台设计搭建_西安活动策划公司_西安会议会场布置_西安展厅设计西安旭阳展览展示 | 聚合氯化铝-碱式氯化铝-聚合硫酸铁-聚氯化铝铁生产厂家多少钱一吨-聚丙烯酰胺价格_河南浩博净水材料有限公司 | 集装箱标准养护室-集装箱移动式养护室-广州璟业试验仪器有限公司 | 深圳激光打标机_激光打标机_激光焊接机_激光切割机_同体激光打标机-深圳市创想激光科技有限公司 深圳快餐店设计-餐饮设计公司-餐饮空间品牌全案设计-深圳市勤蜂装饰工程 | 管家婆-管家婆软件-管家婆辉煌-管家婆进销存-管家婆工贸ERP | 生物风-销售载体,基因,质粒,ATCC细胞,ATCC菌株等,欢迎购买-百风生物 | 专注氟塑料泵_衬氟泵_磁力泵_卧龙泵阀_化工泵专业品牌 - 梭川泵阀 | 世界箱包品牌十大排名,女包小众轻奢品牌推荐200元左右,男包十大奢侈品牌排行榜双肩,学生拉杆箱什么品牌好质量好 - Gouwu3.com | 长沙广告公司|长沙广告制作设计|长沙led灯箱招牌制作找望城湖南锦蓝广告装饰工程有限公司 | 丹佛斯压力传感器,WISE温度传感器,WISE压力开关,丹佛斯温度开关-上海力笙工业设备有限公司 | 沈阳庭院景观设计_私家花园_别墅庭院设计_阳台楼顶花园设计施工公司-【沈阳现代时园艺景观工程有限公司】 | 西门子气候补偿器,锅炉气候补偿器-陕西沃信机电工程有限公司 | 施工围挡-施工PVC围挡-工程围挡-深圳市旭东钢构技术开发有限公司 | 珠海网站建设_响应网站建设_珠海建站公司_珠海网站设计与制作_珠海网讯互联 | 泰国试管婴儿_泰国第三代试管婴儿费用|成功率|医院—新生代海外医疗 | 北京签证代办_签证办理_商务签证_旅游签证_寰球签证网 | 佛山市钱丰金属不锈钢蜂窝板定制厂家|不锈钢装饰线条|不锈钢屏风| 电梯装饰板|不锈钢蜂窝板不锈钢工艺板材厂家佛山市钱丰金属制品有限公司 | 杭州标识标牌|文化墙|展厅|导视|户内外广告|发光字|灯箱|铭阳制作公司 - 杭州标识标牌|文化墙|展厅|导视|户内外广告|发光字|灯箱|铭阳制作公司 | 免联考国际MBA_在职MBA报考条件/科目/排名-MBA信息网 | 颚式破碎机,圆锥破碎机,制砂机-新乡市德诚机电制造有限公司 | H型钢切割机,相贯线切割机,数控钻床,数控平面钻,钢结构设备,槽钢切割机,角钢切割机,翻转机,拼焊矫一体机 | 机械立体车库租赁_立体停车设备出租_智能停车场厂家_春华起重 |