প্রথমবারের ছায়া ম্যাপিংয়ের সমস্যা


9

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

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

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

দ্বিতীয় পাসে, আমি উপরের এমভিপি ম্যাট্রিক্সকে আলোক বিন্দু থেকে ভার্টেক্স শ্যাডারে প্রেরণ করি যা অবস্থানটি হালকা জায়গায় স্থানান্তর করে। টুকরা শেডার দৃষ্টিকোণকে ভাগ করে দেয় এবং অবস্থানের কাঠামো স্থানাঙ্কে পরিবর্তন করে।

এখানে আমার ভার্টেক্স শেডার,


#version 150 core

uniform mat4 ModelViewMatrix;
uniform mat3 NormalMatrix;
uniform mat4 MVPMatrix;
uniform mat4 lightMVP;

uniform float scale;

in vec3 in_Position;
in vec3 in_Normal;
in vec2 in_TexCoord;

smooth out vec3 pass_Normal;
smooth out vec3 pass_Position;
smooth out vec2 TexCoord;
smooth out vec4 lightspace_Position;

void main(void){
    pass_Normal = NormalMatrix * in_Normal; 
    pass_Position = (ModelViewMatrix * vec4(scale * in_Position, 1.0)).xyz;
    lightspace_Position = lightMVP * vec4(scale * in_Position, 1.0);
    TexCoord = in_TexCoord;

    gl_Position = MVPMatrix * vec4(scale * in_Position, 1.0);
}

এবং আমার টুকরা শেডার,


#version 150 core

struct Light{
    vec3 direction;
};

uniform Light light;
uniform sampler2D inSampler;
uniform sampler2D inShadowMap;

smooth in vec3 pass_Normal;
smooth in vec3 pass_Position;
smooth in vec2 TexCoord;
smooth in vec4 lightspace_Position;

out vec4 out_Color;


float CalcShadowFactor(vec4 lightspace_Position){

    vec3 ProjectionCoords = lightspace_Position.xyz / lightspace_Position.w;

    vec2 UVCoords;
    UVCoords.x = 0.5 * ProjectionCoords.x + 0.5;
    UVCoords.y = 0.5 * ProjectionCoords.y + 0.5;

    float Depth = texture(inShadowMap, UVCoords).x;
    if(Depth < (ProjectionCoords.z + 0.001)) return 0.5;
    else return 1.0;
}

void main(void){

    vec3 Normal = normalize(pass_Normal);
    vec3 light_Direction = -normalize(light.direction);
    vec3 camera_Direction = normalize(-pass_Position);
    vec3 half_vector = normalize(camera_Direction + light_Direction);

    float diffuse = max(0.2, dot(Normal, light_Direction));
    vec3 temp_Color = diffuse * vec3(1.0);

    float specular = max( 0.0, dot( Normal, half_vector) );

    float shadowFactor = CalcShadowFactor(lightspace_Position);

    if(diffuse != 0 && shadowFactor > 0.5){
        float fspecular = pow(specular, 128.0);
        temp_Color += fspecular;
    }

    out_Color = vec4(shadowFactor * texture(inSampler, TexCoord).xyz * temp_Color, 1.0);
}

সমস্যার মধ্যে একটি হ'ল স্ব-ছায়াময় হওয়া যেমন আপনি ছবিতে দেখতে পাচ্ছেন, ক্রেটের নিজের নিজস্ব ছায়া রয়েছে। আমি যা চেষ্টা করেছি তা হ'ল বহুভুজ অফসেট সক্ষম করা (অর্থাত্ glEnable (POLYGON_OFFSET_FILL), glPolygonOffset (GLfloat, GLfloat)) তবে এটি খুব বেশি পরিবর্তন হয়নি। আপনি যেমন খণ্ড শেডারটিতে দেখতে পাচ্ছেন, আমি 0.001 এর একটি স্ট্যাটিক অফসেট মান রেখেছি তবে আরও আকাঙ্ক্ষিত প্রভাব পেতে আলোর দূরত্বের উপর নির্ভর করে মানটি পরিবর্তন করতে হবে, যা খুব সহজ নয়। ফ্রেমবফারটি রেন্ডার করার সময় আমি সম্মুখ মুখ কুলিং ব্যবহার করার চেষ্টা করেছি, এটি খুব বেশি পরিবর্তন হয়নি।

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

কিছুটা গুগল করা থেকে, আমি বুঝতে পারি যে এই বিষয়গুলি তুচ্ছ নয়। কারও কাছে এই সমস্যার সমাধান কার্যকর করার কোনও সহজ কি আছে? আপনি আমাকে কিছু অতিরিক্ত টিপস দিতে পারেন?

আপনি যদি আমার কোড সম্পর্কে আরও তথ্য প্রয়োজন দয়া করে আমাকে জিজ্ঞাসা করুন।

এখানে ক্রেটের ক্লোজ-আপের ছায়া ম্যাপিংয়ের সাথে এবং ছাড়াই একটি তুলনা করা হচ্ছে। স্ব-ছায়াময় আরও বেশি দৃশ্যমান।


দেখে মনে হচ্ছে আপনার সমস্যা (গুলি) আরও বিশদে বর্ণনা করা উচিত। আপনার সমস্যা সম্পর্কে আপনার একটি বাক্য রয়েছে এবং পরবর্তী বাক্যটিতে একটির জন্য একটি সমাধানের পরামর্শ দেওয়া হয়। আমাদের বলুন ঠিক কি সমস্যা আছে এবং আপনি কি ইতিমধ্যে সম্পন্ন করেছি চেষ্টা করুন এবং এটি ঠিক করার।
MichaelHouse

আমি আমার পোস্টটি সম্পাদনা করেছি, আশা করি এটি এখন আরও ভাল।
গ্রিভারহার্ট

উত্তর:


6

আলোর মুখোমুখি বহুভুজগুলি আপনাকে ছায়া করা উচিত নয়।

আমি আপনার খণ্ডের শেডারটিকে নীচের কোডে পরিবর্তন করেছি।

float CalcShadowFactor(vec4 lightspace_Position)
{

    vec3 ProjectionCoords = lightspace_Position.xyz / lightspace_Position.w;

    vec2 UVCoords;
    UVCoords.x = 0.5 * ProjectionCoords.x + 0.5;
    UVCoords.y = 0.5 * ProjectionCoords.y + 0.5;

    float Depth = texture(inShadowMap, UVCoords).x;
    if(Depth < (ProjectionCoords.z + 0.001)) return 0.5;
    else return 1.0;
}

void main(void)
{

    vec3 Normal = normalize(pass_Normal);
    vec3 light_Direction = -normalize(light.direction);
    vec3 camera_Direction = normalize(-pass_Position);
    vec3 half_vector = normalize(camera_Direction + light_Direction);

    float fndotl = dot(Normal, light_Direction);
    float shadowFactor = CalcShadowFactor(lightspace_Position);
    float diffuse = max(0.0, fndotl) * shadowFactor + 0.2;
    vec3 temp_Color = vec3(diffuse);

    float specular = max( 0.0, dot( Normal, half_vector) );

    if(shadowFactor > 0.9){
        float fspecular = pow(specular, 128.0);
        temp_Color += fspecular;
    }

    out_Color = vec4(shadowFactor * texture(inSampler, TexCoord).xyz * temp_Color, 1.0);
}

8

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

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

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

পিক্সেল শেডারকে কেবলমাত্র আলোর ভিউ হতাশায় পিক্সেলগুলি আঁকতে সীমাবদ্ধ করতে, একবার আপনি ছায়ার মানচিত্রের ইউভিগুলি গণনা করুন কেবল সেগুলি 0 থেকে 1 এর মধ্যে রয়েছে discardকিনা এবং না (বা আলোর রঙটি শূন্যে সেট করুন) check আরেকটি উপায় হ'ল ছায়ার মানচিত্রের টেক্সচারটি "বর্ডার টু বর্ডার" মোডে সেট করা এবং শূন্যের একটি সীমানা রঙ সেট করা, যা ছায়া মানচিত্রের বাইরের সমস্ত কিছু পুরোপুরি ছায়াময় হয়ে যায় তা নিশ্চিত করবে।


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

ঠিক আছে, এই শটে এটি ছায়া ব্রণের মতো দেখাচ্ছে look ছায়া মানচিত্রে মুখগুলি আঁকলে (এবং সম্মুখ মুখগুলি নয়) এটি ঠিক করা উচিত। আমি জানি আপনি বলেছেন যে আপনি চেষ্টা করেছিলেন, তবে সম্ভবত কিছু ভুল হয়েছে? এটা ঠিক glCullFace(GL_FRONT)। দিকনির্দেশনা বনাম দিকনির্দেশনা হিসাবে, এটি রশ্মির সমস্ত কিছুই। ক্যামেরা রশ্মি একটি দৃষ্টিকোণে একটি বিন্দুতে রূপান্তরিত করে ক্যামেরা এবং হালকা রশ্মি বিন্দু আলোতে একটি বিন্দুতে রূপান্তর করে; ক্যামেরা রশ্মি একটি অর্থোগ্রাফিক ক্যামেরার জন্য সমান্তরাল এবং হালকা রশ্মি একটি নির্দেশিক আলোর জন্য সমান্তরাল l
নাথান রেড

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

যারা দেখতে একই রকম। আপনি দৃশ্যের বাকি অংশের জন্য ব্যাক-ফেস কুলিং ব্যবহার করছেন, তাই না? তুমি কি করেছ glEnable(GL_CULL_FACE)?
নাথান রেড

এগুলি হুবহু এক নয়, বাক্সটি ঘনিষ্ঠভাবে দেখুন। উপরের ছবিতে, ছায়া রেখাটি উত্তল এবং নীচের অংশের একটি অবতল রয়েছে।
গ্রিভারহার্ট

3

লাইট ভিউয়ের বাইরের পিক্সেলগুলি অন্ধকার কারণ তারা লাইটের গভীরতার টেক্সচারের বাইরে থেকে নমুনা তৈরি করছে।

আপনি যখন প্রজেকশন ম্যাট্রিক্স দ্বারা শীর্ষ প্রান্তকে রূপান্তর করবেন আপনি খণ্ডটির ক্লিপ স্থানাঙ্ক [লাইটস্পেস_পজিশন] পাবেন। তারপরে আপনি এটিকে টেক্সচারের স্থানাঙ্কে [ইউভিকর্ডস] এ রূপান্তর করছেন। যাইহোক, কোনও খণ্ডের ক্লিপ স্পেস স্থানাঙ্কগুলি এখনও -1.0 থেকে 1.0 পরিসরের (পর্দার বাইরে এবং তাই ক্লিপড) বাইরে থাকতে পারে এবং তাই রূপান্তরিত জমিনের স্থানাঙ্কগুলি আপনার টেক্সচারের 0.0 থেকে 1.0 রেঞ্জের বাইরে থাকতে পারে।

এটা চেষ্টা কর:

if(UVCoords.x >= 0.0 && UVCoords.x <= 1.0 && UVCoords.y >= 0.0 && UVCoords.y <= 1.0 && (Depth < (ProjectionCoords.z + 0.001)))
    return 0.5;

আপনি আপনার [লাইটএমভিপি] তে একটি বায়াস ম্যাট্রিক্সকেও গুণ করতে পারেন এবং আপনার খণ্ড শেডারটিতে স্থানাঙ্ক রূপান্তর করা এড়াতে পারেন।


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