আমি কীভাবে একটি মাইনক্রাফ্ট-এস্কো ভক্সেল বিশ্বকে অনুকূল করতে পারি?


76

আমি মাইনক্রাফ্টের অসাধারণ বিশাল পৃথিবী নেভিগেট করতে অত্যন্ত ধীর পেয়েছি, এমনকি একটি কোয়াড কোর এবং মাংসযুক্ত গ্রাফিক্স কার্ড সহ।

আমি ধরে নিচ্ছি মাইনক্রাফ্টের স্বচ্ছলতা এসেছে:

  • জাভা, যেমন স্থানীয় পার্টিশন এবং মেমরি পরিচালনা স্থানীয় সি ++ তে দ্রুত হয়।
  • দুর্বল বিশ্ব বিভাজন।

আমি উভয় অনুমান ভুল হতে পারে। যাইহোক, এটি আমাকে বড় ভক্সেল ওয়ার্ল্ডগুলি পরিচালনা করার সর্বোত্তম উপায় সম্পর্কে ভাবতে বাধ্য করেছে। এটি একটি সত্যিকারের 3-ডি বিশ্ব, যেখানে একটি ব্লক পৃথিবীর যে কোন প্রান্তে মধ্যে উপস্থিত পারে, এটা মূলত একটি বড় 3D অ্যারে [x][y][z], যেখানে বিশ্বের প্রতিটি ব্লক একটি টাইপ আছে (অর্থাত BlockType.Empty = 0, BlockType.Dirt = 1ইত্যাদি)

আমি ধরে নিয়েছি যে এই ধরণের বিশ্বকে ভাল পারফর্ম করার জন্য আপনার প্রয়োজন হবে:

  • সমস্ত কিউবগুলি বিভক্ত করার জন্য কিছু জাতের ( অক্ট / কেডি / বিএসপি ) গাছ ব্যবহার করুন ; দেখে মনে হচ্ছে একটি অক্ট / কেডি ভাল বিকল্প হবে, আপনি কেবল প্রতি কিউব স্তরে পার্টিশন করতে পারবেন না প্রতি ত্রিভুজ স্তর হিসাবে।
  • কোন ব্লকটি বর্তমানে দেখা যায় তা নিয়ে কাজ করার জন্য কিছু অ্যালগরিদম ব্যবহার করুন কারণ ব্যবহারকারীর নিকটবর্তী ব্লকগুলি ব্লকগুলি পিছনে পিছনে ফেলে দিতে পারে, যাতে এগুলি রেন্ডার করা অর্থহীন হয়ে পড়ে।
  • ব্লক অবজেক্টটি নিজেরাই হালকা করে রাখুন, তাই গাছগুলি থেকে এগুলি যুক্ত এবং সরিয়ে ফেলা দ্রুত is

আমি অনুমান করি এর সঠিক কোনও উত্তর নেই তবে আমি এই বিষয়ে মানুষের মতামত দেখতে আগ্রহী হব। একটি বৃহত ভক্সেল ভিত্তিক বিশ্বে আপনি কীভাবে পারফরম্যান্সকে উন্নত করবেন?



2
তাহলে আপনি আসলে কি জিজ্ঞাসা করছেন? আপনি কি বিশাল বিশ্ব পরিচালনার জন্য ভাল পদ্ধতির জন্য জিজ্ঞাসা করছেন, বা আপনার নির্দিষ্ট পদ্ধতির বিষয়ে মতামত, বা বৃহত বিশ্ব পরিচালনার বিষয়ে মতামত জিজ্ঞাসা করছেন?
ডপপেলগ্রিনিয়ার

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

2
সুতরাং পরিষ্কার হয়ে যান এবং আপনার পোস্টে একটি প্রশ্ন যুক্ত করুন যাতে আমরা জানি যে আমরা কী প্রশ্নের উত্তর দিচ্ছি। ;)
ডপপেলগ্র্রিনার

3
"চলাচল করতে অত্যন্ত ধীর" বলতে কী বোঝায়? গেমটি নতুন ভূখণ্ড তৈরি করলে অবশ্যই কিছুটা ধীর গতি রয়েছে, তবে এর পরে, মাইনক্রাফ্ট ভূখণ্ডটি বেশ ভালভাবে পরিচালনা করে handle
দাদিয়ান

উত্তর:


107

ভক্সেল ইঞ্জিন রকস

ভক্সেল ইঞ্জিন ঘাস

জাভা বনাম সি ++ এর সাথে আমি উভয়টিতে ভক্সেল ইঞ্জিন লিখেছি (উপরে দেখানো সি ++ সংস্করণ)। আমি ২০০৪ সাল থেকে ভোক্সেল ইঞ্জিনগুলিও লিখছি (যখন তারা প্রচলিত ছিল না)। :) আমি কিছুটা দ্বিধায় বলতে পারি যে সি ++ পারফরম্যান্স অনেক উচ্চতর (তবে কোড করাও এটি আরও কঠিন)। এটি গণনার গতি সম্পর্কে কম এবং মেমরি পরিচালনা সম্পর্কে আরও কম। হ্যান্ডস ডাউন, যখন আপনি কোনও ভক্সেল জগতের যতটুকু ডেটা বরাদ্দ / অবনতি করছেন, তখন সি (++) হ'ল ভাষা হ'ল। যাহোকআপনার লক্ষ্য সম্পর্কে চিন্তা করা উচিত। পারফরম্যান্স যদি আপনার সর্বোচ্চ অগ্রাধিকার হয় তবে সি ++ সহ যান। যদি আপনি কেবল রক্তক্ষরণ প্রবাহের পারফরম্যান্স ছাড়াই কোনও গেম লিখতে চান তবে জাভা অবশ্যই গ্রহণযোগ্য (মিনেক্রাফ্ট দ্বারা প্রমাণিত)। অনেকগুলি তুচ্ছ / প্রান্তযুক্ত মামলা রয়েছে তবে সাধারণভাবে আপনি জাভা প্রায় ভাল লেগেছে (ভাল লেখা) সি ++ এর চেয়ে প্রায় 1.75-2.0 গুণ কম চালাতে পারবেন বলে আশা করতে পারেন। আপনি এখানে আমার ইঞ্জিনটির দুর্বলতর অনুকূলিত, পুরানো সংস্করণটি দেখতে পাচ্ছেন (সম্পাদনা: এখানে নতুন সংস্করণ )। খণ্ড জেনারেশনটি ধীর মনে হতে পারে, তবে মনে রাখবেন এটি সিপিইউতে ব্রুট-ফোর্স পদ্ধতিতে পৃষ্ঠের নরমালগুলি, আলোকসজ্জা, এও এবং ছায়াগুলি গণনা করে 3 ডি ভোরোনাই চিত্রগুলি তৈরি করছে। আমি বিভিন্ন কৌশল চেষ্টা করে দেখেছি এবং বিভিন্ন ক্যাচিং এবং ইনস্ট্যান্সিং কৌশল ব্যবহার করে আমি প্রায় 100x দ্রুত ছাঁটাই উত্পাদন করতে পারি।

আপনার বাকী প্রশ্নের উত্তর দেওয়ার জন্য, কর্মক্ষমতা উন্নত করতে আপনি করতে পারেন এমন অনেকগুলি জিনিস রয়েছে।

  1. ক্যাশিং। আপনি যেখানেই পারেন, আপনার একবার ডেটা গণনা করা উচিত। উদাহরণস্বরূপ, আমি দৃশ্যে আলোকে বেক করি। এটি গতিশীল আলো ব্যবহার করতে পারে (স্ক্রিন স্পেসে, পোস্ট-প্রসেস হিসাবে), তবে আলোতে বেকিংয়ের অর্থ হল যে আমাকে ত্রিভুজগুলির জন্য স্বাভাবিক অবস্থায় যেতে হবে না, যার অর্থ ....
  2. যতটা সম্ভব ভিডিও কার্ডে অল্প ডেটা পাস করুন। লোকেদের একটি জিনিস ভুলে যাওয়ার প্রবণতা হ'ল আপনি জিপিইউতে যত বেশি ডেটা পাস করবেন তত বেশি সময় লাগে। আমি একটি একক রঙ এবং একটি শীর্ষবিন্দু অবস্থানে পাস। আমি যদি দিন / রাত্রি চক্র করতে চাই তবে আমি কেবল রঙিন গ্রেডিং করতে পারি বা সূর্য ধীরে ধীরে পরিবর্তিত হওয়ার সাথে সাথে আমি দৃশ্যের পুনরাবৃত্তি করতে পারি।

  3. যেহেতু জিপিইউতে ডেটা পাস করা এত ব্যয়বহুল, তাই সফ্টওয়্যারটিতে একটি ইঞ্জিন লেখা সম্ভব যা কিছু দিক থেকে দ্রুত is সফ্টওয়্যারটির সুবিধা হ'ল এটি জিপিইউতে সমস্ত ধরণের ডেটা ম্যানিপুলেশন / মেমরি অ্যাক্সেস করতে পারে যা কেবল সম্ভব নয়।

  4. ব্যাচের আকারের সাথে খেলুন। আপনি যদি একটি জিপিইউ ব্যবহার করেন তবে প্রতিটি পার্ফটিক অ্যারে আপনি যে পরিমাণে পাস করেছেন তার উপর ভিত্তি করে পারফরম্যান্স নাটকীয়ভাবে পরিবর্তিত হতে পারে। তদনুসারে, খণ্ডগুলির আকারের সাথে চারপাশে খেলুন (যদি আপনি খণ্ডগুলি ব্যবহার করেন)। আমি পেয়েছি যে 64x64x64 খণ্ডগুলি বেশ ভালভাবে কাজ করে। যাই হোক না কেন, আপনার খণ্ডগুলি কিউবিক রাখুন (কোনও আয়তক্ষেত্রাকার প্রাইম নেই)। এটি কোডিং এবং বিভিন্ন ক্রিয়াকলাপগুলি (যেমন রূপান্তরকরণ) সহজ করে তুলবে এবং কিছু ক্ষেত্রে আরও পারফর্ম্যান্ট। আপনি যদি প্রতিটি মাত্রার দৈর্ঘ্যের জন্য কেবল একটি মান সঞ্চয় করেন তবে গণনা চলাকালীন দুটি কম রেজিস্টার মনে রাখবেন যে চারপাশে অদলবদল হয়।

  5. প্রদর্শন তালিকা বিবেচনা করুন (ওপেনগিএলের জন্য)। যদিও তারা "পুরানো" উপায়, তারা দ্রুত হতে পারে। আপনাকে অবশ্যই একটি প্রদর্শন তালিকাটি একটি চলকতে বেক করতে হবে ... আপনি যদি রিয়েলটাইমে প্রদর্শন তালিকা তৈরির ক্রিয়াকলাপগুলি কল করেন তবে তা ধর্মবিরোধী ধীর হবে। একটি প্রদর্শন তালিকা দ্রুত হয় কিভাবে? এটি কেবলমাত্র রাজ্য আপডেট করে, প্রতি-ভার্টেক্স বৈশিষ্ট্য বনাম। এর অর্থ আমি ছয়টি মুখ পর্যন্ত পাস করতে পারি, তারপরে একটি রঙ (ভক্সেলের প্রতিটি শীর্ষের জন্য একটি রঙ বনাম)। আপনি যদি GL_QUADS এবং কিউবিক ভক্সেল ব্যবহার করে থাকেন তবে এটি ভক্সেলের প্রতি 20 বাইট (160 বিট) পর্যন্ত সাশ্রয় করতে পারে! (কোনও আলফা সহ 15 বাইট, যদিও আপনি সাধারণত 4-বাইট জিনিস প্রান্তিকিত রাখতে চান।)

  6. আমি "খণ্ডগুলি" রেন্ডার করার জন্য একটি হিংস্র শক্তি প্রয়োগ পদ্ধতি বা ডেটা পৃষ্ঠাগুলি ব্যবহার করি যা একটি সাধারণ কৌশল। অক্ট্রিগুলির বিপরীতে, ডেটা পড়া / প্রক্রিয়া করা অনেক সহজ / দ্রুততর, যদিও মেমরির তুলনায় অনেক কম (যদিও এই দিনগুলিতে আপনি ab 200- for 300 ডলারে 64 গিগাবাইট মেমরি পেতে পারেন) ... গড় ব্যবহারকারী যে তা করেন না তা নয়। স্পষ্টতই, আপনি পুরো বিশ্বের জন্য একটি বিশাল অ্যারে বরাদ্দ করতে পারবেন না (ভক্সেলের একটি 1024x1024x1024 সেট 4 গিগাবাইট মেমরি, ভক্সেলের প্রতি 32-বিট ইন্টি ব্যবহার করা হয়েছে বলে ধরে নেওয়া)। সুতরাং আপনি দর্শকের নিকটতার ভিত্তিতে অনেকগুলি ছোট অ্যারে বরাদ্দ / ডিলোক করেন। আপনি ডেটা বরাদ্দ করতে পারেন, প্রয়োজনীয় প্রদর্শন তালিকা পেতে পারেন, তারপরে মেমরি সংরক্ষণ করতে ডেটা ডাম্প করতে পারেন। আমি মনে করি আদর্শ কম্বো হ'ল অষ্টা এবং অ্যারেগুলির একটি হাইব্রিড পদ্ধতির ব্যবহার করা উচিত - বিশ্বের প্রক্রিয়াজাত জেনারেশন, আলোকসজ্জা ইত্যাদি করার সময় একটি অ্যারেতে ডেটা সংরক্ষণ করুন,

  7. কাছাকাছি রেন্ডার করুন ... একটি পিক্সেল ক্লিপ করা সময় সাশ্রয় হয়। ডিপিং বাফার পরীক্ষায় পাস না করলে জিপিইউ একটি পিক্সেল টস করবে।

  8. ভিউপোর্টে কেবল খণ্ডগুলি / পৃষ্ঠাগুলি রেন্ডার করুন (স্ব বর্ণনামূলক)। এমনকি জিপিইউ ভিউপোর্টের বাইরে পলিগিয়নগুলি কীভাবে ক্লিপ করতে জানে, এই ডেটাটি পাস করতে এখনও সময় লাগে। আমি জানি না এর পক্ষে সবচেয়ে দক্ষ কাঠামোটি কী হবে ("লজ্জাজনকভাবে," আমি কখনই কোনও বিএসপি ট্রি লিখিনি), তবে প্রতি অংশের ভিত্তিতে একটি সাধারণ রাইস্কিস্টও পারফরম্যান্সের উন্নতি করতে পারে এবং দৃশ্যত হতাশার বিরুদ্ধে পরীক্ষা করা অবশ্যই কার্যকর হবে সময় বাঁচাতে.

  9. স্পষ্ট তথ্য, তবে নবাবিদের জন্য: পৃষ্ঠের উপরে নেই এমন একক বহুভুজটি সরিয়ে ফেলুন - অর্থাত্ যদি কোনও ভক্সেলের ছয়টি মুখ থাকে তবে এমন মুখগুলি সরিয়ে ফেলুন যা কখনই রেন্ডার হয় না (অন্য ভক্সেলের সাথে স্পর্শ করছে)।

  10. আপনি প্রোগ্রামিংয়ে যা কিছু করেন তার একটি সাধারণ নিয়ম হিসাবে: স্থানীয়ভাবে ক্যাচ করুন! যদি আপনি জিনিসগুলি ক্যাশে-স্থানীয় রাখতে পারেন (এমনকি অল্প সময়ের জন্যও এটি একটি বিশাল পার্থক্য আনবে This এর অর্থ আপনার ডেটা একত্রিত করা (একই মেমরি অঞ্চলে), এবং মেমরির ক্ষেত্রগুলিকে খুব বেশি সময় প্রক্রিয়াতে স্যুইচ না করা So সুতরাং , আদর্শভাবে, থ্রেড প্রতি এক অংশে কাজ করুন এবং সেই স্মৃতিটি থ্রেডের সাথে একচেটিয়া রাখুন এটি কেবল সিপিইউ ক্যাশে প্রযোজ্য না। -> হার্ড ড্রাইভ (আপনার যদি ইতিমধ্যে একটি না থাকে তবে এসএসডি পান), র‌্যাম (আপনার কাছে ইতিমধ্যে এটি না থাকলে ট্রিপল চ্যানেল বা আরও বেশি র‌্যাম পান), সিপিইউ ক্যাশে (গুলি) নিবন্ধ করুন your আপনার ডেটা চালিয়ে যাওয়ার চেষ্টা করুন শেষেরটি, এবং এটি আপনার নিজের চেয়ে বেশি অদলবদল করবে না।

  11. থ্রেডিং। এটা কর. ভক্সেল ওয়ার্ল্ডস থ্রেডিংয়ের জন্য উপযুক্ত, কারণ প্রতিটি অংশ অন্যদের থেকে স্বতন্ত্রভাবে গণনা করা যায় (বেশিরভাগ) ... আমি কার্যত বিশ্বজুড়ে আক্ষরিক অর্থে -4x উন্নতি (একটি 4 কোর, 8 থ্রেড কোর আই 7) দেখেছি যখন আমি লিখেছিলাম থ্রেডিং জন্য রুটিন।

  12. চর / বাইট ডেটা ধরণের ব্যবহার করবেন না। বা শর্টস। আপনার গড় ভোক্তার কাছে একটি আধুনিক এএমডি বা ইন্টেল প্রসেসর থাকবে (যেমন আপনি সম্ভবত করবেন)। এই প্রসেসরের 8 বিট রেজিস্টার নেই। তারা 32 বিট স্লটে রেখে বাইটগুলি গণনা করে তারপরে স্মৃতিতে ফিরে (সম্ভবত) রূপান্তর করে। আপনার সংকলকটি বিভিন্ন ধরণের ভুডু করতে পারে তবে একটি 32 বা 64 বিট নম্বর ব্যবহার করা আপনাকে সবচেয়ে অনুমানযোগ্য (এবং দ্রুততম) ফলাফল দিতে চলেছে) একইভাবে, একটি "বুল" মান 1 বিট নেয় না; সংকলক প্রায়শই একটি বিলের জন্য একটি পুরো 32 বিট ব্যবহার করবে। আপনার ডেটাতে কিছু ধরণের সংকোচনের জন্য এটি লোভনীয় হতে পারে। উদাহরণস্বরূপ, আপনি 8 টি ভক্সেলগুলিকে একক সংখ্যা হিসাবে (2 ^ 8 = 256 সংমিশ্রণ) সংরক্ষণ করতে পারতেন যদি তারা সমস্ত একই ধরণের / রঙ হয়। যাইহোক, আপনাকে এর কৌশলগুলি সম্পর্কে ভাবতে হবে - এটি মেমরির একটি ভাল চুক্তি সঞ্চয় করতে পারে, তবে এটি কার্যক্ষমতার ক্ষেত্রেও বাধা সৃষ্টি করতে পারে, এমনকি একটি ক্ষুদ্র ক্ষুদ্র সময়ের সাথেও, কারণ এমনকি সামান্য পরিমাণে অতিরিক্ত সময়ের পরিমাণ আপনার বিশ্বের আকারের সাথে ঘনক্ষেত্রে স্কেল করে। একটি রাইস্টের গণনা কল্পনা করুন; রাইকাস্টের প্রতিটি পদক্ষেপের জন্য আপনাকে ডিকম্প্রেশন অ্যালগরিদমটি চালাতে হবে (যদি না আপনি একটি রে পদক্ষেপে 8 টি ভক্সেলের গণনা সাধারণীকরণের স্মার্ট উপায় নিয়ে আসতে পারেন)।

  13. হোসে শ্যাভেজ যেমন উল্লেখ করেছেন, ফ্লাইওয়েট ডিজাইনের ধরণটি কার্যকর হতে পারে। আপনি যেমন 2D গেমের টাইলকে উপস্থাপন করতে একটি বিটম্যাপ ব্যবহার করেন, তেমনি আপনি বেশ কয়েকটি 3D টাইল (বা ব্লক) প্রকারের মাধ্যমে আপনার বিশ্ব তৈরি করতে পারেন। এর নেতিবাচক দিকটি টেক্সচারের পুনরাবৃত্তি, তবে আপনি একত্রিত হয়ে যায় এমন ভেরিয়েন্স টেক্সচার ব্যবহার করে এটিকে আরও প্রশমিত করতে পারেন। থাম্বের নিয়ম হিসাবে, আপনি যেখানেই পারেন তত্ক্ষণাত ব্যবহার করতে চান।

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

  15. আপনার লুপগুলি আনওয়াইন্ড করুন এবং অ্যারে ফ্ল্যাট রাখুন! এটি করবেন না:

    for (i = 0; i < chunkLength; i++) {
     for (j = 0; j < chunkLength; j++) {
      for (k = 0; k < chunkLength; k++) {
       MyData[i][j][k] = newVal;
      }
     }
    }
    //Instead, do this:
    for (i = 0; i < chunkLengthCubed; i++) {
     //figure out x, y, z index of chunk using modulus and div operators on i
     //myData should have chunkLengthCubed number of indices, obviously
     myData[i] = newVal;
    }
    

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

2 সম্পাদনা করুন: মাল্টি-ইনডেক্স লুপগুলি ব্যবহার করার সময়, জেড, ওয়াই, এক্স অর্ডার লুপ করা সর্বোপরি অন্য উপায়ের চেয়ে ভাল। আপনার সংকলক এটি অপ্টিমাইজ করতে পারে, তবে এটি যদি হয় তবে আমি অবাক হব। এটি মেমরি অ্যাক্সেস এবং লোকালটিতে দক্ষতা সর্বাধিক করে তোলে।

for (k < 0; k < volumePitch; k++) {
    for (j = 0; j < volumePitch; j++) {
        for (i = 0; i < volumePitch; i++) {
            myIndex = k*volumePitch*volumePitch + j*volumePitch + i;
        }
    }
}
  1. কখনও কখনও আপনাকে অনুমান, সাধারণীকরণ এবং ত্যাগ স্বীকার করতে হয়। আপনি যে সেরাটি তৈরি করতে পারেন তা হ'ল আপনার পৃথিবীর বেশিরভাগ অংশ সম্পূর্ণ স্থিতিশীল, এবং কেবলমাত্র প্রতিটি দম্পতি হাজার ফ্রেম পরিবর্তন করে। বিশ্বের অ্যানিমেটেড অংশগুলির জন্য, সেগুলি পৃথক পাসে করা যেতে পারে। এছাড়াও ধরে নিন আপনার বিশ্বের বেশিরভাগ অংশ সম্পূর্ণ অস্বচ্ছ। স্বচ্ছ জিনিস পৃথক পাসে রেন্ডার করা যায়। ধরে নিন যে টেক্সচারগুলি কেবলমাত্র প্রতিটি এক্স ইউনিটে পরিবর্তিত হয় বা অবজেক্টগুলি কেবল এক্স ইনক্রিমেন্টে রাখা যেতে পারে। একটি স্থির বিশ্বের আকার ধরে ... একটি অসীম বিশ্বের হিসাবে যেমন লোভনীয়, এটি অনির্দেশ্য সিস্টেমের প্রয়োজনীয়তার দিকে পরিচালিত করতে পারে। উদাহরণস্বরূপ, উপরের শিলাগুলিতে ভোরোনাই প্যাটার্ন প্রজন্মকে সহজ করার জন্য, আমি ধরে নিয়েছি যে প্রতিটি ভোরোনাই কেন্দ্র বিন্দু একটি সামান্য গ্রিডে মিথ্যা বলেছিল, সামান্য অফসেট সহ (অন্য কথায়, জড়িত জ্যামিতিক হ্যাশিং)। এমন একটি পৃথিবী ধরে নিন যা মোড় না দেয় (প্রান্তগুলি রয়েছে)। এটি একটি মোড়ানোর সমন্বয় ব্যবস্থা দ্বারা প্রবর্তিত অনেক জটিলতা সহজতর করতে পারে, ব্যবহারকারীর অভিজ্ঞতার জন্য ন্যূনতম ব্যয়ে।

আপনি আমার সাইটে আমার বাস্তবায়ন সম্পর্কে আরও পড়তে পারেন


9
+1 টি। নিবন্ধ পড়ার জন্য উত্সাহ হিসাবে শীর্ষে ছবি সহ সুন্দর স্পর্শ। এখন যেহেতু আমি প্রবন্ধটি পড়েছি আমি বলতে পারি যে তাদের প্রয়োজন হয়নি এবং এটি মূল্যবান ছিল। ;)
জর্জি ডেকেট

ধন্যবাদ - একটি চিত্র হাজার হাজার শব্দের, যেমন তারা বলে। :) আমার পাঠ্যের প্রাচীরটিকে কম ভয় দেখানো ছাড়াও, আমি বর্ণিত কৌশলগুলি ব্যবহার করে যে কতগুলি ভক্সেল যুক্তিসঙ্গত হারে রেন্ডার করতে পারে তা পাঠকদের একটি ধারণা দিতে চেয়েছিলাম।
গাভান উওলারি

14
আমি এখনও চাই এসই প্রিয় নির্দিষ্ট উত্তরগুলির অনুমতি দেবে।
joltmode

2
@ পেট্রিকমুরিয়ার্টি # 15 একটি দুর্দান্ত সাধারণ কৌশল। ধরে নিচ্ছি যে আপনার সংকলকটি এই অপ্টিমাইজেশনটি তৈরি করে না (এটি আপনার লুপটি আনারোল করতে পারে তবে এটি সম্ভবত বহুমাত্রিক অ্যারেটি সংহত করবে না)। আপনি আপনার সমস্ত ডেটা একই ক্যাচিংয়ের জন্য একই মেমরি স্পেসে রাখতে চান। একটি বহুমাত্রিক অ্যারে (সম্ভাব্যভাবে) অনেকগুলি স্থান জুড়ে বরাদ্দ করা যেতে পারে, কারণ এটি পয়েন্টারের একটি অ্যারে। লুপটি আনرولল করার ক্ষেত্রে, সংকলিত কোডটি কেমন দেখাচ্ছে তা ভাবেন। সর্বনিম্ন নিবন্ধভুক্ত এবং ক্যাশে অদলবদলের জন্য, আপনি সবচেয়ে কম বার / নির্দেশাবলী উত্পাদন করতে চান। আপনি কোনটি আরও বেশি সংকলন করেন বলে মনে করেন?
গাভান উওলারি

2
যদিও এখানে কিছু পয়েন্টগুলি ভাল, বিশেষত ক্যাচিং, থ্রেডিং এবং জিপিইউ স্থানান্তরকে হ্রাস করার ক্ষেত্রে, এর কয়েকটি মারাত্মকভাবে ভুল। 5: সবসময় প্রদর্শন তালিকার পরিবর্তে ভিবিও / ভিএও ব্যবহার করুন। 6: আরও র‌্যামের জন্য আরও বেশি ব্যান্ডউইথ প্রয়োজন। 12 এর দিকে বাড়ে: আধুনিক স্মৃতিতে হুবহু বিপরীতটি সত্য, যার জন্য প্রতিটি বাইট সংরক্ষণ করা আরও বেশি ডেটা ক্যাশে রাখার সম্ভাবনা বাড়িয়ে তোলে। 14: মিনক্রাফ্টে পিক্সেলগুলির চেয়ে আরও বেশি শীর্ষগুলি রয়েছে (যারা সমস্ত দূরত্বের কিউবস) তাই পিক্সেল শেডারটিতে গণনা সরিয়ে নিন, অগ্রণীত স্থিত শেডিংয়ের মাধ্যমে।

7

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

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

আমার আদর্শ ব্যবস্থাটি আরও জটিল জটিল স্তরবিন্যাস হবে।

টাইল একটি একক ইউনিট, সম্ভবত উপাদান টাইপ এবং আলো হিসাবে তথ্য রাখতে প্রায় 4 বাইট।

সেগমেন্ট টাইলস একটি 32x32x32 ব্লক হবে।

  1. পুরো দিকটি শক্ত ব্লক হলে ছয় পক্ষের প্রত্যেকটির জন্য পতাকা সেট করা হবে। এটি রেন্ডারকে সেই বিভাগের পিছনে অংশগুলি অন্তর্ভুক্ত করতে দেয়। মাইনক্রাফ্ট বর্তমানে অন্তর্ভুক্তি পরীক্ষা করার জন্য উপস্থিত হয় না। তবে সেখানে হার্ডওয়্যার অবিচ্ছিন্নতা কুলিং উপলব্ধ থাকার কথা উল্লেখ করা হয়েছিল যা কম-বেশি কার্ডগুলিতে প্রচুর পরিমাণে বহুভুজ সরবরাহ করার চেয়ে ব্যয়বহুল তবে ভাল better
  2. বিভাগগুলি কেবল ক্রিয়াকলাপের সময় স্মৃতিতে লোড করা হবে (প্লেয়ার, এনপিসি, জল পদার্থবিজ্ঞান, গাছের বৃদ্ধি, ইত্যাদি)। অন্যথায় তারা সরাসরি ক্লায়েন্টদের থেকে ডিস্ক থেকে সঙ্কুচিত প্রেরণ করা হবে।

সেক্টর অংশগুলির একটি 16x16x8 ব্লক হবে।

  1. সেক্টরগুলি প্রতিটি উল্লম্ব কলামের জন্য সর্বোচ্চ বিভাগটিকে ট্র্যাক করবে যাতে এর চেয়ে বেশি অংশগুলি খালি নির্ধারণ করা যায়।
  2. এটি নীচের অংশযুক্ত অংশটিও ট্র্যাক করবে, যাতে পৃষ্ঠ থেকে রেন্ডার করা প্রতিটি বিভাগটি দ্রুত ধরে ফেলতে পারে।
  3. সেক্টরগুলি পরের বার প্রতিটি বিভাগকে আপডেট করার দরকার পড়বে (জলের পদার্থবিজ্ঞান, গাছের বৃদ্ধি, ইত্যাদি) track প্রতিটি সেক্টরে এইভাবে লোড করা বিশ্বকে বাঁচিয়ে রাখার জন্য যথেষ্ট হবে এবং কেবলমাত্র সেগমেন্টগুলিতে লোড করা তাদের কাজগুলি সম্পন্ন করার জন্য যথেষ্ট দীর্ঘ।
  4. সেক্টরের তুলনায় সমস্ত সত্তা অবস্থানগুলি ট্র্যাক করা হবে। এটি মানচিত্রের কেন্দ্র থেকে খুব দূরে ভ্রমণ করার সময় মাইনক্রাফ্টে উপস্থিত ভাসমান-পয়েন্ট ত্রুটিগুলি প্রতিরোধ করবে।

বিশ্ব খাতগুলির একটি অসীম মানচিত্র হবে।

  1. বিশ্ব সেক্টর পরিচালনা এবং তাদের পরবর্তী আপডেটের জন্য দায়ী হবে।
  2. বিশ্ব তাদের সম্ভাব্য পথে বরাবর খেলোয়াড়দের জন্য প্রিমিটিভভাবে বিভাগগুলি প্রেরণ করবে। মাইনক্রাফ্ট প্রতিক্রিয়া সহ এমন বিভাগগুলি প্রেরণ করে যা ক্লায়েন্ট অনুরোধ করে, বিলম্বিত করে।

আমি সাধারণত এই পরিকল্পনাটি, কিন্তু কিভাবে আপনি, অভ্যন্তরীণভাবে, সেক্টর ম্যাপ হবে পৃথিবী ?
ক্লাশসফট

বিভাগে টাইলস এবং সেক্টরের বিভাগগুলির জন্য একটি অ্যারের সেরা সমাধান হতে পারে তবে বিশ্বের সেক্টরগুলিতে অসীম মানচিত্রের আকারের জন্য আলাদা কিছু প্রয়োজন হবে। আমার পরামর্শ হ্যাশের জন্য এক্সওয়াই স্থানাঙ্ক ব্যবহার করে একটি হ্যাশ টেবিল (সিউডো অভিধান <ভেক্টর 2, সেক্টর>) ব্যবহার করা হবে। তারপরে বিশ্ব কেবল নির্দিষ্ট স্থানাঙ্কগুলিতে সেক্টর সন্ধান করতে পারে।
জোশ ব্রাউন

6

মাইনক্রাফ্টটি খুব দ্রুত, এমনকি আমার 2-কোরেও। জাভা এখানে কোনও সীমাবদ্ধ ফ্যাক্টর বলে মনে হচ্ছে না, যদিও এখানে কিছুটা সার্ভার লগ রয়েছে। স্থানীয় গেমগুলি আরও ভাল করবে বলে মনে হচ্ছে, তাই আমি সেখানে কিছু অদক্ষতা ধরে নেব।

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

একটি অনুমানের মধ্যে, যেমন আপনি অনুমান করেছেন, অ্যাপটিকে অন্য ব্লক দ্বারা অস্পষ্ট করা হয়েছে কিনা তা অবলম্বন করে কোনও ব্লকটি দেখা যাবে কিনা তা নির্ধারণ করতে হবে।

নোট, এছাড়াও, যে ব্লক FACES রয়েছে তা ধরেই নেওয়া যায় না বলে ধরে নেওয়া যেতে পারে, হয় অস্পষ্ট হওয়ার কারণে (যেমন, অন্য একটি ব্লক মুখটি coversেকে দেয়) বা ক্যামেরাটি নির্দেশ করছে কোন দিক দিয়ে (যদি ক্যামেরা উত্তর দিকে মুখ করে থাকে তবে আপনি করতে পারেন) কোনও ব্লকের উত্তরের মুখ দেখতে পাবে না!)

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

আপনি গতি, উপাত্তের আকার বা কী রেন্ডার করতে চান তা যদি আপনার প্রশ্ন পরিষ্কার হয় না। স্পষ্টকরণ সেখানে সহায়ক হবে।


4
"ক্লাম্পস" এর নামগুলি সাধারণত খণ্ডগুলি হয়।
মার্কো

ভাল ক্যাচ (+1); উত্তর আপডেট হয়েছে। (মূলত মেমরির জন্য করছিলাম, এবং সঠিক শব্দটি ভুলে গিয়েছিলেন))
অলি

আপনি যে অদক্ষতাগুলি উল্লেখ করেন সেগুলি "নেটওয়ার্ক" নামেও পরিচিত, এটি একইভাবে শেষ পয়েন্টগুলি যোগাযোগ করেও কখনও কখনও একইভাবে দু'বার কার্যকরভাবে কাজ করে না।
এডউইন বাক

4

এখানে সাধারণ তথ্য এবং পরামর্শের মাত্র কয়েকটি শব্দ দেওয়া আছে, যা আমি একজন, ওম, অতিরিক্ত অভিজ্ঞ মাইনক্রাফ্ট মডডার হিসাবে দিতে পারি (যা কমপক্ষে আপনাকে কিছু দিকনির্দেশনা দিতে পারে))

মাইনক্রাফ্ট ধীর হওয়ার কারণটিতে কিছু প্রশ্নবিদ্ধ, নিম্ন-স্তরের ডিজাইনের সিদ্ধান্তগুলির সাথে প্রচুর সম্পর্ক রয়েছে - উদাহরণস্বরূপ, প্রতিবার কোনও ব্লককে পজিশনিং দ্বারা রেফারেন্স করা হলে, গেমটি প্রায় 7 দিয়ে স্থানাঙ্কগুলিকে বৈধ করে তোলে তা নিশ্চিত করার জন্য যদি বিবৃতি সীমাবদ্ধ না হয় ensure । তদুপরি, কোনও 'অংশ' ধরার কোনও উপায় নেই (গেমটি ব্লকগুলির সাথে কাজ করে এমন একটি 16x16x256 ইউনিট) তারপরে রেফারেন্স ব্লকগুলিতে সরাসরি ক্যাশে লুকআপগুলি এবং, এর্ম, মূর্খতা বৈধতা সম্পর্কিত সমস্যাগুলি (যেমন প্রতিটি ব্লকের রেফারেন্সের সাথে জড়িত থাকে) অন্যান্য জিনিসগুলির মধ্যে একটি খণ্ডন অনুসন্ধান)) আমার মোডে, আমি সরাসরি ব্লকের অ্যারে ধরার এবং পরিবর্তন করার একটি উপায় তৈরি করেছি, যা প্রচুর অন্ধকার জেনারেশনকে অপ্রাপ্যভাবে পিছনে থেকে অদৃশ্যভাবে দ্রুত বাড়িয়ে তোলে।

সম্পাদনা: দাবী সরানো হয়েছে যে ভিন্ন স্কোয়ারে ভেরিয়েবল ঘোষণার ফলে পারফরম্যান্স লাভ হয়েছিল, এটি আসলে তেমনটি দেখা যায় না। আমি এই সময়ে বিশ্বাস করি যে আমি এই ফলাফলটির সাথে অন্য কিছু পরীক্ষা করছিলাম যা (বিশেষত, দ্বৈত এবং একীকরণের মাধ্যমে বিস্ফোরণ সম্পর্কিত কোডে ডাবলস এবং ভাসমানদের মধ্যে ক্যাসট সরিয়ে ডাবলকে একীকরণ করে ... বোধগম্য, এর বিশাল প্রভাব পড়েছিল!)

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

সুতরাং আপনি যে ভাষা চয়ন করুন, বাস্তবায়ন / নিম্ন স্তরের বিশদগুলির সাথে খুব ঘনিষ্ঠ হওয়ার চেষ্টা করুন, কারণ এটির মতো কোনও প্রকল্পের একটি ছোট্ট বিবরণও সমস্ত পার্থক্য আনতে পারে (সি ++ এ আমার জন্য একটি উদাহরণ "সংকলকটি কি স্ট্যাটিকভাবে ইনলাইন ফাংশন করতে পারে? পয়েন্টার? "হ্যাঁ এটি হতে পারে! আমি যে প্রকল্পে কাজ করছিলাম তার মধ্যে একটিতে অবিশ্বাস্য তফাত তৈরি করেছে, যেহেতু আমার কোড কম ছিল এবং ইনলাইন করার সুবিধা ছিল)"

আমি উত্তরটি সত্যিই অপছন্দ করি কারণ এটি উচ্চ-স্তরের নকশাটিকে কঠিন করে তোলে তবে পারফরম্যান্স যদি উদ্বেগজনক হয় তবে এটি বেদনাদায়ক সত্য। আশা করি আপনি এই সহায়ক খুঁজে পেয়েছেন!

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


2

জিনিসটি আপনাকে প্রথমে কীভাবে ডেটা লোড করবে সে সম্পর্কে ভাবতে হবে। আপনি যখন প্রয়োজন হয় তখন নিজের মানচিত্রের ডেটা মেমরিতে প্রবাহিত করেন, আপনি যা রেন্ডার করতে পারেন তার একটি প্রাকৃতিক সীমা রয়েছে, এটি ইতিমধ্যে একটি রেন্ডারিং পারফরম্যান্স আপগ্রেড।

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

আপনি যদি কেবল গ্রাফিক্স পারফরম্যান্স কৌশলগুলি সন্ধান করছেন তবে আমি নিশ্চিত যে আপনি নেটে জিনিসপত্রের পর্বতগুলি খুঁজে পেতে পারেন।


1

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

আমি জানি না যে মাইনক্রাফ্ট প্রতিটি ব্লকের ধরণের জন্য মেমরিটি হ্রাস করতে সঠিক পদ্ধতিটি ব্যবহার করছে, এটি আপনার খেলায় ব্যবহারের সম্ভাব্য উপায়। প্রোটোটাইপ অবজেক্টের মতো একটি মাত্র অবজেক্টের ধারণা থাকাতে এটি সমস্ত ব্লক সম্পর্কিত তথ্য ধারণ করে। পার্থক্য হ'ল প্রতিটি ব্লকের অবস্থান।

তবে এমনকি অবস্থানটিও হ্রাস করা যায়: আপনি যদি জানেন যে একটি জমিগুলির একটি ব্লক একরকমের, তবে কেন সেই জমির মাত্রাগুলি এক সেট অবস্থানের ডেটা সহ এক বিশালাকার ব্লক হিসাবে সংরক্ষণ করবেন না?

স্পষ্টতই জানার একমাত্র উপায় হ'ল আপনার নিজের বাস্তবায়ন শুরু করা, এবং কার্য সম্পাদনের জন্য কিছু মেমরি টেস্ট করা। কীভাবে যায় তা আমাদের জানান!

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.