img

ایجاد افکت های شبه مایع با WebGL

/
/
/

از کتابخانه three.js در WebGL استفاده کنید تا افکت های موج دار، چندضلعی و متحرک برای پس‌زمینه بسازید

اکثر طراحان وب همیشه به دنبال راه هایی برای افزایش تاثیر بر طراحی سایت خود هستند، تا از طریق آن توجه مشتری و کاربران را جلب کنند. این قضیه سال های متمادی ست که از سرتیترهای گرافیکی تا اسلایدشوهای زیر منو تکامل یافته است. آخری در ابعاد کلی مرورگر عرضه شده و اکثر سایت ها از این قالب استفاده می‌کنند. سایت هایی که در جوایز متعدد لقب “سایت روز” را از آن خود کرده اند، چیزهای منحصربه فردتری استفاده می‌کنند. WebGL برای اضافه کردن چیزهای تعاملی به منظور جلب توجه کاربر و القاء منحصر به فرد بودن، مناسب است.
برای ایجاد یک پاشیدگی آب، در این مقاله یک مایع، سطحی منعکس کننده، اضافه می‌شود و در برابر دوربین به صورت موج هایی که به پیش می‌روند متحرک می‌شود. اجزاء دیگری نیز برای تکمیل احساس به پیش رفتن به کار اضافه خواهند شد. در وسط لوگوی سایت خواهد بود و تمام صفحه طبق حرکت موس کاربر حرکت می‌کند و جلوه ای سه بعدی به آن می‌بخشد. لوگو یک فایل شفاف PNG است که به راحتی با طراحی شما قابل دستکاری است. نورها همچنین حرکت می‌کنند، بنابراین هایلایت ها به جای جای موج ها تابیده می‌شوند.

 

۱- متغیرهای اولیه
از فایل های پروژه، پوشه start را باز کرده و آن را در ادیتور کد کشیده و رها کنید. index.html را باز کنید و می‌بینید که کتابخانه های جاوااسکریپت برای شما مرتبط شده اند. داخل تگ های خالی اسکریپت جایی ست که باید کدها وارد آن شوند. در اینجا WebGL مطمئن می‌شود که پروژه قابل اجراست. سپس دسته های زیادی از متغیرها اضافه می‌شوند که در صحنه قابل استفاده اند.

if (!Detector.webgl) Detector.
addGetWebGLMessage();
var SCREEN_WIDTH = window.innerWidth;
var SCREEN_HEIGHT = window.innerHeight;
var renderer, camera, scene, moverGroup,
floorGeometry, floorMaterial, pointLight
pointLight2, pGeometry;
var FLOOR_RES = 60;
var FLOOR_HT = 650;
var stepCount = 0;
var noiseScale = 9.5;
var noiseSeed = Math.random() * 100;

 

 

۲- متغیرهای بیشتر
دسته دیگر متغیرها مشخص می‌کنند که ارتفاع آب و سرعت حرکت ان همگام با موس کاربر چه قدر باید باشد. میانه صفحه قابلیت دستکاری دارد و باید کتابخانه نویزهای آن ارتقا یابد تا سطح آب ایجاد شود.

var FLOOR_WIDTH = 3600;
var FLOOR_DEPTH = 4800;
var MOVE_SPD = 1.9;
var mouseX = 0;
var mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
var snoise = new ImprovedNoise();
var textureLoader = new THREE.
TextureLoader();

 

۳- محاسبه موس
بعضی متغیرهای نهایی برای افکت های پس پردازشی اضافه می‌شوند. یک event listener برای کنترل حرکت موس اضافه می‌شود. صحنه در محل نمایش بر اساس حرکن موس حرکت خواهد کرد. تابعی که اینجا اضافه می‌شود، براساس مقدار حرکتی که مجاز است، عمل میکند.

 

۴- تنظیمات پس پردازشی
تابع params، جایی ست که تمام تنظیمات برای پس پردازش در آن ذخیره می‌شود. اگر هرچیزی را بخواهید تغییر دهید، اینجا باید تغییر کند. شیب میزان تار بودن در چهار خط اول آن مشخص شده است، سپس در خط های بعدی جای حرکت فیلم است. این عموما برای شدت صفحه نمایش و شدت نویز است.

 

۵- پارامترهای نهایی
آخرین پارامترها برای میزان تاریکی دور صفحه نمایش هستند. توابع init و animate برای اجرا فراخوانی شده اند. تابع animate در ادامه ساخته خواهد شد، اما تابع init را همینجا می‌سازیم. دوربین و صحنه طوری تنظیم شده اند که دیدی سه بعدی ایجاد کنند.

effectVignette.uniforms[“offset”].value =
۱٫۰;
effectVignette.uniforms[“darkness”].value
= ۱٫۳;
}
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera(70,
window.innerWidth / window.innerHeight, 1,
۴۰۰۰);
camera.position.z = 2750;
scene = new THREE.Scene();
scene.fog = new THREE.FogExp2(0x1c3c4a,
۰٫۰۰۰۴۵);

 

 

 

۶- اضافه کردن نور

برای دیدن اجزاء صحنه، چهار نور ایجاد می‌شود. نور اول به صورت نیمکره است که برای دسترسی به حالت محیط پایه است. در ادامه نور مرکزی است که نوری آبی رنگ به صحنه اضافه می‌کند. در یک سمت تعبیه می‌شود تا نوری کلی به تمام صحنه بدهد.

var hemisphereLight = new THREE.
HemisphereLight(0xe3feff, 0xe6ddc8, 0.7);
scene.add(hemisphereLight);
hemisphereLight.position.y = 300;
var centerLight = new THREE.
SpotLight(0xb7f9ff, 1);
scene.add(centerLight);
centerLight.position.set(2500, 300, 2000);
centerLight.penumbra = 1;
centerLight.decay = 5;

 

۷- نورهای متحرک
دو نور بعدی که اضافه می‌شوند، نور نقطه ای و نور نقطه ای ۲ هستند که در جهات مختلف در اطراف صحنه تعبیه می‌شوند تا به صورت مداوم در صحنه تغییر کنند، این دو نور رنگی هستند. اولی صورتی و دومی‌نارنجی است. مسیر و فرمت انعکاس عکس ها در دو خط آخر دستور دیده می‌شود.

pointLight = new THREE.PointLight(0xe07bff,
۱٫۵);
pointLight.position.z = 200;
scene.add(pointLight);
pointLight2 = new THREE.PointLight(0xff4e00,
۱٫۲);
pointLight2.position.z = 200;
scene.add(pointLight2);
var path = “img/”;
var format = ‘.jpg’;

 

۸- سطوح براق
سطح مایه، سطحی منعکس کننده و برای خواهد داشت که با ایجاد مکعب انعکاسی به دست می‌آید. مکعبی ۳۶۰درجه که در درون خود skybox دارد که به سطح مایع انعکاس می‌کند. آرایه urls، شامل تصاویری ست که بعد از تنظیم متریال، بارگزاری می‌شود.

 

۹- تنظیم بعضی گروه ها
گروه حرکت‌دهنده شامل اجزائی ست که بعدا اضافه می‌شوند، درحالیکه گروه کف ، محتوی سطح مایع است. یک آبجکت سه بعدی ایجاد می‌شود که مسئول سطح است. دو سطح مایع ایجاد خواهد شد: یکی از آنها حاوی متریال منعکس کننده و دیگری چارچوب floorMaterial را همانطور که در ادامه می‌بینید به همراه خواهد داشت.

moverGroup = new THREE.Object3D();
scene.add(moverGroup);
var floorGroup = new THREE.Object3D();
var floorMaterial = new THREE.
MeshPhongMaterial({
color: 0xeeeeee, side: THREE.DoubleSide,
blending: THREE.AdditiveBlending, wireframe:
true
});
floorGeometry = new THREE.
PlaneGeometry(FLOOR_WIDTH + 1200, FLOOR_
DEPTH, FLOOR_RES, FLOOR_RES);

 

۱۰- ایجاد سطح
دو سطح مایع در اینجا با نام های floorMesh و floorMesh2 ایجاد می‌شوند. در گروه floor قرار می‌گیرند و برای ایجاد یک دید مناسب جلوی دوربین، چرخیده می‌شوند. کاملا مسطح نیست، بلکه کمی‌زاویه دار تشکیل شده تا دیدی بهتر داشته باشد.

var floorMesh = new THREE.
Mesh(floorGeometry, cubeMaterial);
var floorMesh2 = new THREE.
Mesh(floorGeometry, floorMaterial);
floorMesh2.position.y = 20;
floorMesh2.position.z = 5;
floorGroup.add(floorMesh);
floorGroup.add(floorMesh2);
scene.add(floorGroup);
floorMesh.rotation.x = Math.PI / 1.65;
floorMesh2.rotation.x = Math.PI / 1.65;
floorGroup.position.y = 180;

 

۱۱- اضافه کردن اجزاء شناور
قسمتی از کد در اینجا آبجکت هندسی و خالی پدید می‌آورد و داخل آن ۲۰۰۰ متغیر بعنوان اجزاء آن قرار می‌دهد. این ها در محورهای X، Y و Z حرکت می‌کنند. درست بالای سطح floor مایع حرکت می‌کنند.

pGeometry = new THREE.Geometry();
sprite = textureLoader.load(“img/sprite.
png”);
for (i = 0; i < 2000; i++) {
var vertex = new THREE.Vector3();
vertex.x = 4000 * Math.random() – 2000;
vertex.y = -200 + Math.random() * 700;
vertex.z = 5000 * Math.random() – 2000;
pGeometry.vertices.push(vertex);
}

 

۱۲- ایجاد ظاهر
متریال های تعبیه شده در اینجا مسئول چگونه به نظر رسیدن هستند. وقتی متریال ایجاد شد، تصویری که در گام قبلی بارگزاری شده به عنوان تصویر هر جزء در نظر گرفته می‌شود. سپس به هر نقطه هندسی برای تمام اجزاء اعمال می‌شود. این ها سپس به صحنه اضافه می‌شوند.

۱۳٫ اضافه کردن لوگو
لوگو در وسط صفحه گذاشته و سپس روی سطح صافی که رو به روی دوربین است، قرار داده می‌شود. لوگو تقریبا شفاف ساخته شده و blend ای را به صورت افزونه دریافت می‌کند تا زمانی که آبجکت های روشن تر از پشت ان عبور می‌کنند، بیشتر دیده شود. اینگونه در صحنه قرار داده می‌شود.

sprite = textureLoader.load(“img/logo.png”);
geometry = new THREE.
PlaneBufferGeometry(500, 640, 1);
material = new THREE.MeshLambertMaterial({
transparent: true, opacity: 0.8, blending:
THREE.AdditiveBlending, map: sprite, side:
THREE.DoubleSide
});
var plane = new THREE.Mesh(geometry,
material);
plane.position.set(0, 70, 1800);
scene.add(plane);

 

۱۴- اضافه کردن تنظیمات رندر
رندر طوری تنظیم شده است که با وجود اینکه اکنون رنگ پس زمینه ثابت است، محیطی بدون زاویه و نرم بسازد. از آنجا که صحنه در صفحه HTML است، این قضیه به بدنه آن اضافه می‌شود. افکت های پس پردازشی با آغاز به فعالیت کردن رندر و سایه پرداز های مختلف تنظیم می‌شود.

 

۱۵- ساختن عبور
هنگامی‌که فیلم و توقف ها اضافه شدند، یک ایجادکننده افکت ساخته می‌شود که تمام عبورها را باهم می‌سازد. این ها یکی یکی به ایجادکننده اضافه می‌شوند و در آخر طوری رندر صورت می‌پذیرد که صفحه برای بیننده دلپذیر باشد.

 

۱۶- بستن تابع init
آخرین تنظیمات برای آغاز صحنه اضافه شده اند. پارامترهای پس پردازش تنظیم، تنظیمات امواج فراخوانی و یک event listener برای هرجا که مرورگر تغییر سایز می‌دهد، اضافه شده است. این به صفحه نمایش قدرت تغییر ابعاد می‌دهد.

 

۱۷- تنظیم امواج
حالا امواج برای سطح مایع ایجاد شده اند. این قضیه با حرکت از میان هر راس هندسی در محورهای X و Z و حرکت دادن رو به بالای آن در محور Y انجام می‌پذیرد. در این مرحله، لوپ for برای محورهای X و Z ایجاد می‌شود.

function setWaves() {
stepCount++;
moverGroup.position.z = -MOVE_SPD;
var i, ipos;
var offset = stepCount * MOVE_SPD /
FLOOR_DEPTH * FLOOR_RES;
for (i = 0; i < FLOOR_RES + 1; i++) {
for (var j = 0; j < FLOOR_RES + 1; j++) {
ipos = i + offset;

 

۱۸- ساختن امواج
تمام رئوس به سمت بالا به یک جهت تنظیم نمی‌شوند. آن هایی که از دوربین دورهستند، بزرگتر می‌شوند و به مرور به سمت کنارها کوچک می‌شوند و آن هایی که به دوربین نزدیک هستند، در کوچکترین سایز قرار دارند. این قضیه به امواج ظاهری جالب توجه می‌دهد.

if ((i > 30) || (j < 12) || (j > 48)) {
floorGeometry.vertices[i * (FLOOR_RES + 1)
+ j].z = snoise.noise(ipos / FLOOR_RES *
noiseScale, j / FLOOR_RES * noiseScale,
noiseSeed) * FLOOR_HT;
} else if (i > 25 && i < 30) {
floorGeometry.vertices[i * (FLOOR_RES + 1)
+ j].z = snoise.noise(ipos / FLOOR_RES *
noiseScale, j / FLOOR_RES * noiseScale,
noiseSeed) * (FLOOR_HT / 1.2);
} else {
floorGeometry.vertices[i * (FLOOR_RES + 1)
+ j].z = snoise.noise(ipos / FLOOR_RES *
noiseScale, j / FLOOR_RES * noiseScale,
noiseSeed) * (FLOOR_HT / 2);
}
}
}
floorGeometry.verticesNeedUpdate = true;
}

 

۱۹- تغییر سایز و متحرک سازی
وقتی پنجره تغییر سایز دهد، تابع از listener که در گام ۱۶ تنظیم شده بود، فراخوانی می‌شود. دوربین، رندر و سازنده در این مرحله به حالت پاسه خود بر می‌گردند و آماده ابعاد جدید می‌شوند. تابع متحرک خود را در ۶۰ فریم بر ثانیه قرار می‌دهد و تابع رندر را برای به روزرسانی ابعاد فراخوانی می‌کند.

function onWindowResize() {
camera.aspect = window.innerWidth /
window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth,
window.innerHeight);
composer.setSize(window.innerWidth,
window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
render();
}

 

۲۰- هر فریم عملیاتی
تابع رندر هر فریم را فراخوانی می‌کند. نورهای نقطه ای طوری تنظیم شده اند که دور صحنه بچرخند و دوربین براساس حرکت موس تنظیم شده است البته باکمی‌تاخیر تا به آرامی‌به محل برگردد. دوربین بر مرکز صحنه تمرکز دارد.

function render() {
var timer = -0.0002 * Date.now();
pointLight.position.x = 2400 * Math.
cos(timer);
pointLight.position.z = 2400 * Math.
sin(timer);
pointLight2.position.x = 1800 * Math.
cos(-timer * 1.5);
pointLight2.position.z = 1800 * Math.
sin(-timer * 1.5);
camera.position.x += (mouseX – camera.
position.x) * .05;
camera.position.y += (-mouseY – camera.
position.y) * .05;
camera.lookAt(scene.position);

 

۲۱- قدم های نهایی
در قدم نهایی، اجزاء به سمت جلو و در راس مخصوص حرکت داده می‌شوند و اگر به دوربین برخورد کردند، به فاصله معین شده باز می‌گردند. این به روزرسانی می‌شود و تابع setWaves برای به جلو حرکت دادن امواج فراخوانی می‌شود. صحنه با سارنده افکت‌ها، رندر می‌شود.

 

پس پردازش و سایه سازها
دست یابی به یک صحنه سه بعدی زیبا، صرفا به اجزاء موجود در صحنه ختم نمی‌شود. بله مدل سه بعدی همیشه اگر حاضر باشد، صحنه را جذاب می‌کند اما قسمتی از راه جذاب کردن آن از طریق پس پردازش اجرا و تکمیل می‌شود. کاری که انجام می‌دهد گرفتن کل صفحه نمایش و اجرای آن از مدخل سایه ساز است.
سایه سازی فرایندی بسیار سریع است که روی کارت گرافیک انجام می‌شود و حین انجام آن یکباره تمام پیکسل‌ها باهم تحت تاثیر قرار می‌گیرند. صحنه از پنج سایه ساز استفاده می‌کند.
دوتای اول مربوط به تغییر شیب هستند بنابراین سایه ساز برای تار کردن عمودی و افقی اجرا می‌شود. سپس یک بافت زبر، یک تاریک کننده و در آخر توقف های لحظه ای اضافه می‌شوند. اگر می‌خواهید بیشتر راجع به آن ها بدانید به آدرس
https:// thebookofshaders.com
بروید.

نظر بدهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

It is main inner container footer text