আমি কীভাবে কোনও ভক্সেল / মাইনক্রাফ্ট টাইপ গেমের রেন্ডারিং গতি উন্নত করতে পারি?


35

আমি আমার নিজস্ব ক্লোন মাইনক্রাফ্ট লিখছি (জাভাতেও লেখা)। এটি এখন দুর্দান্ত কাজ করে। 40 মিটার দেখার দুরত্বের সাথে আমি আমার ম্যাকবুক প্রো 8,1 এ সহজেই 60 টি এফপিএস হিট করতে পারি। (ইন্টেল আই 5 + ইনটেল এইচডি গ্রাফিক্স 3000)। তবে যদি আমি দেখার দূরত্বটি 70 মিটারের উপরে রাখি তবে আমি কেবল 15-25 এফপিএসে পৌঁছেছি। আসল মাইনক্রাফ্টে, আমি কোনও সমস্যা ছাড়াই দুরত্বের ঝোঁকটি দূরে (= 256 মিটার) রাখতে পারি। সুতরাং আমার প্রশ্নটি হল আমার খেলাটি আরও ভাল করার জন্য আমার কী করা উচিত?

আমি যে আশাবাদগুলি প্রয়োগ করেছি:

  • কেবল স্থানীয় অংশগুলিকে মেমরিতে রাখুন (প্লেয়ারের দেখার দূরত্বের উপর নির্ভর করে)
  • ফ্রাস্টাম কুলিং (প্রথমে খণ্ডে, তারপরে ব্লকগুলিতে)
  • শুধুমাত্র ব্লকের সত্যই দৃশ্যমান মুখগুলি অঙ্কন করা
  • প্রতি অংশে তালিকাগুলি ব্যবহার করে যাতে দৃশ্যমান ব্লক থাকে। দৃশ্যমান হয়ে যাওয়া খণ্ডগুলি এই তালিকায় নিজেকে যুক্ত করবে। যদি তারা অদৃশ্য হয়ে যায় তবে এগুলি স্বয়ংক্রিয়ভাবে এই তালিকা থেকে সরানো হবে। প্রতিবেশী ব্লক তৈরি বা ধ্বংস করে ব্লকগুলি দৃশ্যমান হয়ে ওঠে।
  • আপডেট হওয়া ব্লকগুলি সহ প্রতি অংশের তালিকা ব্যবহার করা। দৃশ্যমান ব্লক তালিকা হিসাবে একই প্রক্রিয়া।
  • প্রায় না ব্যবহার করুন newগেম লুপের ভিতরে বিবৃতি । (আবর্জনা সংগ্রহকারীকে না নেওয়া পর্যন্ত আমার খেলাটি প্রায় 20 সেকেন্ড চলবে)
  • আমি এই মুহুর্তে ওপেনজিএল কল তালিকা ব্যবহার করছি। ( glNewList(), glEndList(), glCallList()) ব্লক একটি ধরনের প্রতিটি পাশ জন্য।

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

পারফরম্যান্স উন্নত করার জন্য অন্য কৌশল আছে?

ভিজ্যুয়ালভিএম প্রোফাইলিং আমাকে এটি দেখায় (70 মিটার দেখার দুরত্বের সাথে কেবল 33 ফ্রেমের জন্য প্রোফাইলিং):

এখানে চিত্র বর্ণনা লিখুন

40 মিটার (246 ফ্রেম) সহ প্রোফাইলিং:

এখানে চিত্র বর্ণনা লিখুন

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

সম্পাদনা করুন: কিছু synchronisedব্লক এবং কিছু অন্যান্য সামান্য উন্নতি সরিয়ে দেওয়ার পরে । পারফরম্যান্স ইতিমধ্যে অনেক ভাল। 70 মিটার সহ এখানে আমার নতুন প্রোফাইলিং ফলাফল:

এখানে চিত্র বর্ণনা লিখুন

আমি মনে করি এটি বেশ স্পষ্ট যে selectVisibleBlocksবিষয়টি এখানে।

আগাম ধন্যবাদ!
Martijn

হালনাগাদ : কিছু অতিরিক্ত উন্নতির পরে (যেমন প্রতিটির স্থলে লুপের জন্য ব্যবহার করা, লুপগুলির বাইরে চলকগুলি বাফার করা ইত্যাদি ইত্যাদি), এখন আমি দর্শনীয় দূরত্ব 60 চালাতে পারি বেশ ভাল।

আমি মনে করি আমি যত তাড়াতাড়ি সম্ভব ভিবিও বাস্তবায়ন করতে যাচ্ছি।

পিএস: সমস্ত সোর্স কোড গিটহাবটিতে উপলব্ধ:
https://github.com/mcourteaux/CraftMania


2
আপনি কি আমাদের 40 মিটারে একটি প্রোফাইল শট দিতে পারেন যাতে আমরা দেখতে পারি যে অন্যের চেয়ে দ্রুত কী পরিমাণ বাড়ছে?
জেমস

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

@ গটোকনু: শিরোনাম হিসাবে আপনি কী পরামর্শ দিচ্ছেন?
মার্তিজান আদালত

5
আপনি কাকে জিজ্ঞাসা করছেন তার উপর নির্ভর করে কিছু লোক বলবেন যে মিনক্রাফট সত্যিই তত দ্রুত নয়।
থেইডিয়ান

আমি মনে করি "কোন কৌশলগুলি 3 ডি গেমটি গতি বাড়িয়ে তুলতে পারে" এর মতো আরও কিছু হওয়া উচিত। কিছু ভাবুন, তবে "সেরা" শব্দটি ব্যবহার না করার বা অন্য কোনও গেমের সাথে তুলনা করার চেষ্টা করুন। তারা কিছু গেমগুলিতে ঠিক কী ব্যবহার করে তা আমরা বলতে পারি না।
গুস্তাভো ম্যাকিয়েল

উত্তর:


15

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

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

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

(দ্রষ্টব্য: আমি মাইনক্রাফ্টের কোডটি পরীক্ষা করি নি this এই সমস্ত তথ্য হ'ল শোনা বা মিনক্রাফ্টের রেন্ডারিংটি খেলতে দেখে আমার নিজস্ব সিদ্ধান্তগুলি from)


আরও সাধারণ পরামর্শ:

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

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

অন্যদিকে, জিপিইউ যদি সীমা থাকে (দুঃখের বিষয়, সাধারণত সুবিধাজনক 0% -100% লোড মনিটর থাকে না) তবে আপনাকে কীভাবে এটি কম ডেটা প্রেরণ করবেন সে সম্পর্কে চিন্তাভাবনা করা উচিত, বা এর চেয়ে কম পিক্সেল পূরণ করার প্রয়োজন রয়েছে।


2
দুর্দান্ত রেফারেন্স, আপনার উইকিতে উল্লিখিত এটি সম্পর্কে আপনার গবেষণা আমার পক্ষে খুব সহায়ক ছিল! +1
গুস্তাভো ম্যাকিয়েল

@ ওপ: কেবলমাত্র দৃশ্যমান মুখগুলি রেন্ডার করুন ( ব্লক নয় )। একটি প্যাথলজিকালিক তবে একঘেয়েতী 16x16x16 অংশে প্রায় 800 দৃশ্যমান মুখ থাকবে, যখন রয়েছে ব্লকগুলিতে 24,000 দৃশ্যমান মুখ থাকবে। একবার আপনি এটি সম্পন্ন করার পরে, কেভিনের উত্তরে পরবর্তী সবচেয়ে গুরুত্বপূর্ণ উন্নতি রয়েছে।
অ্যান্ড্রুস

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

3

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

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

যদি আপনার প্রোফাইলে "অনুরোধ" গণনাটি সঠিক হয়, আপনি কোনও ভয়ঙ্কর জিনিসগুলিকে অনেক ভয়ঙ্কর সময় বলছেন। (Vec3f.set এ 10 মিলিয়ন কল ... আউট!)


আমি টন জিনিস জন্য এই পদ্ধতি ব্যবহার। এটি কেবল ভেক্টরের জন্য তিনটি মান নির্ধারণ করে। এটি প্রতিবার নতুন অবজেক্ট বরাদ্দ করার চেয়ে অনেক ভাল।
মার্টিজন কোর্টেউ

2

আমার বিবরণটি (আমার নিজের পরীক্ষা থেকে) এখানে প্রযোজ্য:

ভক্সেল রেন্ডারিংয়ের জন্য, আরও দক্ষ কী: প্রাক-তৈরি ভিবিও বা জ্যামিতি শেডার?

মাইনক্রাফ্ট এবং আপনার কোড সম্ভবত স্থির ফাংশন পাইপলাইন ব্যবহার করে; আমার নিজের প্রচেষ্টা জিএলএসএল-এর সাথে হয়েছে তবে মূল বক্তব্যটি সাধারণত প্রযোজ্য, আমি অনুভব করি:

(স্মৃতি থেকে) আমি একটি হতাশাকে তৈরি করেছি যা পর্দার হতাশার চেয়ে অর্ধ-ব্লক বড়। আমি তারপরে প্রতিটি খণ্ডের কেন্দ্র-পয়েন্টগুলি পরীক্ষা করেছি ( মাইনক্রাফ্টটিতে 16 * 16 * 128 টি ব্লক রয়েছে) )।

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

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

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

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


আমি আপনার হতাশ অপ্টিমাইজেশনের ধারণা পছন্দ করি। কিন্তু আপনি কি আপনার ব্যাখ্যাতে "ব্লক" এবং "অংশ" পদটি একত্রিত করছেন না?
মার্টিজন কোর্টে

সম্ভবত হ্যাঁ. ব্লকের একটি অংশ ইংরেজিতে ব্লকগুলির একটি ব্লক।
উইল

1

আপনার সমস্ত তুলনা ( BlockDistanceComparator) কোথা থেকে আসছে? যদি এটি কোনও বাছাই ফাংশন থেকে থাকে, তবে কি এটি একটি রেডিক্স সাজ্টের সাথে প্রতিস্থাপন করা যাবে (যা তাত্পর্যপূর্ণভাবে দ্রুত, এবং তুলনার ভিত্তিতে নয়)?

আপনার সময়গুলির দিকে তাকান, এমনকি যদি বাছাই করা নিজেই খারাপ না হয় তবে আপনার relativeToOriginফাংশনটি প্রতিটি compareফাংশনের জন্য দু'বার কল করা হচ্ছে ; যে সমস্ত ডেটা একবার গণনা করা উচিত। একটি সহায়ক কাঠামো বাছাই করার জন্য এটি দ্রুত হওয়া উচিত eg

struct DistanceIndexPair
{
    float m_distanceSquaredFromOrigin;
    int m_index;
};

এবং তারপর সিউডো কোডে

// for i = 0..numBlocks
//     distanceIndexPairs[i].m_distanceSquaredFromOrigin = ...;
///    distanceIndexPairs[i].m_index = i;
// sort distanceIndexPairs
// for i = 0..numBlocks
//    sortedBlock[i] = unsortedBlocks[ distanceIndexPairs.m_index ]

দুঃখিত যদি এটি একটি বৈধ জাভা স্ট্রাক্ট না হয় (আমি জাভা আন্ডারগ্রাডের পরে ছোঁয়নি) তবে আশা করি আপনি ধারণাটি পেয়ে গেছেন।


আমি এই মজাদার খুঁজে। জাভা স্ট্রাইক নেই। ঠিক আছে, জাভা বিশ্বে এরকম কিছু বলা আছে তবে এটি ডেটাবেসগুলির সাথে করতে হবে, একই জিনিস নয়। তারা জনসাধারণের সদস্যদের নিয়ে একটি চূড়ান্ত শ্রেণি তৈরি করতে পারে, আমার ধারণা এটি কাজ করে।
থেরোট

1

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

এর মতো সমস্ত কিছু রেন্ডারিংয়ের পরিবর্তে:

পারিশ্রমিক প্রদান করা

এটি এটিকে এটির মতো উপস্থাপন করে:

render2

এর নেতিবাচক দিকটি হ'ল প্রাথমিক বিশ্ব গড়ার ক্ষেত্রে আপনাকে প্রতি অংশে আরও বেশি গণনা করতে হবে, বা প্লেয়ার যদি কোনও ব্লক সরিয়ে / যুক্ত করে।

ভাল পারফরম্যান্সের জন্য কোনও ধরণের ভক্সেল ইঞ্জিনের এটি প্রয়োজন।

এটি যা করে তা হ'ল এটি যাচাই করা হয় যে ব্লকটির মুখটি অন্য ব্লকের মুখের সাথে স্পর্শ করছে কিনা এবং যদি তাই হয়: কেবলমাত্র একটি (বা শূন্য) ব্লক ফেস (গুলি) হিসাবে রেন্ডার করুন। আপনি সত্যিই দ্রুত অংশগুলি সরবরাহ করছেন যখন এটি একটি ব্যয়বহুল স্পর্শ।

public void greedyMesh(int p, BlockData[][][] blockData){
        boolean[][][][] mask = new boolean[blockData.length][blockData[0].length][blockData[0][0].length][6];

    for(int side=0; side<6; side++){
        for(int x=0; x<blockData.length; x++){
            for(int y=0; y<blockData[0].length; y++){
                for(int z=0; z<blockData[0][0].length; z++){
                    if(data[x][y][z] > Material.AIR && !mask[x][y][z][side] && blockData[x][y][z].faces[side]){
                        if(side == 0 || side == 1){
                            int width = 0;
                            int height = 0;
                            loop:
                            for(int i=y; i<blockData[0].length; i++){
                                if(i == y){
                                    for(int j=z; j<blockData[0][0].length; j++){
                                        if(!mask[x][i][j][side] && blockData[x][i][j].id == blockData[x][y][z].id && blockData[x][i][j].faces[side]){
                                            width++;
                                        }else{
                                            break;
                                        }
                                    }
                                }else{
                                    for(int j=0; j<width; j++){
                                        if(mask[x][i][z+j][side] || blockData[x][i][z+j].id != blockData[x][y][z].id || !blockData[x][i][z+j].faces[side]){
                                            break loop;
                                        }
                                    }
                                }
                                height++;
                            }
                            for(int i=0; i<height; i++){
                                for(int j=0; j<width; j++){
                                    mask[x][y+i][z+j][side] = true;
                                }
                            }

                            if(side == 0)
                                meshes.get(p).add(new Mesh(new VoxelVector3i(x+1, y, z), new VoxelVector3i(x+1, y+height, z+width), new VoxelVector3i(1, 0, 0), Material.getColor(data[x][y][z])));
                            else
                                meshes.get(p).add(new Mesh(new VoxelVector3i(x, y, z+width), new VoxelVector3i(x, y+height, z), new VoxelVector3i(-1, 0, 0), Material.getColor(data[x][y][z])));
                        }else if(side == 2 || side == 3){
                            int width = 0;
                            int height = 0;
                            loop:
                            for(int i=x; i<blockData.length; i++){
                                if(i == x){
                                    for(int j=z; j<blockData[0][0].length; j++){
                                        if(!mask[i][y][j][side] && blockData[i][y][j].id == blockData[x][y][z].id && blockData[i][y][j].faces[side]){
                                            width++;
                                        }else{
                                            break;
                                        }
                                    }
                                }else{
                                    for(int j=0; j<width; j++){
                                        if(mask[i][y][z+j][side] || blockData[i][y][z+j].id != blockData[x][y][z].id || !blockData[i][y][z+j].faces[side]){
                                            break loop;
                                        }
                                    }
                                }
                                height++;
                            }
                            for(int i=0; i<height; i++){
                                for(int j=0; j<width; j++){
                                    mask[x+i][y][z+j][side] = true;
                                }
                            }

                            if(side == 2)
                                meshes.get(p).add(new Mesh(new VoxelVector3i(x, y+1, z+width), new VoxelVector3i(x+height, y+1, z), new VoxelVector3i(0, 1, 0), Material.getColor(data[x][y][z])));
                            else
                                meshes.get(p).add(new Mesh(new VoxelVector3i(x+height, y, z+width), new VoxelVector3i(x, y, z), new VoxelVector3i(0, -1, 0), Material.getColor(data[x][y][z])));
                        }else if(side == 4 || side == 5){
                            int width = 0;
                            int height = 0;
                            loop:
                            for(int i=x; i<blockData.length; i++){
                                if(i == x){
                                    for(int j=y; j<blockData[0].length; j++){
                                        if(!mask[i][j][z][side] && blockData[i][j][z].id == blockData[x][y][z].id && blockData[i][j][z].faces[side]){
                                            width++;
                                        }else{
                                            break;
                                        }
                                    }
                                }else{
                                    for(int j=0; j<width; j++){
                                        if(mask[i][y+j][z][side] || blockData[i][y+j][z].id != blockData[x][y][z].id || !blockData[i][y+j][z].faces[side]){
                                            break loop;
                                        }
                                    }
                                }
                                height++;
                            }
                            for(int i=0; i<height; i++){
                                for(int j=0; j<width; j++){
                                    mask[x+i][y+j][z][side] = true;
                                }
                            }

                            if(side == 4)
                                meshes.get(p).add(new Mesh(new VoxelVector3i(x+height, y, z+1), new VoxelVector3i(x, y+width, z+1), new VoxelVector3i(0, 0, 1), Material.getColor(data[x][y][z])));
                            else
                                meshes.get(p).add(new Mesh(new VoxelVector3i(x, y, z), new VoxelVector3i(x+height, y+width, z), new VoxelVector3i(0, 0, -1), Material.getColor(data[x][y][z])));
                        }
                    }
                }
            }
        }
    }
}

1
এবং এটা মূল্য? দেখে মনে হচ্ছে একটি এলওডি সিস্টেম আরও উপযুক্ত হবে।
মাইকেলহাউস

0

দেখে মনে হবে আপনার কোড বস্তু এবং ফাংশন কলগুলিতে ডুবে যাচ্ছে। সংখ্যাগুলি দেখে, মনে হচ্ছে এমন কোনও অভ্যন্তরীণ ঘটনা ঘটছে।

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

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

* অতিরিক্ত মাত্রায় ওরিয়েন্টেড


হ্যাঁ, আপনি স্মৃতি সঞ্চয় করবেন, তবে সিপিইউ হারাবেন! সুতরাং ওওও রিয়েলটাইম গেমগুলিতে খুব ভাল নয়।
গুস্তাভো ম্যাকিয়েল

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

@ গোটোকনু এটি সর্বজনীনভাবে সত্য নয়, ওও এর কিছু স্তরে ফাংশন কলগুলি ইনলাইন কোডের চেয়ে বেশি মেমরি নিতে শুরু করে। আমি বলতে চাইবে কোডের একটি ভাল অংশ রয়েছে যা স্মৃতির জন্য বিরতি এমনকি পয়েন্টের চারপাশে।
aaaaaaaaaaaa

0

আপনি বিটওয়াইড অপারেটরদের কাছে ম্যাথ অপারেশনগুলি ভেঙে দেওয়ার চেষ্টা করতে পারেন। যদি তোমার থাকে128 / 16 একটি bitwise অপারেটর চেষ্টা করুন: 128 << 4। এটি আপনার সমস্যার সাথে অনেক সহায়তা করবে। জিনিসগুলিকে পুরো গতিতে চালিত করার চেষ্টা করবেন না। আপনার গেমটি 60 বা কিছু হারে আপডেট করুন এবং এমনকি এটি অন্য কিছুতেও ভেঙে ফেলুন, তবে আপনাকে ধ্বংস করতে হবে এবং ভক্সেল স্থাপন করতে হবে বা আপনাকে একটি টুড-লিস্ট তৈরি করতে হবে যা আপনার fps কে নামিয়ে আনবে। সত্ত্বার জন্য আপনি প্রায় 20 এর আপডেট রেটটি করতে পারেন। এবং বিশ্ব আপডেট এবং বা প্রজন্মের জন্য 10 এর মতো কিছু।

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