لقد اتخذت قرارًا حكيمًا بالتعمق في عالم WebGL، وهو عالم مليء بالإبداع والتحديات الشيقة. يعد WebGL تقنية تمكنك من رسم وتفاعل مع الرسوميات ثلاثية الأبعاد في متصفح الويب الخاص بك، مما يفتح الباب أمام إمكانيات مذهلة في تصميم وتطوير الويب.
على الرغم من أن مكتبات WebGL مثل Three.js و Babylon.js قد تكون مفيدة لتبسيط عملية تطوير التطبيقات ثلاثية الأبعاد، إلا أنه من الممكن تعلم WebGL بشكل مباشر دون الحاجة إلى تلك المكتبات الكبيرة. من خلال استخدام WebGL بشكل مباشر، ستكسب فهمًا أعمق لكيفية عمل هذه التقنية وستكون قادرًا على تخصيص تجربة الرسوميات الخاصة بك بدقة أكبر.
في المثال الذي قدمته، يتم استخدام عنصر canvas لرسم نقاط وتدرجات ألوان باستخدام سياق 2D. ولكن لنقم بتحويل هذا السياق إلى WebGL.
للبدء، يجب علينا إنشاء سياق WebGL باستخدام getContext('webgl')
بدلاً من getContext('2d')
. بمجرد الحصول على السياق، يمكننا استخدام WebGL API لرسم النقاط وتطبيق التدرجات.
في البداية، نحتاج إلى تحويل وظيفة DrawPoint
لتعمل مع WebGL. سنقوم بذلك باستخدام برنامج التظليل لتحديد النقطة وتطبيق التدرج. يبدو ذلك مثل هذا:
function DrawPoint(gl, x, y, size, blur, opacity) {
var vertexShaderSource = `
attribute vec2 position;
void main() {
gl_Position = vec4(position, 0.0, 1.0);
}
`;
var fragmentShaderSource = `
precision mediump float;
uniform vec2 center;
uniform float size;
uniform float blur;
uniform float opacity;
void main() {
float dist = distance(gl_FragCoord.xy, center);
float alpha = smoothstep(size, size - blur, dist);
gl_FragColor = vec4(1.0, 1.0, 1.0, alpha * opacity);
}
`;
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSource);
gl.compileShader(vertexShader);
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSource);
gl.compileShader(fragmentShader);
var program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
var positionAttributeLocation = gl.getAttribLocation(program, "position");
var positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
var positions = [
x, y,
x + size, y,
x, y + size,
x, y + size,
x + size, y,
x + size, y + size
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(positionAttributeLocation);
var centerLocation = gl.getUniformLocation(program, "center");
gl.uniform2f(centerLocation, x + size / 2, y + size / 2);
var sizeLocation = gl.getUniformLocation(program, "size");
gl.uniform1f(sizeLocation, size / 2);
var blurLocation = gl.getUniformLocation(program, "blur");
gl.uniform1f(blurLocation, blur);
var opacityLocation = gl.getUniformLocation(program, "opacity");
gl.uniform1f(opacityLocation, opacity);
gl.drawArrays(gl.TRIANGLES, 0, 6);
}
ومن ثم، سنحتاج إلى تعديل الدالة DrawcGradient
لتعمل مع WebGL:
function DrawcGradient(gl) {
var w = 500;
var h = 200;
var pointR = w / 2;
var x = (w / 2);
var y = (h / 2);
var vertexShaderSource = `
attribute vec2 position;
void main() {
gl_Position = vec4(position, 0.0, 1.0);
}
`;
var fragmentShaderSource = `
precision mediump float;
uniform vec2 center;
uniform float pointR;
void main() {
float dist = distance(gl_FragCoord.xy, center);
float alpha = smoothstep(pointR, pointR - 1.0, dist);
gl_FragColor = mix(vec4(0.353, 0.412, 0.467, 1.0), vec4(0.0, 0.0, 0.0, 1.0), alpha);
}
`;
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSource);
gl.compileShader(vertexShader);
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSource);
gl.compileShader(fragmentShader);
var program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
var positionAttributeLocation = gl.getAttribLocation(program, "position");
var positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
var positions = [
0, 0,
w, 0,
0, h,
0, h,
w, 0,
w, h
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(positionAttributeLocation);
var centerLocation = gl.getUniformLocation(program, "center");
gl.uniform2f(centerLocation, x, y);
var pointRLocation = gl.getUniformLocation(program, "pointR");
gl.uniform1f(pointRLocation, pointR);
gl.drawArrays(gl.TRIANGLES, 0, 6);
}
لكن هذا ليس كل شيء، يجب علينا أيضًا تعديل العلامة canvas
في النص الأساسي لتناسب WebGL. هذا ما سنقوم به:
<canvas id="canvas" width="500" height="200">canvas>
<script type='text/javascript'>
var canvas = document.getElementById('canvas');
var gl = canvas.getContext('webgl');
if (!gl) {
console.log('WebGL not supported, falling back on experimental-webgl');
gl = canvas.getContext('experimental-webgl');
}
if (!gl) {
alert('Your browser does not support WebGL');
}
DrawcGradient(gl);
DrawPoint(gl, 50, 100, 50, 0.5, 0.2);
DrawPoint(gl, 70, 10, 150, 0.93, 0.2);
script>
بعد هذه التغييرات، يجب أن تعمل الرموز المعدّلة بنجاح في تقديم نفس التأثيرات على الرسم النهائي كما في الكود السابق. بالتأكيد، يمكنك تعديل وتحسين هذه الأكواد لتناسب احتياجاتك ولإضافة المزيد من الميزات الرائعة.