সম্প্রতি আমি এমন একটি গেমের সাথে কাজ শুরু করেছি যা প্রক্রিয়াগতভাবে উত্পন্ন সৌরজগতে ঘটে। কিছুটা শেখার বক্ররেখার পরে (স্ক্যালা, ওপেনজিএল 2 ইএস বা লিবিগডিএক্স এর আগে কখনও কাজ করেনি), আমার একটি বেসিক টেক ডেমো রয়েছে যেখানে আপনি একক পদ্ধতিগতভাবে টেক্সচার্ড গ্রহের চারদিকে ঘুরবেন:
আমি যে সমস্যাটির মধ্যে যাচ্ছি তা হ'ল টেক্সচার জেনারেশনের অভিনয়। আমি কী করছি তার একটি দ্রুত সংক্ষিপ্ত বিবরণ: একটি গ্রহ একটি ঘনক যা গোলককে বিকৃত করা হয়েছে। প্রতিটি পক্ষেই, অ্যাসেন (উদাহরণস্বরূপ 256 x 256) টেক্সচার প্রয়োগ করা হয়, যা এক 8n এক্সএন টেক্সচারে বান্ডিল করা হয় যা টুকরা শেডারে প্রেরণ করা হয়। শেষ দুটি স্পেস ব্যবহার করা হয়নি, তারা কেবল প্রস্থের 2 পাওয়ার শক্তি তা নিশ্চিত করার জন্য সেখানে রয়েছে তবে বর্তমানে টেক্সচারটি সিপিইউতে তৈরি হয়েছে, কাগজে লিঙ্কযুক্ত সিমপ্লেক্স শোর অ্যালগরিদমের হালনাগাদ 2012 সংস্করণ ব্যবহার করে Simp শব্দ নষ্ট '। আমি যে দৃশ্যটি অ্যালগরিদম পরীক্ষা করতে ব্যবহার করছি তাতে দুটি ক্ষেত্র রয়েছে: গ্রহ এবং পটভূমি। উভয়ই থ্রিডি সিমপ্লেক্স শব্দের ছয়টি অষ্টভর সমন্বয়ে একটি গ্রেস্কেল টেক্সচার ব্যবহার করেন, উদাহরণস্বরূপ যদি আমরা টেক্সচারের আকার হিসাবে 128x128 বেছে নিই তবে শব্দটি ফাংশনে 128 x 128 x 6 x 2 x 6 = প্রায় 1.2 মিলিয়ন কল রয়েছে।
আপনি গ্রহের নিকটে সবচেয়ে কাছাকাছি যা স্ক্রিনশটটিতে দেখানো হয়েছে সে সম্পর্কে এবং যেহেতু গেমটির লক্ষ্য রেজোলিউশন 1280x720, এর অর্থ আমি 512x512 টেক্সচার ব্যবহার করতে পছন্দ করব। একত্রিত করুন যে প্রকৃত টেক্সচার অবশ্যই বেসিক শব্দের চেয়ে আরও জটিল হবে (একটি দিন এবং রাতের টেক্সচার থাকবে, সূর্যের আলোর উপর ভিত্তি করে খন্ডের শেডারে মিশ্রিত হবে। , মেঘ, নগর আলো, ইত্যাদি) এবং আমরা 512 x 512 x 6 x 3 x 15 = 70 মিলিয়ন শোনার কলটির মতো একাকী গ্রহের জন্য চাই। চূড়ান্ত গেমটিতে, গ্রহগুলির মধ্যে ভ্রমণ করার সময় ক্রিয়াকলাপ হবে, সুতরাং 5 বা 10 সেকেন্ডের অপেক্ষা, সম্ভবত 20, গ্রহণযোগ্য হবে কারণ ভ্রমণের সময় আমি পটভূমিতে টেক্সচারটি গণনা করতে পারি, যদিও স্পষ্টতই তত দ্রুততর।
আমাদের পরীক্ষার দৃশ্যে ফিরে আসার জন্য, আমার পিসিতে পারফরম্যান্স খুব ভয়ঙ্কর নয়, যদিও চূড়ান্ত ফলাফলটি বিবেচনা করে খুব ধীর গতিতে প্রায় times০ গুণ খারাপ হতে চলেছে:
128x128 : 0.1s
256x256 : 0.4s
512x512 : 1.7s
এটি আমি সমস্ত পারফরম্যান্স-সমালোচনামূলক কোডটি জাভাতে স্থানান্তরিত করার পরে, যেহেতু স্কালায় এটি করার চেষ্টা করা ছিল আরও খারাপ। এটি আমার ফোনে চালানো (একটি স্যামসং গ্যালাক্সি এস 3) তবে আরও সমস্যাযুক্ত ফলাফল আনবে:
128x128 : 2s
256x256 : 7s
512x512 : 29s
ইতিমধ্যে অনেক দীর্ঘ, এবং এটি এমনকি চূড়ান্ত সংস্করণে কয়েক সেকেন্ডের পরিবর্তে কয়েক মিনিট হবে এই সত্যটি প্রমাণ করে না। স্পষ্টতই কিছু করা দরকার। ব্যক্তিগতভাবে, আমি কয়েকটি সম্ভাব্য উপায় দেখছি, যদিও আমি এখনও তাদের কোনওটির জন্য বিশেষভাবে আগ্রহী নই:
- টেক্সচারগুলি প্রাক্কলকুলেট করবেন না, তবে খণ্ডের শেডারকে সমস্ত কিছু গণনা করতে দিন। সম্ভবত সম্ভাব্য নয়, কারণ এক পর্যায়ে আমার পিক্সেল শেডার সহ পূর্ণস্ক্রিন কোয়াড হিসাবে ব্যাকগ্রাউন্ড ছিল এবং আমি আমার ফোনে প্রায় 1 এফপিএস পেয়েছিলাম।
- টেক্সচারটি একবার রেন্ডার করতে জিপিইউ ব্যবহার করুন, এটি সংরক্ষণ করুন এবং তারপর থেকে সঞ্চিত টেক্সচারটি ব্যবহার করুন। উপরিভাগ: জিপিইউ ভাসমান পয়েন্ট গণনার ক্ষেত্রে দ্রুত হওয়ার কথা বলে সিপিইউতে এটি করার চেয়ে দ্রুত হতে পারে। ডাউনসাইড: প্রভাবগুলি (সহজেই) সিমপ্লেক্স শব্দের কার্যকারিতা হিসাবে প্রকাশ করা যায় না (যেমন গ্যাস গ্রহের ভেরটিসস, মুন ক্রেটার্স ইত্যাদি) স্কেলা / জাভার চেয়ে জিএলএসএল কোড করা আরও অনেক কঠিন।
- প্রচুর পরিমাণে শব্দের টেক্সচার গণনা করুন এবং অ্যাপ্লিকেশন সহ তাদের শিপ করুন। আমি যদি সম্ভব হয় তবে এড়াতে চাই।
- রেজোলিউশন কমিয়ে দিন। আমাকে একটি 4x পারফরম্যান্স লাভ কিনে, যা সত্যই যথেষ্ট নয় প্লাস আমি অনেক গুণমান হারাতে পারি।
- একটি দ্রুত শব্দ অ্যালগরিদম খুঁজুন। কারও যদি এটি থাকে তবে আমি সব কান, তবে সিম্পলেক্সের ইতিমধ্যে পার্লিনের চেয়ে দ্রুত হওয়া উচিত।
- কম রেজোলিউশন টেক্সচার এবং কম গোলমাল অক্টেভের জন্য মঞ্জুরি দিয়ে পিক্সেল আর্ট স্টাইলটি গ্রহণ করুন। আমি মূলত এই স্টাইলটিতে গেমটি কল্পনা করার সময়, আমি বাস্তববাদী পদ্ধতির পছন্দ করতে এসেছি।
- আমি কিছু ভুল করছি এবং পারফরম্যান্সটি ইতিমধ্যে এক বা দুটি আদেশের চেয়ে ভাল হওয়া উচিত। যদি এটি হয় তবে দয়া করে আমাকে জানান।
কারও কাছে যদি এই সমস্যা সম্পর্কিত কোনও পরামর্শ, টিপস, কর্মক্ষেত্র বা অন্য মন্তব্য থাকে তবে আমি সেগুলি শুনতে পছন্দ করব।
লেওরিকের প্রতিক্রিয়া হিসাবে, আমি যে কোডটি ব্যবহার করছি তা এখানে:
//The function that generates the simplex noise texture
public static Texture simplex(int size) {
byte[] data = new byte[size * size * columns * 4];
int offset = 0;
for (int y = 0; y < size; y++) {
for (int s = 0; s < columns; s++) {
for (int x = 0; x < size; x++) {
//Scale x and y to [-1,1] range
double tx = ((double)x / (size - 1)) * 2 - 1;
double ty = 1 - ((double)y / (size - 1)) * 2;
//Determine point on cube in worldspace
double cx = 0, cy = 0, cz = 0;
if (s == 0) { cx = 1; cy = tx; cz = ty; }
else if (s == 1) { cx = -tx; cy = 1; cz = ty; }
else if (s == 2) { cx = - 1; cy = -tx; cz = ty; }
else if (s == 3) { cx = tx; cy = - 1; cz = ty; }
else if (s == 4) { cx = -ty; cy = tx; cz = 1; }
else if (s == 5) { cx = ty; cy = tx; cz = - 1; }
//Determine point on sphere in worldspace
double sx = cx * Math.sqrt(1 - cy*cy/2 - cz*cz/2 + cy*cy*cz*cz/3);
double sy = cy * Math.sqrt(1 - cz*cz/2 - cx*cx/2 + cz*cz*cx*cx/3);
double sz = cz * Math.sqrt(1 - cx*cx/2 - cy*cy/2 + cx*cx*cy*cy/3);
//Generate 6 octaves of noise
float gray = (float)(SimplexNoise.fbm(6, sx, sy, sz, 8) / 2 + 0.5);
//Set components of the current pixel
data[offset ] = (byte)(gray * 255);
data[offset + 1] = (byte)(gray * 255);
data[offset + 2] = (byte)(gray * 255);
data[offset + 3] = (byte)(255);
//Move to the next pixel
offset += 4;
}
}
}
Pixmap pixmap = new Pixmap(columns * size, size, Pixmap.Format.RGBA8888);
pixmap.getPixels().put(data).position(0);
Texture texture = new Texture(pixmap, true);
texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
return texture;
}
//SimplexNoise.fbm
//The noise function is the same one found in http://webstaff.itn.liu.se/~stegu/simplexnoise/SimplexNoise.java
//the only modification being that I replaced the 32 in the last line with 16 in order to end up with
//noise in the range [-0.5, 0.5] instead of [-1,1]
public static double fbm(int octaves, double x, double y, double z, double frequency) {
double value = 0;
double f = frequency;
double amp = 1;
for (int i = 0; i < octaves; i++) {
value += noise(x*f, y*f, z*f) * amp;
f *= 2;
amp /= 2;
}
return value;
}