欧美日韩精品一区二区在线线,一级无码在线收看,精品国产高清91,久久精品欧美电影

# 紋理

紋理Texture是GPU中的圖像,供著色器采樣使用。在框架中其一般被作為材質(zhì)的一部uniforms使用。

由于紋理來源的復(fù)雜性,有普通紋理、立方體紋理、視頻紋理、渲染紋理等,它們均有不同的創(chuàng)建或者加載方式,卻往往有相同的用法,所以框架為其特別約定了一套資源引用方式,詳見使用紋理一節(jié)。

# 普通紋理

普通紋理即2D紋理,創(chuàng)建普通紋理一般有以下幾種方式:

# 通過加載器

通過加載器加載是最為通用的方式,我們可以用標(biāo)簽來加載:

<xr-asset-load type="texture" asset-id="waifu" src="/assets/waifu.png" options="wrapU:1,wrapV:2" />

也可以使用代碼加載:

scene.assets.loadAsset({type: 'texture', assetId: 'waifu', src: '/assets/waifu.png'});

注意這里的options我們可以給紋理添加一些配置選項,比如wrap、filter等,其對應(yīng)的值都是枚舉,詳細(xì)可見ITextureLoaderOptions

# 代碼創(chuàng)建

除了加載器,還可以通過代碼創(chuàng)建的方式,這里的options詳見ITextureOptions

function createGreenTexture(scene: XrFrame.Scene) {
  return scene.createTexture({
    source: [new Uint8Array([0, 1, 0, 1])],
    pixelFormat: xrFrameSystem.ETextureFormat.RGBA8,
    width: 1,
    height: 1,
    magFilter: xrFrameSystem.EFilterMode.NEAREST,
    minFilter: xrFrameSystem.EFilterMode.NEAREST,
    wrapU: xrFrameSystem.EWrapMode.CLAMP_TO_EDGE,
    wrapV: xrFrameSystem.EWrapMode.CLAMP_TO_EDGE,
    anisoLevel:1
  });
}

// 可以將其注冊到資源系統(tǒng)
xrFrameSystem.registerTexture('green', createGreenTexture);

# 更新

除了一開始就創(chuàng)建完畢,有時候開發(fā)者可能需要去動態(tài)更新紋理的內(nèi)容:

tex.update({
  buffer: source,
  xoffset: 0, yoffset: 0,
  width: 256, height: 256
});

這里面的buffer可以是ArrayBufferArrayBufferView或者IImage(圖像)。

# 圖像

圖像資源在框架中一般用于作為紋理的source或者AR識別的來源等,有兩種方式來創(chuàng)建圖片,首先是xml中:

<xr-asset-load type="image" asset-id="waifu-img" src="/assets/waifu.png" />

也可以用代碼加載:

scene.createImage({type: 'texture', assetId: 'waifu-img', src: '/assets/waifu.png'})

還可以代碼創(chuàng)建:

const image = scene.createImage();
image.onload = () => {};
image.onerror = error => {};
image.src = '/assets/waifu.png';

# 立方體紋理

立方體紋理CubeTexture是一種特殊的紋理,一般用于實現(xiàn)天空盒或者環(huán)境貼圖,雖然在框架中一般使用普通全景紋理,但仍然提供給開發(fā)者一個選擇。

# 通過加載器

立方體紋理的創(chuàng)建也可以通過加載的方式創(chuàng)建。用xml加載:

<xr-asset-load
  type="cube-texture" asset-id="sky" src="/assets/sky/"
  options="faces: right.jpg left.jpg top.jpg bottom.jpg front.jpg back.jpg,wrapU:1,wrapV:2"
/>

或是使用代碼加載:

scene.assets.loadAsset({
  type: 'cube-texture', assetId: 'sky', src: '/assets/sky/',
  options: {faces: ['right.jpg', 'left.jpg', 'top.jpg', 'bottom.jpg', 'front.jpg', 'back.jpg']}
});

options中除了faces用于配置每個面的紋理地址,其他參數(shù)和TextureLoader一致。

# 代碼創(chuàng)建

也可以代碼創(chuàng)建,通過注冊加入資源系統(tǒng):

function createGreenCubeTexture(scene: XrFrame.Scene) {
  const buffer = new Uint8Array([0, 1, 0, 1]);
  return scene.createTexture({
    type: xrFrameSystem.ETextureType.Cube,
    slices: 6,
    source: [buffer, buffer, buffer, buffer, buffer, buffer],
    pixelFormat: xrFrameSystem.ETextureFormat.RGBA8,
    width: 1,
    height: 1,
    magFilter: xrFrameSystem.EFilterMode.NEAREST,
    minFilter: xrFrameSystem.EFilterMode.NEAREST,
    wrapU: xrFrameSystem.EWrapMode.CLAMP_TO_EDGE,
    wrapV: xrFrameSystem.EWrapMode.CLAMP_TO_EDGE,
    anisoLevel:1
  });
}

// 可以將其注冊到資源系統(tǒng)
xrFrameSystem.registerCubeTexture('green', createGreenCubeTexture);

可見其實它也是一種普通的紋理,只不過類型不一樣。

立方體紋理也支持更新,和普通紋理基本一致,只不過必須提供slice參數(shù)。

# 視頻紋理

有時候我們需要將視頻放入場景中進(jìn)行渲染,使用視頻紋理VideoTexture資源就可以實現(xiàn)這個需求。視頻紋理本質(zhì)上是創(chuàng)建一個普通紋理,然后定時用視頻解碼數(shù)據(jù)對它進(jìn)行更新。

# 通過加載器

視頻紋理的創(chuàng)建也可以通過加載的方式創(chuàng)建。用xml加載:

<xr-asset-load
  type="video-texture" asset-id="vt" src="/assets/video.mp4"
  options="autoPlay:true,loop:true,abortAudio:false,placeHolder:/assets/video.jpg"
/>

或是使用代碼加載:

scene.assets.loadAsset({
  type: 'video-texture', assetId: 'vt', src: '/assets/video.mp4',
  options: {autoPlay: true}
});

注意到視頻紋理的幾個選項,autoPlay開啟后視頻加載成功時會自動播放,loop開啟時會循環(huán)播放,abortAudio用于指定是否要禁止聲音(默認(rèn)禁止),placeHolder則是作為視頻尚未加載成功時的一個占位圖,可選。

特別注意,placeHolder的尺寸必須和視頻完全一致?。。?/span>

# 代碼創(chuàng)建

視頻紋理也可以手動在代碼中創(chuàng)建:

const vt = await createVideoTexture({src, autoPlay, loop, placeHolder});

注意這是個異步方法,在有placeHolder時會在圖片加載完畢時返回,否則將在視頻準(zhǔn)備好時返回。

# 控制

視頻紋理對于開發(fā)者而言主要是視頻,所以我們提供了一些用于控制視頻播放的方法:

// 開始播放,異步方法
await vt.play();

// 從`pos`秒開始播放,異步方法
await vt.seek(pos);

// 停止播放
vt.stop();

// 釋放視頻
vt.release();

// 在播放結(jié)束并且非loop的情況下,會執(zhí)行
vt.onEnd = () => {};

// 在基礎(chǔ)庫`v2.33.0`及以上,提供了暫停/喚醒方法
// 同時可以配合新暴露的播放狀態(tài)使用
const xrSystem = wx.getXrFrameSystem();
if (vt.state === xrSystem.EVideoState.Playing) {
  vt.pause();
} else if (vt.state === xrSystem.EVideoState.Paused) {
  vt.resume();
}

注意,如果是自己創(chuàng)建的視頻資源,請務(wù)必自己調(diào)用release方法釋放?。?!

# 渲染紋理

渲染紋理比較特殊,詳見渲染紋理。

# 使用紋理

加載或者創(chuàng)建了紋理后,便可以在組件或者材質(zhì)的uniforms中使用。但通過以上的章節(jié),我們知道了紋理的種類有許多,雖然組件數(shù)據(jù)可以通過指定具體的類型,比如cube-texture來取得具體的類型的資源,但對于uniforms來說是無法判斷的,同時也比較繁瑣。

為了解決這個問題,我們遵循約定大于配置的原則,對于所有這些紋理資源,開發(fā)者只需要將組件數(shù)據(jù)類型指定為texture,加上不同的前綴,資源系統(tǒng)會自動匹配獲取對應(yīng)的資源:

  1. 不加前綴,取得普通紋理。
  2. cube-前綴,取得立方體紋理資源。
  3. video-前綴,取得視頻紋理。
  4. render-前綴,取得渲染紋理。

如果是應(yīng)用于uniforms中,開發(fā)者不需要自己去關(guān)心它們的區(qū)別,只需要uniforms="u_baseColorMap:video-vt"這樣即可,但如果是自定義組件數(shù)據(jù),就需要開發(fā)者自己處理一下了:

onUpdate(data: {texture: XrFrame.Texture | XrFrame.ITextureWrapper}) {
  const realTex = xrFrameSystem.isTextureWrapper(data.texture)
    ? data.texture.texture
    : data.texture;
}