webgl學(xué)習(xí)02-繪制一個(gè)點(diǎn)
繪制一個(gè)點(diǎn)
編寫簡單的著色器代碼
首先,我們先了解一下代碼中用到的 GLSL 語言的 類型 和 內(nèi)置變量。
頂點(diǎn)著色器
用到的數(shù)據(jù)類型

頂點(diǎn)著色器的內(nèi)置變量

內(nèi)置函數(shù)

gl_Position的類型—— vec4 明顯比 gl_PointSize 的 float 要特別。如果說我們需要的頂點(diǎn)坐標(biāo)數(shù)據(jù)是 (x, y, z),那么好像也才只有 3 個(gè)浮點(diǎn)數(shù),那第 4 個(gè)數(shù)是什么呢?
通常,我們添加 1.0 作為第四個(gè)參數(shù) w,也就是 (x, y, z, 1.0)。由四個(gè)數(shù)組成的矢量叫做 齊次坐標(biāo),齊次坐標(biāo) (x, y, z, w) 其實(shí)等價(jià)于三維坐標(biāo) (x/w, y/w, z/w) 。拋開這么多復(fù)雜的概念,我們當(dāng)前只需要明確一點(diǎn):當(dāng)我們使用齊次坐標(biāo)表示三維頂點(diǎn)坐標(biāo)時(shí),最后一個(gè)值傳 1.0 即可。
片元著色器
片元著色器的內(nèi)置變量

當(dāng)然,片元著色器中 gl_FragColor 的值類型是 vec4 就很好理解了,因?yàn)槠湟灰粚?duì)應(yīng) RGBA 中的每一位。需要注意的是 WebGL 繼承 OpenGl 的顏色取值,它的范圍是 (0.0, 1.0),RGB 的值越高顏色越亮,而對(duì)于透明度 A 來說,值越高就越不透明。
著色器代碼
首先是頂點(diǎn)著色器
- 定義了一個(gè)
main函數(shù) - 設(shè)置
gl_Position頂點(diǎn)的三維坐標(biāo)對(duì)應(yīng)為 (0, 0, 0) - 設(shè)置
gl_PointSize大小為 50 像素
const VertexSource = /* glsl */ ` void main() { gl_Position = vec4(0.0, 0.0, 0.0, 1.0); gl_PointSize = 50.0; } `
然后是片元著色器
- 同樣定義了一個(gè)
main函數(shù) - 設(shè)置
gl_FragColor的值為藍(lán)色(R=0, G=0, B=0.9, A=1)
const FragSource = /* glsl */ ` void main() { gl_FragColor = vec4(0.0, 0.0, 0.9, 1.0); } `
清空繪圖區(qū)

清空繪圖區(qū)代碼
清空繪圖區(qū)其實(shí)就是清空顏色緩沖區(qū),所以接口 gl.clear 的參數(shù)中,我們僅需要使用 gl.COLOR_BUFFER_BIT,其他的可以先不用管。
需要注意,gl.clearColor(r, g, b, a) 是有記憶的,如果我們后續(xù)清空繪圖區(qū)的顏色不需要改變,那我們只需要 指定一次 clearColor 即可
const canvas = document.querySelector("#c");
const gl = canvas.getContext("webgl");
// 設(shè)置 canvas 背景色(若無需變化顏色,則只需要設(shè)置一次即可)
gl.clearColor(0.0, 0.0, 0.0, 1.0);
// 清空 canvas
gl.clear(gl.COLOR_BUFFER_BIT);
繪制一個(gè)點(diǎn)
接下來是畫點(diǎn)
創(chuàng)建著色器
整個(gè)部分為
- 獲取繪圖上下文
gl - 編寫著色器代碼
vertexCode、fragmentCode - 創(chuàng)建著色器
createShader - 創(chuàng)建著色器程序
createProgram連接頂點(diǎn)、片元著色器
// 頂點(diǎn)著色器 const vertexShader = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(vertexShader, VertexSource); gl.compileShader(vertexShader); // 片元著色器 const fragShader = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(fragShader, FragSource); gl.compileShader(fragShader); // 創(chuàng)建著色器程序 const program = gl.createProgram(); // 為著色器程序賦予shader gl.attachShader(program, vertexShader); gl.attachShader(program, fragShader); // 連接 頂點(diǎn)著色器 和 片元著色器 gl.linkProgram(program); // 應(yīng)用著色器程序 gl.useProgram(program);
繪制點(diǎn)
調(diào)用繪制函數(shù) gl.drawArrays 并傳入一定參數(shù)即可完成點(diǎn)的繪制
mode 總共有七種參數(shù)值,包括且不限于 gl.POINTS、gl.LINE_STRIP 等等

繪制代碼:
// 繪制點(diǎn) gl.drawArrays(gl.POINTS, 0, 1);
完整代碼
const VertexSource = /* glsl */ ` void main() { gl_Position = vec4(0.0, 0.0, 0.0, 1.0); gl_PointSize = 50.0; } ` const FragSource = /* glsl */ ` void main() { gl_FragColor = vec4(0.0, 0.0, 0.9, 1.0); } ` const canvas = document.querySelector("#c"); const gl = canvas.getContext("webgl"); // 設(shè)置 canvas 背景色(若無需變化顏色,則只需要設(shè)置一次即可) gl.clearColor(0.0, 0.0, 0.0, 1.0); // 清空 canvas gl.clear(gl.COLOR_BUFFER_BIT); // 頂點(diǎn)著色器 const vertexShader = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(vertexShader, VertexSource); gl.compileShader(vertexShader); // 片元著色器 const fragShader = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(fragShader, FragSource); gl.compileShader(fragShader); // 創(chuàng)建著色器程序 const program = gl.createProgram(); // 為著色器程序賦予shader gl.attachShader(program, vertexShader); gl.attachShader(program, fragShader); // 連接 頂點(diǎn)著色器 和 片元著色器 gl.linkProgram(program); // 應(yīng)用著色器程序 gl.useProgram(program); // 繪制點(diǎn) gl.drawArrays(gl.POINTS, 0, 1);

浙公網(wǎng)安備 33010602011771號(hào)