ข้ามไปยังเนื้อหาหลัก
คู่มือระบบ เนื้อหาผ่านการตรวจสอบแล้ว

WebGL

บทความนี้แนะนำ WebGL ซึ่งเป็น API สำหรับสร้างกราฟิก 3D ในเบราว์เซอร์ โดยเน้นที่การสร้าง WebGL context, การใช้ shaders เพื่อควบคุมการแสดงผล, และการใช้ textures เ...

WebGL: สร้างกราฟิก 3D ในเบราว์เซอร์

จากบทที่แล้วที่เราได้สำรวจ Canvas API สำหรับการวาดภาพ 2D คราวนี้เราจะก้าวข้ามไปอีกขั้นด้วย WebGL (Web Graphics Library) ซึ่งเป็น API ที่ช่วยให้เราสร้างกราฟิก 3D ที่ซับซ้อนและมีประสิทธิภาพสูงในเบราว์เซอร์ได้โดยตรง WebGL ไม่ได้เป็นภาษาใหม่ แต่เป็น JavaScript API ที่ใช้ประโยชน์จากความสามารถของ GPU (Graphics Processing Unit) เพื่อเร่งการแสดงผลภาพสามมิติ

WebGL Context: จุดเริ่มต้นของการวาดภาพ 3D

เช่นเดียวกับ Canvas API ที่เราต้องดึง context เพื่อวาดภาพ WebGL ก็เช่นกัน เราต้องสร้าง WebGL context เพื่อเข้าถึงฟังก์ชันและทรัพยากรที่เกี่ยวข้องกับการวาดภาพ 3D ขั้นตอนการสร้าง context คล้ายกับ Canvas API แต่มีรายละเอียดที่แตกต่างกันเล็กน้อย:

const canvas = document.getElementById('myCanvas');
const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');

if (!gl) {
  alert('WebGL ไม่รองรับบนเบราว์เซอร์นี้');
} else {
  // WebGL พร้อมใช้งาน!
  gl.clearColor(0.0, 0.0, 0.0, 1.0); // กำหนดสีพื้นหลังเป็นสีดำ
  gl.clear(gl.COLOR_BUFFER_BIT); // เคลียร์ canvas ด้วยสีพื้นหลัง
}

ในโค้ดข้างต้น เราพยายามดึง WebGL context โดยใช้ `getContext('webgl')` หากไม่สำเร็จ เราจะลองใช้ `getContext('experimental-webgl')` ซึ่งเป็นเวอร์ชันเก่าที่อาจยังรองรับในบางเบราว์เซอร์ หากทั้งสองวิธีล้มเหลว แสดงว่าเบราว์เซอร์ไม่รองรับ WebGL

เมื่อได้ WebGL context มาแล้ว เราสามารถเริ่มต้นการวาดภาพได้ ตัวอย่างเช่น เรากำหนดสีพื้นหลังเป็นสีดำด้วย `gl.clearColor()` และเคลียร์ canvas ด้วยสีนั้นด้วย `gl.clear()`

เหตุผลเชิงออกแบบ: การแยก context ออกมาเป็น object ต่างหากช่วยให้ WebGL API มีความยืดหยุ่นและสามารถจัดการทรัพยากรได้อย่างมีประสิทธิภาพ context ทำหน้าที่เป็นตัวกลางระหว่าง JavaScript code ของเรากับ GPU ช่วยให้เราสามารถสั่ง GPU ให้ทำงานต่างๆ เช่น การวาดรูปทรง การใส่สี และการจัดการแสงเงา

Shaders: หัวใจสำคัญของการแสดงผล 3D

Shaders คือโปรแกรมขนาดเล็กที่ทำงานบน GPU โดยตรง ทำหน้าที่แปลงข้อมูล vertices (จุดยอด) และ fragments (pixel) เป็นภาพที่แสดงบนหน้าจอ WebGL ใช้ Shaders สองประเภทหลัก:

  • Vertex Shader: ทำหน้าที่แปลงตำแหน่งของจุดยอด (vertices) จาก space หนึ่งไปอีก space หนึ่ง เช่น จาก model space ไปเป็น clip space Vertex shader ยังสามารถใช้ในการคำนวณข้อมูลอื่นๆ ที่จำเป็นสำหรับการแสดงผล เช่น normals (เวกเตอร์ที่ชี้ออกจากพื้นผิว) และ texture coordinates
  • Fragment Shader: ทำหน้าที่คำนวณสีของแต่ละ fragment (pixel) โดยพิจารณาจากข้อมูลที่ส่งมาจาก vertex shader เช่น ตำแหน่ง แสงเงา และ texture

Shaders เขียนด้วยภาษา GLSL (OpenGL Shading Language) ซึ่งเป็นภาษา C-like ที่ออกแบบมาสำหรับการเขียนโปรแกรม GPU

ตัวอย่าง Vertex Shader:

attribute vec4 aVertexPosition;

uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;

void main() {
  gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;
}

ตัวอย่าง Fragment Shader:

void main() {
  gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); // สีขาว
}

อธิบายโค้ด: ใน vertex shader เราประกาศ attribute `aVertexPosition` ซึ่งเป็นข้อมูลตำแหน่งของจุดยอด และ uniforms `uModelViewMatrix` และ `uProjectionMatrix` ซึ่งเป็น matrices ที่ใช้ในการแปลงตำแหน่งของจุดยอด `gl_Position` คือ output variable ที่เก็บตำแหน่งของจุดยอดใน clip space

ใน fragment shader เรากำหนดสีของทุก fragment เป็นสีขาวโดยกำหนดค่า `gl_FragColor` เป็น `vec4(1.0, 1.0, 1.0, 1.0)` (red, green, blue, alpha)

ขั้นตอนการใช้งาน Shaders:

  1. สร้าง Shader Objects: สร้าง vertex shader object และ fragment shader object โดยใช้ `gl.createShader()`
  2. กำหนด Source Code: กำหนด source code ของ shader โดยใช้ `gl.shaderSource()`
  3. Compile Shaders: compile shaders โดยใช้ `gl.compileShader()`
  4. สร้าง Program Object: สร้าง program object โดยใช้ `gl.createProgram()`
  5. Attach Shaders: attach vertex shader และ fragment shader เข้ากับ program object โดยใช้ `gl.attachShader()`
  6. Link Program: link program โดยใช้ `gl.linkProgram()`
  7. Use Program: บอก WebGL ให้ใช้ program นี้ โดยใช้ `gl.useProgram()`

เหตุผลเชิงออกแบบ: การใช้ Shaders ช่วยให้เราสามารถปรับแต่งกระบวนการแสดงผลภาพได้อย่างละเอียด เราสามารถเขียน shaders ที่ซับซ้อนเพื่อสร้างเอฟเฟกต์แสงเงา วัสดุ และพื้นผิวที่สมจริง Shaders ยังช่วยให้เราสามารถใช้ประโยชน์จากความสามารถของ GPU ได้อย่างเต็มที่ ทำให้การแสดงผลภาพ 3D เป็นไปอย่างรวดเร็วและมีประสิทธิภาพ

Textures: เพิ่มรายละเอียดให้กับพื้นผิว

Textures คือรูปภาพที่ใช้ในการเพิ่มรายละเอียดให้กับพื้นผิวของวัตถุ 3D WebGL รองรับ textures หลายประเภท เช่น 2D textures, cube maps, และ 3D textures

ขั้นตอนการใช้งาน Textures:

  1. สร้าง Texture Object: สร้าง texture object โดยใช้ `gl.createTexture()`
  2. Load Image: โหลดรูปภาพที่เราต้องการใช้เป็น texture
  3. Bind Texture: bind texture object ไปยัง texture unit ที่ต้องการ โดยใช้ `gl.bindTexture()`
  4. Configure Texture Parameters: กำหนด parameters ของ texture เช่น filtering และ wrapping modes โดยใช้ `gl.texParameteri()`
  5. Upload Image Data: อัปโหลดข้อมูลรูปภาพไปยัง texture object โดยใช้ `gl.texImage2D()`
  6. Generate Mipmaps (Optional): สร้าง mipmaps เพื่อปรับปรุงประสิทธิภาพในการแสดงผลวัตถุที่อยู่ไกล โดยใช้ `gl.generateMipmap()`

ตัวอย่างการใช้งาน Textures:

const texture = gl.createTexture();
const image = new Image();

image.onload = function() {
  gl.bindTexture(gl.TEXTURE_2D, texture);
  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  gl.generateMipmap(gl.TEXTURE_2D);
  // ... วาดวัตถุ ...
};

image.src = 'path/to/your/image.jpg';

อธิบายโค้ด: เราสร้าง texture object และโหลดรูปภาพ เมื่อรูปภาพโหลดเสร็จ เรา bind texture object ไปยัง `gl.TEXTURE_2D` จากนั้นเราอัปโหลดข้อมูลรูปภาพไปยัง texture object และกำหนด parameters สำหรับ filtering (การปรับขนาด texture) และ mipmapping

เหตุผลเชิงออกแบบ: Textures ช่วยให้เราสามารถเพิ่มรายละเอียดให้กับพื้นผิวของวัตถุ 3D ได้อย่างมาก โดยไม่ต้องเพิ่มจำนวน vertices ซึ่งจะช่วยลดภาระของ GPU และปรับปรุงประสิทธิภาพในการแสดงผล นอกจากนี้ textures ยังสามารถใช้ในการสร้างเอฟเฟกต์ต่างๆ เช่น การสะท้อนแสง การหักเหแสง และการ bump mapping

สรุป

WebGL เป็นเครื่องมือที่ทรงพลังสำหรับการสร้างกราฟิก 3D ในเบราว์เซอร์ การทำความเข้าใจ WebGL context, shaders, และ textures เป็นสิ่งสำคัญในการเริ่มต้นใช้งาน WebGL แม้ว่า WebGL จะมีความซับซ้อน แต่ผลลัพธ์ที่ได้ก็คุ้มค่า เพราะมันช่วยให้เราสร้างประสบการณ์การใช้งานที่น่าทึ่งและสมจริงบนเว็บได้

ในบทต่อไป เราจะเริ่มสำรวจ Node.js ซึ่งเป็น JavaScript runtime environment ที่ช่วยให้เราสามารถเขียนโปรแกรม JavaScript ที่ทำงานบน server ได้

Office.in.th Custom Service

ต้องการพัฒนาระบบหรือปรับแต่งจากโครงสร้างนี้?

Office.in.th รับพัฒนาและออกแบบ Enterprise Web Application, API Integration และระบบบริหารงานภาครัฐ/เอกชน พร้อมการสนับสนุนระยะยาว

ดูบริการรับพัฒนาซอฟต์แวร์