জাভাস্ক্রিপ্ট এবং ওয়েবজিএল

জাভাস্ক্রিপ্ট এবং ওয়েবজিএল

এই প্রবন্ধটি জাভাস্ক্রিপ্ট এবং ওয়েবজিএল ব্যাখ্যা করে।

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 &amp; 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>

জাভাস্ক্রিপ্ট এবং ওয়েবজিএল

ব্রাউজারে ইন্টারঅ্যাকটিভ, উচ্চমানের 3D গ্রাফিক্স প্রদানে আধুনিক ওয়েব ডেভেলপমেন্টে JavaScript ও WebGL শক্তিশালী টুল। WebGL ব্যবহার করে আপনি কার্যকর রেন্ডারিংয়ের জন্য সরাসরি GPU কাজে লাগাতে পারেন এবং গেম, ডাটা ভিজুয়ালাইজেশন, ও VR/AR অ্যাপ্লিকেশনসহ সমৃদ্ধ ওয়েব অ্যাপ্লিকেশন তৈরি করতে পারেন।

ওয়েবজিএল কী?

WebGL (Web Graphics Library) হলো HTML5-এর অংশ হিসেবে সরবরাহকৃত একটি লো-লেভেল গ্রাফিক্স API, যা ব্রাউজারেই সরাসরি 3D রেন্ডারিং করতে ব্যবহৃত হয়। এটি OpenGL ES 2.0 স্পেসিফিকেশনের ওপর ভিত্তি করে এবং JavaScript থেকে GPU নিয়ন্ত্রণ করে। WebGL ব্যবহার করে আপনি বিশেষ কোনো প্লাগইনের প্রয়োজন ছাড়াই প্রায় সব আধুনিক ব্রাউজারে উন্নত 3D গ্রাফিক্স প্রদর্শন করতে পারেন।

ওয়েবজিএলের মৌলিক বিষয়গুলি

ওয়েবজিএল দিয়ে রেন্ডারিং করতে, আপনাকে কয়েকটি মূল ধারণা বুঝতে হবে। অন্যান্য গ্রাফিক্স এপিআই (যেমন OpenGL এবং DirectX) এর মতো, ওয়েবজিএল একটি গ্রাফিক্স পাইপলাইনের মাধ্যমে ডেটা প্রক্রিয়া করে এবং জিপিইউ-তে ইমেজ তৈরি করে।

কনটেক্সট আহরণ

WebGL, HTML5-এর <canvas> এলিমেন্ট ব্যবহার করে রেন্ডার করে। জাভাস্ক্রিপ্টে, প্রথমে আপনাকে ওয়েবজিএল কনটেক্সট পেতে হবে।

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}
  • <canvas> এলিমেন্ট থেকে WebGL কনটেক্সট নিন। এর মাধ্যমে আপনি JavaScript দিয়ে GPU রেন্ডারিং নিয়ন্ত্রণ করতে পারবেন।

শেডার সংজ্ঞায়ন

WebGL দিয়ে রেন্ডার করতে দুটি ধরনের শেডার ব্যবহার করা হয়: ভার্টেক্স শেডার এবং ফ্র্যাগমেন্ট শেডার। ভের্টেক্স শেডার একটি অবজেক্টের প্রত্যেকটি ভের্টেক্সের অবস্থান হিসাব করে, এবং ফ্র্যাগমেন্ট শেডার প্রতিটি পিক্সেলের রঙ হিসাব করে। এই শেডারগুলি হল প্রোগ্রাম যা জিপিইউ-তে রান করে। শেডারগুলি 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}`;
  • ভার্টেক্স শেডার ভার্টেক্সের অবস্থান প্রক্রিয়াকরণ করে, আর ফ্র্যাগমেন্ট শেডার প্রতি-পিক্সেল রঙ নির্ধারণ করে। এখানে আমরা লাল রঙ আউটপুট করছি।

শেডার কমপাইল ও লিঙ্ক করা

শেডারের সোর্স কোড WebGL প্রোগ্রামে অন্তর্ভুক্ত করতে শেডারগুলো কমপাইল করে লিঙ্ক করে একটি প্রোগ্রাম তৈরি করুন।

 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}
  • প্রতিটি শেডার কমপাইল করে সেগুলো লিঙ্ক করে একটি প্রোগ্রাম বানান। এতে GPU-তে চলমান একটি রেন্ডারিং পাইপলাইন তৈরি হয়।

বাফার ও ভার্টেক্স ডেটা প্রস্তুত করা

এরপর আঁকার জন্য জ্যামিতিক ডেটা প্রস্তুত করে তা WebGL বাফারে পাঠান। এই ডেটাতে রয়েছে ভের্টেক্সের অবস্থান, রঙ, টেক্সচার কোঅর্ডিনেট ইত্যাদি।

 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);
  • একটি আয়তক্ষেত্রের ভার্টেক্সের কোঅর্ডিনেট নির্ধারণ করে সেগুলো GPU বাফারে আপলোড করুন। STATIC_DRAW নির্দেশ করে যে ডেটা ঘন ঘন পরিবর্তিত হয় না।

রেন্ডারিং প্রক্রিয়া

শেষে, শেডার ও ডেটা ব্যবহার করে WebGL দিয়ে আসল রেন্ডারিং করান। WebGL রেন্ডারিং পাইপলাইন সঠিকভাবে কনফিগার করুন এবং GPU-তে ড্র কমান্ড পাঠান। এখানে আমরা ব্যাকগ্রাউন্ড কালো করে নিই এবং নির্ধারিত ভার্টেক্স ডেটা ও শেডার প্রোগ্রাম ব্যবহার করে একটি লাল আয়তক্ষেত্র আঁকি।

 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);
  • এই কোডে আমরা WebGL রেন্ডারিং পাইপলাইন সেট আপ করে একটি আয়তক্ষেত্র রেন্ডার করেছি। gl.clear() দিয়ে স্ক্রিন ইনিশিয়ালাইজ করে এবং gl.drawArrays() দিয়ে GPU-তে ড্র কমান্ড পাঠিয়ে, শেডার দ্বারা প্রক্রিয়াকৃত ডেটা বাস্তবে স্ক্রিনে প্রদর্শিত হয়।

ওয়েবজিএল-এর উন্নত বৈশিষ্ট্যগুলি

ওয়েবজিএল ব্যবহার করে, মৌলিক রেন্ডারিংয়ের বাইরে বিভিন্ন উন্নত বৈশিষ্ট্যগুলি ব্যবহার করতে পারেন। এখানে, আমরা সেই বৈশিষ্ট্যগুলির মধ্যে কিছু পরিচয় করিয়ে দিচ্ছি।

টেক্সচার ম্যাপিং

ওয়েবজিএল টেক্সচার ম্যাপিং সমর্থন করে, যা আপনাকে চিত্র বা প্যাটার্ন 3D অবজেক্টে প্রয়োগ করার অনুমতি দেয়। এটি আপনাকে সাধারণ রঙের পরিবর্তে বস্তুগুলিকে আরও জটিল এবং বাস্তবসম্মত চেহারা দিতে সহায়তা করে।

 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};
  • ছবিগুলো টেক্সচার হিসেবে লোড করে অবজেক্টের পৃষ্ঠে প্রয়োগ করুন, যাতে আরও বাস্তবসম্মত দেখায়।

আলো এবং শেডিং

আপনি শেডিং মডেলের সাহায্যে 3D অবজেক্টগুলিতে বাস্তবসম্মত আলোর প্রভাব প্রয়োগ করতে পারেন। ভিন্ন শেডিং মডেলগুলির উপর ভিত্তি করে, যেমন ফং শেডিং এবং গোরাউড শেডিং, একটি বস্তুর পৃষ্ঠ কীভাবে আলো প্রতিফলিত করে তা গণনা করুন।

 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}`;
  • আলোর দিক ও নরমালগুলোর মধ্যকার কোণের ওপর ভিত্তি করে উজ্জ্বলতা গণনা করুন। এটাই Phong এবং Gouraud মডেলের মতো শেডিং কৌশলগুলোর ভিত্তি।

অপ্টিমাইজেশন এবং পারফরম্যান্স

ওয়েবজিএল সরাসরি জিপিইউ-তে কাজ করে, তাই পারফরম্যান্স অপ্টিমাইজেশন অত্যন্ত গুরুত্বপূর্ণ। বেশি পরিমাণের ভরটেক্স তথ্য বা জটিল শেডার ব্যবহার পারফরম্যান্স হ্রাসের কারণ হতে পারে। পারফরম্যান্স অপ্টিমাইজেশনের জন্য সাধারণ কৌশলগুলি নিচে দেওয়া হল।

  • ভার্টেক্স বাফারের দক্ষ ব্যবহার ভার্টেক্স বাফার ঘন ঘন আপডেট করার বদলে, একবার তৈরি করা বাফারগুলো যতটা সম্ভব পুনর্ব্যবহার করুন।
  • ফ্রেম রেট সমন্বয় অ্যানিমেশন রেন্ডারিং নিয়ন্ত্রণ করতে এবং কার্যকর ফ্রেম রেট বজায় রাখতে requestAnimationFrame ব্যবহার করুন।
  • অক্লুশন কালিং দৃষ্টিসীমার বাইরে থাকা অবজেক্টগুলোর রেন্ডারিং বাদ দেওয়ার একটি কৌশল। এটি রেন্ডারিংয়ের লোড কমাতে সহায়তা করে।
 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();
  • requestAnimationFrame দিয়ে রেন্ডারিং লুপ নিয়ন্ত্রণ করুন এবং ব্রাউজারের রেন্ডারিং টাইমিংয়ের সাথে সামঞ্জস্য রেখে দক্ষতার সাথে ফ্রেম আপডেট করুন।

সারসংক্ষেপ

জাভাস্ক্রিপ্ট এবং ওয়েবজিএল একত্রিত করে ব্রাউজারে বাস্তব সময়ে কাজ করা উন্নত 3D গ্রাফিক্স অর্জন করা সম্ভব। ওয়েবজিএল শেডার এবং বাফার ম্যানেজমেন্টের মৌলিক ধারণা থেকে শুরু করে টেক্সচার প্রয়োগ, পারফরম্যান্স অপ্টিমাইজেশনের মতো অনেক উপাদান অন্তর্ভুক্ত করে; তবে এগুলি কার্যকরভাবে ব্যবহার করে, আপনি ইন্টার‌অ্যাকটিভ এবং দৃষ্টিনন্দন সমৃদ্ধ অ্যাপ্লিকেশন তৈরি করতে পারেন।

আপনি আমাদের ইউটিউব চ্যানেলে ভিজ্যুয়াল স্টুডিও কোড ব্যবহার করে উপরের নিবন্ধটি অনুসরণ করতে পারেন। দয়া করে ইউটিউব চ্যানেলটিও দেখুন।

YouTube Video