ভার্চুয়াল টেক্সচারিং টেক্সচার অ্যাটলেসের যৌক্তিক চরম extreme
টেক্সচার অ্যাটলাস হ'ল একক দৈত্য টেক্সচার যা এর অভ্যন্তরে পৃথক মেসের জন্য টেক্সচার ধারণ করে:
টেক্সচার অ্যাটলেসগুলি এই কারণেই জনপ্রিয় হয়ে ওঠে যে টেক্সচার পরিবর্তনের ফলে জিপিইউতে একটি সম্পূর্ণ পাইপলাইন ফ্লাশ হয়। মেস তৈরি করার সময়, ইউভিগুলি সংকুচিত / স্থানান্তরিত হয় যাতে তারা পুরো টেক্সচার অ্যাটলাসের সঠিক 'অংশ' উপস্থাপন করে।
মন্তব্যে @ নাথান-রিড যেমন উল্লেখ করেছেন, টেক্সচার অ্যাটলেসের অন্যতম প্রধান অসুবিধাগুলি পুনরাবৃত্তি, বাতা, সীমান্ত ইত্যাদির মতো মোড়ানো পদ্ধতিগুলি হারাচ্ছে এছাড়াও, যদি টেক্সচারগুলির চারপাশে পর্যাপ্ত সীমানা না থাকে তবে আপনি দুর্ঘটনাক্রমে ফিল্টারিং করার সময় সংলগ্ন টেক্সচার থেকে নমুনা। এর ফলে রক্তক্ষরণে নিদর্শনগুলি হতে পারে।
টেক্সচার অ্যাটলেসের একটি বড় সীমাবদ্ধতা রয়েছে: আকার। গ্রাফিক্স API গুলি কত বড় টেক্সচার হতে পারে তার উপর নরম সীমা রাখে। বলেছিল, গ্রাফিক্সের স্মৃতি কেবল এত বড়। সুতরাং আপনার ভি-র্যামের আকার অনুসারে জমিনের আকারের ক্ষেত্রেও একটি কঠোর সীমা রয়েছে। ভার্চুয়াল টেক্সচারগুলি ভার্চুয়াল মেমরি থেকে ধারণাগুলি ধার করে এই সমস্যার সমাধান করে ।
ভার্চুয়াল টেক্সচারগুলি এই সত্যটিকে কাজে লাগায় যে বেশিরভাগ দৃশ্যে, আপনি কেবল সমস্ত টেক্সচারের একটি ছোট্ট অংশ দেখতে পান। সুতরাং, কেবলমাত্র টেক্সচারের উপসেটটি ভ্র্যামে থাকা দরকার। বাকিগুলি মূল র্যামে বা ডিস্কে থাকতে পারে।
এটি বাস্তবায়নের কয়েকটি উপায় রয়েছে তবে আমি শন ব্যারেট তার জিডিসির আলোচনায় বর্ণিত বাস্তবায়নটি ব্যাখ্যা করব । (যা আমি দেখার জন্য সুপারিশ করি)
আমাদের তিনটি প্রধান উপাদান রয়েছে: ভার্চুয়াল টেক্সচার, শারীরিক টেক্সচার এবং লুকিং টেবিল।
ভার্চুয়াল টেক্সচারটি তাত্ত্বিক মেগা অ্যাটলাসকে উপস্থাপন করে যদি আমাদের কাছে সবকিছু ফিট করার জন্য পর্যাপ্ত পরিমাণে ভ্র্যাম থাকে। এটি আসলে কোথাও মেমরিতে বিদ্যমান নেই। শারীরিক টেক্সচারটি আমাদের কাছে ভি্রামে আসলে কী পিক্সেল ডেটা উপস্থাপন করে। লুক টেবিলটি হ'ল উভয়ের মধ্যে ম্যাপিং। সুবিধার জন্য, আমরা তিনটি উপাদানকে সমান আকারের টাইলস বা পৃষ্ঠাগুলিতে বিভক্ত করি।
সন্ধানের টেবিলটি শারীরিক জমিনে টাইলের উপরের-বাম কোণার অবস্থান সঞ্চয় করে। সুতরাং, পুরো ভার্চুয়াল টেক্সচারকে একটি UV দেওয়া, আমরা কীভাবে শারীরিক টেক্সচারের জন্য সংশ্লিষ্ট UV পাই?
প্রথমত, আমাদের দৈহিক জমিনের মধ্যে পৃষ্ঠার অবস্থানটি সন্ধান করতে হবে। তারপরে আমাদেরকে পৃষ্ঠার মধ্যে ইউভির অবস্থান গণনা করতে হবে। অবশেষে আমরা এই দুটি অফসেট একসাথে শারীরিক টেক্সচারের মধ্যে ইউভির অবস্থান পেতে পারি
float2 pageLocInPhysicalTex = ...
float2 inPageLocation = ...
float2 physicalTexUV = pageLocationInPhysicalTex + inPageLocation;
পৃষ্ঠা লোক গণনা ফিজিক্যালটেক্স
যদি আমরা ভার্চুয়াল টেক্সচারে টাইলসের সংখ্যার মতো একই আকারের আকার তৈরি করি, আমরা কেবল নিকটবর্তী প্রতিবেশী নমুনা সহ লুকিং টেবিলটি নমুনা করতে পারি এবং আমরা শারীরিক টেক্সচারের মধ্যে পৃষ্ঠার উপরের-বাম কোণটি পেয়ে যাব।
float2 pageLocInPhysicalTex = lookupTable.Sample(virtTexUV, nearestNeighborSampler);
InPageLocation গণনা করা হচ্ছে
ইনপেজলোকেশন হ'ল একটি ইউভি স্থানাঙ্ক যা পুরো টেক্সচারের উপরের-বামের চেয়ে পৃষ্ঠার উপরের-বামের সাথে সম্পর্কিত।
এটি গণনা করার একটি উপায় হ'ল পৃষ্ঠার উপরের বাম দিকের UV কে বিয়োগ করে পৃষ্ঠার আকার পর্যন্ত স্কেল করে। তবে এটি গণিতের বেশ কিছুটা। পরিবর্তে, আমরা কীভাবে আইইইই ভাসমান পয়েন্ট উপস্থাপন করা হয় তা কাজে লাগাতে পারি। আইইইই ভাসমান বিন্দু বেস 2 ভগ্নাংশের একটি সিরিজ দ্বারা সংখ্যার ভগ্নাংশ অংশ সঞ্চয় করে।
এই উদাহরণে, নম্বরটি হ'ল:
number = 0 + (1/2) + (1/8) + (1/16) = 0.6875
এখন আসুন ভার্চুয়াল টেক্সচারের সরলিকৃত সংস্করণটি দেখুন:
যদি আমরা টেক্সচারের বাম অর্ধেক বা ডানদিকে থাকি তবে 1/2 বিট আমাদের জানায়। ১/৪ বিট আমাদের জানায় যে আমরা অর্ধেকের কোন চতুর্থাংশ রয়েছি this উদাহরণস্বরূপ, যেহেতু টেক্সচারটি 16 বা 4 ভাগে বিভক্ত হয়েছে, এই প্রথম দুটি বিট আমাদের কী পৃষ্ঠায় রয়েছে তা জানিয়ে দেয় remaining বিটস আমাদের পৃষ্ঠার ভিতরে অবস্থানটি বলে।
এক্সপ 2 () দিয়ে ভাসাটি স্থানান্তর করে এবং ফ্র্যাক্ট () দিয়ে এগুলি সরিয়ে দিয়ে আমরা বাকী বিটগুলি পেতে পারি
float2 inPageLocation = virtTexUV * exp2(sqrt(numTiles));
inPageLocation = fract(inPageLocation);
যেখানে numTiles টেক্সচারের পাশে প্রতি টাইল সংখ্যা প্রদান করে একটি int2। আমাদের উদাহরণস্বরূপ, এটি হবে (4, 4)
তাহলে গ্রিন পয়েন্টের জন্য ইনপেজলোকেশন গণনা করা যাক, (x, y) = (0.6875, 0.375)
inPageLocation = float2(0.6875, 0.375) * exp2(sqrt(int2(4, 4));
= float2(0.6875, 0.375) * int2(2, 2);
= float2(1.375, 0.75);
inPageLocation = fract(float2(1.375, 0.75));
= float2(0.375, 0.75);
আমাদের শেষ হওয়ার আগে একটি শেষ কাজ। বর্তমানে, ইনপেজলোকেশন ভার্চুয়াল টেক্সচার 'স্পেস' এর একটি ইউভি সমন্বয়ক। তবে, আমরা দৈহিক জমিন 'স্পেস' এর জন্য একটি ইউভি সমন্বয় চাই want এটি করার জন্য আমাদের কেবলমাত্র ভার্চুয়াল টেক্সচারের আকারের সাথে শারীরিক জমিনের আকারের অনুপাত অনুসারে পেজলোকেশনটি স্কেল করতে হবে
inPageLocation *= physicalTextureSize / virtualTextureSize;
সুতরাং সমাপ্ত ফাংশনটি হ'ল:
float2 CalculatePhysicalTexUV(float2 virtTexUV, Texture2D<float2> lookupTable, uint2 physicalTexSize, uint2 virtualTexSize, uint2 numTiles) {
float2 pageLocInPhysicalTex = lookupTable.Sample(virtTexUV, nearestNeighborSampler);
float2 inPageLocation = virtTexUV * exp2(sqrt(numTiles));
inPageLocation = fract(inPageLocation);
inPageLocation *= physicalTexSize / virtualTexSize;
return pageLocInPhysicalTex + inPageLocation;
}