1 LẬP TRÌNH ĐỒ HỌA 3D TRƯỜNG ĐẠI HỌC THỦY LỢI KHOA CÔNG NGHỆ THÔNG TIN Th S Trần Thị Minh Hoàn Email hoantm@tlu edu vn 2 Mục đích môn học Giới thiệu đồ họa máy tính 3D và lập trình đồ họa bằng WebGL[.]
Trang 2Mục đích môn học
Giới thiệu đồ họa máy tính 3D và lập trình đồ họa bằng WebGL và JavaScript Giúp sinh viên xây dựng chương trình tương tác đồ họa 3D chạy trên Windows và một trình duyệt web
Bao gồm chủ đề:
Giới thiệu JavaScript,
Ngôn ngữ tô bóng OpenGL ES,
Toán học trong đồ họa 3D
Các phép biến đổi, kết cấu, chiếu sáng, quản lý cảnh,
và tương tác đối tượng
Trang 3Nội dung môn học
3
Giới thiệu môn học, HTML và JavaScript
Lưới hình học và bộ đệm đối tượng
Các phép biến đổi
Quan sát, quy trình đồ họa
Ôn tập, kiểm tra giữa kì
Chiếu sáng
Tô bóng
Ánh xạ kết cấu
Ôn tập cuối kì
Trang 4Tài liệu tham khảo
Tài liệu chính Bài giảng Lập trình WebGL
Trần Thị Minh Hoàn hoantm@tlu.edu.vn
Kouichi Matsuda, Rodger Lea
Trang web môn học:
https://sites.google.com/site/laptrinhwebgl
Trang 5Tổng quan về WebGL
một công nghệ cho phép vẽ, hiển thị,
và tương tác với đồ họa máy tính ba chiều phức tạp ("đồ họa 3D") từ các trình duyệt web Dễ sử dụng và tạo giao diện trực quan cho người dùng và nội dung trang web
5
Trang 6 Theo truyền thống, đồ họa 3D sử dụng một ngôn ngữ lập trình như C hoặc C++ cùng với thư viện đồ hoạ như OpenGL và Direct3D Tuy nhiên, với WebGL, đồ họa 3D như là một phần của trang web chuẩn với HTML5 và JavaScript Có nghĩa là WebGL được gắn liền với trình duyệt, khi dựng hình đồ họa 3D, ta có thể sử dụng WebGL trực tiếp mà không cần các thư
Trang 7Ưu điểm WebGL
3D và sử dụng 3D để mô phỏng thông tin trên mạng
Trang 8Ưu điểm WebGL
trên web chuẩn
trình duyệt
nghiên cứu và phát triển
Trang 9Bản chất của WebGL
9
Trang 10 Ngôn ngữ lập trình để tạo các shader
được gọi là OpenGL ES shading
language (GLSL ES) Bởi vì WebGL
dựa trên OpenGL ES 2.0, nó cũng sử dụng GLSL ES để tạo shaders
Trang 11Cấu trúc ứng dụng WebGL
11
Trang 12Giới thiệu JavaScript
được nhúng vào các trang HTML
JavaScript nâng cao tính động và khả
năng tương tác cho trang web bằng các hiệu ứng như tính toán, tạo form, viết các trò chơi, bổ sung hiệu ứng đặc biệt, tùy biến các chọn lựa đồ họa, tạo ra các mật khẩu bảo mật và hơn thế nữa
Trang 13Mục đích JavaScript
Tương tác với người dùng Các đoạn mã đáp
lại các sự kiện Các sự kiện phát sinh từ người dùng (nhấp chuột) hay hệ thống (chỉnh kích thước trang), v.v
Thay đổi nội dung động Có thể thay đổi nội
dung và vị trí các phần tử trên một trang theo yêu cầu người dùng
Kiểm tra tính hợp lệ dữ liệu Có thể kiểm tra
tính hợp lệ của dữ liệu do người dùng nhập và trước khi nó được gửi lên Web server để xử lí
13
Trang 14Nhúng JavaScript vào file HTML
file bên ngoài
Trang 15Dùng JavaScript trong trình xử lí
sự kiện
một thẻ HTML dùng mã JavaScript
khi người dùng nhấp chuột vào phần tử BUTTON Trình xử lí sự kiện được gọi
để đáp trả sự kiện đó
15
Trang 17thông tin tuổi hợp lệ, nếu
không thì thông báo bạn
chưa đủ tuổi Trong
Trang 18Bài 2 Chương trình yêu cầu bạn nhập một biểu thức vào ô biểu thức, nhấn nút tính toán
và chương trình hiện giá trị kết quả vào ô kết quả Chương trình sử dụng sự kiện Onclick, lệnh điều kiện, và các hàm
Trang 1919
Trang 20<input type = "checkbox" id = "ct" onchange =
"kt()"> kiểm tra
function kt() {
thebox= document.getElementById("ct")
if (thebox.checked==false) document.bgColor= 'white';
else document.bgColor= 'black';
}
Trang 21<form name ="myform">
<input type = "radio" name="tat" onclick="nuttat()"> nút tắt
<input type = "radio" name="bat" onclick="nutbat()"> nút bật
Trang 23Bài 2 Nhập các thông tin cá nhân của một người họ tên, địa chỉ và số điện thoại (trái) Khi kích nút hiển thị thì sẽ sẽ hiện thông tin của người đó (phải)
23
Trang 24Bài 3 Cho 2 radio button có cùng tên là gender (giới tính) gồm hai giá trị là Nam và
Nữ, hãy tạo ra một button và xử lý sự kiện khi click vào button đó thì in ra giá trị của giới tính
mà người dùng đã chọn (đã checked)
Trang 25 Bài 4 Cho một checkbox, hãy viết chương trình xử lý khi người dùng thay đổi trạng thái của checkbox từ uncheck sang checked thì thông báo là "bạn vừa thích zingmp3.vn", và ngược lại thì thông báo là "bạn vừa bỏ thích zingmp3.vn"
25
Trang 26LẬP TRÌNH ĐỒ HỌA
TRƯỜNG ĐẠI HỌC THỦY LỢI KHOA CÔNG NGHỆ THÔNG TIN
Th.S Trần Thị Minh Hoàn Email: hoantm@tlu.edu.vn
Trang 27Cơ sở của WebGL
Chương này bao gồm
Giới thiệu phần tử <canvas>
Liên kết giữa HTML và WebGL bằng việc sử dụng JavaScript
Các hàm vẽ WebGL đơn giản
Vai trò của các chương trình tô bóng trong
WebGL
2
Trang 28Thẻ <canvas>
Thẻ <canvas> định nghĩa một vùng vẽ trên một trang web Bắt đầu có trong HTML5
Ví dụ: Định nghĩa vùng vẽ 400 x 400
điểm ảnh, thuộc tính width và height,
vùng được gán tên qua thuộc tính id
<body onload="main()">
<canvas id="example" width="400"
height="400"></canvas>
Trang 29Viết chương trình vẽ hình chữ nhật màu xanh
Trang 31DrawRectangle.js bao gồm ba bước để vẽ
đồ họa hai chiều trên khung canvas
1 Lấy phần tử <canvas>
2 Yêu cầu dựng hình "context" 2D từ phần tử
3 Vẽ đồ họa 2D bằng cách sử dụng các phương thức mà context hỗ trợ
6
Trang 34Chương trình WebGL ngắn nhất
Trang 35<canvas id="webgl" width="400" height="400">
Please use a browser that supports "canvas"
Trang 38Hàm WebGLContext() là một hàm tiện ích được định nghĩa trong cuon-utils.js, thay vì sử dụng canvas.getContext() để giấu sự khác biệt giữa các trình duyệt
7 var gl = getWebGLContext(canvas);
getWebGLContext(element [, debug])
Dựng hình context cho WebGL, thiết lập cài đặt gỡ lỗi cho WebGL và hiển thị mọi thông báo lỗi trong bảng điều khiển trình duyệt khi có lỗi Parameters Element Chỉ ra phần tử <canvas> được yêu cầu
debug (optional) Ngầm định là true Khi thiết lập true, các lỗi
JavaScript được hiển thị trong bảng điều khiển Lưu ý: Tắt sau khi gỡ lỗi; nếu không, hiệu suất
sẽ bị ảnh hưởng
Return non-null Dựng hình context cho WebGL
Trang 39Thiết lập màu vẽ trước khi xóa
14
gl.clearColor ( red , green, blue , alpha)
Chỉ ra màu nền cho một vùng vẽ
Parameters red Chỉ giá trị đỏ (từ 0.0 đến 1.0)
green Chỉ giá trị xanh lục (từ 0.0 đến 1.0)
blue Chỉ giá trị xanh dương (từ 0.0 đến 1.0)
alpha Chỉ giá trị alpha (độ trong suốt) (từ 0.0 đến 1.0), 0: trong suốt và 1 là đục hoàn toàn
Nếu giá trị các biến này nhỏ hơn 0.0 hoặc lớn hơn 1.0, nó được cắt thành 0.0 hoặc 1.0, một cách tương ứng
Trang 40Chỉ định bộ đệm màu Chỉ định bộ đệm độ sâu Chỉ định bộ đệm stencil
Trang 41Giá trị mặc định các bộ đệm
16
Trang 42Thử nghiệm với giá trị màu
Trang 43Chương trình vẽ một điểm
lên màn hình
được gọi là shader, chúng là một cơ
chế cốt lõi trong WebGL, là công cụ
mạnh nhưng phức tạp
18
Trang 44Javascript)
Trang 45Sơ đồ chương trình Javascript
20
Trang 46Các hàm shader
WebGL cần hai kiểu shader
Vertex shader: là các chương trình mô tả các tính trạng (vị trí, kích thước, v.v ) của một đỉnh vertex là một điểm trong
không gian 2D/3D, ví dụ: góc hoặc giao điểm của một shape 2D/3D
Trong chương trình mẫu, vị trí là (0.0, 0.0, 0.0), và kích thước
Trang 47Hàm Vertex Shader
22
Trang 48Hàm Fragment Shader
Trang 49Luồng xử lí trong hàm main()
24
Trang 50Hàm tiện ích initShaders() được định nghĩa trong cuon-util.js
Trang 51Thao tác vẽ
39 gl.drawArrays (gl.POINTS, 0, 1);
26
Trang 52Các hình dạng cơ sở
Trang 53Hệ tọa độ webGL
28
Trang 55Vẽ một điểm ảnh sử dụng
biến thuộc tính
Biến thuộc tính là biến GLSL ES được sử dụng
để truyền dữ liệu từ thế giới bên ngoài vertex shader vào shader
Để sử dụng biến thuộc tính, chương trình mẫu bao gồm bốn bước sau:
Khai báo biến thuộc tính
Gán biến thuộc tính cho gl_Position
Lấy vị trí lưu trữ của biến thuộc tính
Truyền dữ liệu vào biến lưu trữ
30
Trang 564 'attribute vec4 a_Position;\n' +
Khai báo a_Position là một biến thuộc tính với kiểu dữ liệu vec4 vì nó sẽ được gán cho gl_Position, chúng có kiểu vec4
Trang 57gl.getAttribLocation(program, name)
Lấy lại vị trí lưu trữ của biến thuộc tính được chỉ ra bởi biến name
Parameters program Chỉ ra đối tượng chương trình chứa một vertex
shader và một fragment shader
name Tên của biến thuộc tính vị trí của nó sẽ được truy xuất
Return
value
0 vị trí của biến thuộc tính được chỉ định
-1 Biến thuộc tính chỉ định không tồn tại hoặc
tên của nó bắt đầu bằng tiền tố gl_ hoặc webgl_
Errors INVALID_OPERATION program không kết nối thành công (Xem
Chương 9)
INVALID_VALUE Độ dài của name lớn hơn mức tối đa (mặc
định là 256) cho tên biến thuộc tính
Trang 58Đặt vị trí đỉnh cho biến thuộc tính
41 gl.vertexAttrib3f(a_Position, 0.0, 0.0, 0.0);
gl.vertexAttrib3f (location, v0, v1, v2)
Gán dữ liệu (v0, v1 và v2) cho biến thuộc tính được chỉ ra bởi location
Parameters location Chỉ định vị trí lưu trữ của một biến thuộc tính được sửa đổi
v0 Chỉ ra giá trị được sử dụng làm phần tử đầu tiên cho biến
Return value None
Errors INVALID_OPERATION Không có đối tượng chương trình hiện tại
INVALID_VALUE location lớn hơn hoặc bằng giá trị lớn nhất của biến
Trang 60Bài tập
kích thước (20.0) và vị trí của điểm ảnh
được hiển thị trên khung vẽ màu (Góc
trên bên trái)
Trang 62Biến đồng nhất
Biến đồng nhất là một biến để truyền dữ liệu
"đồng nhất" (không biến đổi) từ chương trình JavaScript đến tất cả các đỉnh hay các mảnh trong shader
Cách khai báo biến
<Storage Qualifier> <Type> <Variable
name>
Trang 63Bài toán
Sử dụng biến đồng nhất để truyền màu xanh lục từ Javascript đến Shader
3
Trang 64Thay đổi màu điểm
Các bước thực hiện trong fragment shader
1 Chuẩn bị các biến đồng nhất cho màu trong fragment shader
2 Gán biến đồng nhất cho biến gl_FragColor
3 Lấy vị trí lưu trữ của biến đồng nhất
4 Chuyển dữ liệu màu đến biến đồng nhất từ chương trình JavaScript
Trang 65Sử dụng trong chương trình
10 // Fragment shader program
11 var FSHADER_SOURCE =
12 'precision mediump float;\n' +
13 'uniform vec4 u_FragColor;\n' + //
Trang 66Lấy lại vị trí lưu trữ (storage location) của biến đồng nhất
43 var u_FragColor = gl.getUniformLocation (
Trang 67Chi tiết getUniformLocation
7
Trang 68Gán giá trị màu xanh lục cho biến đồng
nhất
gl.uniform4f(u_FragColor, 1.0, 0.0, 0.0,
1.0);
Trang 69Gán giá trị cho một biến đồng nhất
9
Trang 71Bài toán: Vẽ một điểm ảnh sử dụng kích chuột
Quan tâm đến hai vấn đề:
chuột)
11
Trang 72Đăng kí trình xử lí sự kiện
Sử dụng thuộc tính onmousedown của
<canvas> cho sự kiện nhấp chuột
41 canvas.onmousedown = function(ev) {
click(ev, gl, canvas, a_Position); };
Trang 73var g_points = [];
function click(ev, gl, canvas, a_Position) {
// Lấy vị trí nhấp chuột và lưu trữ vào mảng
var x = ev.clientX; var y = ev.clientY;
var rect = ev.target.getBoundingClientRect() ;
x = ((x - rect.left) - canvas.width/2)/(canvas.width/2);
y = (canvas.height/2 - (y - rect.top))/(canvas.height/2);
g_points.push(x); g_points.push(y);
gl.clear(gl.COLOR_BUFFER_BIT); //xóa canvas
//với mỗi vị trí lưu trữ, vẽ từng điểm
var len = g_points.length;
for(var i = 0; i < len; i += 2) {
gl.vertexAttrib3f(a_Position, g_points[i], g_points[i+1], 0.0);
gl.drawArrays(gl.POINTS, 0, 1); }} 13
Trang 7551 function click(ev, gl, canvas, a_Position) {
Trang 76Lấy vị trí nhấp chuột
Trang 77Lấy vị trí nhấp chuột
17
Trang 78Gắn vị trí nhấp chuột vào mảng g_points
g_points.push (x); g_points.push (y);
Trang 7961 // Clear <canvas>
62 gl.clear(gl.COLOR_BUFFER_BIT); <- (2)
19
Xóa canvas
Trang 80Với mỗi vị trí lưu trữ trong mảng,
vẽ một điểm
64 var len = g_points.length;
65 for(var i = 0; i < len; i+=2) {
66 // Pass the position of a point to
Trang 81Bài tập
vào điểm (100, 50) trong cửa sổ windows, biết rằng canvas có kích thước 400x400 tại vị trí (10, 10)
vị trí kích chuột (Bỏ mảng động g_points)
thì các điểm ảnh biến mất Nền hiện lên là
Trang 82Xây dựng chương trình thay đổi màu điểm
như sau
Trang 84Cách 1: if (i==10) {
gl.clearColor (1.0,1.0,0.0,1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
break; } Cách 2: if (len<=10)
for(var i = 0; i < len; i += 2) { gl.vertexAttrib3f(a_Position, g_points[i], g_points[i+1], 0.0); gl.drawArrays(gl.POINTS, 0, 1); }
else {
gl.clearColor(1.0, 1.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
}
Trang 86Nội dung học
1 Bộ đệm đối tượng, lưới hình học
2 Các hình học cơ sở
3 Các phép biến đổi
Trang 87Vẽ nhiều điểm
3
Trang 88Vẽ nhiều điểm sử dụng ClickedPoints
65 for(var i = 0; i<len; i+=2) {
66 // Pass the position of a point to a_Position variable
67 gl.vertexAttrib3f(a_Position, g_points[i], g_points[i+1], 0.0);
Trang 89Bộ đệm đối tượng
Bộ đệm đối tượng là một vùng bộ nhớ có thể lưu trữ nhiều đỉnh trong hệ thống WebGL Nó được sử dụng để truyền đồng thời các đỉnh đến một vertex shader
5
Trang 90Luồng xử lí cho MultiPoint.js
Trang 91Sử dụng bộ đệm đối tượng
7
Trang 92Các bước truyền dữ liệu tới vertex shader bằng bộ đệm đối tượng
1 Tạo một bộ đệm đối tượng (gl.createBuffer())
2 Gắn bộ đệm đối tượng vào một target
Trang 94B1.Tạo một bộ đệm đối tượng
56 // Create a buffer object <- (1)
57 var vertexBuffer = gl.createBuffer();
Trang 95B2 Gắn một bộ đệm đối tượng vào một target
64 gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
11
Trang 96gl.bindBuffer(target, buffer)
Kích hoạt bộ đệm đối tượng được chỉ ra bởi buffer và gắn nó với target Target có thể là một trong các giá trị sau:
gl.ARRAY_BUFFER Chỉ ra bộ đệm đối tượng chứa dữ liệu đỉnh
gl.ELEMENT_ARRAY_BUFFER Chỉ ra bộ đệm đối tượng chứa các giá trị chỉ
số mà trỏ đến dữ liệu đỉnh (Xem Chương 6,
“OpenGL ES Shading Language [GLSL ES].)
buffer Chỉ ra bộ đệm đối tượng được tạo bởi lời gọi
trước đó tới gl.createBuffer () null, việc gắn với target bị vô hiệu hóa
Return
value
Errors INVALID_ENUM target không phải giá trị nào ở trên Trong
trường hợp này, việc gắn kết hiện tại được 12
Trang 97B3 Ghi dữ liệu vào bộ đệm đối tượng
66 gl.bufferData(gl.ARRAY_BUFFER, vertices,
gl.STATIC_DRAW);
13
Trang 9851 var vertices = new Float32Array([
52 0.0, 0.5, -0.5, -0.5, 0.5, -0.5
53 ]);
54 var n = 3; // The number of vertices
Float32Array ở dòng 51 là một ví dụ của mảng định kiểu (typed array) và được sử dụng để chứa tọa độ đỉnh hoặc màu sắc
Trang 99Các mảng định kiểu trong WebGL
15
Trang 100Phương thức gl.bufferData()
gl.bufferData(target, data, usage)
Phân bổ lưu trữ và ghi dữ liệu chỉ định data vào bộ đệm đối tượng gắn với target
Parameters target Chỉ địnhgl.ARRAY_BUFFER hoặcgl.ELEMENT_ARRAY_BUFFER
data Chỉ định dữ liệu được ghi vào bộ đệm đối tượng (mảng định kiểu;
xem phần tiếp theo)
usage Chỉ ra gợi ý về chương trình sẽ sử dụng dữ liệu lưu trữ trong bộ đệm
đối tượng như thế nào Gợi ý này giúp WebGL tối ưu hóa hiệu suất nhưng sẽ không dừng được chương trình của bạn nếu bạn làm sai
gl.STATIC_DRAW Dữ liệu bộ đệm đối tượng sẽ được chỉ ra một lần
Trang 101B4 Gán các bộ đệm đối tượng cho biến thuộc tính
74 gl.vertexAttribPointer(a_Position, 2,
gl.FLOAT, false, 0, 0);
17
Trang 102gl.vertexAttribPointer(location, size, type, normalized, stride, offset)
Gán bộ đệm đối tượng đệm được gắn với gl.ARRAY_BUFFER đến biến thuộc tính được chỉ ra bởi location
Parameters location Chỉ định vị trí lưu trữ của biến thuộc tính
size Chỉ định số lượng thành phần trên mỗi đỉnh trong bộ đệm đối
tượng (giá trị hợp lệ là 1 đến 4) Nếu size nhỏ hơn số lượng thành phần được yêu cầu bởi biến thuộc tính, các thành phần bị thiếu được cấp tự động như gl.vertexAttrib[1234]f()
type Chỉ ra các dạng dữ liệu bằng một trong các cách sau:
gl.UNSIGNED_BYTE unsigned byte for Uint8Array
gl.SHORT signed short integer for Int16Array gl.UNSIGNED_SHORT unsigned short integer for Uint16Array gl.INT signed integer for Int32Array gl.UNSIGNED_INT unsigned integer for Uint32Array gl.FLOAT floating point number for Float32Array
normalized Hoặc true hoặc false để biểu thị xem dữ liệu nonfloating nên được
chuẩn hóa thành [0, 1] hay [–1, 1]
stride Chỉ định số byte giữa các phần tử dữ liệu đỉnh khác nhau, hoặc
zero cho stride mặc định (xem Chương 4)
offset Chỉ định offset (tính bằng byte) trong một bộ đệm đối tượng để
chỉ ra dữ liệu đỉnh được lưu trữ từ byte thứ mấy Nếu dữ liệu được lưu trữ từ đầu, offset là 0
Return value None
Errors INVALID_OPERATION Không có đối tượng chương trình hiện tại