從相片建立 WebGL 紋理

使用任意相片為「變形」範例建立 WebGL 紋理。

載入相片

WebGL 使用相片建立紋理,讓形狀變得更真實或實用。雖然在「變形」範例中可以使用任意大小的相片,但是 WebGL 需要設定影像大小才會有作用。為了縮放所選用的影像,範例會使用包含三個步驟的程序來建立 WebGL 紋理。

下列程式碼和步驟說明「變形」範例如何使用 2D 畫布命令,在影像載入為紋理之前先加以縮放。

這個程式碼會取得影像、進行縮放,然後將它放置在 2D 畫布上。


// load a the user's image.
this.loadImageX = function (dataURL) {
    var image = new Image();
    
    image.onload = function () {
        renderer.loadImage2(image);
    }

    image.src = dataURL;
}

// This function does the heavy lifting of creating the texture from the image.
this.loadImage2 = function (image) {
    // Convert the image to a square image via the temporary 2d canvas. 
    var canvas = document.getElementById("2dcanvas");
    var ctx = canvas.getContext("2d");
    var canvHeight = document.getElementById("2dcanvas").height;

    var x = 0;
    var y = 0;
    var xx = canvHeight;
    var yy = canvHeight;

    ctx.clearRect(0, 0, canvHeight, canvHeight);
    // If image isn't square, adjust width, height, and origin so it's centered.
       if (image.width < image.height) {
        // Change origin and dimensions if the image isn't square.
        // Change x, xx
        xx = image.width / image.height * canvHeight;
        x = (canvHeight - xx) / 2;
    }
    if (image.width > image.height) {
        // Change y, yy 
      yy = image.height / image.width * canvHeight;
      y = (canvHeight - yy) / 2;
    }

// Put the image on the canvas, scaled using xx & yy.
    ctx.drawImage(image, 0, 0, image.width, image.height, x, y, xx, yy);


  1. 當相片完成載入後,會建立 Image 物件和呼叫 loadImage2 函式的事件。
  2. 當影像完成載入時,會呼叫 loadImage2。
  3. LoadImage2 使用 document.getElementById,從 HTML 程式碼取得 2D 畫布。
  4. 使用畫布,函式接著可以使用 getContext("2d") 從畫布元素取得 2D 內容。
  5. 取得畫布高度並建立四個變數;也就是用來將影像放置在畫布上的原點 x、原點 y、高度及寬度。因為畫布是正方形,所以高度同時做為高度與寬度。
  6. 使用 clearRect 清除畫布。
  7. 取得影像的最大尺寸。如果影像不是正方形,則計算縮放的高度或寬度,為較短的一邊在畫布上設定位移。
  8. 使用 drawImage 將影像放到畫布上。 drawImage 方法會將影像放置到畫布的特定原點上,並根據為畫布指定的原點、高度和寬度自動縮放影像。

LoadImage2 會使用下列步驟建立紋理物件並從畫布載入影像:


// Create a texture object that will contain the image.
var texture = gl.createTexture();

// Bind the texture the target (TEXTURE_2D) of the active texture unit.
gl.bindTexture(gl.TEXTURE_2D, texture);

// Flip the image's Y axis to match the WebGL texture coordinate space.
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
    
// Set the parameters so we can render any size image.        
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);

  // Upload the resized canvas image into the texture.
//    Note: a canvas is used here but can be replaced by an image object. 
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas);


  1. 使用 createTexture 取得 WebGL 內容 (gl) 並建立新的 WebGLTexture 物件。CreateTexture 接受 WebGLTexture 物件,以及要使用的紋理類型 (TEXTURE_2D 或 TEXTURE_CUBE_MAP)。「變形」範例使用 TEXTURE_2D。
  2. 使用 bindTexture 繫結紋理,讓它成為使用中紋理。將這個紋理設定為使用中,可讓後續的紋理操作都使用該紋理。
  3. 變更紋理的座標系統,使 WebGL 紋理座標系統符合 pixelStorei。使用旗標 UNPACK_FLIP_Y_WEBGL,將 Y 軸從左上角的零變更為左下角的零。請參閱下方的附註。
  4. 使用 texParameteri 搭配 TEXTURE_WRAP_S 與 TEXTURE_WRAP_T,指定 WebGL 處理包裝影像的方式。這些常數告訴 WebGL 在填滿大於影像的區域時,應如何填滿影像側面或上方與下方的區域。CLAMP_TO_EDGE 參數告知 WebGL 要拼貼影像。例如,如果您在座標 1.5 的位置上進行影像取樣,這與在座標 .5 取樣相同。
  5. 另外使用 texParameteri 搭配 TEXTURE_MIN_FILTER 與 TEXTURE_MAX_FILTER 常數,指定計算色彩的方式。使用 LINEAR 旗標告訴 WebGL,當紋理延伸超出起始大小時,要使用最接近的四個像素來計算新像素的色彩。
  6. 使用 texImage2D 搭配目標紋理類型 (TEXTURE_2D)、層級 (一律為 0)、內部格式和影像格式 (皆為 RGBA)、紋理資料類型 (UNSIGNED_BYTE),以及最後的影像 (本例為 2D 畫布),將影像載入紋理。
  7. 使用 clearRect 清除畫布。

附註  

紋理使用名為 s/t 座標系統,原點位於左下角的 0,0,s 軸為水平方向,而 t 軸為垂直方向。您可以將它想向成朝向側邊 (s),以及朝向上方 (t),您稍後就會看到。使用 s/t 命名可與 WebGL 使用的 x/y/z 座標系統有所區別。將影像複製到紋理時,若使用 pixelStorei 將影像傳送至 GPU,可設定 texImage2D 來翻轉影像。若要將相片從左上角原點 0,0 的座標系統切換為左下角原點 0,0 的 s/t 系統,請使用旗標 UNPACK_FLIP_Y_WEBGL 呼叫 pixelStorei。一次使用多個紋理時,這非常重要。

UI 支援中,您可以對範例、取得檔案、滑鼠移動以及檔案儲存等有概觀的了解。

相關主題

使用 GLSL 撰寫 WebGL 著色器
UI 支援
WebGL 示範、參考及資源

 

 

顯示:
© 2014 Microsoft