রাশিয়ান রুলেটকে বোঝার জন্য, আসুন একটি খুব প্রাথমিক ব্যাকগ্রাউন্ড পাথ ট্রেসার দেখুন:
void RenderPixel(uint x, uint y, UniformSampler *sampler) {
Ray ray = m_scene->Camera.CalculateRayFromPixel(x, y, sampler);
float3 color(0.0f);
float3 throughput(1.0f);
// Bounce the ray around the scene
for (uint bounces = 0; bounces < 10; ++bounces) {
m_scene->Intersect(ray);
// The ray missed. Return the background color
if (ray.geomID == RTC_INVALID_GEOMETRY_ID) {
color += throughput * float3(0.846f, 0.933f, 0.949f);
break;
}
// We hit an object
// Fetch the material
Material *material = m_scene->GetMaterial(ray.geomID);
// The object might be emissive. If so, it will have a corresponding light
// Otherwise, GetLight will return nullptr
Light *light = m_scene->GetLight(ray.geomID);
// If we hit a light, add the emmisive light
if (light != nullptr) {
color += throughput * light->Le();
}
float3 normal = normalize(ray.Ng);
float3 wo = normalize(-ray.dir);
float3 surfacePos = ray.org + ray.dir * ray.tfar;
// Get the new ray direction
// Choose the direction based on the material
float3 wi = material->Sample(wo, normal, sampler);
float pdf = material->Pdf(wi, normal);
// Accumulate the brdf attenuation
throughput = throughput * material->Eval(wi, wo, normal) / pdf;
// Shoot a new ray
// Set the origin at the intersection point
ray.org = surfacePos;
// Reset the other ray properties
ray.dir = wi;
ray.tnear = 0.001f;
ray.tfar = embree::inf;
ray.geomID = RTC_INVALID_GEOMETRY_ID;
ray.primID = RTC_INVALID_GEOMETRY_ID;
ray.instID = RTC_INVALID_GEOMETRY_ID;
ray.mask = 0xFFFFFFFF;
ray.time = 0.0f;
}
m_scene->Camera.FrameBuffer.SplatPixel(x, y, color);
}
অর্থাৎ। আমরা দৃশ্যের চারদিকে বাউন্স করি, রঙ হিসাবে এবং আলোতে আলোকপাত করি। অর্ডার সম্পূর্ণরূপে গাণিতিকভাবে পক্ষপাতিত্বহীন হতে, bounces উচিত অনন্ত যান। তবে এটি অবাস্তব নয়, এবং যেমনটি আপনি উল্লেখ করেছেন, চাক্ষুষরূপে প্রয়োজনীয় নয়; বেশিরভাগ দৃশ্যের জন্য, নির্দিষ্ট কিছু বাউন্সের পরে, 10 বলুন, চূড়ান্ত রঙে অবদানের পরিমাণ খুব ন্যূনতম।
সুতরাং কম্পিউটিং সংস্থানগুলি সংরক্ষণ করার জন্য, অনেক পাথ ট্রেসারদের বাউন্সের সংখ্যার একটি কঠোর সীমা থাকে। এটি পক্ষপাতমূলক যোগ করে।
এটি বলেছিল, সেই কঠিন সীমাটি কী হওয়া উচিত তা চয়ন করা শক্ত। কিছু দৃশ্য 2 বাউন্স পরে দুর্দান্ত দেখায়; অন্যরা (সংক্রমণ বা এসএসএস সহ বলুন) 10 বা 20 পর্যন্ত সময় নিতে পারে।
আমরা যদি খুব কম নির্বাচন করি তবে চিত্রটি দৃশ্যত পক্ষপাতদুষ্ট হবে। তবে আমরা যদি খুব উচ্চতর চয়ন করি তবে আমরা গণনার শক্তি এবং সময় নষ্ট করছি।
এটি সমাধানের একটি উপায়, যেমন আপনি উল্লেখ করেছেন যে, রাস্তাঘাটটি কিছুটা ক্ষুধার দ্বারপ্রান্তে পৌঁছানোর পরে শেষ করা। এটি পক্ষপাতও যুক্ত করে।
একটি দোরের পরে ক্ল্যাম্পিং, কাজ করবে , কিন্তু আবার, আমরা কীভাবে প্রান্তিকতাটি বেছে নেব ? যদি আমরা খুব বড় চয়ন করি তবে চিত্রটি দৃশ্যমান পক্ষপাতী, খুব ছোট হবে এবং আমরা সংস্থানগুলি নষ্ট করছি।
রাশিয়ান রুলেট নিরপেক্ষভাবে এই সমস্যাগুলি সমাধান করার চেষ্টা করে। প্রথমত, এখানে কোডটি রয়েছে:
void RenderPixel(uint x, uint y, UniformSampler *sampler) {
Ray ray = m_scene->Camera.CalculateRayFromPixel(x, y, sampler);
float3 color(0.0f);
float3 throughput(1.0f);
// Bounce the ray around the scene
for (uint bounces = 0; bounces < 10; ++bounces) {
m_scene->Intersect(ray);
// The ray missed. Return the background color
if (ray.geomID == RTC_INVALID_GEOMETRY_ID) {
color += throughput * float3(0.846f, 0.933f, 0.949f);
break;
}
// We hit an object
// Fetch the material
Material *material = m_scene->GetMaterial(ray.geomID);
// The object might be emissive. If so, it will have a corresponding light
// Otherwise, GetLight will return nullptr
Light *light = m_scene->GetLight(ray.geomID);
// If we hit a light, add the emmisive light
if (light != nullptr) {
color += throughput * light->Le();
}
float3 normal = normalize(ray.Ng);
float3 wo = normalize(-ray.dir);
float3 surfacePos = ray.org + ray.dir * ray.tfar;
// Get the new ray direction
// Choose the direction based on the material
float3 wi = material->Sample(wo, normal, sampler);
float pdf = material->Pdf(wi, normal);
// Accumulate the brdf attenuation
throughput = throughput * material->Eval(wi, wo, normal) / pdf;
// Russian Roulette
// Randomly terminate a path with a probability inversely equal to the throughput
float p = std::max(throughput.x, std::max(throughput.y, throughput.z));
if (sampler->NextFloat() > p) {
break;
}
// Add the energy we 'lose' by randomly terminating paths
throughput *= 1 / p;
// Shoot a new ray
// Set the origin at the intersection point
ray.org = surfacePos;
// Reset the other ray properties
ray.dir = wi;
ray.tnear = 0.001f;
ray.tfar = embree::inf;
ray.geomID = RTC_INVALID_GEOMETRY_ID;
ray.primID = RTC_INVALID_GEOMETRY_ID;
ray.instID = RTC_INVALID_GEOMETRY_ID;
ray.mask = 0xFFFFFFFF;
ray.time = 0.0f;
}
m_scene->Camera.FrameBuffer.SplatPixel(x, y, color);
}
রাশিয়ান রুলেট এলোমেলোভাবে একটি সম্ভাবনা বিপরীতভাবে থ্রুপুট সমান একটি পথ অবসান করে। সুতরাং দৃশ্যে খুব বেশি অবদান রাখে না এমন কম থ্রুপুট সহ পাথগুলি বন্ধ হওয়ার সম্ভাবনা বেশি।
আমরা যদি সেখানে থামি তবে আমরা পক্ষপাতদুষ্ট। আমরা এলোমেলোভাবে শেষ করি সেই পথটির শক্তি আমরা 'হারাতে' পারি। একে পক্ষপাতহীন করার জন্য, আমরা তাদের অবসান হওয়ার সম্ভাবনা দ্বারা অ-টার্মিনেটেড পাথের শক্তি বাড়িয়ে তুলি। এটি এলোমেলো হওয়ার পাশাপাশি রাশিয়ান রুলেটকে নিরপেক্ষ করে তোলে।
আপনার শেষ প্রশ্নের উত্তর দিতে:
- রাশিয়ান রুলেট কি নিরপেক্ষ ফলাফল দেয়?
- নিরপেক্ষ ফলাফলের জন্য কি রাশিয়ান রুলেট প্রয়োজনীয়?
- নিরপেক্ষতার দ্বারা আপনি কী বোঝাতে চান তার উপর নির্ভর করে। আপনি যদি গণিত বলতে চান, তবে হ্যাঁ। তবে, আপনি যদি দৃষ্টিভঙ্গি বলতে চান, তবে না no আপনাকে কেবল খুব সাবধানতার সাথে আপনার সর্বোচ্চ পথের গভীরতা এবং কাট অফের প্রান্তিকে বেছে নিতে হবে। এটি দৃশ্য থেকে দৃশ্যে পরিবর্তিত হতে পারে বলে এটি খুব ক্লান্তিকর হতে পারে।
- আপনি কি একটি স্থির সম্ভাবনা (কাট-অফ) ব্যবহার করতে পারেন এবং তারপরে 'হারানো' শক্তিটি পুনরায় বিতরণ করতে পারেন। এটা কি নিরপেক্ষ?
- আপনি যদি একটি স্থির সম্ভাবনা ব্যবহার করেন তবে আপনি পক্ষপাতিত্ব যুক্ত করছেন। 'হারানো' শক্তি পুনরায় বিতরণ করে আপনি পক্ষপাত হ্রাস করেন তবে এটি এখনও গাণিতিকভাবে পক্ষপাতদুষ্ট। সম্পূর্ণ পক্ষপাতহীন হওয়ার জন্য এটি অবশ্যই এলোমেলো হতে হবে।
- যদি তার শক্তি পুনরায় বিতরণ না করেই একটি রশ্মি বন্ধ করে যে শক্তিটি নষ্ট হয়ে যায় শেষ পর্যন্ত যেভাবে হ্রাস পায় (যে রেগুলিতে এটি পুনরায় বিতরণ করা হয় তাও শেষ পর্যন্ত সমাপ্ত হয়), কীভাবে পরিস্থিতির উন্নতি হয়?
- রাশিয়ান রুলেট কেবল বাউন্সিং থামায়। এটি নমুনা পুরোপুরি সরিয়ে দেয় না। এছাড়াও, 'হারিয়ে যাওয়া' শক্তিটি সমাপ্তির অবধি বাউন্সে গণ্য হয়। সুতরাং শক্তিটি 'শেষ পর্যন্ত যেভাবেই হারাতে পারে' হওয়ার একমাত্র উপায় হ'ল সম্পূর্ণ কালো ঘর।
শেষ পর্যন্ত, রাশিয়ান রুলেট একটি খুব সাধারণ অ্যালগরিদম যা খুব সামান্য পরিমাণে অতিরিক্ত গুণগত সংস্থান ব্যবহার করে। বিনিময়ে, এটি প্রচুর পরিমাণে গণ্য সংস্থান সংরক্ষণ করতে পারে। সুতরাং, আমি সত্যিই এটি ব্যবহার না করার কারণ দেখতে পাচ্ছি না ।
to be completely unbiased it must be random
। আমি মনে করি আপনি এখনও রাশিয়ান রুলেটকে চাপানো বাইনারি পাস / ড্রপের চেয়ে নমুনাগুলির ভগ্নাংশ ওয়েগিং ব্যবহার করে গণিত-ঠিকানার ফলাফল অর্জন করতে পারেন, এটি কেবলমাত্র রউলেট দ্রুত রূপান্তরিত করবে কারণ এটি একটি নিখুঁত গুরুত্বের নমুনা পরিচালনা করছে।