成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

簡(jiǎn)單一招搞定 three.js 屏幕適配

騫諱護(hù) / 2100人閱讀

摘要:我們先規(guī)定好相機(jī)到平面的距離為,然后試試看能不能通過(guò)計(jì)算設(shè)置值,剛好讓平面填滿一個(gè)寬高比為的屏幕。最終代碼與效果計(jì)算相機(jī)的函數(shù)在相機(jī)前方距離想要看到最大正方形區(qū)域邊長(zhǎng)為屏幕寬高比效果的完整代碼原文鏈接

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

做過(guò)手機(jī) H5 的同學(xué)可能會(huì)覺(jué)得屏幕適配挺麻煩。原因是設(shè)計(jì)師提供的設(shè)計(jì)稿尺寸比固定,但是前端開發(fā)者卻要適配不同大小、長(zhǎng)寬比的目標(biāo)設(shè)備。適配的終極目標(biāo)無(wú)非是最大程度把主體內(nèi)容優(yōu)雅地呈現(xiàn)給用戶。開發(fā)和設(shè)計(jì)如果沒(méi)有協(xié)調(diào)好的話可能會(huì)妥協(xié)比較丑陋的方案,例如由于設(shè)計(jì)比例問(wèn)題,為了照顧主體內(nèi)容不被裁剪,只好設(shè)備兩邊,或者上下留黑邊這種。

不過(guò)在 3D 的世界里,我們不用擔(dān)心會(huì)有黑邊的問(wèn)題,因?yàn)?3D 場(chǎng)景是無(wú)限延伸的,總能填滿任何比例的屏幕。

先看看 PerspectiveCamera 官方 API 說(shuō)明如下:

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.

上面四個(gè)參數(shù)都會(huì)影響成像結(jié)果,fovaspect 設(shè)置 XY 平面的范圍,也就是廣度。 nearfar 影響的是縱深 Z 軸的范圍,也就是深度??v深只要保證物體離相機(jī)距離在這個(gè)范圍就可以了,這是為了性能而設(shè)置的參數(shù),由用戶設(shè)置,只渲染必要的東西。實(shí)際上真實(shí)的相機(jī)這兩個(gè)值對(duì)應(yīng)的是 0 到 無(wú)限遠(yuǎn)。

這些參數(shù)設(shè)置好之后,成像就相應(yīng)確定了。最后 three.js 把相機(jī)拍攝到的矩形區(qū)域?qū)?yīng)好四個(gè)頂點(diǎn)渲染到屏幕上。同樣比例的屏幕看到的圖像是一致的,與屏幕大小無(wú)關(guān)

下面我用一個(gè)簡(jiǎn)單的場(chǎng)景來(lái)看一下這些參數(shù)對(duì)成像的影響。

場(chǎng)景元素

相機(jī) (PerspectiveCamera)

一個(gè)邊長(zhǎng)為 100 的平面(主體內(nèi)容范圍),放在世界坐標(biāo)中心。

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(0xffffdffffd);
wireFrameMat.wireframe = true;

var plane = THREE.SceneUtils.createMultiMaterialObject(planeGemo, [meshMaterial, wireFrameMat]);

scene.add(plane);
目標(biāo)

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

設(shè)置 fov 參數(shù)

可以直接想到的一種適配方法是——改變 camera 到目標(biāo)物體的距離以控制成像的內(nèi)容,但是這樣做計(jì)算成本比較高,而且還有可能影響其他一些數(shù)值,然后需要相應(yīng)一起計(jì)算修改。
我想到改變視角也可以達(dá)到控制成像內(nèi)容多少的目的,于是我想可不可以只通過(guò)改變 fov 一個(gè)數(shù)值,達(dá)到我要的效果。

fov 官網(wǎng)的定義翻譯過(guò)來(lái)是垂直方向的視角大小。我們先規(guī)定好相機(jī)到平面的距離為 100,然后試試看能不能通過(guò)計(jì)算設(shè)置 fov 值,剛好讓平面填滿一個(gè)寬高比為 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();

設(shè)置完剛剛求出的 fov 值,將場(chǎng)景渲染到 寬高比為 1:1 的畫布上。

渲染結(jié)果和預(yù)想的一樣,平面剛好填滿了 1:1 的畫布。

fov 和寬高比例的關(guān)系

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

因?yàn)閒ov設(shè)置的是垂直方向的視角范圍,可以看到無(wú)論我們?cè)趺锤淖儗捀弑壤?,垂直方向的渲染范圍,都是一致的。水平方向則是以裁剪的方式顯示。也就是說(shuō)當(dāng)我們?cè)O(shè)置好視角讓垂直方向范圍剛好等于主體內(nèi)容的范圍,只要寬高比大于1,我們得到的渲染結(jié)果,已經(jīng)是最佳的了。問(wèn)題就只剩下當(dāng)寬高比小于1的情況了。

寬高比小于1的時(shí)候,垂直方向顯示的高度剛好是等于主體內(nèi)容的高度。為了能讓水平方向完整顯示主體內(nèi)容,我們只有將垂直方向范圍增大,也就是將 fov 設(shè)置一個(gè)更大的值,此時(shí)水平方向的范圍也會(huì)隨之增大。當(dāng)將 fov調(diào)整到 水平方向剛好能顯示主體內(nèi)容時(shí),垂直方向此時(shí)顯示的范圍是超過(guò)主體內(nèi)容垂直方向的范圍的。其中的關(guān)系,其實(shí)可以用很簡(jiǎn)單的函數(shù)求出來(lái)。

已知 照相機(jī)到主題內(nèi)容的距離為 d
正方形主體內(nèi)容的邊長(zhǎng)為 w

設(shè)寬高比為 r,求照相機(jī)垂直方向的視角 f

當(dāng) r >= 1 時(shí),照相機(jī)拍攝到的垂直方向范圍等于 w

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

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

這樣,任意寬高比例的屏幕應(yīng)該對(duì)應(yīng)多大的垂直視角就確定了。

最終代碼與效果
var controls = new function () {

    camera.position.z = CAMERA_TO_MAIN_DIS;

    this.width = 500;
    this.height = 500;
    this.planeRY = 0;

    /**
    * 計(jì)算相機(jī) fov 的函數(shù)
    * @param d : 在相機(jī)前方 d 距離
    * @param w : 想要看到最大正方形區(qū)域邊長(zhǎng)為 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
原文鏈接:http://gnauhca.com/blog/2016/11/24/threejs/THREEJS%E5%B1%8F%E5%B9%95%E9%80%82%E9%85%8D/

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/82162.html

相關(guān)文章

  • SegmentFault 技術(shù)周刊 Vol.35 - WebGL:打開網(wǎng)頁(yè)看大片

    摘要:在文末,我會(huì)附上一個(gè)可加載的模型方便學(xué)習(xí)中文藝術(shù)字渲染用原生可以很容易地繪制文字,但是原生提供的文字效果美化功能十分有限。 showImg(https://segmentfault.com/img/bVWYnb?w=900&h=385); WebGL 可以說(shuō)是 HTML5 技術(shù)生態(tài)鏈中最為令人振奮的標(biāo)準(zhǔn)之一,它把 Web 帶入了 3D 的時(shí)代。 初識(shí) WebGL 先通過(guò)幾個(gè)使用 Web...

    objc94 評(píng)論0 收藏0
  • 【51單片機(jī)】??萬(wàn)物互聯(lián)??一招搞定單片機(jī)(持續(xù)更新中......)

    目錄 第一章:?jiǎn)纹瑱C(jī)概述 單片機(jī)的應(yīng)用領(lǐng)域: STC89C52單片機(jī): 單片機(jī)命名規(guī)則: ?單片機(jī)內(nèi)部結(jié)構(gòu)圖: ?單片機(jī)管腳圖: ?單片機(jī)最小系統(tǒng): 進(jìn)制表: 新建一個(gè)工程:? 檢查單片機(jī)驅(qū)動(dòng)是否安裝完成: 打開Keil uVision集成開發(fā)環(huán)境 選擇Atmel下的AT89C52 創(chuàng)建源文件? ?第二章:LED LED介紹: ?點(diǎn)亮LED:?? 第一章:?jiǎn)纹瑱C(jī)概述 單片機(jī)(Micro Contr...

    idisfkj 評(píng)論0 收藏0
  • 全鏈路壓測(cè)一招搞定,阿里云性能測(cè)試鉑金版發(fā)布

    摘要:摘要阿里云性能測(cè)試是卓越的性能測(cè)試平臺(tái),具備強(qiáng)大的分布式壓測(cè)能力,可模擬海量用戶的真實(shí)業(yè)務(wù)場(chǎng)景,讓所有性能問(wèn)題無(wú)所遁形。近日,宣布推出了基于阿里雙全鏈路壓測(cè)平臺(tái)的鉑金版。 摘要: 阿里云性能測(cè)試(Performance Testing Service)是卓越的SaaS性能測(cè)試平臺(tái),具備強(qiáng)大的分布式壓測(cè)能力,可模擬海量用戶的真實(shí)業(yè)務(wù)場(chǎng)景,讓所有性能問(wèn)題無(wú)所遁形。近日,PTS宣布推出了基于...

    zhaochunqi 評(píng)論0 收藏0
  • 全鏈路壓測(cè)一招搞定,阿里云性能測(cè)試鉑金版發(fā)布

    摘要:摘要阿里云性能測(cè)試是卓越的性能測(cè)試平臺(tái),具備強(qiáng)大的分布式壓測(cè)能力,可模擬海量用戶的真實(shí)業(yè)務(wù)場(chǎng)景,讓所有性能問(wèn)題無(wú)所遁形。近日,宣布推出了基于阿里雙全鏈路壓測(cè)平臺(tái)的鉑金版。 摘要: 阿里云性能測(cè)試(Performance Testing Service)是卓越的SaaS性能測(cè)試平臺(tái),具備強(qiáng)大的分布式壓測(cè)能力,可模擬海量用戶的真實(shí)業(yè)務(wù)場(chǎng)景,讓所有性能問(wèn)題無(wú)所遁形。近日,PTS宣布推出了基于...

    gotham 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<