日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

简单一招搞定 three.js 屏幕适配

發布時間:2025/4/9 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 简单一招搞定 three.js 屏幕适配 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這篇文章只討論?PerspectiveCamera?的適配方法

做過手機 H5 的同學可能會覺得屏幕適配挺麻煩。原因是設計師提供的設計稿尺寸比固定,但是前端開發者卻要適配不同大小、長寬比的目標設備。適配的終極目標無非是最大程度把主體內容優雅地呈現給用戶。開發和設計如果沒有協調好的話可能會妥協比較丑陋的方案,例如由于設計比例問題,為了照顧主體內容不被裁剪,只好設備兩邊,或者上下留黑邊這種。

不過在 3D 的世界里,我們不用擔心會有黑邊的問題,因為 3D 場景是無限延伸的,總能填滿任何比例的屏幕。

先看看 PerspectiveCamera 官方 API 說明如下:

PerspectiveCamera( fov, aspect, near, far )fov — Camera frustum vertical field of view. aspect — Camera frustum aspect ratio. near — Camera frustum near plane. far — Camera frustum far plane.

上面四個參數都會影響成像結果,fov?和?aspect?設置 XY 平面的范圍,也就是廣度。?near?和?far?影響的是縱深 Z 軸的范圍,也就是深度。縱深只要保證物體離相機距離在這個范圍就可以了,這是為了性能而設置的參數,由用戶設置,只渲染必要的東西。實際上真實的相機這兩個值對應的是 0 到 無限遠。

這些參數設置好之后,成像就相應確定了。最后 three.js 把相機拍攝到的矩形區域對應好四個頂點渲染到屏幕上。同樣比例的屏幕看到的圖像是一致的,與屏幕大小無關</span>。

下面我用一個簡單的場景來看一下這些參數對成像的影響。

場景元素

  • 相機 (PerspectiveCamera)

  • 一個邊長為 100 的平面(主體內容范圍),放在世界坐標中心。

var camera = new THREE.PerspectiveCamera(53, 500 / 500, 0.1, 1000); var planeGemo = new THREE.PlaneGeometry( 100, 100, 10, 10 ) var meshMaterial = new THREE.MeshLambertMaterial(); meshMaterial.color = new THREE.Color(0x2dcaf1); meshMaterial.side = THREE.DoubleSide; var wireFrameMat = new THREE.MeshBasicMaterial(); wireFrameMat.color = new THREE.Color(0xdddddd); wireFrameMat.wireframe = true; var plane = THREE.SceneUtils.createMultiMaterialObject(planeGemo, [meshMaterial, wireFrameMat]); scene.add(plane);

目標

在任何屏幕下,都能最大程度地顯示完整的立方體。最大程度,就是最少多余空間的意思。下面是要達到效果

設置 fov 參數

可以直接想到的一種適配方法是——改變 camera 到目標物體的距離以控制成像的內容,但是這樣做計算成本比較高,而且還有可能影響其他一些數值,然后需要相應一起計算修改。
我想到改變視角也可以達到控制成像內容多少的目的,于是我想可不可以只通過改變 fov 一個數值,達到我要的效果。

fov 官網的定義翻譯過來是垂直方向的視角大小。我們先規定好相機到平面的距離為 100,然后試試看能不能通過計算設置 fov 值,剛好讓平面填滿一個寬高比為 1:1 的屏幕。

plane.position.set(0,0,0); camera.position.set(0,0,100); camera.lookAt(new THREE.Vector3);

觀察上面的圖,可以很容易求出 fov 的值, fov = arctan((100/2)/100) * 2; fov 為 0.9272952180016122,約等于 53 度。

camera.fov = Math.atan((100/2)/100) * 2 * (180 / Math.PI); camera.updateProjectionMatrix();

設置完剛剛求出的 fov 值,將場景渲染到 寬高比為 1:1 的畫布上。

渲染結果和預想的一樣,平面剛好填滿了 1:1 的畫布。

fov 和寬高比例的關系

下面在固定的 fov 下,使用 dat.gui 工具調整寬高比,觀察渲染區域的變化。

因為fov設置的是垂直方向的視角范圍,可以看到無論我們怎么改變寬高比例,垂直方向的渲染范圍,都是一致的。水平方向則是以裁剪的方式顯示。也就是說當我們設置好視角讓垂直方向范圍剛好等于主體內容的范圍,只要寬高比大于1,我們得到的渲染結果,已經是最佳的了。問題就只剩下當寬高比小于1的情況了。

寬高比小于1的時候,垂直方向顯示的高度剛好是等于主體內容的高度。為了能讓水平方向完整顯示主體內容,我們只有將垂直方向范圍增大,也就是將 fov 設置一個更大的值,此時水平方向的范圍也會隨之增大。當將 fov調整到 水平方向剛好能顯示主體內容時,垂直方向此時顯示的范圍是超過主體內容垂直方向的范圍的。其中的關系,其實可以用很簡單的函數求出來。

已知 照相機到主題內容的距離為 d
正方形主體內容的邊長為 w

設寬高比為 r,求照相機垂直方向的視角 f

當 r >= 1 時,照相機拍攝到的垂直方向范圍等于 w

當 r > 1
d * tan(f/2) * 2 = w

當 r < 1 時,照相機拍攝到的水平方向范圍等于 w,垂直方向范圍應該是 w/r
d * tan(f/2) * 2 = w/r

這樣,任意寬高比例的屏幕應該對應多大的垂直視角就確定了。

最終代碼與效果

var controls = new function () { camera.position.z = CAMERA_TO_MAIN_DIS; this.width = 500; this.height = 500; this.planeRY = 0; /** * 計算相機 fov 的函數 * @param d : 在相機前方 d 距離 * @param w : 想要看到最大正方形區域邊長為 w * @param r : 屏幕寬高比 */ function calcFov(d, w, r) { var f; var vertical = w; if (r < 1) { vertical = vertical/r; } f = Math.atan(vertical/d/2)*2 * (180 / Math.PI); return f; } this.redraw = ()=>{ webGLRenderer.setSize(this.width, this.height); plane.rotation.y = this.planeRY; camera.fov = calcFov(CAMERA_TO_MAIN_DIS, MAIN_CONTENT_WIDTH, this.width / this.height); camera.aspect = this.width / this.height; camera.updateProjectionMatrix(); } }

效果:

demo 的完整代碼:http://codepen.io/JasonTurbo/pen/ZLwJMo點擊預覽
原文鏈接:https://segmentfault.com/a/1190000008796468

轉載于:https://www.cnblogs.com/ningxiaofang/p/8554785.html

總結

以上是生活随笔為你收集整理的简单一招搞定 three.js 屏幕适配的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 午夜色福利 | xx99小雪| 任你操精品视频 | 九九热九九爱 | 日本一区二区观看 | 色综合久久88色综合天天免费 | 日韩中文在线观看 | 亚洲精品一线二线三线 | 亚洲视频精品在线观看 | 亚洲精品福利 | 国产视频一区二区在线播放 | 亚洲综合大片69999 | 久久99国产精品成人 | 欧美精品久久久久 | 天天摸天天操天天射 | 成人字幕| 亚洲一区二区三区视频在线 | 精品xxx | 日本在线视频播放 | 国模少妇一区二区三区 | 人妻互换一二三区激情视频 | 精品久久精品 | 免费黄色在线播放 | 午夜少妇视频 | 奇米精品一区二区三区在线观看一 | 黄色大片在线免费观看 | 亚洲av无码一区二区二三区 | 99riav3国产精品视频 | 国产精品久久久久久婷婷天堂 | 在线免费观看国产 | 一级淫片a | 久久叉 | av综合网站 | 色综合激情网 | 国产二三区 | 爱上av | 亚洲精品成人a | 日韩成人黄色 | 久热网站 | 永久中文字幕 | 视频二区中文字幕 | 日韩精品在线视频免费观看 | 动漫美女被吸乳奶动漫视频 | 特一级黄色片 | 日韩久久久久久久久久久 | 黑森林av| 在线h网站 | 福利视频在线免费观看 | 中文字幕色站 | 97视频久久久 | 欧美性狂猛xxxxxbbbbb | 国产精品免费视频一区二区三区 | av黄色网址 | 夜间福利视频 | 免费av资源 | 中文写幕一区二区三区免费观成熟 | 久久精品视频一区二区 | 一级大毛片 | 日韩免费av一区二区 | 国产男女视频在线观看 | 日本55丰满熟妇厨房伦 | 北条麻妃久久精品 | 欧美黄色一区 | 综合久久久久久 | 久久精品国产99久久久 | 麻豆一区二区三区四区 | 国产男女猛烈无遮挡 | 在线免费精品 | 久久视频在线观看免费 | 久久y | 嫩草嫩草嫩草嫩草嫩草 | 日韩簧片在线观看 | 狠狠综合一区 | 自拍欧美日韩 | 性欢交69国产精品 | 久久免费资源 | 亚洲欧美日韩精品一区 | 日韩精品一区二区三区视频 | 久久国产中文字幕 | 亚洲欧洲一区二区三区 | 韩日成人 | 人妻互换一区二区激情偷拍 | 亚洲另类自拍 | 亚洲va欧美 | 中文字幕一区二区三区精品 | 欧美日韩黑人 | 人妻互换免费中文字幕 | 三级网站国产 | 黄色欧美在线 | 午夜不卡在线观看 | 国产精品九九视频 | 欧美区二区三区 | 又骚又黄的视频 | 污片在线观看 | 国产一区福利 | 蜜臀一区二区三区精品免费视频 | 老子影院午夜精品无码 | 妹子干综合网 | 亚洲精品久久久蜜桃 |