ホームページ  >  記事  >  ウェブフロントエンド  >  Web 学習: テクスチャ マップの使用方法

Web 学習: テクスチャ マップの使用方法

little bottle
little bottle転載
2019-04-30 11:29:012325ブラウズ

グラフィックスに実物に近い質感を持たせるためには、一般的にテクスチャが使用されますが、テクスチャには主に拡散反射マップと鏡面ハイライトマップの2種類があります。拡散反射マップは、拡散反射光と環境光の効果を同時に実現できます。
実際の効果についてはデモをご覧ください: テクスチャ マッピング

Web 学習: テクスチャ マップの使用方法

2D テクスチャ

を使用する必要があります。テクスチャを実装するにはテクスチャを使用します。一般的に使用されるテクスチャ形式は、2D テクスチャ、キューブ テクスチャ、3D テクスチャです。最も基本的な 2D テクスチャを使用して、このセクションで必要な効果を実現できます。テクスチャの使用に必要な API を見てみましょう。関連チュートリアル: js ビデオ チュートリアル

テクスチャの座標原点は左下隅にあり、通常の左上隅の座標原点とは正反対であるため、次は次のようになります。便宜上、Y軸に従って反転するように座標を設定します。

gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);

テクスチャをアクティブにしてバインドします。gl.TEXTURE0 はテクスチャ番号 0 を意味し、0 から最大まで増加できます。 TEXTURE_2D は 2D テクスチャを表します。

gl.activeTexture(gl.TEXTURE0);//激活纹理
gl.bindTexture(gl.TEXTURE_2D, texture);//绑定纹理

次のステップは、テクスチャ パラメータを設定することです。この API は非常に重要であり、テクスチャの最も複雑な部分でもあります。

gl.texParameteri(target, pname, param)、param の値を、ターゲットにバインドされたテクスチャ オブジェクトの pname パラメータに割り当てます。パラメータ:

  • target: gl.TEXTURE_2D または gl.TEXTURE_CUBE_MAP

  • pname: はい4 つのテクスチャ パラメータを指定します。

    1. Magnify (gl.TEXTURE_MAP_FILTER): テクスチャの描画範囲がテクスチャ自体よりも大きい場合に、テクスチャのカラーを取得する方法。たとえば、16*16 のテクスチャ イメージが 32*32 ピクセル空間にマッピングされると、テクスチャ サイズは元のサイズの 2 倍になります。デフォルト値は gl.LINEAR です。
    2. Minify (gl.TEXTURE_MIN_FILTER): テクスチャの描画リターンがテクスチャ自体より小さい場合にテクセル カラーを取得する方法。たとえば、32*32 のテクスチャ イメージが 16*16 ピクセル空間にマッピングされる場合、テクスチャのサイズは元のサイズのみになります。デフォルト値は gl.NEAREST_MIPMAP_LINEAR です。
    3. 水平塗りつぶし (gl.TEXTURE_WRAP_S): テクスチャ画像の左側または右側の領域を塗りつぶす方法を示します。デフォルト値は gl.REPEAT です。
    4. 垂直塗りつぶし (gl.TEXTURE_WRAP_T): テクスチャ イメージの上下の領域を塗りつぶす方法を示します。デフォルト値は gl.REPEAT です。
  • param: テクスチャ パラメータ

    1. の値は gl.TEXTURE_MAP_FILTER および # に割り当てることができます。 ##gl .TEXTURE_MIN_FILTER パラメータ値

      gl.NEAREST: マップされたピクセルの中心に最も近い元のテクスチャ上のピクセルのカラー値を値として使用します。新しいピクセルの。

      gl.LINEAR: 新しいピクセルの中心に最も近い 4 つのピクセルのカラー値の加重平均を新しいピクセルの値として使用します (gl.LINEAR と比較)。最も近い、この方法は画質が優れていますが、オーバーヘッドも大きくなります。)

    2. gl.TEXTURE_WRAP_S および gl.TEXTURE_WRAP_T## に割り当て可能な定数#:

      gl.REPEAT

      : タイルの繰り返しテクスチャ

      gl.MIRRORED_REPEAT

      : ミラー化された対称の繰り返しテクスチャ# gl.CLAMP_TO_EDGE: テクスチャ イメージのエッジ値を使用する

    3. 設定例は次のとおりです。
    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.NEAREST);
gl .texImage2D

、バインドされたテクスチャ オブジェクトにピクセルを割り当てます。この API には、

WebGL1

および WebGL2 に十数個のオーバーロードされた関数があり、形式の種類は非常に多様です。ピクセル パラメータには画像、キャンバス、またはビデオを指定できます。WebGL1 の呼び出しフォームのみを確認します。

// WebGL1:
void gl.texImage2D(target, level, internalformat, width, height, border, format, type, ArrayBufferView? pixels);
void gl.texImage2D(target, level, internalformat, format, type, ImageData? pixels);
void gl.texImage2D(target, level, internalformat, format, type, HTMLImageElement? pixels);
void gl.texImage2D(target, level, internalformat, format, type, HTMLCanvasElement? pixels);
void gl.texImage2D(target, level, internalformat, format, type, HTMLVideoElement? pixels);
void gl.texImage2D(target, level, internalformat, format, type, ImageBitmap? pixels);

// WebGL2:
//...
テクスチャ ロード関数をカプセル化しました。各 API の呼び出し形式を使用して情報を表示できます。まず、必要な効果を達成する必要があります。
function loadTexture(url) {
    const texture = gl.createTexture();
    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
    gl.activeTexture(gl.TEXTURE0);
    gl.bindTexture(gl.TEXTURE_2D, texture);
    
    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);
    
    let textureInfo = {
        width: 1,
        height: 1,
        texture: texture,
    };
    const img = new Image();
    return new Promise((resolve,reject) => {
        img.onload = function() {
            textureInfo.width = img.width;
            textureInfo.height = img.height;
            gl.bindTexture(gl.TEXTURE_2D, textureInfo.texture);
            gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
            resolve(textureInfo);
        };
        img.src = url;
    });
}
拡散反射マップ

まず拡散反射ライト マップを実装し、さまざまな種類のマップが含まれるフロア マップをインターネットからダウンロードします。

バッファは、テクセルと呼ばれる対応するテクスチャ ピクセルをテクスチャ座標を通じて見つけることができるように、頂点に対応するテクスチャ座標を追加する必要があります。

const arrays = {
    position: [
        -1, 0, -1,
        -1, 0, 1,
        1, 0, -1,
        1, 0, 1
    ],
    texcoord: [
        0.0, 1.0,
        0.0, 0.0,
        1.0, 1.0,
        1.0, 0.0
    ],
    normal: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1 ],
};

頂点シェーダー間の唯一の違いは、テクスチャ座標の追加です。これには、フラグメント シェーダーに補間を渡す必要があります。

//...
attribute vec2 a_texcoord;
varying vec2 v_texcoord;

void main() { 
        //...
    v_texcoord = a_texcoord;
}

フラグメント シェーダーをさらに変更する必要があります。主に

texture2D

を使用して、対応する座標のテクセルを取得し、前の色を置き換えます。以下はフラグメントシェーダ関連のコードです

//...
vec3 normal = normalize(v_normal);
vec4 diffMap = texture2D(u_samplerD, v_texcoord);

//光线方向
vec3 lightDirection = normalize(u_lightPosition - v_position);
// 计算光线方向和法向量夹角
float nDotL = max(dot(lightDirection, normal), 0.0);
// 漫反射光亮度
vec3 diffuse = u_diffuseColor * nDotL * diffMap.rgb;
// 环境光亮度
vec3 ambient = u_ambientColor * diffMap.rgb;
//...

js部分はテクスチャに相当する画像を読み込み、テクスチャユニットを渡してレンダリングを行います

//...
(async function (){
    const ret = await loadTexture('/model/floor_tiles_06_diff_1k.jpg')
    setUniforms(program, {
        u_samplerD: 0//0号纹理
    });
    //...
    draw();
})()
効果は以下の通りです。床なのでハイライト部分が眩しすぎますが、鏡のような滑らかで強い反射はありません。

镜面Web 学習: テクスチャ マップの使用方法

为了实现更逼真的高光效果,继续实现Web 学習: テクスチャ マップの使用方法,实现原理和漫反射一样,把对应的高光颜色替换成Web 学習: テクスチャ マップの使用方法纹素就可以了。
下面就是片元着色器增加修改高光部分

//...
vec3 normal = normalize(v_normal);
vec4 diffMap = texture2D(u_samplerD, v_texcoord);
vec4 specMap = texture2D(u_samplerS, v_texcoord);

//光线方向
vec3 lightDirection = normalize(u_lightPosition - v_position);
// 计算光线方向和法向量夹角
float nDotL = max(dot(lightDirection, normal), 0.0);
// 漫反射光亮度
vec3 diffuse = u_diffuseColor * nDotL * diffMap.rgb;
// 环境光亮度
vec3 ambient = u_ambientColor * diffMap.rgb;
// 镜面高光
vec3 eyeDirection = normalize(u_viewPosition - v_position);// 反射方向
vec3 halfwayDir = normalize(lightDirection + eyeDirection);
float specularIntensity = pow(max(dot(normal, halfwayDir), 0.0), u_shininess);
vec3 specular = (vec3(0.2,0.2,0.2) + specMap.rgb) * specularIntensity;
//...

js同时加载漫反射和Web 学習: テクスチャ マップの使用方法

//...
(async function (){
    const ret = await Promise.all([
        loadTexture('/model/floor_tiles_06_diff_1k.jpg'),
        loadTexture('/model/floor_tiles_06_spec_1k.jpg',1)
    ]);
    setUniforms(program, {
        u_samplerD: 0,//0号纹理
        u_samplerS: 1 //1号纹理
    });
    //...
    draw();
})()

最后实现的效果如下,明显更加接近真实的地板

Web 学習: テクスチャ マップの使用方法

以上がWeb 学習: テクスチャ マップの使用方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcnblogs.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。