টেক্সচার অ্যাটলাসে টেক্সচার রক্তপাত কীভাবে এড়ানো যায়?


46

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

ভক্সেল ভিত্তিক ভূখণ্ডের জন্য টেক্সচার অ্যাটলাস

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

ভুল রঙের ফিতেযুক্ত ভূখণ্ডের স্ক্রিনশট

আপাতত আমি এই ইন্টারপোলেশন সেটিংস ব্যবহার করি তবে আমি প্রতিটি সংমিশ্রণ চেষ্টা করেছি এবং GL_NEARESTএমপম্যাপিং ছাড়াও আরও ভাল ফলাফল সরবরাহ করে না।

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

টাইলের সামান্য ছোট অঞ্চল বাছাই করার জন্য আমি টেক্সচার সমন্বয়গুলিতে একটি অফসেট যুক্ত করার চেষ্টা করেছি তবে যেহেতু অযাচিত প্রভাব ক্যামেরার দূরত্বের উপর নির্ভর করে এটি সমস্যার সম্পূর্ণ সমাধান করতে পারে না। দূরত্বে স্ট্রিপগুলি যেভাবেই ঘটে occur

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


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

যেমনটি আমি বলেছিলাম দুঃখের সাথে মিপম্যাপিং বন্ধ করা সমস্যার সমাধান করে না। মিপম্যাপ ব্যতীত এটি রৈখিক বিভাজন করবে GL_LINEARযা একইরকম ফলাফল দেয় বা নিকটতম পিক্সেলটি বাছাই করবে GL_NEARESTযা ফলস্বরূপ ব্লকের মধ্যে স্ট্রাইপের ফলেও ঘটে। শেষ উল্লিখিত বিকল্পটি হ্রাস পেয়েছে তবে পিক্সেলের ত্রুটি দূর করে না।
দানিজার

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

1
আমার আগে এই সমস্যা ছিল এবং এটি প্রতিটি আলাদা টেক্সচারের মধ্যে আপনার আটলাসে 1-2 পিক্সেল প্যাডিং যুক্ত করে সমাধান করা হয়েছিল।
ছক ডি

1
@Kylotan। সমস্যাটি টেক্সচার রিজাইজিং সম্পর্কিত হয় এটি মিপম্যাপস, লিনিয়ার ইন্টারপোলেশন বা নিকটস্থ পিক্সেল বাছাইয়ের মাধ্যমে সম্পন্ন না করেই।
দানিজার

উত্তর:


34

ঠিক আছে, আমার মনে হয় আপনার এখানে দুটি সমস্যা চলছে।

প্রথম সমস্যাটি মিপম্যাপিং নিয়ে। সাধারণভাবে, আপনি নির্লিপ্তভাবে মিটম্যাপিংয়ের সাথে অ্যাটলসিং মিশ্রিত করতে চান না, কারণ আপনার সমস্ত সাবটেক্সচারগুলি ঠিক 1x1 পিক্সেল আকারের না হলে আপনি জমিনের রক্তপাতের অভিজ্ঞতা অর্জন করতে পারবেন। প্যাডিং যুক্ত করার ফলে সমস্যাটি কেবলমাত্র নিম্ন স্তরের স্তরে চলে যাবে।

থাম্বের নিয়ম হিসাবে, 2 ডি এর জন্য, যেখানে আপনি সাধারণত অ্যাটলসিং করেন, আপনি এমপম্যাপ করেন না; 3 ডি-র জন্য, যেখানে আপনি মাইপম্যাপ করছেন, আপনি অ্যাটলাস করবেন না (আসলে আপনার ত্বক এমনভাবে হয় যাতে রক্তক্ষরণ কোনও সমস্যা না হয়)

যাইহোক, আমি এখনই আপনার প্রোগ্রামটির সাথে যা চলছে বলে মনে করি তা হল আপনি সম্ভবত সঠিক টেক্সচারের স্থানাঙ্ক ব্যবহার করছেন না এবং এর কারণে আপনার অঙ্গগুলি রক্তক্ষরণ হচ্ছে।

ধরা যাক একটি 8x8 টেক্সচার। আপনি সম্ভবত (0,0) থেকে (0.5, 0.5) এর UV স্থানাঙ্ক ব্যবহার করে উপরের-বাম কোয়ার্টারটি পেয়ে যাচ্ছেন:

ভুল ম্যাপিং

এবং সমস্যাটি হ'ল ইউ-কো-অর্ডিনেট ০.০ এ, নমুনাটি বাম টেক্সেলের অর্ধেক এবং ডান টেক্সেলের অর্ধেক ব্যবহার করে গন্তব্য খণ্ডটি বিভক্ত করবে। একইভাবে u- স্থানাঙ্ক 0 এ ঘটবে এবং ভি-স্থানাঙ্কের ক্ষেত্রেও এটি ঘটবে। এটি কারণ আপনি টেক্সেলগুলির মধ্যে সীমান্তগুলিকে সম্বোধন করছেন, এবং কেন্দ্রগুলি নয়।

পরিবর্তে আপনার যা করা উচিত তা হ'ল প্রতিটি টেক্সেলের কেন্দ্রে সম্বোধন করা। এই উদাহরণস্বরূপ, এটি আপনার ব্যবহার করতে চান স্থানাঙ্কগুলি:

সঠিক ম্যাপিং

এই ক্ষেত্রে, আপনি সর্বদা প্রতিটি টেক্সেলের কেন্দ্রে নমুনা রাখবেন এবং আপনার কোনও রক্তপাত হবে না ... আপনি যদি মাইপম্যাপিং ব্যবহার না করেন তবে এই ক্ষেত্রে আপনি সর্বদা মিপ স্তর থেকে রক্তপাত শুরু করবেন যেখানে স্কেল করা সাবটেক্টচারটি ঝরঝরে নয় where পিক্সেল গ্রিডের ভিতরে ফিট করুন

সাধারণকরণের জন্য, আপনি যদি কোনও নির্দিষ্ট টেক্সেল অ্যাক্সেস করতে চান তবে স্থানাঙ্কগুলি গণনা করা হয়:

function get_texel_coords(x, y, tex_width, tex_height)
    u = (x + 0.5) / tex_width
    v = (y + 0.5) / tex_height
    return u, v
end

একে "অর্ধ পিক্সেল সংশোধন" বলা হয়। আপনি যদি আগ্রহী হন তবে এখানে আরও বিস্তারিত ব্যাখ্যা রয়েছে ।


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

@ শেয়ারেটিস যদি আপনার অবশ্যই অ্যাটলস থাকতে হয় তবে নিশ্চিত হয়ে নিন যে আপনার সাবটেক্সচারগুলিতে 2 টির আকার রয়েছে, যাতে আপনি রক্তপাতকে সর্বনিম্ন মিউপ স্তরে সীমাবদ্ধ করতে পারেন। যদি আপনি এটি করেন তবে আপনার নিজের মিপম্যাপগুলি হস্তক্ষেপ করার দরকার নেই।
পান্ডা পাইজামা

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

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

1
@ Sharethis এই অন্য উত্তরটি আমি যা লিখেছি তা যাচাই করে দেখুন যা আপনাকে গেমদেব.স্ট্যাকেক্সেঞ্জার
পান্ডা

19

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

http://www.opengl.org/wiki/Array_Texture


যদি সেগুলি উপলভ্য থাকে তবে সেগুলি আরও ভাল সমাধান - আপনি অন্যান্য বৈশিষ্ট্যগুলিও পান, মোড়ক মোড়ানোর মতো, যা আপনি অ্যাটলাসে মিস করেন।
জারি কম্প্পা

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

8
@ Sharethis আপত্তিজনকভাবে উচ্চতর প্রযুক্তিগত সমাধানগুলি খারিজ করা কারণ আপনি "সাধারণ" হতে চান ব্যর্থতার একটি রেসিপি। আপনি যদি কোন গেম লিখেন তবে ইঞ্জিনটি লিখবেন না।
সাম হোচেভার

@SamHocevar। আমি একটি ইঞ্জিন লিখছি এবং আমার প্রকল্পটি একটি নির্দিষ্ট আর্কিটেকচার সম্পর্কে ছিল উপাদানগুলি সম্পূর্ণরূপে decoupled ছিল। সুতরাং ফর্ম উপাদানটি ভূখণ্ডের উপাদানটির যত্ন নেওয়া উচিত নয় যা কেবলমাত্র স্ট্যান্ডার্ড বাফার এবং একটি স্ট্যান্ডার্ড টেক্সচার সরবরাহ করতে পারে।
দঞ্জির

1
পছন্দ করুন প্রশ্নের কোনও অংশে "আমার খেলায়" আমি কোনওভাবে বিভ্রান্ত হয়েছিলাম।
সাম হোচেভার

6

এই সমস্যাটি নিয়ে অনেক লড়াইয়ের পরে অবশেষে আমি একটি সমাধান নিয়ে এসেছি।

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

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

এই পরামিতিগুলির সাথে, কোনও রক্তপাত হয় না।

কাস্টম মিপম্যাপগুলি সরবরাহ করার সময় আপনার একটি জিনিস খেয়াল করতে হবে। যেহেতু প্রতিটি টাইল ইতিমধ্যে অ্যাটলাস সঙ্কুচিত করা কোনও 1x1অর্থবোধ করে না, তাই আপনার সরবরাহ অনুযায়ী সর্বাধিক মিপম্যাপ স্তরটি সেট করা উচিত।

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 7); // pick mipmap level 7 or lower

অন্যান্য সমস্ত উত্তর এবং খুব সহায়ক মন্তব্যের জন্য ধন্যবাদ! যাইহোক, আমি এখনও লিনিয়ার আপ স্কেলিং কীভাবে ব্যবহার করতে পারি তা জানি না তবে আমি অনুমান করি যে এর কোনও উপায় নেই।


আপনি এটি সমাধান পেয়েছিলাম জেনে ভাল। আপনার উত্তরটি আমার পরিবর্তে সঠিক হিসাবে চিহ্নিত করা উচিত।
পান্ডা পাইজামা

মিপম্যাপিং একচেটিয়াভাবে ডাউনসাম্পলিংয়ের জন্য একটি কৌশল, যা আপসাম্পলিংয়ের কোনও অর্থ দেয় না। ধারণাটিটি হ'ল আপনি যদি একটি ছোট ত্রিভুজ আঁকতে চলেছেন তবে একটি বড় টেক্সচারটি থেকে কয়েক পিক্সেল বেরিয়ে আসতে কেবল নমুনা করতে অনেক সময় লাগবে, তাই আপনি এটি প্রাক-ডাউনসাম্পল করে উপযুক্ত মাইপ স্তরটি ব্যবহার করার সময় ছোট ত্রিভুজ অঙ্কন। বৃহত্তর ত্রিভুজগুলির জন্য, বৃহত্তর এমআইপি স্তর থেকে আলাদা কিছু ব্যবহার করা বোধগম্য নয়, সুতরাং এটির মতো কিছু করা একটি ত্রুটিglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_FILTER, GL_NEAREST_MIPMAP_LINEAR);
পান্ড পাজামা

@PandaPajama। আপনি ঠিক বলেছেন, আমি আমার উত্তর সংশোধন করেছি। সেট করতে GL_TEXTURE_MAX_FILTERকরতে GL_NEAREST_MIPMAP_LINEARনা রক্তপাত mipmapping কারণে সৃষ্টি করে কিন্তু ক্ষেপক এর কারণে। সুতরাং এই ক্ষেত্রে এটি GL_LINEARযেহেতু সর্বনিম্ন মিপম্যাপ স্তরটি ব্যবহৃত হয় তার সমতুল্য ।
ডানিজার

@ ডানিজার - আপনি কীভাবে নিজেকে ডাউনস্যাম্পলিং সম্পাদন করেন এবং আপনি ওপেনজিএলকে কীভাবে (এবং কখন) ডাউনস্যাম্পলড অ্যাটলাস ব্যবহার করবেন তা কীভাবে আরও বিশদে ব্যাখ্যা করতে পারবেন?
টিম কেন

1
@ টিমকেনে টলসগুলিতে অ্যাটলাস বিভক্ত করুন। প্রতিটি মিপম্যাপ স্তরের জন্য, দ্বৈত দ্বৈতভাবে টাইলগুলি নমুনা করুন, তাদের একত্রিত করুন এবং এটি জিপিইউতে আপলোড করুন যা মাইপম্যাপ স্তরটিকে প্যারামিটার হিসাবে নির্দিষ্ট করে glTexImage2D()। জিপিইউ স্ক্রিনে অবজেক্ট আকারের উপর ভিত্তি করে স্বয়ংক্রিয়ভাবে সঠিক স্তরটি চয়ন করে।
দানিজার

4

দেখে মনে হচ্ছে বিষয়টি এমএসএএ দ্বারা সৃষ্ট হতে পারে। দেখুন এই উত্তর এবং লিঙ্ক নিবন্ধ :

"আপনি যখন এমএসএএ চালু করেন, তখন শ্যাডারের পক্ষে পিক্সেল অঞ্চলের অভ্যন্তরের নমুনাগুলির জন্য মৃত্যুদণ্ড কার্যকর করা সম্ভব হয় তবে ত্রিভুজ অঞ্চলের বাইরে"

সমাধানটি হ'ল সেন্ট্রয়েড স্যাম্পলিং ব্যবহার করা। আপনি যদি কোনও ভার্টেক্স শেডারে টেক্সচারের স্থানাঙ্কগুলির মোড়কের গণনা করে থাকেন তবে সেই যুক্তিকে খণ্ড শ্যাডারে সরানোও সমস্যার সমাধান করতে পারে।


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

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

1

এটি একটি পুরানো বিষয়, এবং আমার বিষয়টির সাথেও একই সমস্যা ছিল।

আমার টেক্সচারের স্থানাঙ্কগুলি ঠিক ছিল, তবে ক্যামেরার অবস্থানটি (যা আমার উপাদানটির অবস্থান পরিবর্তন করেছে) তেমন লেখার মাধ্যমে:

public static void tween(Camera cam, Direction dir, Vec2 buffer, Vec2 start, Vec2 end) {
    if(step > steps) {
        tweening = false;
        return;
    }

    final float alpha = step/steps;

    switch(dir) {
    case UP:
    case DOWN:
        buffer = new Vec2(start.getX(), Util.lerp(start.getY(), (float)end.getY(), alpha));
        cam.getPosition().set(buffer);
        break;
    case LEFT:
    case RIGHT:
        buffer = new Vec2(Util.lerp(start.getX(), end.getX(), alpha), start.getY());
        cam.getPosition().set(buffer);
        break;
    }

    step += 1;
}

পুরো সমস্যাটি ছিল ইউটিল.লર્প () ফ্লোট বা ডাবল দেয়। এটি খারাপ ছিল কারণ ক্যামেরাটি অফ-গ্রিড অনুবাদ করছিল এবং টেক্সচার স্নিপেটগুলির সাথে কিছু অদ্ভুত সমস্যা সৃষ্টি করছিল যেখানে> 0 এবং এক্স 0 এ>।

টিএলডিআর: ফ্লোটগুলি ব্যবহার করে না কিছু বা কিছু না don't

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