商域無疆 (http://blog.csdn.net/omni360/)
本文遵循“署名-非商業用途-保持一緻”創作公用協定
轉載請保留此句:商域無疆 - 本部落格專注于 靈活開發及移動和物聯裝置研究:資料可視化、GOLANG、Html5、WEBGL、THREE.JS,否則,出自本部落格的文章拒絕轉載或再轉載,謝謝合作。
俺也是剛開始學,好多地兒肯定不對還請見諒.
以下代碼是THREE.JS 源碼檔案中extras/ImageUtils.js檔案的注釋.
更多更新在 : https://github.com/omni360/three.js.sourcecode
/**
* @author alteredq / http://alteredqualia.com/
* @author mrdoob / http://mrdoob.com/
* @author Daosheng Mu / https://github.com/DaoshengMu/
*/
/**************************************************************
* ImageUtils image對象的工具集,更友善的加載圖檔的輔助類.
**************************************************************/
THREE.ImageUtils = {
crossOrigin: undefined, //跨域加載圖檔.
/*
///loadTexture加載url指定的位置的圖檔資源,并建立紋理,傳回紋理對象.
*/
///<summary>loadTexture</summary>
///<param name ="url" type="URLString">圖像資源定位符</param>
///<param name ="mapping" type="Number">映射模式,可用常量參考下面注釋</param>
///<param name ="onLoad" type="CallbackFunction">回調函數</param>
///<param name ="onError" type="CallbackFunction">回調函數</param>
///<returns type="THREE.Texture">傳回建立的紋理對象.</returns>
loadTexture: function ( url, mapping, onLoad, onError ) {
//建立圖檔加載器.
var loader = new THREE.ImageLoader();
loader.crossOrigin = this.crossOrigin;
var texture = new THREE.Texture( undefined, mapping ); //建立紋理對象
//從圖像資源定位符加載指定的圖檔.
loader.load( url, function ( image ) {
texture.image = image;
texture.needsUpdate = true; //當設定為true時,标記文理已經更新
if ( onLoad ) onLoad( texture ); //如果有回調函數,執行回調函數
}, undefined, function ( event ) {
if ( onError ) onError( event );
} );
texture.sourceFile = url; //源檔案位置.
return texture; //傳回建立的紋理對象
},
/*
///loadTextureCube加載url數組中指定的位置的圖檔資源,并建立紋理,傳回立方體紋理對象.
*/
///<summary>loadTextureCube</summary>
///<param name ="array" type="URLStringArray">圖像資源定位符數組</param>
///<param name ="mapping" type="Number">映射模式,可用常量參考下面注釋</param>
///<param name ="onLoad" type="CallbackFunction">回調函數</param>
///<param name ="onError" type="CallbackFunction">回調函數</param>
///<returns type="THREE.Texture">傳回立方體紋理對象.</returns>
loadTextureCube: function ( array, mapping, onLoad, onError ) {
var images = [];
var loader = new THREE.ImageLoader();
loader.crossOrigin = this.crossOrigin;
var texture = new THREE.CubeTexture( images, mapping ); //建立立方體紋理對象
// no flipping needed for cube textures
texture.flipY = false;
var loaded = 0;
var loadTexture = function ( i ) {
loader.load( array[ i ], function ( image ) {
texture.images[ i ] = image;
loaded += 1;
if ( loaded === 6 ) {
texture.needsUpdate = true;
if ( onLoad ) onLoad( texture );
}
} );
}
for ( var i = 0, il = array.length; i < il; ++ i ) { //周遊數組中的圖檔資源
loadTexture( i ); //一一加載并建立紋理對象.
}
return texture; //傳回立方體紋理對象
},
/*
///loadCompressedTexture加載壓縮紋理對象,該方法已經被删除,這裡保留為了向後相容,使用THREE.DDSLoader替換.
*/
///<summary>loadCompressedTexture</summary>
loadCompressedTexture: function () {
console.error( 'THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.' )
},
/*
///loadCompressedTextureCube加載壓縮的立方體紋理對象,該方法已經被删除,這裡保留為了向後相容,使用THREE.DDSLoader替換.
*/
///<summary>loadCompressedTextureCube</summary>
loadCompressedTextureCube: function () {
console.error( 'THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.' )
},
/*
///getNormalMap通過參數image(圖像對象),參數(深度資訊),獲得法線貼圖.
///法線貼圖(Normal mapping)在三維計算機圖形學中,是凸凹貼圖(Bump mapping)技術的一種應用,法線貼圖有時也稱為“Dot3(仿立體)
///凸凹紋理貼圖”。凸凹與紋理貼圖通常是在現有的模型法線添加擾動不同,法線貼圖要完全更新法線。與凸凹貼圖類似的是,它也是用來在
///不增加多邊形的情況下在濃淡效果中添加細節。但是凸凹貼圖通常根據一個單獨的灰階圖像通道進行計算,而法線貼圖的資料源圖像通常是
///從更加細緻版本的物體得到的多通道圖像,即紅、綠、藍通道都是作為一個單獨的顔色對待。
*/
///<summary>getNormalMap</summary>
///<param name ="image" type="Image">圖像對象</param>
///<param name ="depth" type="float">深度資訊0.0-1.0</param>
///<returns type="THREE.Texture">傳回法線貼圖.</returns>
getNormalMap: function ( image, depth ) {
// Adapted from http://www.paulbrunt.co.uk/lab/heightnormal/
var cross = function ( a, b ) {
return [ a[ 1 ] * b[ 2 ] - a[ 2 ] * b[ 1 ], a[ 2 ] * b[ 0 ] - a[ 0 ] * b[ 2 ], a[ 0 ] * b[ 1 ] - a[ 1 ] * b[ 0 ] ];
}
var subtract = function ( a, b ) {
return [ a[ 0 ] - b[ 0 ], a[ 1 ] - b[ 1 ], a[ 2 ] - b[ 2 ] ];
}
/*
///normalize方法将傳回向量的長度為1(隻讀).
/// 複習一下國中的幾何吧,三角恒等式,給你準備好了 :) ,見維基百科:
/// http://zh.wikipedia.org/wiki/%E4%B8%89%E8%A7%92%E5%87%BD%E6%95%B0#.E4.B8.89.E8.A7.92.E6.81.92.E7.AD.89.E5.BC.8F
*/
///<summary>normalize</summary>
///<returns type="number">傳回向量的長度為1(隻讀)</returns>
var normalize = function ( a ) {
var l = Math.sqrt( a[ 0 ] * a[ 0 ] + a[ 1 ] * a[ 1 ] + a[ 2 ] * a[ 2 ] );
return [ a[ 0 ] / l, a[ 1 ] / l, a[ 2 ] / l ];
}
depth = depth | 1;
var width = image.width;
var height = image.height;
var canvas = document.createElement( 'canvas' );
canvas.width = width;
canvas.height = height;
var context = canvas.getContext( '2d' );
context.drawImage( image, 0, 0 );
var data = context.getImageData( 0, 0, width, height ).data;
var imageData = context.createImageData( width, height );
var output = imageData.data;
for ( var x = 0; x < width; x ++ ) {
for ( var y = 0; y < height; y ++ ) {
var ly = y - 1 < 0 ? 0 : y - 1;
var uy = y + 1 > height - 1 ? height - 1 : y + 1;
var lx = x - 1 < 0 ? 0 : x - 1;
var ux = x + 1 > width - 1 ? width - 1 : x + 1;
var points = [];
var origin = [ 0, 0, data[ ( y * width + x ) * 4 ] / 255 * depth ];
points.push( [ - 1, 0, data[ ( y * width + lx ) * 4 ] / 255 * depth ] );
points.push( [ - 1, - 1, data[ ( ly * width + lx ) * 4 ] / 255 * depth ] );
points.push( [ 0, - 1, data[ ( ly * width + x ) * 4 ] / 255 * depth ] );
points.push( [ 1, - 1, data[ ( ly * width + ux ) * 4 ] / 255 * depth ] );
points.push( [ 1, 0, data[ ( y * width + ux ) * 4 ] / 255 * depth ] );
points.push( [ 1, 1, data[ ( uy * width + ux ) * 4 ] / 255 * depth ] );
points.push( [ 0, 1, data[ ( uy * width + x ) * 4 ] / 255 * depth ] );
points.push( [ - 1, 1, data[ ( uy * width + lx ) * 4 ] / 255 * depth ] );
var normals = [];
var num_points = points.length;
for ( var i = 0; i < num_points; i ++ ) {
var v1 = points[ i ];
var v2 = points[ ( i + 1 ) % num_points ];
v1 = subtract( v1, origin );
v2 = subtract( v2, origin );
normals.push( normalize( cross( v1, v2 ) ) );
}
var normal = [ 0, 0, 0 ];
for ( var i = 0; i < normals.length; i ++ ) {
normal[ 0 ] += normals[ i ][ 0 ];
normal[ 1 ] += normals[ i ][ 1 ];
normal[ 2 ] += normals[ i ][ 2 ];
}
normal[ 0 ] /= normals.length;
normal[ 1 ] /= normals.length;
normal[ 2 ] /= normals.length;
var idx = ( y * width + x ) * 4;
output[ idx ] = ( ( normal[ 0 ] + 1.0 ) / 2.0 * 255 ) | 0;
output[ idx + 1 ] = ( ( normal[ 1 ] + 1.0 ) / 2.0 * 255 ) | 0;
output[ idx + 2 ] = ( normal[ 2 ] * 255 ) | 0;
output[ idx + 3 ] = 255;
}
}
context.putImageData( imageData, 0, 0 );
return canvas; //傳回法線貼圖.
},
/*
///generateDataTexture類生成DataTexture對象使用的圖像資料.
*/
///<summary>DataTexture</summary>
///<param name ="width" type="Number">圖像寬度</param>
///<param name ="height" type="Number">圖像高度</param>
///<param name ="color" type="Color">顔色</param>
generateDataTexture: function ( width, height, color ) {
var size = width * height;
var data = new Uint8Array( 3 * size ); //建立8位無符号整數數組,數組長度是高乘寬的3倍.
var r = Math.floor( color.r * 255 ); //
var g = Math.floor( color.g * 255 );
var b = Math.floor( color.b * 255 );
for ( var i = 0; i < size; i ++ ) {
data[ i * 3 ] = r;
data[ i * 3 + 1 ] = g;
data[ i * 3 + 2 ] = b;
}
var texture = new THREE.DataTexture( data, width, height, THREE.RGBFormat ); //建立基于圖像資料的反射或者折射紋理貼圖.
texture.needsUpdate = true; //标記紋理需要更新.
return texture; //傳回紋理對象.
}
};
商域無疆 (http://blog.csdn.net/omni360/)
本文遵循“署名-非商業用途-保持一緻”創作公用協定
轉載請保留此句:商域無疆 - 本部落格專注于 靈活開發及移動和物聯裝置研究:資料可視化、GOLANG、Html5、WEBGL、THREE.JS,否則,出自本部落格的文章拒絕轉載或再轉載,謝謝合作。
以下代碼是THREE.JS 源碼檔案中extras/ImageUtils.js檔案的注釋.
更多更新在 : https://github.com/omni360/three.js.sourcecode