国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

H5打造3d場景不完全攻略(二): Amazing CSS3D

fancyLuo / 3600人閱讀

摘要:實(shí)現(xiàn)方法可參考這篇文章純打造的模型渲染器實(shí)現(xiàn)全景。天空盒子相信很多打造過或有了解過全景的同行們都知道這個(gè)概念。首先將創(chuàng)建好的六個(gè)面切割出來,以命名標(biāo)記位置。柱形柱形全景也不算復(fù)雜。

前言

對(duì)的,本文就是著重介紹如何使用CSS3中的3D變換打造出H5中的3D效果。靈感來源于造物節(jié)團(tuán)隊(duì)的3d引擎,因?yàn)槭褂梅椒ū容^復(fù)雜,也沒有開源的API文檔,于是想自己另外造個(gè)輪子,便開始了相關(guān)內(nèi)容的學(xué)習(xí)和實(shí)踐。
眾所周知,目前市面上的H5 3D類庫(如Three)、引擎(Egret)、構(gòu)建工具(kpano、720云)都或存在體積太大、不開源、非免費(fèi)、學(xué)習(xí)成本高等問題。對(duì)于我們較為熟悉的CSS3,為什么就不對(duì)它好好利用一把呢?誠然,CSS3存在我們比較清楚的短板,CSS對(duì)平面的渲染能力高,但是對(duì)3D建模方面便力不從心了。

我們知道3D的表現(xiàn)形式即讓我們通過平面可從不同角度看到真實(shí)物體的展示效果。

在計(jì)算機(jī)世界里,3D世界是由點(diǎn)組成,兩個(gè)點(diǎn)能夠組成一條直線,三個(gè)不在一條直線上的點(diǎn)就能夠組成一個(gè)三角形面,無數(shù)三角形面就能夠組成各種形狀的物體,如下圖。

我們通常把這種網(wǎng)格模型叫做Mesh模型。給物體貼上皮膚,或者專業(yè)點(diǎn)就叫做紋理,那么這個(gè)物體就活靈活現(xiàn)了。最后無數(shù)的物體就組成了我們的3D世界。

Three中模型解析器的原理是將頂點(diǎn)數(shù)組將模型的頂點(diǎn)用數(shù)組儲(chǔ)存起來,再利用three中的face函數(shù)取得定點(diǎn)數(shù)組中的三個(gè)或四個(gè)頂點(diǎn)的索引構(gòu)成空間平面。如此反復(fù),模型就被完整構(gòu)造出來了。

于是,越復(fù)雜的物體就需要越多的網(wǎng)面拼接。而css中是不存在根據(jù)坐標(biāo)建立空間平面的能力的。

(插個(gè)題外話,其實(shí)css有一個(gè)屬性與坐標(biāo)有關(guān),那就是clip-path。這個(gè)屬性的特性賦予了css3一定的建模能力。實(shí)現(xiàn)方法可參考這篇文章 純clip-path打造的3D模型渲染器)

CSS3實(shí)現(xiàn)3D全景

。上篇文章介紹了Web3D的一些表現(xiàn)形式,這里著重談?wù)勗趺匆訡SS3實(shí)現(xiàn)3D全景。下面會(huì)探索Three實(shí)現(xiàn)全景的方案,因?yàn)閃ebGL門檻和學(xué)習(xí)成本還是比較高的,不適于用于快速開發(fā)。造物節(jié)的CSS3d全景已有文章對(duì)其進(jìn)行了技術(shù)探秘,但都未深入談及具體實(shí)現(xiàn)方式。

要清晰理解實(shí)現(xiàn)方式,必須對(duì)CSS3的transform、perspective有一定的認(rèn)識(shí)。
原理方面的東西我就不深入講了,大家可以先看看這篇文章,對(duì)CSS3D有一個(gè)大致的概念。
玩轉(zhuǎn) CSS 3D - 原理篇

CSS全景可通過建立柱形或者立方體再通過貼圖方式實(shí)現(xiàn)。也許會(huì)有人問,球體行不行?實(shí)際上是不行的,球體模型由無數(shù)個(gè)極小的平面拼接構(gòu)成連貫曲面,而CSS缺乏使平面扭曲的屬性。球體模型我們可以使用上文提過的Clip-3d建造出,但是,貼圖問題就解決不了了。

天空盒子

相信很多打造過或有了解過3d全景的同行們都知道這個(gè)概念。實(shí)際上Skybox就是一個(gè)立方體,通過給六個(gè)面貼上不同的,邊緣可以無縫貼合的圖片,再將視角伸入盒子內(nèi)部。可以想象成我們自己站入了一個(gè)巨型立方體盒子內(nèi)部,移動(dòng)視角便能看到不同的場景。

1、貼圖
來看一張?zhí)炜蘸凶拥馁N圖,剪頭指向的邊緣代表需要無縫貼合的邊。

從上圖可以看出只要相互貼合的兩個(gè)面上的圖像能夠無縫拼接,那么再通過對(duì)各個(gè)面進(jìn)行一定的旋轉(zhuǎn)變換,天空盒子就能被打造出來了。

那么問題來了,怎么去拍攝制作這樣的圖片呢?這就需要通過一些專業(yè)軟件了,比如pano2vr,max等。其實(shí),需要用到這些專業(yè)工具打造的全景對(duì)畫質(zhì)和拼合度的要求都非常高了,而單純依靠CSS3中的變化給不了它們很好的體驗(yàn)。

但我們今天討論的是某些運(yùn)營活動(dòng)H5打造的全景,此全景不一定真實(shí)存在,或者是和真實(shí)場景有一定的比例差距。例如星空、海底。對(duì)于這類貼合度可人為改變的全景圖的打造,我們可以采用現(xiàn)有的高清圖片,再經(jīng)由PS轉(zhuǎn)換成六面全景圖。
貼一篇文章 Create a Skybox From Photos
其實(shí)主要思想是
在一張大圖上勾畫出六個(gè)面的選取 >
選擇大圖中某個(gè)面的相鄰面將其旋轉(zhuǎn)到需要拼合的盒子的某個(gè)面上,使他們完美貼合 >
得到最合理的六面貼圖后,觀察有無創(chuàng)造出新的邊緣,通過蒙版等工具使他們自然融合。

2、構(gòu)造
貼圖完成就可以創(chuàng)建立方體了。首先將創(chuàng)建好的六個(gè)面切割出來,以front、back、left、right…命名標(biāo)記位置。

 .sence {
      -webkit-perspective: 1000px;
    }
    .cube {
      width: 500px;
      height: 500px;
      margin: 100px auto;
      transform-style: preserve-3d;
    }
    .cube img {
      width: 130px;
      height: 130px;
      position: absolute;
    }
    .cube img:nth-child(1) {

    }
    .cube img:nth-child(2) {
      transform:  rotateY(180deg);
    }
    .cube img:nth-child(3) {
      transform:  rotateY(90deg);
    }
    .cube img:nth-child(4) {
      transform:  rotateY(-90deg);
    }
    .cube img:nth-child(5) {
      transform:  rotateX(90deg);
    }
    .cube img:nth-child(6) {
      transform:  rotateX(-90deg);
    }

準(zhǔn)備好6個(gè)面,載入貼圖。通過旋轉(zhuǎn),使得每個(gè)面旋轉(zhuǎn)到相印的位置。如左邊的面由原本面朝我們的圖片繞Y軸逆時(shí)針旋轉(zhuǎn)90°得到。(注意Y軸逆時(shí)針旋轉(zhuǎn)是正數(shù))

此時(shí)會(huì)得到下圖這樣的效果:

但是由于每個(gè)面的旋轉(zhuǎn)中心都在其正中位置,因此還不能形成正方體。于是我們需要讓每個(gè)面產(chǎn)生一定的位移。

貼一張坐標(biāo)系圖以助于大家理解。

現(xiàn)在首先讓front位移到應(yīng)該到的位置,由于全景圖的鏡頭在立方體內(nèi)部,因此,可以想象一下,我們需要將圖片往后移動(dòng)。移動(dòng)距離很明顯為立方體邊長的一半。在這里是65px。得到下圖結(jié)果。

.cube img:nth-child(1) {
      transform: translateZ(-65px);
    }

照這樣看,是不是back位移為translateZ(65px),left為translateX(-65px),top translateY(-65px)呢?但結(jié)果并不是我們想要的。

重新看回上文空間坐標(biāo)系的那張貼圖,我們會(huì)發(fā)現(xiàn),平面旋轉(zhuǎn)后,其對(duì)應(yīng)的三個(gè)軸的位置也改變了。如圖片繞Y旋轉(zhuǎn)后,Z軸指向?yàn)槠聊坏乃椒较颉@@X旋轉(zhuǎn)后,Z軸指向垂直方向。因此我們很容易發(fā)現(xiàn),其實(shí)要將貼面移動(dòng)到正確的位置,都只需要讓他們translateZ(-width/2px)就可以了。

為了讓大家容易理解,我這里設(shè)置了一個(gè)較大的perspective。要想得到全景的效果,我們將鏡頭拉近讓它進(jìn)入到box里面就可以了。

接下來綁定手勢,就可以讓它動(dòng)起來啦。

部分代碼:

viewer.on("touchstart", function(e) {
    x1 = e.targetTouches[0].pageX; - $(this).offset().left;
    y1 = e.targetTouches[0].pageY; - $(this).offset().top;
});

viewer.on("touchmove",function(){
    var dist_x = x2 - x1,
        dist_y = y2 - y1,
        deg_x = Math.atan2(dist_y, perspective) / Math.PI * 180,
        deg_y = -Math.atan2(dist_x, perspective) / Math.PI * 180,
        i,
        c_x_deg += deg_x;
        c_y_deg += deg_y;
        
    cube.css("transform", "rotateX(" + deg_x + "deg) rotateY(" + deg_y + "deg)");
})

Math.atan2(y,x) 方法:得到從 x 軸到點(diǎn) (x,y) 之間的角度。對(duì)于空間左邊系比較難理解,大家可以想象成一張以空間Z軸為Y軸的平面繞X軸正方向旋轉(zhuǎn)的角度即為cube繞空間Y軸旋轉(zhuǎn)的角度。

柱形

柱形全景也不算復(fù)雜。關(guān)于圓柱形的打造方法,大家可以參考下這篇文章CSS3 3D transforms系列教程-3D旋轉(zhuǎn)木馬
有了這個(gè)基礎(chǔ),我們可以寫一段函數(shù)快速構(gòu)造柱形全景。

先來看下頁面結(jié)構(gòu)




  
function creCylinder(lenZ,pieceWid,angle,slice){

    /* 
    pieceWid 表示單個(gè)柱形塊狀寬度
    angle表示柱形內(nèi)角
    slice表示有多少個(gè)面拼接 
    slice越多,拼合的面越接近曲面
    */
    
  var l = pieceWid*slice; // 畫布全長
  var ag = angle/slice // 旋轉(zhuǎn)角度

  var html = "";

  /*
    設(shè)置每個(gè)面的旋轉(zhuǎn)角度和位移 因?yàn)橐指畛啥鄠€(gè)面,所以應(yīng)該為每個(gè)面的背景圖設(shè)置不同的`background-position`
    */

  for(var i=0,len=slice;i
"; } return html; } function renderPano(pieceWid,angle,slice){ var vw = $(window).width(); var RADIAN = 0.017453293; // 弧度制 將角度轉(zhuǎn)成弧度 var innerAngle = angle/(2*slice); //內(nèi)角,用來計(jì)算translateZ // 這里的原理和上文旋轉(zhuǎn)木馬鏈接一致 var lenZ = -(pieceWid/2)*Math.tan((90-innerAngle)*RADIAN); /* 因?yàn)槟J(rèn)是由畫布的最左端開始旋轉(zhuǎn) 所以處于我們面前的是畫布的最左端和最右端及其連接處 要想畫布中央顯示再我們面前,這里需要給cube_bg加上一定的繞Y旋轉(zhuǎn)角度 */ var rotate = ((angle/slice)*(slice-1))/2, perspective = -lenZ-5; var cube_bg = $(".cube_bg"), scene = $(".scene"); var cylinder = creCylinder(lenZ,pieceWid,angle,slice); cube_bg.html(cylinder).css("transform","rotateY("+rotate+"deg)"); scence.css("-webkit-perspective",perspective+"px"); //最后調(diào)用一下 renderPano(128,360,20);

這里解釋一下perspective為什么要設(shè)成 -lenZ-5
看一張圖,上面的lenZtranslateZ值,為負(fù)值。
perspective為鏡頭到屏幕的距離,因?yàn)榇藭r(shí)鏡頭在柱體內(nèi)部,因此不能看到柱體后面的圖像。
當(dāng)perspective值為-lenZ值時(shí),正好柱體back面能與鏡頭在同一平面上,為了避免它有一定的機(jī)率遮擋鏡頭,我們可以將鏡頭拉近一些。便設(shè)成了-lenZ-5。這個(gè)時(shí)候就能保證鏡頭處于柱體內(nèi)部,同時(shí)也能更廣角度地觀察到柱體全景。

大家可以復(fù)制代碼體驗(yàn)一下。這里的背景圖我選用的是自己拼合成的造物節(jié)背景圖。

優(yōu)劣勢對(duì)比

相信大家也有體會(huì),天空盒制造起來會(huì)相對(duì)的簡單,并且天空和地面都能被考慮進(jìn)去。但是由于面面間的貼合角度太大,若物體正好處于相互貼合的兩個(gè)面,會(huì)給人一種被攔腰折斷的感覺。而柱形圖對(duì)這種情況有了比較好的解決,但是天空和地面的貼圖就比較困難了,一般情況下只能通過給scene添加背景圖片模擬。

未完待續(xù)…

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/111675.html

相關(guān)文章

  • H5實(shí)例教學(xué)--3D全景(ThreeJs全景Demo)

    摘要:前言在現(xiàn)在市面上很多全景的環(huán)境下,要實(shí)現(xiàn)全景的方式有很多,可以用直接構(gòu)建也可以用基于的庫來實(shí)現(xiàn),還有很多別的制作全景的軟件使用本教學(xué)適用于未開發(fā)過全景的工程獅如果覺得內(nèi)容太無聊可以直接跳到最后下載代碼理論整個(gè)全景所用的相關(guān)理論就不多說了,就 前言 在現(xiàn)在市面上很多全景H5的環(huán)境下,要實(shí)現(xiàn)全景的方式有很多,可以用css3直接構(gòu)建也可以用基于threeJs的庫來實(shí)現(xiàn),還有很多別的制作全景的...

    GraphQuery 評(píng)論0 收藏0
  • H5實(shí)例教學(xué)--3D全景(ThreeJs全景Demo)

    摘要:前言在現(xiàn)在市面上很多全景的環(huán)境下,要實(shí)現(xiàn)全景的方式有很多,可以用直接構(gòu)建也可以用基于的庫來實(shí)現(xiàn),還有很多別的制作全景的軟件使用本教學(xué)適用于未開發(fā)過全景的工程獅如果覺得內(nèi)容太無聊可以直接跳到最后下載代碼理論整個(gè)全景所用的相關(guān)理論就不多說了,就 前言 在現(xiàn)在市面上很多全景H5的環(huán)境下,要實(shí)現(xiàn)全景的方式有很多,可以用css3直接構(gòu)建也可以用基于threeJs的庫來實(shí)現(xiàn),還有很多別的制作全景的...

    VPointer 評(píng)論0 收藏0
  • SegmentFault 技術(shù)周刊 Vol.35 - WebGL:打開網(wǎng)頁看大片

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

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

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

0條評(píng)論

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