100,000 তারকা তৈরি করা

হ্যালো! আমার নাম মাইকেল চ্যাং এবং আমি Google-এ ডেটা আর্টস টিমের সাথে কাজ করি। সম্প্রতি, আমরা 100,000 স্টারগুলি সম্পন্ন করেছি, একটি Chrome পরীক্ষা যা কাছাকাছি তারাগুলিকে কল্পনা করে৷ প্রকল্পটি THREE.js এবং CSS3D দিয়ে নির্মিত হয়েছিল। এই কেস স্টাডিতে আমি আবিষ্কারের প্রক্রিয়ার রূপরেখা দেব, কিছু প্রোগ্রামিং কৌশল শেয়ার করব এবং ভবিষ্যতে উন্নতির জন্য কিছু চিন্তাভাবনা শেষ করব।

এখানে আলোচিত বিষয়গুলি মোটামুটি বিস্তৃত হবে, এবং THREE.js এর কিছু জ্ঞানের প্রয়োজন, যদিও এটি আমার আশা যে আপনি এখনও একটি প্রযুক্তিগত পোস্টমর্টেম হিসাবে এটি উপভোগ করতে পারবেন। ডানদিকে বিষয়বস্তুর সারণী বোতামটি ব্যবহার করে আগ্রহের একটি এলাকায় ঝাঁপিয়ে পড়তে নির্দ্বিধায়৷ প্রথমে, আমি প্রজেক্টের রেন্ডারিং অংশ দেখাব, তারপরে শেডার ম্যানেজমেন্ট এবং অবশেষে ওয়েবজিএল-এর সাথে কীভাবে সিএসএস টেক্সট লেবেল ব্যবহার করতে হয়।

100,000 স্টার, ডেটা আর্টস টিমের একটি Chrome পরীক্ষা৷
100,000 তারা THREE.js ব্যবহার করে আকাশগঙ্গার কাছাকাছি নক্ষত্রগুলিকে কল্পনা করতে

মহাকাশ আবিষ্কার

আমরা Small Arms Globe শেষ করার কিছুক্ষণ পরে, আমি একটি THREE.js কণা ডেমো নিয়ে পরীক্ষা করছিলাম ডেপথ অফ ফিল্ড সহ। আমি লক্ষ্য করেছি যে আমি প্রয়োগকৃত প্রভাবের পরিমাণ সামঞ্জস্য করে দৃশ্যের ব্যাখ্যা করা "স্কেল" পরিবর্তন করতে পারি। যখন ক্ষেত্রের প্রভাবের গভীরতা সত্যিই চরম ছিল, তখন দূরবর্তী বস্তুগুলি সত্যই অস্পষ্ট হয়ে ওঠে যেভাবে টিল্ট-শিফ্ট ফটোগ্রাফি একজনকে একটি মাইক্রোস্কোপিক দৃশ্য দেখার বিভ্রম দেওয়ার জন্য কাজ করে। বিপরীতভাবে, প্রভাবটি প্রত্যাখ্যান করা এটিকে এমনভাবে দেখায় যে আপনি গভীর স্থানের দিকে তাকাচ্ছেন।

আমি এমন ডেটা খোঁজা শুরু করি যা দিয়ে আমি কণার অবস্থান ইনজেক্ট করতে ব্যবহার করতে পারি, একটি পথ যা আমাকে astronexus.com- এর HYG ডাটাবেসে নিয়ে যায়, তিনটি ডেটা উৎসের সংকলন (Hipparcos, Yale Bright Star Catalog, এবং Gliese/Jahreiss Catalog) প্রাক-গণনা করা xyz কার্টেসিয়ান স্থানাঙ্ক দ্বারা। চল শুরু করি!

তারকা তথ্য প্লট করা.
প্রথম ধাপ হল ক্যাটালগের প্রতিটি তারাকে একটি একক কণা হিসাবে প্লট করা।
নামকরা তারা।
ক্যাটালগের কিছু তারার সঠিক নাম আছে, এখানে লেবেল করা আছে।

3D স্পেসে তারকা ডেটা স্থাপন করে এমন কিছু হ্যাক করতে প্রায় এক ঘন্টা সময় লেগেছে। ডেটা সেটে ঠিক 119,617 তারা রয়েছে, তাই প্রতিটি তারাকে একটি কণা দিয়ে উপস্থাপন করা একটি আধুনিক GPU-এর জন্য কোনও সমস্যা নয়। এছাড়াও 87টি স্বতন্ত্রভাবে চিহ্নিত তারা রয়েছে, তাই আমি স্মল আর্মস গ্লোবে বর্ণিত একই কৌশল ব্যবহার করে একটি CSS মার্কার ওভারলে তৈরি করেছি।

এই সময়ে আমি সবেমাত্র ম্যাস ইফেক্ট সিরিজ শেষ করেছি। গেমটিতে খেলোয়াড়কে গ্যালাক্সি অন্বেষণ করতে এবং বিভিন্ন গ্রহ স্ক্যান করার জন্য আমন্ত্রণ জানানো হয় এবং তাদের সম্পূর্ণ কাল্পনিক, উইকিপিডিয়া-সাউন্ডিং ইতিহাস সম্পর্কে পড়তে হয় : গ্রহে কী প্রজাতির উন্নতি হয়েছিল, এর ভূতাত্ত্বিক ইতিহাস এবং আরও অনেক কিছু।

নক্ষত্র সম্পর্কে প্রকৃত তথ্যের সম্পদ জেনে, কেউ একইভাবে গ্যালাক্সি সম্পর্কে বাস্তব তথ্য উপস্থাপন করতে পারে। এই প্রকল্পের চূড়ান্ত লক্ষ্য হবে এই ডেটাকে জীবন্ত করে তোলা, দর্শককে গ্যালাক্সি à la Mass Effect অন্বেষণ করতে, তারা এবং তাদের বিতরণ সম্পর্কে জানতে এবং মহাকাশ সম্পর্কে বিস্ময় ও বিস্ময়ের অনুভূতি অনুপ্রাণিত করা। ফাউ!

আমার সম্ভবত এই কেস-স্টাডির বাকি অংশটি এই বলে দেওয়া উচিত যে আমি কোনওভাবেই একজন জ্যোতির্বিজ্ঞানী নই, এবং এটি বহিরাগত বিশেষজ্ঞদের কিছু পরামর্শ দ্বারা সমর্থিত অপেশাদার গবেষণার কাজ । এই প্রকল্পটি অবশ্যই স্থানের একটি শিল্পী ব্যাখ্যা হিসাবে ব্যাখ্যা করা উচিত।

একটি গ্যালাক্সি নির্মাণ

আমার পরিকল্পনা ছিল পদ্ধতিগতভাবে গ্যালাক্সির একটি মডেল তৈরি করা যা নক্ষত্রের ডেটাকে প্রসঙ্গে রাখতে পারে -- এবং আশা করি মিল্কিওয়েতে আমাদের স্থানের একটি দুর্দান্ত দৃশ্য দিতে পারে।

গ্যালাক্সির একটি প্রাথমিক প্রোটোটাইপ।
মিল্কিওয়ে কণা সিস্টেমের একটি প্রাথমিক প্রোটোটাইপ।

মিল্কিওয়ে তৈরি করার জন্য, আমি 100,000 কণা তৈরি করেছি এবং গ্যালাকটিক অস্ত্র তৈরির উপায় অনুকরণ করে একটি সর্পিলে স্থাপন করেছি। আমি সর্পিল আর্ম গঠনের বিশেষত্ব সম্পর্কে খুব বেশি চিন্তিত ছিলাম না কারণ এটি একটি গাণিতিক মডেলের পরিবর্তে একটি প্রতিনিধিত্বমূলক মডেল হবে। তবে আমি সর্পিল বাহুগুলির সংখ্যা কমবেশি সঠিক এবং "সঠিক দিকে" ঘুরতে চেষ্টা করেছি।

মিল্কিওয়ে মডেলের পরবর্তী সংস্করণগুলিতে আমি কণাগুলির সাথে ছায়াপথের একটি প্ল্যানার ইমেজের পক্ষে কণার ব্যবহারের উপর জোর দিয়েছি, আশা করি এটিকে আরও একটি ফটোগ্রাফিক চেহারা দেবে। প্রকৃত চিত্রটি আমাদের থেকে প্রায় 70 মিলিয়ন আলোকবর্ষ দূরে সর্পিল গ্যালাক্সি NGC 1232-এর , যা মিল্কিওয়ের মতো দেখতে চিত্র-পরিচালিত।

ছায়াপথের স্কেল বের করা।
প্রতিটি GL ইউনিট একটি আলোকবর্ষ। এই ক্ষেত্রে গোলকটি 110,000 আলোকবর্ষ প্রশস্ত, কণা ব্যবস্থাকে ঘিরে।

আমি প্রাথমিকভাবে একটি GL ইউনিটকে প্রতিনিধিত্ব করার সিদ্ধান্ত নিয়েছিলাম, মূলত 3D-তে একটি পিক্সেল, এক আলোকবর্ষ হিসাবে -- একটি সম্মেলন যা কল্পনা করা সমস্ত কিছুর জন্য একীভূত স্থান নির্ধারণ করে, এবং দুর্ভাগ্যবশত পরবর্তীতে আমাকে গুরুতর নির্ভুলতার সমস্যা দেয়।

আরেকটি কনভেনশন যা আমি সিদ্ধান্ত নিয়েছিলাম তা হল ক্যামেরা সরানোর পরিবর্তে পুরো দৃশ্যটি ঘোরানো, যা আমি আরও কয়েকটি প্রকল্পে করেছি। একটি সুবিধা হল যে সবকিছু একটি "টার্নটেবল" এর উপর স্থাপন করা হয় যাতে মাউস-টেনে বাম এবং ডানে প্রশ্ন করা বস্তুটিকে ঘোরাতে পারে, কিন্তু জুম ইন করা শুধুমাত্র ক্যামেরা.position.z পরিবর্তনের বিষয়।

ক্যামেরার জন্য ক্ষেত্র অফ ভিউ (বা FOV)ও গতিশীল। একজন বাইরের দিকে টেনে নেওয়ার সাথে সাথে দৃশ্যের ক্ষেত্রটি প্রশস্ত হয়, গ্যালাক্সিকে আরও বেশি করে নিয়ে যায়। বিপরীতটি সত্য যখন একটি তারার দিকে ভিতরের দিকে অগ্রসর হয়, দেখার ক্ষেত্রটি সংকীর্ণ হয়। এটি ক্যামেরাকে এফওভি-কে দেবতার মতো ম্যাগনিফাইং গ্লাসের মতো কিছুতে স্কুইশ করে অসীম জিনিসগুলি দেখতে দেয় (গ্যালাক্সির তুলনায়) কাছাকাছি প্লেনের ক্লিপিং সমস্যাগুলি মোকাবেলা না করেই৷

একটি গ্যালাক্সি রেন্ডার করার বিভিন্ন উপায়।
(উপরে) প্রারম্ভিক কণা ছায়াপথ। (নীচে) একটি চিত্র সমতল দ্বারা অনুষঙ্গী কণা.

এখান থেকে আমি গ্যালাক্টিক কোর থেকে কিছু সংখ্যক ইউনিট দূরে সূর্যকে "স্থাপন" করতে সক্ষম হয়েছি। আমি কুইপার ক্লিফের ব্যাসার্ধ ম্যাপ করে সৌরজগতের আপেক্ষিক আকার কল্পনা করতেও সক্ষম হয়েছিলাম (অবশেষে আমি উর্ট ক্লাউডকে কল্পনা করতে বেছে নিয়েছিলাম) পরিবর্তে। এই মডেল সৌরজগতের মধ্যে, আমি পৃথিবীর একটি সরলীকৃত কক্ষপথ এবং তুলনা করে সূর্যের প্রকৃত ব্যাসার্ধও কল্পনা করতে পারি।

সৌরজগৎ.
সূর্য গ্রহ এবং কুইপার বেল্টের প্রতিনিধিত্বকারী একটি গোলক দ্বারা প্রদক্ষিণ করে।

সূর্য রেন্ডার করা কঠিন ছিল. আমি যতটা রিয়েল-টাইম গ্রাফিক্স কৌশল জানতাম তার সাথে প্রতারণা করতে হয়েছিল। সূর্যের পৃষ্ঠটি রক্তরসের একটি উত্তপ্ত ঝর্ণা এবং সময়ের সাথে সাথে স্পন্দন এবং পরিবর্তনের প্রয়োজন। এটি সৌর পৃষ্ঠের একটি ইনফ্রারেড চিত্রের একটি বিটম্যাপ টেক্সচারের মাধ্যমে সিমুলেট করা হয়েছিল। সারফেস শেডার এই টেক্সচারের গ্রেস্কেলের উপর ভিত্তি করে একটি কালার লুক-আপ করে এবং একটি আলাদা রঙের র‌্যাম্পে লুক-আপ করে। সময়ের সাথে সাথে যখন এই লুক-আপটি স্থানান্তরিত হয় তখন এটি লাভার মতো বিকৃতি তৈরি করে।

সূর্যের করোনার জন্য অনুরূপ একটি কৌশল ব্যবহার করা হয়েছিল, তবে এটি একটি ফ্ল্যাট স্প্রাইট কার্ড যা সর্বদা https://github.com/mrdoob/three.js/blob/master/src/extras/core ব্যবহার করে ক্যামেরার মুখোমুখি হবে। /Gyroscope.js

রেন্ডারিং সল.
সূর্যের প্রাথমিক সংস্করণ।

সৌর শিখাগুলি একটি টরাসে প্রয়োগ করা শীর্ষবিন্দু এবং টুকরো শেডারের মাধ্যমে তৈরি করা হয়েছিল, সৌর পৃষ্ঠের ঠিক প্রান্তের চারপাশে ঘুরছে। ভার্টেক্স শেডারের একটি শব্দ ফাংশন রয়েছে যার ফলে এটি একটি ব্লবের মতো ফ্যাশনে বুনতে পারে।

এখানেই আমি জিএল নির্ভুলতার কারণে কিছু জেড-ফাইটিং সমস্যা অনুভব করতে শুরু করেছি। নির্ভুলতার জন্য সমস্ত ভেরিয়েবল THREE.js-এ পূর্ব-সংজ্ঞায়িত ছিল, তাই আমি প্রচুর পরিমানে কাজ ছাড়া নির্ভুলতাকে বাস্তবসম্মতভাবে বাম্প করতে পারিনি। নির্ভুলতা সমস্যা উৎপত্তি কাছাকাছি হিসাবে খারাপ ছিল না. যাইহোক, একবার আমি অন্যান্য তারকা সিস্টেমের মডেলিং শুরু করলে, এটি একটি সমস্যা হয়ে ওঠে।

তারকা মডেল।
সূর্যকে রেন্ডার করার কোডটি পরে অন্যান্য নক্ষত্র রেন্ডার করার জন্য সাধারণীকরণ করা হয়েছিল।

জেড-ফাইটিং প্রশমিত করার জন্য আমি নিযুক্ত কয়েকটি হ্যাক ছিল। THREE's Material.polygonoffset এমন একটি সম্পত্তি যা বহুভুজকে একটি ভিন্ন অনুভূত স্থানে রেন্ডার করার অনুমতি দেয় (যতদূর আমি বুঝি)। এটি করোনা প্লেনকে সর্বদা সূর্যের পৃষ্ঠের উপরে রেন্ডার করতে বাধ্য করতে ব্যবহৃত হয়েছিল। এর নীচে, গোলক থেকে দূরে সরে যাওয়া তীক্ষ্ণ আলোক রশ্মি দেওয়ার জন্য একটি সূর্য "হ্যালো" রেন্ডার করা হয়েছিল।

নির্ভুলতার সাথে সম্পর্কিত একটি ভিন্ন সমস্যা ছিল যে দৃশ্যটি জুম করার সাথে সাথে তারকা মডেলগুলি ঝাঁকুনি দেওয়া শুরু করবে৷ এটি ঠিক করার জন্য আমাকে দৃশ্যের ঘূর্ণনকে "শূন্য আউট" করতে হয়েছিল এবং আপনি প্রদক্ষিণ করছেন এমন বিভ্রম দেওয়ার জন্য আলাদাভাবে তারকা মডেল এবং পরিবেশের মানচিত্রটি ঘোরাতে হয়েছিল৷ তারা.

লেন্সফ্লেয়ার তৈরি করা

মহান শক্তি দিয়ে মহান দায়িত্ব আসে।
মহান শক্তি দিয়ে মহান দায়িত্ব আসে।

স্পেস ভিজ্যুয়ালাইজেশনগুলি হল যেখানে আমার মনে হয় আমি লেন্সফ্লেয়ারের অত্যধিক ব্যবহার থেকে দূরে থাকতে পারি। THREE.LensFlare এই উদ্দেশ্যে কাজ করে, আমাকে যা করতে হবে তা হল কিছু অ্যানামরফিক হেক্সাগন এবং জেজে আব্রামসের একটি ড্যাশ। নীচের স্নিপেটটি দেখায় যে কীভাবে সেগুলি আপনার দৃশ্যে তৈরি করবেন।

// This function returns a lesnflare THREE object to be .add()ed to the scene graph
function addLensFlare(x,y,z, size, overrideImage){
var flareColor = new THREE.Color( 0xffffff );

lensFlare = new THREE.LensFlare( overrideImage, 700, 0.0, THREE.AdditiveBlending, flareColor );

// we're going to be using multiple sub-lens-flare artifacts, each with a different size
lensFlare.add( textureFlare1, 4096, 0.0, THREE.AdditiveBlending );
lensFlare.add( textureFlare2, 512, 0.0, THREE.AdditiveBlending );
lensFlare.add( textureFlare2, 512, 0.0, THREE.AdditiveBlending );
lensFlare.add( textureFlare2, 512, 0.0, THREE.AdditiveBlending );

// and run each through a function below
lensFlare.customUpdateCallback = lensFlareUpdateCallback;

lensFlare.position = new THREE.Vector3(x,y,z);
lensFlare.size = size ? size : 16000 ;
return lensFlare;
}

// this function will operate over each lensflare artifact, moving them around the screen
function lensFlareUpdateCallback( object ) {
var f, fl = this.lensFlares.length;
var flare;
var vecX = -this.positionScreen.x _ 2;
var vecY = -this.positionScreen.y _ 2;
var size = object.size ? object.size : 16000;

var camDistance = camera.position.length();

for( f = 0; f < fl; f ++ ) {
flare = this.lensFlares[ f ];

flare.x = this.positionScreen.x + vecX * flare.distance;
flare.y = this.positionScreen.y + vecY * flare.distance;

flare.scale = size / camDistance;
flare.rotation = 0;

}
}

টেক্সচার স্ক্রলিং করার একটি সহজ উপায়

হোমওয়ার্ল্ড দ্বারা অনুপ্রাণিত.
মহাকাশে স্থানিক অভিযোজনে সাহায্য করার জন্য একটি কার্টেসিয়ান প্লেন।

"স্থানিক ওরিয়েন্টেশন প্লেন" এর জন্য, একটি বিশাল থ্রি.সিলিন্ডার জিওমেট্রি() তৈরি করা হয়েছিল এবং সূর্যকে কেন্দ্র করে। "আলোর তরঙ্গ" তৈরি করতে বাইরের দিকে ফ্যানিং, আমি সময়ের সাথে সাথে এর টেক্সচার অফসেট পরিবর্তন করেছি:

mesh.material.map.needsUpdate = true;
mesh.material.map.onUpdate = function(){
this.offset.y -= 0.001;
this.needsUpdate = true;
}

map হল উপাদানের অন্তর্গত টেক্সচার, যা একটি onUpdate ফাংশন পায় যা আপনি ওভার-রাইট করতে পারেন। এর অফসেট সেট করার ফলে টেক্সচারটিকে সেই অক্ষ বরাবর "স্ক্রোল করা" হয় এবং স্প্যামিং needUpdate = true এই আচরণটিকে লুপ করতে বাধ্য করবে।

রঙিন র‌্যাম্প ব্যবহার করে

প্রতিটি তারার একটি "রঙ-সূচক" এর উপর ভিত্তি করে আলাদা রঙ রয়েছে যা জ্যোতির্বিজ্ঞানীরা তাদের নির্ধারণ করেছেন। সাধারণভাবে, লাল নক্ষত্রগুলি শীতল এবং নীল/বেগুনি নক্ষত্রগুলি আরও গরম। এই গ্রেডিয়েন্টে সাদা এবং মধ্যবর্তী কমলা রঙের একটি ব্যান্ড বিদ্যমান।

তারা রেন্ডার করার সময় আমি এই ডেটার উপর ভিত্তি করে প্রতিটি কণাকে তার নিজস্ব রঙ দিতে চেয়েছিলাম। এটি করার উপায় ছিল কণাগুলিতে প্রয়োগ করা শেডার উপাদানগুলিতে দেওয়া "গুণাবলী" দিয়ে।

var shaderMaterial = new THREE.ShaderMaterial( {
uniforms: datastarUniforms,
attributes: datastarAttributes,
/_ ... etc _/
});
var datastarAttributes = {
size: { type: 'f', value: [] },
colorIndex: { type: 'f', value: [] },
};

ColorIndex অ্যারে পূরণ করা প্রতিটি কণাকে শেডারে তার অনন্য রঙ দেবে। সাধারণত কেউ একটি রঙ vec3 এ পাস করবে, কিন্তু এই উদাহরণে আমি চূড়ান্ত রঙের র‌্যাম্প লুক-আপের জন্য একটি ফ্লোটে যাচ্ছি।

রঙের র‌্যাম্প।
একটি রঙের র‌্যাম্প একটি তারকা রঙের সূচক থেকে দৃশ্যমান রঙ দেখতে ব্যবহৃত হয়।

রঙের র‌্যাম্পটি এইরকম দেখাচ্ছিল, তবে আমাকে জাভাস্ক্রিপ্ট থেকে এর বিটম্যাপ রঙের ডেটা অ্যাক্সেস করতে হবে। আমি যেভাবে এটি করেছি তা হল প্রথমে ইমেজটিকে DOM-এ লোড করা, এটি একটি ক্যানভাস উপাদানে আঁকুন, তারপর ক্যানভাস বিটম্যাপ অ্যাক্সেস করুন।

// make a blank canvas, sized to the image, in this case gradientImage is a dom image element
gradientCanvas = document.createElement('canvas');
gradientCanvas.width = gradientImage.width;
gradientCanvas.height = gradientImage.height;

// draw the image
gradientCanvas.getContext('2d').drawImage( gradientImage, 0, 0, gradientImage.width, gradientImage.height );

// a function to grab the pixel color based on a normalized percentage value
gradientCanvas.getColor = function( percentage ){
return this.getContext('2d').getImageData(percentage \* gradientImage.width,0, 1, 1).data;
}

এই একই পদ্ধতি তারপর তারকা মডেল দৃশ্যে পৃথক তারা রঙ করার জন্য ব্যবহার করা হয়।

আমার চোখ!
নক্ষত্রের বর্ণালী শ্রেণীর রঙের সন্ধান করতে একই কৌশল ব্যবহার করা হয়।

Shader ঝগড়া

পুরো প্রকল্প জুড়ে আমি আবিষ্কার করেছি যে সমস্ত ভিজ্যুয়াল প্রভাবগুলি সম্পাদন করার জন্য আমাকে আরও বেশি শেডার লিখতে হবে। আমি এই উদ্দেশ্যে একটি কাস্টম শেডার লোডার লিখেছিলাম কারণ আমি index.html এ শেডার লাইভ থাকতে ক্লান্ত হয়ে পড়েছিলাম।

// list of shaders we'll load
var shaderList = ['shaders/starsurface', 'shaders/starhalo', 'shaders/starflare', 'shaders/galacticstars', /*...etc...*/];

// a small util to pre-fetch all shaders and put them in a data structure (replacing the list above)
function loadShaders( list, callback ){
var shaders = {};

var expectedFiles = list.length \* 2;
var loadedFiles = 0;

function makeCallback( name, type ){
return function(data){
if( shaders[name] === undefined ){
shaders[name] = {};
}

    shaders[name][type] = data;

    //  check if done
    loadedFiles++;
    if( loadedFiles == expectedFiles ){
    callback( shaders );
    }

};

}

for( var i=0; i<list.length; i++ ){
var vertexShaderFile = list[i] + '.vsh';
var fragmentShaderFile = list[i] + '.fsh';

//  find the filename, use it as the identifier
var splitted = list[i].split('/');
var shaderName = splitted[splitted.length-1];
$(document).load( vertexShaderFile, makeCallback(shaderName, 'vertex') );
$(document).load( fragmentShaderFile,  makeCallback(shaderName, 'fragment') );

}
}

loadShaders() ফাংশন শেডার ফাইলের নামের একটি তালিকা নেয় (খণ্ডের জন্য .fsh এবং ভার্টেক্স শেডারের জন্য .vsh আশা করে), তাদের ডেটা লোড করার চেষ্টা করে এবং তারপরে কেবলমাত্র বস্তুর সাথে তালিকাটি প্রতিস্থাপন করে। শেষ ফলাফল হল আপনার THREE.js ইউনিফর্মে আপনি এটিতে শেডার পাঠাতে পারেন এভাবে:

var galacticShaderMaterial = new THREE.ShaderMaterial( {
vertexShader: shaderList.galacticstars.vertex,
fragmentShader: shaderList.galacticstars.fragment,
/_..._/
});

আমি সম্ভবত প্রয়োজন.js ব্যবহার করতে পারতাম যদিও এই উদ্দেশ্যে কিছু কোড পুনরায় একত্রিত করার প্রয়োজন ছিল। এই সমাধান, যদিও অনেক সহজ, আমি মনে করি উন্নত করা যেতে পারে, সম্ভবত একটি THREE.js এক্সটেনশন হিসাবেও। আপনার যদি এটি আরও ভাল করার পরামর্শ বা উপায় থাকে তবে দয়া করে আমাকে জানান!

THREE.js এর উপরে CSS টেক্সট লেবেল

আমাদের শেষ প্রজেক্ট, Small Arms Globe-এ, আমি একটি THREE.js দৃশ্যের উপরে পাঠ্য লেবেল তৈরি করার জন্য খেলছি। আমি যে পদ্ধতিটি ব্যবহার করছিলাম সেটির পরম মডেল অবস্থান গণনা করে যেখানে আমি টেক্সটটি দেখাতে চাই, তারপরে THREE.Projector() ব্যবহার করে স্ক্রীনের অবস্থানের সমাধান করে এবং অবশেষে CSS উপাদানগুলিকে পছন্দসই স্থানে রাখতে CSS "top" এবং "left" ব্যবহার করে অবস্থান

এই প্রকল্পের প্রাথমিক পুনরাবৃত্তি এই একই কৌশল ব্যবহার করেছিল, তবে আমি লুইস ক্রুজ দ্বারা বর্ণিত এই অন্য পদ্ধতিটি চেষ্টা করার জন্য চুলকানি করছি।

মূল ধারণা: CSS3D-এর ম্যাট্রিক্স রূপান্তরকে থ্রি-এর ক্যামেরা এবং দৃশ্যের সাথে মিলিয়ে নিন এবং আপনি 3D-তে CSS উপাদানগুলিকে "স্থাপন" করতে পারেন যেন এটি থ্রি-এর দৃশ্যের উপরে। যদিও এর সীমাবদ্ধতা রয়েছে, উদাহরণস্বরূপ আপনি একটি THREE.js অবজেক্টের নীচে পাঠ্য রাখতে পারবেন না। এটি এখনও "শীর্ষ" এবং "বাম" CSS বৈশিষ্ট্যগুলি ব্যবহার করে লেআউট সম্পাদন করার চেষ্টা করার চেয়ে অনেক দ্রুত।

টেক্সট লেবেল।
WebGL এর উপরে পাঠ্য লেবেল স্থাপন করতে CSS3D রূপান্তর ব্যবহার করে।

আপনি এখানে এর জন্য ডেমো (এবং ভিউ সোর্সে কোড) খুঁজে পেতে পারেন। যাইহোক আমি খুঁজে পেয়েছি যে ম্যাট্রিক্স অর্ডারটি THREE.js এর জন্য পরিবর্তিত হয়েছে। আমি যে ফাংশন আপডেট করেছি:

/_ Fixes the difference between WebGL coordinates to CSS coordinates _/
function toCSSMatrix(threeMat4, b) {
var a = threeMat4, f;
if (b) {
f = [
a.elements[0], -a.elements[1], a.elements[2], a.elements[3],
a.elements[4], -a.elements[5], a.elements[6], a.elements[7],
a.elements[8], -a.elements[9], a.elements[10], a.elements[11],
a.elements[12], -a.elements[13], a.elements[14], a.elements[15]
];
} else {
f = [
a.elements[0], a.elements[1], a.elements[2], a.elements[3],
a.elements[4], a.elements[5], a.elements[6], a.elements[7],
a.elements[8], a.elements[9], a.elements[10], a.elements[11],
a.elements[12], a.elements[13], a.elements[14], a.elements[15]
];
}
for (var e in f) {
f[e] = epsilon(f[e]);
}
return "matrix3d(" + f.join(",") + ")";
}

যেহেতু সবকিছু রূপান্তরিত হয়েছে, পাঠ্যটি আর ক্যামেরার মুখোমুখি হবে না। সমাধানটি ছিল THREE.Gyroscope() ব্যবহার করা যা একটি Object3D কে দৃশ্য থেকে তার উত্তরাধিকারসূত্রে প্রাপ্ত অভিযোজন "হারাতে" বাধ্য করে। এই কৌশলটিকে "বিলবোর্ডিং" বলা হয়, এবং গাইরোস্কোপ এটি করার জন্য উপযুক্ত।

যেটা সত্যিই চমৎকার তা হল যে সমস্ত সাধারণ DOM এবং CSS এখনও বাজানো হয়, যেমন একটি 3D টেক্সট লেবেল মাউস-ওভার করতে সক্ষম হওয়া এবং ড্রপ শ্যাডোর সাথে এটিকে উজ্জ্বল করা।

টেক্সট লেবেল।
টেক্সট লেবেলগুলি সবসময় ক্যামেরার মুখোমুখি একটি 3.Gyroscope() এর সাথে সংযুক্ত করে।

জুম ইন করার সময় আমি দেখতে পেলাম টাইপোগ্রাফির স্কেলিং পজিশনিং নিয়ে সমস্যা সৃষ্টি করছে। সম্ভবত এটি পাঠ্যের কার্নিং এবং প্যাডিংয়ের কারণে? আরেকটি সমস্যা ছিল যে টেক্সটটি জুম ইন করার সময় পিক্সেলেট হয়ে যায় যেহেতু DOM রেন্ডারার রেন্ডার করা টেক্সটকে টেক্সচারড কোয়াড হিসেবে বিবেচনা করে, এই পদ্ধতিটি ব্যবহার করার সময় সচেতন হতে হবে। পশ্চাদপসরণে, আমি শুধু বিশাল ফন্ট-আকারের পাঠ্য ব্যবহার করতে পারতাম, এবং সম্ভবত এটি ভবিষ্যতের অন্বেষণের জন্য কিছু। এই প্রকল্পে আমি সৌরজগতের গ্রহগুলির সাথে থাকা সত্যিই ছোট উপাদানগুলির জন্য "শীর্ষ/বাম" CSS প্লেসমেন্ট টেক্সট লেবেলগুলি ব্যবহার করেছি, যা আগে বর্ণিত হয়েছে।

সঙ্গীত প্লেব্যাক এবং লুপিং

ম্যাস ইফেক্টের 'গ্যালাকটিক ম্যাপ'-এর সময় বায়োওয়্যার সুরকার স্যাম হুলিক এবং জ্যাক ওয়ালের সঙ্গীতের টুকরোটি বাজানো হয়েছিল এবং এতে আমি দর্শকদের অভিজ্ঞতা পেতে চেয়েছিলাম। আমরা আমাদের প্রকল্পে কিছু সঙ্গীত চেয়েছিলাম কারণ আমরা অনুভব করেছি যে এটি বায়ুমণ্ডলের একটি গুরুত্বপূর্ণ অংশ, যা আমরা লক্ষ্য করার চেষ্টা করছি সেই বিস্ময় এবং বিস্ময়ের অনুভূতি তৈরি করতে সহায়তা করে।

আমাদের প্রযোজক Valdean Klump স্যাম-এর সাথে যোগাযোগ করেছিলেন যার কাছে Mass Effect থেকে "কাটিং ফ্লোর" মিউজিকের একটি গুচ্ছ ছিল যা তিনি খুব করুণার সাথে আমাদের ব্যবহার করতে দিয়েছেন। ট্র্যাকটির নাম ‘ইন এ স্ট্রেঞ্জ ল্যান্ড’।

আমি সঙ্গীত প্লেব্যাকের জন্য অডিও ট্যাগ ব্যবহার করেছি, যদিও ক্রোমেও "লুপ" বৈশিষ্ট্যটি অবিশ্বস্ত ছিল -- কখনও কখনও এটি লুপ করতে ব্যর্থ হবে৷ শেষ পর্যন্ত এই ডুয়াল অডিও ট্যাগ হ্যাকটি প্লেব্যাকের সমাপ্তি পরীক্ষা করতে এবং খেলার জন্য অন্য ট্যাগে সাইকেল চালানোর জন্য ব্যবহার করা হয়েছিল। যা হতাশাজনক ছিল তা হল যে এটি এখনও সব সময় পুরোপুরি লুপ ছিল না, হায় আমার মনে হয় এটিই আমার পক্ষে করা সেরা ছিল।

var musicA = document.getElementById('bgmusicA');
var musicB = document.getElementById('bgmusicB');
musicA.addEventListener('ended', function(){
this.currentTime = 0;
this.pause();
var playB = function(){
musicB.play();
}
// make it wait 15 seconds before playing again
setTimeout( playB, 15000 );
}, false);

musicB.addEventListener('ended', function(){
this.currentTime = 0;
this.pause();
var playA = function(){
musicA.play();
}
// otherwise the music will drive you insane
setTimeout( playA, 15000 );
}, false);

// okay so there's a bit of code redundancy, I admit it
musicA.play();

উন্নতির জন্য রুম

কিছুক্ষণের জন্য THREE.js এর সাথে কাজ করার পরে, আমি মনে করি আমি এমন জায়গায় পৌঁছেছি যেখানে আমার ডেটা আমার কোডের সাথে খুব বেশি মিশ্রিত হয়েছিল। উদাহরণস্বরূপ উপকরণ, টেক্সচার এবং জ্যামিতি নির্দেশাবলী ইন-লাইনে সংজ্ঞায়িত করার সময়, আমি মূলত "কোড সহ 3D মডেলিং" ছিলাম। এটি সত্যিই খারাপ অনুভূত হয়েছে, এবং এটি এমন একটি ক্ষেত্র যেখানে THREE.js এর সাথে ভবিষ্যতের প্রচেষ্টাগুলি ব্যাপকভাবে উন্নতি করতে পারে, উদাহরণস্বরূপ একটি পৃথক ফাইলে উপাদান ডেটা সংজ্ঞায়িত করা, বিশেষভাবে দর্শনযোগ্য এবং কিছু প্রসঙ্গে পরিবর্তনযোগ্য, এবং মূল প্রকল্পে ফিরিয়ে আনা যেতে পারে৷

আমাদের সহকর্মী রে ম্যাকক্লুরও কিছু দুর্দান্ত জেনারেটিভ "স্পেস নয়েজ" তৈরিতে কিছু সময় ব্যয় করেছেন যা ওয়েব অডিও API অস্থির হওয়ার কারণে, প্রায়ই Chrome ক্র্যাশ করে কাটতে হয়েছিল৷ এটা দুর্ভাগ্যজনক… কিন্তু এটা অবশ্যই আমাদের ভবিষ্যতের কাজের জন্য সাউন্ড স্পেসে আরও চিন্তা করতে বাধ্য করেছে। এই লেখার সময় আমাকে জানানো হয়েছে যে ওয়েব অডিও এপিআই প্যাচ করা হয়েছে তাই এটা সম্ভব যে এটি এখন কাজ করছে, ভবিষ্যতে দেখার জন্য কিছু।

WebGL এর সাথে যুক্ত টাইপোগ্রাফিক উপাদানগুলি এখনও একটি চ্যালেঞ্জ হিসাবে রয়ে গেছে, এবং আমি 100% নিশ্চিত নই যে আমরা এখানে যা করছি তা সঠিক উপায়। এটা এখনও একটি হ্যাক মত মনে হয়. সম্ভবত থ্রি-এর ভবিষ্যৎ সংস্করণ, এর আপ এবং আসন্ন CSS রেন্ডারার সহ, দুটি জগতে আরও ভালভাবে যোগদানের জন্য ব্যবহার করা যেতে পারে।

ক্রেডিট

এই প্রকল্পের সাথে আমাকে শহরে যেতে দেওয়ার জন্য অ্যারন কোবলিনকে ধন্যবাদ। চমৎকার UI ডিজাইন + বাস্তবায়ন, টাইপ ট্রিটমেন্ট এবং ট্যুর বাস্তবায়নের জন্য জোনো ব্র্যান্ডেল। প্রকল্পের একটি নাম এবং সমস্ত অনুলিপি দেওয়ার জন্য Valdean Klump. সাবাহ আহমেদ ডেটা এবং ইমেজ উত্সগুলির জন্য মেট্রিক টন ব্যবহারের অধিকারগুলি সাফ করার জন্য। প্রকাশনার জন্য সঠিক লোকেদের কাছে পৌঁছানোর জন্য ক্লেম রাইট। প্রযুক্তিগত শ্রেষ্ঠত্বের জন্য ডগ ফ্রিটজ। আমাকে JS এবং CSS শেখানোর জন্য জর্জ ব্রাউয়ার। এবং অবশ্যই জনাব Doob THREE.js এর জন্য।

তথ্যসূত্র