Web學習之怎麼使用紋理貼圖
為了讓圖形能獲得接近真實物體的材質效果,一般會使用貼圖,貼圖類型主要包括兩種:漫反射貼圖和鏡面高光貼圖。其中漫反射貼圖可以同時實現漫反射光和環境光的效果。
實際效果請看demo:紋理貼圖
#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個紋理參數
- 放大(gl.TEXTURE_MAP_FILTER):當紋理的繪製範圍比紋理本身更大時,如何取得紋理顏色。例如,將16*16的紋理影像映射到32*32像素的空間時,紋理的尺寸會變成原始的兩倍。預設值為gl.LINEAR。
- 縮小(gl.TEXTURE_MIN_FILTER): 當紋理的繪製回傳比紋理本身更小時,如何取得紋素顏色。例如,將32*32的紋理影像映射到16*16像素空間裡,紋理的尺寸就只有原始的普通。預設值為gl.NEAREST_MIPMAP_LINEAR。
- 水平填充(gl.TEXTURE_WRAP_S): 表示如何對紋理圖像左側或右側區域進行填充。預設值為gl.REPEAT。
- 垂直填入(gl.TEXTURE_WRAP_T): 表示如何對紋理影像上方和下方的區域進行填滿。預設值為gl.REPEAT。
param: 紋理參數的值
#可賦給gl.TEXTURE_MAP_FILTER 和gl .TEXTURE_MIN_FILTER 參數的值
gl.NEAREST: 使用原紋理上距離映射後像素中心最近的那個像素的顏色值,作為新像素的值。
gl.LINEAR: 使用距離新像素中心最近的四個像素的顏色值的加權平均,作為新像素的值(和gl.NEAREST相比,該方法圖像質量更好,但也會有較大的開銷。)
可賦給gl.TEXTURE_WRAP_S 和gl.TEXTURE_WRAP_T 的常數:
gl.REPEAT: 平鋪式的重複紋理
#gl.MIRRORED_REPEAT: 鏡像對稱的重複紋理
gl.CLAMP_TO_EDGE: 使用紋理影像邊緣值
#設定樣例如下所示:
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,將pixels 指定給綁定的紋理對象,這個api在WebGL1 和WebGL2 中的重載函數多達十幾個,格式類型非常多樣。 pixels參數既可以是圖像,canvas,也可以是視頻,我們只看 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學習之怎麼使用紋理貼圖的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

人臉偵測辨識技術已經是一個比較成熟且應用廣泛的技術。而目前最廣泛的網路應用語言非JS莫屬,在Web前端實現人臉偵測辨識相比後端的人臉辨識有優勢也有弱勢。優點包括減少網路互動、即時識別,大大縮短了使用者等待時間,提高了使用者體驗;弱勢是:受到模型大小限制,其中準確率也有限。如何在web端使用js實現人臉偵測呢?為了實現Web端人臉識別,需要熟悉相關的程式語言和技術,如JavaScript、HTML、CSS、WebRTC等。同時也需要掌握相關的電腦視覺和人工智慧技術。值得注意的是,由於Web端的計

股票分析必備工具:學習PHP和JS繪製蠟燭圖的步驟,需要具體程式碼範例隨著網路和科技的快速發展,股票交易已成為許多投資者的重要途徑之一。而股票分析是投資人決策的重要一環,其中蠟燭圖被廣泛應用於技術分析。學習如何使用PHP和JS繪製蠟燭圖將為投資者提供更多直觀的信息,幫助他們更好地做出決策。蠟燭圖是一種以蠟燭形狀來展示股票價格的技術圖表。它展示了股票價格的

如何使用PHP和JS創建股票蠟燭圖股票蠟燭圖是股票市場中常見的技術分析圖形,透過繪製股票的開盤價、收盤價、最高價和最低價等數據,幫助投資者更直觀地了解股票的價格波動情形。本文將教你如何使用PHP和JS創建股票蠟燭圖,並附上具體的程式碼範例。一、準備工作在開始之前,我們需要準備以下環境:1.一台運行PHP的伺服器2.一個支援HTML5和Canvas的瀏覽器3

如何使用JS和百度地圖實現地圖點擊事件處理功能概述:在網路開發中,經常需要使用地圖功能來展示地理位置和地理資訊。而地圖上的點擊事件處理是地圖功能中常用且重要的一環。本文將介紹如何使用JS和百度地圖API來實現地圖的點擊事件處理功能,並給出具體的程式碼範例。步驟:匯入百度地圖的API檔案首先,要在HTML檔案中匯入百度地圖API的文件,可以透過以下程式碼實現:

隨著網路金融的快速發展,股票投資已經成為了越來越多人的選擇。而在股票交易中,蠟燭圖是常用的技術分析方法,它能夠顯示股票價格的變動趨勢,幫助投資人做出更精準的決策。本文將透過介紹PHP和JS的開發技巧,帶領讀者了解如何繪製股票蠟燭圖,並提供具體的程式碼範例。一、了解股票蠟燭圖在介紹如何繪製股票蠟燭圖之前,我們首先需要先了解什麼是蠟燭圖。蠟燭圖是由日本人

js和vue的關係:1、JS作為Web開發基石;2、Vue.js作為前端框架的崛起;3、JS與Vue的互補關係;4、JS與Vue的實踐應用。

Cockpit是一個面向Linux伺服器的基於Web的圖形介面。它主要是為了使新用戶/專家用戶更容易管理Linux伺服器。在本文中,我們將討論Cockpit存取模式以及如何從CockpitWebUI切換Cockpit的管理存取。內容主題:駕駛艙進入模式查找當前駕駛艙訪問模式從CockpitWebUI啟用Cockpit的管理訪問從CockpitWebUI禁用Cockpit的管理訪問結論駕駛艙進入模式駕駛艙有兩種訪問模式:受限訪問:這是駕駛艙的默認訪問模式。在這種存取模式下,您無法從駕駛艙Web用戶

web是全球廣域網,也稱為萬維網,是互聯網的一種應用形式。 Web 是一種基於超文本和超媒體的資訊系統,它允許使用者透過超連結在不同的網頁之間跳轉,從而瀏覽和獲取資訊。 Web 的基礎是互聯網,它使用統一、標準化的協定和語言,使得不同電腦之間能夠進行資料交換和資訊共享。
