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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

threejs纹理

發(fā)布時(shí)間:2023/12/10 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 threejs纹理 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

紋理

紋理用來表現(xiàn)物體的細(xì)節(jié)。理論上可以將物體的每個(gè)細(xì)節(jié)建模出來,但是這樣時(shí)間成本和性能成本都太高,因此,將物體的一些細(xì)節(jié)用紋理來表示。

圖片紋理

圖片紋理直接在物體表面應(yīng)用圖片。可以使用TextureLoader類的load方法來加載紋理。

function loadImgTexture(){var loader = new THREE.TextureLoader();loader.load("metal-rust.jpg",function(texture){var geometry = new THREE.BoxGeometry(10,10,10);var material = new THREE.MeshBasicMaterial({color:0x739783,map:texture});mesh = new THREE.Mesh(geometry,material);scene.add(mesh);}) }

注意加載圖片是異步的,所以這里我們使用render循環(huán)來渲染:

function render(){requestAnimationFrame(render);renderer.render(scene,camera); }

凹凸貼圖

凹凸貼圖可以使紋理也有厚度,看起來更立體。凹凸貼圖一般使用一張灰度圖,設(shè)置成材料的bumpMap屬性

function loadImgTexture(){var loader = new THREE.TextureLoader();loader.load("stone.jpg",function(texture){loader.load("stone-bump.jpg",function(bumpTexture){var geometry = new THREE.BoxGeometry(10,10,10);var material = new THREE.MeshPhongMaterial({map:texture,bumpMap:bumpTexture,bumpScale:0.2});mesh = new THREE.Mesh(geometry,material);mesh.rotation.x = 30/180Math.PI;scene.add(mesh);})}) }

凹凸貼圖雖然看起來更立體,但是其只是有深度,沒有方向,所以只有在某個(gè)方向看是很立體,在其它方向看又不好。如果貼圖的對(duì)象不怎么轉(zhuǎn)動(dòng),光線也不怎么變化,倒可以使用凹凸貼圖。

法向貼圖

法向貼圖使用一張法向圖來表示紋理圖片某個(gè)點(diǎn)的法向量。即用一張圖片保存另一張圖片的法向量信息,然后再在threejs中將這兩個(gè)圖片的信息合在一起,就形成了一個(gè)細(xì)節(jié)豐富的立體紋理。創(chuàng)建法向貼圖如下,注意這里不要再使用MeshBasicMaterial:

function loadImgTexture(){var loader = new THREE.TextureLoader();loader.load("plaster.jpg",function(texture){loader.load("plaster-normal.jpg",function(normalTexture){var geometry = new THREE.BoxGeometry(10,10,10);var material = new THREE.MeshPhongMaterial({map:texture,normalMap:normalTexture,bumpScale:0.2});mesh = new THREE.Mesh(geometry,material);mesh.rotation.x = 30/180Math.PI;scene.add(mesh);})}) }

法向貼圖可以生成細(xì)節(jié)豐富的紋理,同時(shí)不損害渲染性能。但是法向圖這張圖片創(chuàng)建起來稍有困難,使用Blender或Photo創(chuàng)建。

光照貼圖

環(huán)境貼圖

環(huán)境貼圖是使用上下左右前后六張圖或者一張全景圖來模擬真實(shí)的環(huán)境,threejs會(huì)將這些圖片渲染成無縫的環(huán)境盒子,例子可看【threejs-cubeMap例子】,其中貌似真實(shí)的環(huán)境,球的反光效果,都是用這張全景圖渲染出來的:

球的反光看起來非常逼真,但其實(shí)是假的,也就四并沒有使用光線追蹤來表現(xiàn)出反光效果。光線追蹤是很耗cpu的,所以,使用環(huán)境貼圖即節(jié)約性能,又能表現(xiàn)出很逼真的效果。

UV貼圖

關(guān)于uv貼圖,【blender wiki】里面說得很好:

UV貼圖是將2D紋理映射到3D物體最靈活的一種方式.在這個(gè)過程中三維曲面網(wǎng)絡(luò)("mesh")的X Y Z被展平到一副二維(X Y 或者說 我們將要看到的 U V)圖片中,這樣圖片中的顏色就被映射到曲面網(wǎng)絡(luò)("mesh")中。 有助于理解UV貼圖的最形象的比喻是切開一個(gè)硬紙盒.盒子是一個(gè)三維物體,正如同加到場景中的一個(gè)曲面網(wǎng)絡(luò)("mesh")方塊. 如果沿著邊縫或折痕剪開盒子,可以把盒子攤開在一個(gè)桌面上.當(dāng)我們從上往下俯視桌子時(shí),我們可以認(rèn)為U是左右方向,V是上下方向.盒子上的圖片就在一個(gè)二維坐標(biāo)中.我們使用U V代表"紋理坐標(biāo)系"來代替通常在三維空間使用的 X Y.

如果給模型的每個(gè)面都用一張圖片去貼紋理,這將要加載很多紋理圖片,如果可以只將圖片的某個(gè)部分映射到模型,那就只需要一張圖片就夠了。uv貼圖就能夠?qū)D片的某部分映射到模型的某個(gè)面,如果還不好理解,類比一下CSS Sprite技術(shù)。比如,上一篇【加載3D模型例子】例子中,我們用到了一張圖片:

這張圖里面凌亂的放著攤開的人皮、衣服、手、眼睛等圖片元素。而我們加載出來的模型是這樣的:

在這張圖中,臉是臉,衣服是衣服,都在它們應(yīng)該出現(xiàn)的位置。這便是使用了uv映射,將圖中的某部分作為紋理,貼到模型中的對(duì)應(yīng)部分。

但是,圖中的各個(gè)部分,是怎么和模型對(duì)應(yīng)起來的呢?一個(gè)人的模型有那么多個(gè)面,純手工編碼一個(gè)個(gè)去對(duì)應(yīng),感覺會(huì)出人命。其實(shí),uv貼圖一般是做模型的時(shí)候就做好了,圖和模型的對(duì)應(yīng)關(guān)系也包含在模型文件(就是那個(gè).dae文件)中了,編程的時(shí)候一般是不用關(guān)心這個(gè)。

雖說如此,我們加載模型之后,也可以通過Geometry對(duì)象的faceVertexUvs屬性看看具體是怎么映射的。簡單起見,創(chuàng)建一個(gè)BoxGometry,查看一個(gè)其內(nèi)置的uv映射:

var geom = new THREE.BoxGeometry(24, 24, 24); console.log(geom.faceVertexUvs);

打印出:

是一個(gè)有12個(gè)元素的數(shù)組,12代表的就是立方體的12個(gè)三角面。再看數(shù)組的具體某一個(gè)元素:

又是一個(gè)長度為3的Vector2數(shù)組,代表紋理圖片中的三個(gè)位置,這三個(gè)點(diǎn)圍成的部分就是這個(gè)三角面的紋理。上面的(0,0),(1,0),(1,1)都是比例,0代表0%,1代表100%。點(diǎn)是從右下角開始按逆時(shí)針排列的,比如A(0,0),B(1,0),C(1,1)三點(diǎn),在圖片中圍成的區(qū)域如下:

將這張圖加載到立方體,能更清晰立方體是如何通過uv映射來處理紋理的,【例子】。


【持續(xù)更新看這里】

總結(jié)

以上是生活随笔為你收集整理的threejs纹理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。