JavaScript at WebGL
Ipinapaliwanag ng artikulong ito ang JavaScript at WebGL.
YouTube Video
javascript-web-gl-texture.js
1// Get WebGL context
2const canvas = document.getElementById("glCanvas");
3const gl = canvas.getContext("webgl");
4if (!gl) {
5 alert("WebGL is not supported by your browser.");
6}
7
8// Vertex shader program
9const vsSource = `
10 attribute vec4 aVertexPosition;
11 attribute vec2 aTextureCoord;
12 varying highp vec2 vTextureCoord;
13 void main(void) {
14 gl_Position = aVertexPosition;
15 vTextureCoord = aTextureCoord;
16 }
17`;
18
19// Fragment shader program
20const fsSource = `
21 varying highp vec2 vTextureCoord;
22 uniform sampler2D uSampler;
23 void main(void) {
24 gl_FragColor = texture2D(uSampler, vTextureCoord);
25 }
26`;
27
28// Compile shader
29function loadShader(type, source) {
30 const shader = gl.createShader(type);
31 gl.shaderSource(shader, source);
32 gl.compileShader(shader);
33 if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
34 console.error("Shader compile failed: ", gl.getShaderInfoLog(shader));
35 gl.deleteShader(shader);
36 return null;
37 }
38 return shader;
39}
40
41// Initialize shader program
42function initShaderProgram(vsSource, fsSource) {
43 const vertexShader = loadShader(gl.VERTEX_SHADER, vsSource);
44 const fragmentShader = loadShader(gl.FRAGMENT_SHADER, fsSource);
45 const shaderProgram = gl.createProgram();
46 gl.attachShader(shaderProgram, vertexShader);
47 gl.attachShader(shaderProgram, fragmentShader);
48 gl.linkProgram(shaderProgram);
49 if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
50 console.error("Unable to initialize the shader program: " + gl.getProgramInfoLog(shaderProgram));
51 return null;
52 }
53 return shaderProgram;
54}
55
56const shaderProgram = initShaderProgram(vsSource, fsSource);
57const programInfo = {
58 program: shaderProgram,
59 attribLocations: {
60 vertexPosition: gl.getAttribLocation(shaderProgram, "aVertexPosition"),
61 textureCoord: gl.getAttribLocation(shaderProgram, "aTextureCoord"),
62 },
63 uniformLocations: {
64 uSampler: gl.getUniformLocation(shaderProgram, "uSampler"),
65 },
66};
67
68// Define positions and texture coordinates
69const positions = new Float32Array([
70 -1.0, 1.0,
71 1.0, 1.0,
72 -1.0, -1.0,
73 1.0, -1.0,
74]);
75
76const textureCoordinates = new Float32Array([
77 0.0, 0.0,
78 1.0, 0.0,
79 0.0, 1.0,
80 1.0, 1.0,
81]);
82
83// Create position buffer
84const positionBuffer = gl.createBuffer();
85gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
86gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
87
88// Create texture coordinate buffer
89const texCoordBuffer = gl.createBuffer();
90gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
91gl.bufferData(gl.ARRAY_BUFFER, textureCoordinates, gl.STATIC_DRAW);
92
93// Create and load texture
94const texture = gl.createTexture();
95gl.bindTexture(gl.TEXTURE_2D, texture);
96
97const image = new Image();
98image.src = "texture.png";
99image.onload = () => {
100 gl.bindTexture(gl.TEXTURE_2D, texture);
101 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
102 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
103 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
104 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
105 drawScene();
106};
107
108// Draw function
109function drawScene() {
110 gl.clearColor(0.0, 0.0, 0.0, 1.0); // Clear to black
111 gl.clear(gl.COLOR_BUFFER_BIT);
112
113 gl.useProgram(programInfo.program);
114
115 // Bind vertex position buffer
116 gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
117 gl.vertexAttribPointer(programInfo.attribLocations.vertexPosition, 2, gl.FLOAT, false, 0, 0);
118 gl.enableVertexAttribArray(programInfo.attribLocations.vertexPosition);
119
120 // Bind texture coordinate buffer
121 gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
122 gl.vertexAttribPointer(programInfo.attribLocations.textureCoord, 2, gl.FLOAT, false, 0, 0);
123 gl.enableVertexAttribArray(programInfo.attribLocations.textureCoord);
124
125 // Bind texture
126 gl.activeTexture(gl.TEXTURE0);
127 gl.bindTexture(gl.TEXTURE_2D, texture);
128 gl.uniform1i(programInfo.uniformLocations.uSampler, 0);
129
130 // Draw rectangle
131 gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
132}javascript-web-gl-lighting.js
1// Get the WebGL context
2const canvas = document.getElementById("glCanvas");
3const gl = canvas.getContext("webgl");
4if (!gl) {
5 alert("WebGL not supported");
6 throw new Error("WebGL not supported");
7}
8
9// Vertex shader
10const vertexShaderSource = `
11attribute vec3 aPosition;
12attribute vec3 aNormal;
13uniform mat4 uModelViewMatrix;
14uniform mat4 uProjectionMatrix;
15varying vec3 vNormal;
16
17void main(void) {
18 gl_Position = uProjectionMatrix * uModelViewMatrix * vec4(aPosition, 1.0);
19 vNormal = aNormal;
20}
21`;
22
23// Fragment shader (with lighting)
24const fragmentShaderSourceWithLighting = `
25precision mediump float;
26uniform vec3 uLightingDirection;
27uniform vec4 uLightColor;
28varying vec3 vNormal;
29
30void main(void) {
31 vec3 lightDirection = normalize(uLightingDirection);
32 float directionalLightWeighting = max(dot(normalize(vNormal), lightDirection), 0.0);
33 gl_FragColor = uLightColor * directionalLightWeighting;
34}
35`;
36
37// Shader creation helper
38function createShader(gl, type, source) {
39 const shader = gl.createShader(type);
40 gl.shaderSource(shader, source);
41 gl.compileShader(shader);
42 if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
43 console.error("Shader compile error:", gl.getShaderInfoLog(shader));
44 gl.deleteShader(shader);
45 return null;
46 }
47 return shader;
48}
49
50// Create program
51function createProgram(gl, vs, fs) {
52 const program = gl.createProgram();
53 gl.attachShader(program, vs);
54 gl.attachShader(program, fs);
55 gl.linkProgram(program);
56 if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
57 console.error("Program link error:", gl.getProgramInfoLog(program));
58 return null;
59 }
60 return program;
61}
62
63const vs = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
64const fs = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSourceWithLighting);
65const program = createProgram(gl, vs, fs);
66gl.useProgram(program);
67
68// Cube data
69const vertices = new Float32Array([
70 -1,-1,1, 1,-1,1, 1,1,1, -1,1,1, // Front
71 -1,-1,-1, -1,1,-1, 1,1,-1, 1,-1,-1, // Back
72 -1,1,-1, -1,1,1, 1,1,1, 1,1,-1, // Top
73 -1,-1,-1, 1,-1,-1, 1,-1,1, -1,-1,1, // Bottom
74 1,-1,-1, 1,1,-1, 1,1,1, 1,-1,1, // Right
75 -1,-1,-1, -1,-1,1, -1,1,1, -1,1,-1 // Left
76]);
77
78const normals = new Float32Array([
79 0,0,1, 0,0,1, 0,0,1, 0,0,1,
80 0,0,-1, 0,0,-1, 0,0,-1, 0,0,-1,
81 0,1,0, 0,1,0, 0,1,0, 0,1,0,
82 0,-1,0, 0,-1,0, 0,-1,0, 0,-1,0,
83 1,0,0, 1,0,0, 1,0,0, 1,0,0,
84 -1,0,0, -1,0,0, -1,0,0, -1,0,0
85]);
86
87const indices = new Uint16Array([
88 0,1,2, 0,2,3,
89 4,5,6, 4,6,7,
90 8,9,10, 8,10,11,
91 12,13,14, 12,14,15,
92 16,17,18, 16,18,19,
93 20,21,22, 20,22,23
94]);
95
96// Buffers
97const vertexBuffer = gl.createBuffer();
98gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
99gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
100
101const normalBuffer = gl.createBuffer();
102gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
103gl.bufferData(gl.ARRAY_BUFFER, normals, gl.STATIC_DRAW);
104
105const indexBuffer = gl.createBuffer();
106gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
107gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
108
109// Attribute locations
110const aPosition = gl.getAttribLocation(program, "aPosition");
111const aNormal = gl.getAttribLocation(program, "aNormal");
112
113// Uniforms
114const uProjectionMatrix = gl.getUniformLocation(program, "uProjectionMatrix");
115const uModelViewMatrix = gl.getUniformLocation(program, "uModelViewMatrix");
116const uLightingDirection = gl.getUniformLocation(program, "uLightingDirection");
117const uLightColor = gl.getUniformLocation(program, "uLightColor");
118
119// Projection
120function perspectiveMatrix(fov, aspect, near, far) {
121 const f = 1.0 / Math.tan((fov / 2) * Math.PI / 180);
122 return new Float32Array([
123 f/aspect,0,0,0,
124 0,f,0,0,
125 0,0,(far+near)/(near-far),-1,
126 0,0,(2*far*near)/(near-far),0
127 ]);
128}
129
130function identityMatrix() {
131 return new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);
132}
133
134gl.uniformMatrix4fv(uProjectionMatrix, false, perspectiveMatrix(45, canvas.width / canvas.height, 0.1, 100.0));
135gl.uniform3fv(uLightingDirection, [0.5, 0.7, 1.0]);
136gl.uniform4fv(uLightColor, [1.0, 1.0, 1.0, 1.0]);
137
138// Clear settings
139gl.clearColor(0.1, 0.1, 0.1, 1.0);
140gl.enable(gl.DEPTH_TEST);
141
142// Draw loop
143let angle = 0;
144function draw() {
145 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
146
147 // Bind position buffer
148 gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
149 gl.vertexAttribPointer(aPosition, 3, gl.FLOAT, false, 0, 0);
150 gl.enableVertexAttribArray(aPosition);
151
152 // Bind normal buffer
153 gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
154 gl.vertexAttribPointer(aNormal, 3, gl.FLOAT, false, 0, 0);
155 gl.enableVertexAttribArray(aNormal);
156
157 // Compute rotation
158 const mv = identityMatrix();
159 mv[0] = Math.cos(angle);
160 mv[2] = Math.sin(angle);
161 mv[8] = -Math.sin(angle);
162 mv[10] = Math.cos(angle);
163 mv[14] = -6.0;
164 gl.uniformMatrix4fv(uModelViewMatrix, false, mv);
165
166 // Draw
167 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
168 gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
169
170 angle += 0.01;
171 requestAnimationFrame(draw);
172}
173
174draw();javascript-web-gl.html
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <title>JavaScript & HTML</title>
6 <style>
7 * {
8 box-sizing: border-box;
9 }
10
11 body {
12 margin: 0;
13 padding: 1em;
14 padding-bottom: 10em;
15 font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
16 background-color: #f7f9fc;
17 color: #333;
18 line-height: 1.6;
19 }
20
21 .container {
22 max-width: 800px;
23 margin: 0 auto;
24 padding: 1em;
25 background-color: #ffffff;
26 border: 1px solid #ccc;
27 border-radius: 10px;
28 box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
29 }
30
31 .container-flex {
32 display: flex;
33 flex-wrap: wrap;
34 gap: 2em;
35 max-width: 1000px;
36 margin: 0 auto;
37 padding: 1em;
38 background-color: #ffffff;
39 border: 1px solid #ccc;
40 border-radius: 10px;
41 box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
42 }
43
44 .left-column, .right-column {
45 flex: 1 1 200px;
46 min-width: 200px;
47 }
48
49 h1, h2 {
50 font-size: 1.2rem;
51 color: #007bff;
52 margin-top: 0.5em;
53 margin-bottom: 0.5em;
54 border-left: 5px solid #007bff;
55 padding-left: 0.6em;
56 background-color: #e9f2ff;
57 }
58
59 button {
60 display: inline;
61 margin: 0.25em;
62 padding: 0.75em 1.5em;
63 font-size: 1rem;
64 background-color: #007bff;
65 color: white;
66 border: none;
67 border-radius: 6px;
68 cursor: pointer;
69 transition: background-color 0.3s ease;
70 }
71
72 button:hover {
73 background-color: #0056b3;
74 }
75
76 #output {
77 margin-top: 1em;
78 background-color: #1e1e1e;
79 color: #0f0;
80 padding: 1em;
81 border-radius: 8px;
82 min-height: 200px;
83 font-family: Consolas, monospace;
84 font-size: 0.95rem;
85 overflow-y: auto;
86 white-space: pre-wrap;
87 }
88
89 .highlight {
90 outline: 3px solid #ffc107; /* yellow border */
91 background-color: #fff8e1; /* soft yellow background */
92 transition: background-color 0.3s ease, outline 0.3s ease;
93 }
94
95 .active {
96 background-color: #28a745; /* green background */
97 color: #fff;
98 box-shadow: 0 0 10px rgba(40, 167, 69, 0.5);
99 transition: background-color 0.3s ease, box-shadow 0.3s ease;
100 }
101 </style>
102</head>
103<body>
104 <div class="container">
105 <h1>JavaScript Console</h1>
106 <button id="executeBtn">Execute</button>
107 <button id="executeTextureBtn">Execute Texture</button>
108 <button id="executeLightingBtn">Execute Lighting</button>
109 <div id="output"></div>
110 </div>
111 <div class="container">
112 <h1>WebGL Canvas</h1>
113 <canvas id="glCanvas"></canvas>
114 </div>
115
116 <script>
117 // Override console.log to display messages in the #output element
118 (function () {
119 // Override console.log
120 const originalLog = console.log;
121 console.log = function (...args) {
122 originalLog.apply(console, args);
123 const message = document.createElement('div');
124 message.textContent = args.map(String).join(' ');
125 output.appendChild(message);
126 };
127
128 // Override console.error
129 const originalError = console.error;
130 console.error = function (...args) {
131 originalError.apply(console, args);
132 const message = document.createElement('div');
133 message.textContent = args.map(String).join(' ');
134 message.style.color = 'red'; // Color error messages red
135 output.appendChild(message);
136 };
137 })();
138
139 document.getElementById('executeBtn').addEventListener('click', () => {
140 // Prevent multiple loads
141 if (document.getElementById('externalScript')) return;
142
143 const script = document.createElement('script');
144 script.src = 'javascript-web-gl.js';
145 script.id = 'externalScript';
146 document.body.appendChild(script);
147 });
148
149 document.getElementById('executeTextureBtn').addEventListener('click', () => {
150 // Prevent multiple loads
151 if (document.getElementById('externalScript')) return;
152
153 const script = document.createElement('script');
154 script.src = 'javascript-web-gl-texture.js';
155 script.id = 'externalScript';
156 document.body.appendChild(script);
157 });
158
159 document.getElementById('executeLightingBtn').addEventListener('click', () => {
160 // Prevent multiple loads
161 if (document.getElementById('externalScript')) return;
162
163 const script = document.createElement('script');
164 script.src = 'javascript-web-gl-lighting.js';
165 script.id = 'externalScript';
166 document.body.appendChild(script);
167 });
168 </script>
169</body>
170</html>JavaScript at WebGL
Ang JavaScript at WebGL ay makapangyarihang mga kasangkapan sa makabagong web development upang maghatid ng interaktibo at mataas na kalidad na 3D graphics sa browser. Sa paggamit ng WebGL, maaari mong direktang gamitin ang GPU para sa mabisa na pagre-render at bumuo ng mga ekspresibong web application gaya ng mga laro, data visualization, at mga VR/AR application.
Ano ang WebGL?
Ang WebGL (Web Graphics Library) ay isang low-level graphics API na bahagi ng HTML5, na ginagamit para magsagawa ng 3D rendering nang direkta sa browser. Batay ito sa spesipikasyon ng OpenGL ES 2.0 at kinokontrol ang GPU mula sa JavaScript. Sa paggamit ng WebGL, maaari kang magpakita ng advanced na 3D graphics sa halos lahat ng makabagong browser nang hindi nangangailangan ng mga espesyal na plugin.
Mga Pangunahing Konsepto ng WebGL
Upang magsagawa ng rendering gamit ang WebGL, kailangan mong maunawaan ang ilang mahahalagang konsepto. Katulad ng iba pang mga graphics APIs (tulad ng OpenGL at DirectX), ang WebGL ay nagpoproseso ng data sa pamamagitan ng graphics pipeline at lumilikha ng mga imahe sa GPU.
Pagkuha ng konteksto
Nagre-render ang WebGL gamit ang elementong <canvas> ng HTML5. Sa JavaScript, kailangan mo munang kunin ang WebGL context.
1const canvas = document.getElementById("glCanvas");
2const gl = canvas.getContext("webgl");
3if (!gl) {
4 console.error("WebGL not supported, falling back on experimental-webgl");
5 gl = canvas.getContext("experimental-webgl");
6}
7if (!gl) {
8 alert("Your browser does not support WebGL");
9}- Kunin ang konteksto ng WebGL mula sa elementong
<canvas>. Sa ganitong paraan, makokontrol mo ang pagre-render ng GPU sa pamamagitan ng JavaScript.
Pagde-define ng mga shader
Para mag-render gamit ang WebGL, gumagamit ka ng dalawang uri ng shader: isang vertex shader at isang fragment shader. Ang vertex shaders ay nagkakalkula ng posisyon ng bawat vertex ng isang object, at ang fragment shaders ay nagkakalkula ng kulay ng bawat pixel. Ang mga shaders na ito ay mga program na tumatakbo sa GPU. Ang mga shaders ay isinusulat gamit ang wika na tinatawag na GLSL.
1const vertexShaderSource = `
2attribute vec4 aVertexPosition;
3void main(void) {
4 gl_Position = aVertexPosition;
5}`;
6const fragmentShaderSource = `
7void main(void) {
8 gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // Red color
9}`;- Ang vertex shader ay nagpoproseso ng mga posisyon ng vertex, at ang fragment shader ang nagtatakda ng kulay kada pixel. Dito, naglalabas tayo ng kulay pula.
Pag-compile at pag-link ng mga shader
Upang maisama ang source code ng shader sa isang WebGL program, i-compile ang mga shader at i-link ang mga ito upang makalikha ng isang programa.
1function createShader(gl, type, source) {
2 const shader = gl.createShader(type);
3 gl.shaderSource(shader, source);
4 gl.compileShader(shader);
5 if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
6 console.error("An error occurred compiling the shaders:", gl.getShaderInfoLog(shader));
7 gl.deleteShader(shader);
8 return null;
9 }
10 return shader;
11}
12
13const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
14const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
15
16const shaderProgram = gl.createProgram();
17gl.attachShader(shaderProgram, vertexShader);
18gl.attachShader(shaderProgram, fragmentShader);
19gl.linkProgram(shaderProgram);
20if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
21 console.error("Unable to initialize the shader program:", gl.getProgramInfoLog(shaderProgram));
22}- I-compile ang bawat shader at i-link ang mga ito sa isang programa. Gumagawa ito ng rendering pipeline na maipapatakbo sa GPU.
Paghahanda ng mga buffer at vertex data
Susunod, ihanda ang geometry data na iguguhit at ipadala ito sa isang WebGL buffer. Kasama sa data na ito ang mga posisyon ng vertex, kulay, texture coordinates, at iba pa.
1const vertices = new Float32Array([
2 -1.0, -1.0,
3 1.0, -1.0,
4 1.0, 1.0,
5 -1.0, 1.0,
6]);
7
8const vertexBuffer = gl.createBuffer();
9gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
10gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);- I-define ang mga vertex coordinate ng isang parihaba at i-upload ang mga ito sa isang GPU buffer.
STATIC_DRAWang nagpapahiwatig na ang data ay hindi madalas nagbabago.
Proseso ng pagre-render
Sa huli, ipagawa sa WebGL ang aktuwal na pagre-render gamit ang mga shader at data. I-configure nang tama ang WebGL rendering pipeline at mag-isyu ng mga utos sa pagguhit sa GPU. Dito, nililinis natin ang background sa itim at gumuguhit ng pulang parihaba gamit ang tinukoy na vertex data at shader program.
1gl.clearColor(0.0, 0.0, 0.0, 1.0); // Clear to black
2gl.clear(gl.COLOR_BUFFER_BIT);
3
4// Use the shader program
5gl.useProgram(shaderProgram);
6
7// Bind vertex buffer
8const positionAttributeLocation = gl.getAttribLocation(shaderProgram, "aVertexPosition");
9gl.enableVertexAttribArray(positionAttributeLocation);
10gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
11gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
12
13// Draw
14gl.drawArrays(gl.TRIANGLE_FAN, 0, 4);- Sa code na ito, ise-setup natin ang WebGL rendering pipeline at magre-render ng isang parihaba. Sa pag-initialize ng screen gamit ang gl.clear() at sa pagpapadala ng mga utos sa pagguhit sa GPU gamit ang gl.drawArrays(), naipapakita talaga sa screen ang datang naproseso ng mga shader.
Mga Advanced na Tampok ng WebGL
Sa WebGL, maaari mong gamitin ang iba't ibang advanced na tampok na lampas sa simpleng pag-render. Narito, ipinapakilala namin ang ilan sa mga tampok na iyon.
Pagmamapa ng Tekstura
Sinuportahan ng WebGL ang pagmamapa ng tekstura, na nagbibigay-daan sa iyo na mag-apply ng mga larawan o pattern sa mga 3D na bagay. Binibigyang-daan ka nitong magbigay ng mas kumplikado at makatotohanang hitsura sa mga bagay sa halip na simpleng mga kulay.
1/* Fragment of source code */
2const texture = gl.createTexture();
3gl.bindTexture(gl.TEXTURE_2D, texture);
4
5// Load an image as the texture
6const image = new Image();
7image.src = "texture.png";
8image.onload = () => {
9 gl.bindTexture(gl.TEXTURE_2D, texture);
10 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
11
12 // Set texture parameters
13 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
14 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
15 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
16
17 // Draw the scene again with the texture applied
18 drawScene();
19};- Mag-load ng mga larawan bilang mga texture at ilapat ang mga ito sa mga ibabaw ng object upang makamit ang mas makatotohanang hitsura.
Pag-iilaw at Pagpapa-anino
Maaari mong gamitin ang mga modelo ng anino upang mag-apply ng makatotohanang mga epekto sa pag-iilaw sa mga 3D na bagay. I-kalkula kung paano nire-reflect ng ibabaw ng isang bagay ang ilaw batay sa iba't ibang modelo ng anino tulad ng Phong shading at Gouraud shading.
1/* Fragment of source code */
2const fragmentShaderSourceWithLighting = `
3precision mediump float;
4uniform vec3 uLightingDirection;
5uniform vec4 uLightColor;
6void main(void) {
7 vec3 lightDirection = normalize(uLightingDirection);
8 float directionalLightWeighting = max(dot(vNormal, lightDirection), 0.0);
9 gl_FragColor = uLightColor * directionalLightWeighting;
10}`;- Kalkulahin ang liwanag batay sa anggulo sa pagitan ng direksyon ng ilaw at ng mga normal. Ito ang batayan ng mga teknik sa shading tulad ng mga modelong Phong at Gouraud.
Pag-optimize at Pagganap
Dahil direktang gumagana ang WebGL sa GPU, ang pag-optimize ng pagganap ay napakahalaga. Ang paggamit ng malaking dami ng vertex data o kumplikadong shaders ay maaaring magdulot ng pagbaba sa pagganap. Ang mga sumusunod ay mga karaniwang diskarte para sa pag-optimize ng pagganap.
- Mas mabisang paggamit ng vertex buffers Sa halip na madalas i-update ang mga vertex buffer, muling gamitin ang mga buffer na nalikha na hangga't maaari.
- Pag-aayos ng frame rate
Gamitin ang
requestAnimationFrameupang kontrolin ang pagre-render ng animasyon at mapanatili ang episyenteng frame rate. - Occlusion culling Isang teknik na nilalaktawan ang pagre-render ng mga object na wala sa saklaw ng tanaw. Maaari nitong bawasan ang bigat ng pag-render.
1function render() {
2 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
3
4 // Logic to update objects in the scene
5
6 // Use requestAnimationFrame for smooth rendering
7 requestAnimationFrame(render);
8}
9
10render();- Kontrolin ang rendering loop gamit ang
requestAnimationFrameat episyenteng i-update ang mga frame nang naka-sync sa timing ng pagre-render ng browser.
Buod
Sa pamamagitan ng pagsasama ng JavaScript at WebGL, maaaring makamit ang advanced na 3D graphics na gumagana sa real-time sa browser. Binubuo ng WebGL ang maraming elemento mula sa mga pangunahing konsepto ng shaders at buffer management, paglalagay ng mga tekstura, hanggang sa pag-optimize ng pagganap, ngunit sa pamamagitan ng epektibong paggamit ng mga ito, maaari kang bumuo ng mga interactive at makulay na aplikasyon.
Maaari mong sundan ang artikulo sa itaas gamit ang Visual Studio Code sa aming YouTube channel. Paki-check din ang aming YouTube channel.