three.js WebGLRenderTarget

今天郭先生說一說WebGLRenderTarget,它是一個緩衝,就是在這個緩衝中,視頻卡爲正在後臺渲染的場景繪製像素。 它用於不一樣的效果,例如把它作爲貼圖使用或者圖像後期處理。線案例請點擊博客原文。
app

話很少說,下來看看他的屬性了方法。dom

1. WebGLRenderTarget的屬性和方法

WebGLRenderTarget的構造器有三個參數,分別是width,height和options。寬高就是RenderTarget的高,設置的同時也會把它們賦值給texture.image的width和height屬性。options包含如下屬性測試

屬性 默認值 描述
wrapS ClampToEdgeWrapping 包裹模式--使用RepeatWrapping,紋理將簡單地重複到無窮大。使用ClampToEdgeWrapping紋理中的最後一個像素將延伸到網格的邊緣。使用MirroredRepeatWrapping, 紋理將重複到無窮大,在每次重複時將進行鏡像。
wrapT ClampToEdgeWrapping 同上
magFilter LinearFilter 放大濾鏡--NearestFilter返回與指定紋理座標(在曼哈頓距離以內)最接近的紋理元素的值。LinearFilter是默認值,返回距離指定的紋理座標最近的四個紋理元素的加權平均值
minFilter LinearFilter 縮小濾鏡--NearestFilter返回與指定紋理座標(在曼哈頓距離以內)最接近的紋理元素的值。NearestMipmapNearestFilter選擇與被紋理化像素的尺寸最匹配的mipmap, 並以NearestFilter(最靠近像素中心的紋理元素)爲標準來生成紋理值。NearestMipmapLinearFilter選擇與被紋理化像素的尺寸最接近的兩個mipmap, 並以NearestFilter爲標準來從每一個mipmap中生成紋理值。最終的紋理值是這兩個值的加權平均值。LinearFilter是默認值,返回距離指定的紋理座標最近的四個紋理元素的加權平均值。LinearMipmapNearestFilter選擇與被紋理化像素的尺寸最匹配的mipmap, 並以LinearFilter(最靠近像素中心的四個紋理元素的加權平均值)爲標準來生成紋理值。LinearMipmapLinearFilter選擇與被紋理化像素的尺寸最接近的兩個mipmap, 並以LinearFilter爲標準來從每一個mipmap中生成紋理值。最終的紋理值是這兩個值的加權平均值。
format RGBAFormat AlphaFormat 丟棄紅、綠、藍份量,僅讀取Alpha份量。RedFormat丟棄綠色和藍色份量,只讀取紅色份量RedIntegerFormat丟棄綠色和藍色份量,只讀取紅色份量。texel被讀取爲整數而不是浮點。(只能與WebGL 2呈現上下文一塊兒使用)。RGFormat丟棄alpha和blue組件並讀取紅色和綠色組件。(只能與WebGL 2呈現上下文一塊兒使用)。RGIntegerFormat丟棄alpha和blue組件並讀取紅色和綠色組件。texel被讀取爲整數而不是浮點。(只能與WebGL 2呈現上下文一塊兒使用)。RGBFormat 丟棄Alpha份量,僅讀取紅、綠、藍份量。RGBIntegerFormat丟棄alpha組件並讀取紅色、綠色和藍色組件。(只能與WebGL 2呈現上下文一塊兒使用)。RGBAFormat將讀取紅、綠、藍和Alpha份量。RGBAIntegerFormat讀取紅色、綠色、藍色和alpha份量。texel被讀取爲整數而不是浮點。(只能與WebGL 2呈現上下文一塊兒使用)。LuminanceFormat 將每一個元素做爲單獨的亮度份量來讀取。 將其轉換爲範圍限制在[0,1]區間的浮點數,而後經過將亮度值放入紅、綠、藍通道,並將1.0賦給Alpha通道,來組裝成一個RGBA元素。LuminanceAlphaFormat 將每一個元素同時做爲亮度份量和Alpha份量來讀取。 和上面LuminanceFormat的處理過程是一致的,除了Alpha份量具備除了1.0之外的值。RGBEFormat 與 RGBAFormat 是相同的。DepthFormat將每一個元素做爲單獨的深度值來讀取,將其轉換爲範圍限制在[0,1]區間的浮點數。 它是DepthTexture的默認值。DepthStencilFormat將每一個元素同時做爲一對深度值和模板值來讀取。 其中的深度份量解釋爲DepthFormat。 模板份量基於深度+模板的內部格式來進行解釋。
type UnsignedByteType THREE.UnsignedByteType,THREE.ByteType,THREE.ShortType,THREE.UnsignedShortType,THREE.IntType,THREE.UnsignedIntType,THREE.FloatType,THREE.HalfFloatType,THREE.UnsignedShort4444Type,THREE.UnsignedShort5551Type,THREE.UnsignedShort565Type,THREE.UnsignedInt248Type。這些常量用於紋理的type屬性,這些屬性必須與正確的格式相對應。詳情請查看下方。
anisotropy Texture.anisotropy 沿着軸,經過具備最高紋素密度的像素的樣本數。 默認狀況下,這個值爲1。設置一個較高的值將會產生比基本的mipmap更清晰的效果,代價是須要使用更多紋理樣本。 使用renderer.getMaxAnisotropy() 來查詢GPU中各向異性的最大有效值;這個值一般是2的冪。
encoding LinearEncoding THREE.LinearEncoding,THREE.sRGBEncoding,THREE.GammaEncoding,THREE.RGBEEncoding,THREE.LogLuvEncoding,THREE.RGBM7Encoding,THREE.RGBM16Encoding,THREE.RGBDEncoding,THREE.BasicDepthPacking,THREE.RGBADepthPacking。若是編碼類型在紋理已被一個材質使用以後發生了改變, 你須要來設置Material.needsUpdate爲true來使得材質從新編譯。
depthBuffer true 深度緩衝器
stencilBuffer false 模具緩衝區

WebGLRenderTarget的屬性this

屬性 描述
width 渲染目標寬度
height 渲染目標高度
scissor 渲染目標視口內的一個矩形區域,區域以外的片元將會被丟棄
scissorTest 代表是否激活了剪裁測試
viewport 渲染目標的視口
texture 紋理實例保存這渲染的像素,用做進一步處理的輸入值
depthBuffer 渲染到深度緩衝區。默認true
stencilBuffer 渲染到模具緩衝區。默認false
depthTexture 若是設置,那麼場景的深度將會被渲染到此紋理上。默認是null

WebGLRenderTarget的方法編碼

方法 描述
setSize 設置渲染目標的大小
clone 建立一個渲染目標副本
copy 採用傳入的渲染目標的設置
dispose 發出一個處理事件

2 使用WebGLRenderTarget做爲貼圖案例

1 作一個網格

首先作一個幾何體,這裏咱們以THREE.Line爲例spa

let pointArr = [];
let colorArr = [];
const points = GeometryUtils.hilbert2D(new THREE.Vector3( 0, 0, 0 ), 10, 3);
for(let i=0; i<points.length; i++) {
    pointArr.push(points[i].x, points[i].y, points[i].z);
    colorArr.push(Math.random(), Math.random(), Math.random());
}

const geometry = new THREE.BufferGeometry();
const positionAttribute = new THREE.Float32BufferAttribute( pointArr, 3 );
geometry.setAttribute( 'position', positionAttribute );
geometry.center();

const colorAttribute = new THREE.BufferAttribute( new Float32Array( colorArr ), 3 );
colorAttribute.setUsage( THREE.DynamicDrawUsage );
geometry.setAttribute( 'color', colorAttribute );                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  

const material = new THREE.LineBasicMaterial( { vertexColors: true } );

line = new THREE.Line( geometry, material );
sceneRTT.add( line );

這就作好了一個line,這裏說一下scene是咱們的主場景,camera是拍攝主場景的相機,sceneRTT是renderTarget的場景,cameraRTT是rennderTarget的相機。GeometryUtils.hilbert2D是生成希爾伯特曲線的方法。rest

2. 建立render target

咱們建立一個render target,裏面的參數不清楚的能夠屢次嘗試一下code

target = new THREE.WebGLRenderTarget(200, 200, { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat });
target.viewport = new THREE.Vector4(10,10,180,180);

這裏咱們設置視口起點從(10, 10)開始,寬高分別爲180的矩形。orm

3. 建立渲染器和要貼圖的Mesh

接下來咱們建立渲染器和要貼圖的Mesh視頻

renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(window.innerWidth, window.innerHeight);
this.$refs.box.appendChild(renderer.domElement);

let boxGeom = new THREE.BoxBufferGeometry(100, 100, 100);
let boxMate = new THREE.MeshBasicMaterial({map: target.texture});
let boxMesh = new THREE.Mesh(boxGeom, boxMate);
scene.add(boxMesh)

直接調用target的Texture屬性來作材質的貼圖

4. 渲染

這裏要渲染render target的場景,這樣調用target.texture才能返回一個正經的貼圖,同時咱們讓這個貼圖隨時間變換,最後渲染主場景,代碼以下。

onst colorAttribute = line.geometry.getAttribute( 'color' );
const l = colorAttribute.count;
for(let i=0; i<l; i++) {
    const h = ( ( offset + i ) % l ) / l * 20;
    color.setHSL(h, 0.8, 0.5);
    colorAttribute.setX( i, color.r );
    colorAttribute.setY( i, color.g );
    colorAttribute.setZ( i, color.b );
}

colorAttribute.needsUpdate = true;


offset -= 0.2;

renderer.setRenderTarget( target );
renderer.setClearColor(0xffddff);
renderer.clear();
renderer.render( sceneTT, cameraTT );

renderer.setRenderTarget( null );

renderer.setClearColor(0x000000);
renderer.render( scene, camera );
this.globalID = requestAnimationFrame(this.render);

這樣就能夠把render target做爲貼圖使用了。

 

轉載請註明地址:郭先生的博客

相關文章
相關標籤/搜索