1. 程式人生 > >WEBGL學習【五】紋理貼圖

WEBGL學習【五】紋理貼圖

<html lang="zh-CN">
<!--伺服器執行地址:http://127.0.0.1:8080/webgl/LearnNeHeWebGL/NeHeWebGL4.html-->
<head>
    <title>NeHe's WebGL</title>
    <meta charset="UTF-8"/>
<!--引入需要的庫檔案-->
<script type="text/javascript" src="Oak3D_v_0_5.js"></script>
<!--片元著色器;為JavaScript
片段指定一個ID編號,後面我可以更具這個ID編號來獲取這段片元著色器的JavaScript片段程式碼--> <script id="shader-fs" type="x-shader/x-fragment"> precision mediump float; varying vec4 vTextureCoord; uniform sampler2D uSampler; void main(void) { gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t)); } </
script> <!--頂點著色器;後面可以通過ID編號來獲取這段頂點著色器程式碼--> <script id="shader-vs" type="x-shader/x-vertex"> attribute vec3 aVertexPosition; attribute vec4 aTextureCoord; uniform mat4 uMVMatrix; uniform mat4 uPMatrix; varying vec4 vTextureCoord; void main(void) { gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); vTextureCoord = aTextureCoord; } </
script> <script type="text/javascript"> var gl; //初始化WEBGL function initGL(canvas) { try { //獲取WEBGL上下文 gl = canvas.getContext("experimental-webgl"); //gl這個上下文中存放了一些屬性(canvas的寬度、長度和其他相關屬性資料) //設定我的視口的寬度和高度 gl.viewportWidth = canvas.width; gl.viewportHeight = canvas.height; } catch (e) { } //如果獲取失敗 if (!gl) { alert("Could not initialise WebGL, sorry :-("); } } //獲取我的著色器物件 function getShader(gl, id) { //根據id獲取著色器源程式程式碼 var shaderScript = document.getElementById(id); if (!shaderScript) { return null; } var str = ""; var k = shaderScript.firstChild; while (k) { if (k.nodeType == 3) { str += k.textContent; } k = k.nextSibling; } var shader; //1.根據著色器的型別建立相應的著色器物件 if (shaderScript.type == "x-shader/x-fragment") { shader = gl.createShader(gl.FRAGMENT_SHADER); } else if (shaderScript.type == "x-shader/x-vertex") { shader = gl.createShader(gl.VERTEX_SHADER); } else { return null; } //2.向著色器物件中指定相應的GLSL ES原始碼(以字串的形式傳遞進去) gl.shaderSource(shader, str); //3.開始編譯著色器(編譯成為二進位制的可執行檔案) gl.compileShader(shader); //檢查下著色器的狀態(是否編譯成功) if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { alert(gl.getShaderInfoLog(shader)); return null; } return shader; } //一個著色器物件必須包含一個頂點著色器和一個片元著色器 var shaderProgram; //初始化著色器 function initShaders() { //獲取我的頂點著色器和片元著色器 var fragmentShader = getShader(gl, "shader-fs"); var vertexShader = getShader(gl, "shader-vs"); //每一個program中可以存放一個頂點著色器和一個片元著色器 //4.建立我的程式物件 shaderProgram = gl.createProgram(); //5.為程式物件分配著色器物件 gl.attachShader(shaderProgram, vertexShader); gl.attachShader(shaderProgram, fragmentShader); //6.連結程式物件 /** * 1.可以保證頂點著色器和片元著色器同名並且是同類型的 * 2.attributeuniformvarying變數個數不超過著色器的上限 */ gl.linkProgram(shaderProgram); //檢測是否連線成功 if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { alert("Could not initialise shaders"); } //7.告訴WEBGL要使用的程式物件 gl.useProgram(shaderProgram); //指定一個新的屬性;gl.enableVertexAttribArray,我們使用它來告訴WebGL我們會用一個數組來為屬性賦值 //頂點的位置資訊 shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute); //獲取我的頂點著色器中的attribute紋理座標引數資料 shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord"); gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute); //program中取得另外的兩個屬性值(模型檢視投影矩陣) shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); } //定義了我的模型檢視矩陣和投影矩陣 var mvMatrix; var pMatrix; //在這裡實現我的矩陣的進棧和出棧操作 var mvMatrixStack = []; function myPushMatrix() { var copy = new okMat4(); mvMatrix.clone(copy); mvMatrixStack.push(copy); } function myPopMatrix() { if (mvMatrixStack.length == 0) { throw "Invalid popMatrix!"; } mvMatrix = mvMatrixStack.pop(); } //把我們新設定的模型檢視投影矩陣傳給頂點著色器中的uniform變數 function setMatrixUniforms() { gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix.toArray()); gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix.toArray()); } //定義我的三角形和矩形緩衝區頂點位置 var pyramidVertexPositionBuffer; var cubeVertexPositionBuffer; //定義我的三角形和矩形緩衝區的頂點顏色 var pyramidVertexColorBuffer; var cubeVertexTextureCoordBuffer ; //定義我的立方體索引下標 var cubeVertexIndexBuffer; //緩衝區的初始化 function initBuffers() { //1.新建三角形頂點緩衝區物件 pyramidVertexPositionBuffer = gl.createBuffer(); //2.繫結目標物件到緩衝區 gl.bindBuffer(gl.ARRAY_BUFFER, pyramidVertexPositionBuffer); //初始化我的頂點陣列 var vertices = [ // Front face 0.0, 1.0, 0.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, // Right face 0.0, 1.0, 0.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, // Back face 0.0, 1.0, 0.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, // Left face 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0 ]; //3.緩衝區物件中寫入資料 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); //計算頂點陣列的大小和頂點個數 pyramidVertexPositionBuffer.itemSize = 3; pyramidVertexPositionBuffer.numItems = 12; //1.建立我的顏色緩衝區 pyramidVertexColorBuffer = gl.createBuffer(); //2.繫結我的顏色緩衝區到目標物件 gl.bindBuffer(gl.ARRAY_BUFFER, pyramidVertexColorBuffer); //初始化我的顏色陣列(對每一個頂點指定相應的顏色) var colors = [ //注意保證在同一個頂點上面的顏色要相同 // Front face 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, // Right face 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, // Back face 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, // Left face 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0 ]; //3.向緩衝區物件中寫入資料 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW); //計算三角形頂點顏色陣列的大小和頂點個數 pyramidVertexColorBuffer.itemSize = 4; pyramidVertexColorBuffer.numItems = 12; //1.新建矩形頂點緩衝區物件 cubeVertexPositionBuffer = gl.createBuffer(); //2.繫結目標物件到緩衝區 gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); //立方體的頂點位置陣列 vertices = [ // Front face(123第一個三角形, 134第二個三角形) -1.0, -1.0, 1.0, //左下 1.0, -1.0, 1.0, //右下 1.0, 1.0, 1.0, //右上 -1.0, 1.0, 1.0, //左上 // Back face -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, // Top face -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, // Bottom face -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, // Right face 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, // Left face -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0 ]; //3.向緩衝區物件中寫入資料 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); //計算矩形頂點陣列每一項資料的大小,和頂點個數(有四個不同的頂點位置,每個頂點由3個數字組成) cubeVertexPositionBuffer.itemSize = 3; cubeVertexPositionBuffer.numItems = 24; //1.建立我的立方體的頂點紋理圖片緩衝區 cubeVertexTextureCoordBuffer = gl.createBuffer(); //2.繫結目標物件到緩衝區 gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexTextureCoordBuffer ); //定義我的矩形的顏色陣列 var textureCoords = [ // Front face 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, // Back face 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, // Top face 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, // Bottom face 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, // Right face 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, // Left face 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, ]; //3.向緩衝區物件中寫入資料 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoords), gl.STATIC_DRAW); //計算我的正方形的頂點陣列 cubeVertexTextureCoordBuffer .itemSize = 2; cubeVertexTextureCoordBuffer .numItems = 24; //開始定義我的頂點位置陣列 //1.建立我的頂點索引緩衝區物件 cubeVertexIndexBuffer = gl.createBuffer(); //2.繫結目標物件到緩衝區 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer); //設定我的頂點索引陣列 var cubeVertexIndices = [ 0, 1, 2, 0, 2, 3, // Front face 4, 5, 6, 4, 6, 7, // Back face 8, 9, 10, 8, 10, 11, // Top face 12, 13, 14, 12, 14, 15, // Bottom face 16, 17, 18, 16, 18, 19, // Right face 20, 21, 22, 20, 22, 23 // Left face ]; //3.向緩衝區物件寫入資料 gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW); //計算我的頂點索引陣列的大小(每一項資料的大小,總共

相關推薦

WEBGL學習紋理

<html lang="zh-CN"> <!--伺服器執行地址:http://127.0.0.1:8080/webgl/LearnNeHeWebGL/NeHeWebGL4.html--> <head> <title>N

WEBGL學習模型檢視矩陣

<html lang="zh-CN"> <!--伺服器執行地址:http://127.0.0.1:8080/webgl/LearnNeHeWebGL/NeHeWebGL4.html--> <head> <title>N

GLSL教程(八)紋理

簡單的紋理貼圖(Simple Texture)為了在GLSL中應用紋理,我們需要訪問每個頂點的紋理座標。GLSL中提供了一些屬性變數,每個紋理單元一個: attribute vec4 gl_MultiTexCoord0;

一步步學OpenGL 16 -《紋理

教程16 紋理貼圖基礎 背景 紋理貼圖意思是將任意型別的圖片貼在3d模型的一個或者多個面上。圖片可以是任意的但通常是一種通用的樣式,比如:磚塊、植物、荒蕪的土地等等,可以提高場景的真實性。比較下面兩幅圖片: 為了實現紋理貼圖我們需

ShaderLab學習小結(十)法線的簡單Shader

otl mvp truct 沒有 模型 視覺 有一個 rdb 值範圍 目標:賦予材質法線貼圖,並能響應光照的變化,體現出凹凸感。場景中只有一個主平行光找了一張法線貼圖(網上蕩的)在unity裏別忘了把這張圖設為normalmap先看一下,如果只是作為普通貼圖,賦在Diffu

WebGL---6.3D紋理

一、例項程式碼 <html> <canvas id='c' width='640' height='480'></canvas> <script type="x-shader/x-vertex" id="vertex-shader">

redis學習基於redis的分散式鎖實現

    在單個JVM中,我們可以很方便的用sychronized或者reentrantLock在資源競爭時進行加鎖,保證高併發下資料執行緒安全。但是若是分散式環境下,多個JVM同時對一個資源進行競爭時,我們該如何保證執行緒安全呢?分散式鎖便能實現我們的要求。   &n

蝸龍徒行-Spark學習筆記IDEA中叢集執行模式的配置

問題現象 在IDEA中執行sparkPI,報錯: Exception in thread “main” org.apache.spark.SparkException: A master URL must be set in your configurati

大前端學習筆記整理rem與px換算的計算方式

前言 這段時間的小專案中算是真正意義上使用了rem來進行移動端的頁面佈局,專案結束了我反思了一下之前的對於rem的使用...原來我以前對rem用法完全是在搞笑啊!!結合這次這個小專案,我覺得我也有必要對rem佈局以及用法進行一次總結。 ps.文筆可能不太好... 1.什麼是rem 來自於鵝廠ISUX團隊的解釋

大前端學習筆記整理關於JavaScript中的關鍵字——this

寫在前面 工作有那麼一段時間了,但是在工作中,發現自己的理論知識還是有所欠缺。特別是在javascript上,很多東西其實自己屬於知道要用這個,但是不知道為什麼要這麼用...這種情況很是尷尬了,所以寫部落格的很重要一個目的就是鍛鍊我自己的總結能力,把學到的東西總結出來,感覺這樣能讓我更快的去理解所學到的東西。

小程式開發之前端開發學習第二節

接著上一篇說,下面說一下事件物件,如果沒特殊說明,當元件觸發事件時,邏輯層繫結該事件的事件處理函式會收到一個事件物件 <view bindtap="myevent">view</view> myevent:function(e){ console.l

20 WebGL使用紋理

案例檢視地址:點選這裡WebGL中紋理的限制WebGL中的紋理需要注意一點,所使用的圖片資料的大小必須是2的階乘,橫豎的畫素長度大小必須是32x32,128x128等2的階乘的形式。當然,做一些處理的話,不是2的階乘的圖片資料也是可以用的,但是基本上作為紋理使用的影象資料的大

Shader實戰篇PBR之Specular鏡面

1:Specular鏡面貼圖:shader有standard還有Standard(Specular setup)兩種,只不過第一種裡有一個金屬度貼圖,第二種換成了鏡面貼圖。不過Specular鏡面貼圖

Windows 8 Directx 開發學習筆記(十一)地形紋理

前一篇實現木箱貼圖時,木箱的六個面都正好用一整張紋理圖,即六個面的紋理座標均在[0,1]內。然而在為比較大的模型貼圖時,像山峰河谷模型,如果只用一張紋理圖,那麼每個三角形只得到幾個紋理元素,無法為提供足夠高的解析度。這時可以在模型表面上平鋪紋理貼圖,像給牆面貼磁磚一樣,只需

Unity實用小方法判斷是否為透明

private bool JudgeTransparentPic(TextureFormat format) { //所有貼圖格式帶alpha通道的格式,帶alpha通

C++ STL學習容器set和multiset

一、set和multiset基礎 set和multiset會根據特定的排序準則,自動將元素進行排序。不同的是後者允許元素重複而前者不允許。 需要包含標頭檔案: #include <set> set和multiset都是定義在std空間裡的類模板: templ

Shader實戰篇PBR之Normal Map

首先Normal Map是法線貼圖,用於增加模型的細節。其本身是一張藍色的凹凸圖。 如圖:,它和金屬貼圖,反射貼圖置於一起。 這是沒有加發現貼圖的:           可以看到在箭頭指向的方向上

Mybatis學習總結實現關聯表查詢----一對多關聯(collection)

實現關聯表查詢----一對多關聯(collection) 一對多需求:即一張表class中又含有多張表(teacher,student)內容。現根據class_id 來獲取對應的班級資訊(包括學生和老師資訊)。 1 、建立表和資料: CREATE TABLE studen

Windows 8 Directx 開發學習筆記(十)紋理實現旋轉的木箱

紋理貼圖對映(texturemapping)是可以顯著提高場景細節和真實感的一種技術,基本原理是將影象資料對映到3D三角形表面(之前的文章提到過,三維模型其實是由很多個三角形拼接而成)。當使用紋理資源時,只要將每個3D三角形與紋理資源上的三角形對應,就可以實現貼圖效果。如圖

Spark-core學習 RDD寬窄依賴 & Stage

spark red schedule 例如 shell 落地 版本 進行 規則 環境  虛擬機:VMware 10   Linux版本:CentOS-6.5-x86_64   客戶端:Xshell4  FTP:Xftp4  jdk1.8  scala-2.10.4(依賴jd