Hello World 2 載入紋理

2021-08-11 00:16:30 字數 3156 閱讀 4698

給地面新增紋理

背面的紋理

在前一節的基礎上,新增了有紋理的地面 、輔助座標。

init()中加入

// floor

); var geom = new three.planegeometry(1000, 1000, 1, 1);

var floor = new three.mesh(geom, mat);

scene.add(floor);

}

和前面建立cube一樣,這裡建立地面。

不過用的是planegeometry建立乙個平面;引數分別是寬、長、寬分段、長分段。

接著執行,你會看到乙個白色的平面在方塊後面。

讓我們再改變一下它的角度,在scene.add()前加入

floor.rotation.x = math.pi * -0.5;
opengl使用的是右手座標系,旋轉方向也是右手定義的。

你可以將右手伸出做個good的手勢,大拇指沿x軸正方向,那麼你的其餘四指就是旋轉的正方向。

於是——上述**將floor繞x軸順時針旋轉90度。

然後執行,你會看到方塊被白色的地面埋了一半。

我們不打算改變地面高度,於是你得修改cube的座標。

在建立cube的**中加入

cube.position.set(0, 50, 0);
執行,你會看到方塊冒出來了。

你可能很需要畫乙個座標軸,特別是在複雜的場景中確定空間位置的時候。

init()中加入

// axes

這裡用了three.axeshelper()來建立輔助座標軸,引數是軸的長度。

執行,你會看到乙個座標軸從方塊中心冒出來 。

你可能發現地面上的軸不是那麼清晰,因為軸線和地面重合了。我們將它往上挪一點點,在add前加入

axes.position.y = 1;
接著執行,你會發現軸線清晰了。

在opengl中,面重合往往會帶來一些麻煩,造成面閃爍;因為浮點數精度是有限的,如果你用opengl畫陰影貼圖,你肯定會遇到這個問題。

xyz軸上面並沒有標上字母啊,我怎麼知道哪根軸是x軸?
我們表達顏色時用的是rgb,而表達座標時用的是xyz,很自然地會用r對應x這樣,於是紅色就是x軸,綠y軸,藍z軸。

而且在資料結構方面,rgb和xyz都用的是同乙個資料結構是three.vector3,為乙個三維向量。

材質可以表達物體的光澤屬性,讓我們分辨物體是金屬還是塑料;紋理則表達物體表面紋路。

通常二者結合起來就可以渲染出很不錯的畫面了。

我們在floor中建立mat材質前,加入

var tex = new three.textureloader().load('src/img/colors.png');
然後刪掉原來的mat,替換成下面的

var mat = new three.meshbasicmaterial();
map:tex 設定我們的紋理對映是tex,我們用這個紋理就不再需要color了。

執行,你會看到被貼到地面上了

拉近了看,是不是紋理有點粗糙?

因為紋理畫素是有限的,放大了自然會這樣。

既然這是乙個地面,我們可以接受重複,於是在建立tex後加入

tex.repeat.set(10, 10);
上述**設定紋理對映在水平和垂直方向重複10次。

執行,你會發現

這是怎麼了?

紋理座標可以用st或者uv表示,是乙個意思。

原點(0,0)在紋理的左上角,s/u是右,而t/v是下。右下角是(1,1)。

於是我們可以推斷紋理的座標範圍不會超過1。

我們這裡重複了10次,紋理座標是10。而超出1這個範圍的紋理該怎麼取座標呢?

預設值為第1種,即超出的部分取紋理邊緣的顏色。

第2種是超出後就重複紋理,等於丟棄座標中整數的部分。

第3種是映象,一般地面會用這個模式。當紋理的整數部分是奇數時是第2種,是偶數時則會對應翻轉。

如果我們知道了為什麼紋理會變成這樣,我們接著新增一句

上述**分別設定2個方向上的重複模式,由此可見不同方向上可以用不同的模式。

我們這裡沒有用第3種模式,因為我們的貼圖有點像瓷磚,重複起來會感覺很和諧。

如果貼圖是一張草地的話,會用第3種模式。因為全是一樣的草看來很假,不需要重複感。

執行,你會看到好得多的紋理渲染。

如果你把鏡頭拉到下方,你又可以看到奇怪的現象

這是因為三維世界中,物體是有正反面區分的。

而為了執行效率,opengl缺省會只繪製正面(如果你在前面把地面給轉反了,那麼你只會在下方才看到地面)。

我們需要設定紋理也貼到背面去。

mat建立時的**改為這樣

var mat = new three.meshbasicmaterial();
這樣我們就貼在正反面都應用了同乙個紋理。

執行,你可以發現地面的反面也會渲染了,但是cube那裡有些閃爍。

前面已經提到了面重合帶來的問題,我們修改cube那裡的**,將cube向上移一點點

cube.position.set(0, 51, 0);
執行,終於正確了。

載入helloworld模組

include include if config modversions 1 define modversions include endif include include include module license gpl static int hello init void static ...

cocos2d 紋理載入機制

cocos2d 紋理載入機制 cocos2d主要的渲染目標是vao vbo 屬性 紋理 主要看看紋理載入的相關 texture2d texturecache addimage const std string path 注意 image new image bool bret image initw...

iOS OpenGL ES載入紋理(GLKit)

void setupcontext 被繪製物件引數的設定 glkview view glkview self.view view.context context 顏色格式 rgba每個顏色通道站8位 view.drawablecolorformat glkviewdrawablecolorforma...