मैं LearnOpenGL विधि का उपयोग किए बिना ओपनजीएल पर प्रतिबिंब सीखने की कोशिश कर रहा हूं, लेकिन मैं यह नहीं समझ सकता कि प्रतिबिंबों में क्या गलत है। ऐसा लगता है कि कैमरे के दृश्य के कुछ हिस्सों में किसी प्रकार का युद्ध और फ़्लिप हो रहा है। अब तक, मैं केवल कोड के लिए व्यू मैट्रिक्स का उपयोग कर रहा हूं।

इस प्रकार गोलाकार प्रतिबिंब दिखता है।

मैंने क्यूब का उपयोग करने की भी कोशिश की। यहां तक ​​​​कि जब मेरा माउस सही चलता रहा, तो प्रतिबिंब विकृत हो गया और फिर वह छवि दिखा रहा था जो युद्ध से पहले मौजूद थी।

घन प्रतिबिंब

स्काईबॉक्स छवि

यह स्काईबॉक्स वर्टेक्स शेडर है

#version 330 core
layout (location = 0) in vec3 aPos;

out vec3 o_pos;

void main()
{
    o_pos = aPos;
    gl_Position = vec4(aPos, 1.0);
}

यह स्काईबॉक्स टुकड़ा शेडर है। मैं व्यू मैट्रिक्स को सीधे टुकड़े टुकड़े करने के लिए पास करता हूं।

#version 330 core
out vec4 FragColor;

in vec3 o_pos;

uniform vec3 view_up;
uniform vec3 view_right;
uniform vec3 view_forward;

uniform samplerCube cubeTex;

void main()
{
    vec3 pv = mat3(view_right, view_up, view_forward) * vec3(o_pos.xy, 1.0);
    FragColor = vec4(texture(cubeTex, pv).rgb, 1.0);
}

यह ऑब्जेक्ट वर्टेक्स शेडर है

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 normal;

out vec3 o_normal;
out vec3 o_pos;

void main()
{
    o_pos = aPos;
    o_normal = normal;
    gl_Position = vec4(o_pos, 1.0f);
}

यह वस्तु टुकड़ा शेडर है। यह Learnopengl shader के समान है।

#version 330 core
in vec3 o_pos;
in vec3 o_normal;

out vec4 fragColor;

uniform vec3 eye_pos;
uniform samplerCube cubeTex;

void main()
{
    vec3 incident = normalize(o_pos - eye_pos);
    vec3 reflection = reflect(incident, normalize(o_normal));
    fragColor = vec4(texture(cubeTex, reflection).rgb, 1.0);
}

यहाँ रेंडर लूप है

    while (!glfwWindowShouldClose(window))
    {
        // input
        processInput(window);

        // render
        glClearColor(0.9f, 0.8f, 0.5f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        // change view using mouse input
        double xpos, ypos;
        glfwGetCursorPos(window, &xpos, &ypos);
        ypos = (ypos/SCR_HEIGHT) * PI * PI * 0.5;
        xpos = (xpos/SCR_WIDTH) * 2 * PI - PI;
        if (ypos < PI/2) ypos = 1.6f;
        if (ypos > 3*PI/2) ypos = 4.7f;
        eye_forward = normalize(glm::vec3{(GLfloat)(cos(ypos) * cos(xpos)),
                                (GLfloat)sin(ypos),
                                (GLfloat)(cos(ypos) * sin(xpos))});
        eye_right = glm::normalize(glm::cross(eye_forward, glm::vec3{0.0, 1.0, 0.0}));
        eye_up = glm::cross(eye_right, eye_forward);

        // draw skybox
        glUseProgram(shaderProgram);
        glUniform1i(u_cubeTex, 0);
        glUniform3fv(u_view_up, 1, (GLfloat*)&eye_up);
        glUniform3fv(u_view_right, 1, (GLfloat*)&eye_right);
        glUniform3fv(u_view_forward, 1, (GLfloat*)&eye_forward);
        glBindVertexArray(vao);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, cube.size());

        // draw UV sphere
        glUseProgram(sphereProgram);
        glUniform1i(u_cubeTex2, 0);
        glUniform3fv(u_eye_pos, 1, (GLfloat*)&eye_forward);
        glBindVertexArray(sphereVAO);
        glDrawArrays(GL_TRIANGLE, 0, sphere.size());

        glfwSwapBuffers(window);
        glfwPollEvents();
    }
1
J. Chan 3 मार्च 2019, 13:38

1 उत्तर

सबसे बढ़िया उत्तर

eye_pos विश्व अंतरिक्ष में एक स्थान है।
o_pos व्यू स्पेस, क्लिप स्पेस और नॉर्मलाइज्ड डिवाइस स्पेस में एक पोजीशन है। आपके मामले में यह सब समान है, क्योंकि आपके पास प्रोजेक्शन मैट्रिक्स नहीं है और वर्टेक्स कोऑर्डिनेट एट्रीब्यूट सीधे वर्टेक्स शेडर में क्लिप स्पेस पोजीशन को सौंपा गया है:

 gl_Position = vec4(aPos, 1.0);

वैसे भी, एक विश्व अंतरिक्ष स्थिति से एक दृश्य स्थान की स्थिति में एक वेक्टर की गणना करने का कोई मतलब नहीं है, जैसा कि आप करते हैं:

 vec3 incident = normalize(o_pos - eye_pos);

दृश्य स्थान में आँख की स्थिति (0, 0, 0) है। तो घटना दृश्य वेक्टर अंतरिक्ष में है:

vec3 incident = normalize(o_pos - vec3(0.0, 0.0, 0.0));

इस वेक्टर को फॉर्म व्यू स्पेस को वर्ल्ड स्पेस में बदलना होगा, जिसे व्यू के ओरिएंटेशन मैट्रिक्स (mat3(view_right, view_up, view_forward)) द्वारा हासिल किया जा सकता है, उसी तरह जैसे आप इसे स्काईबॉक्स फ्रैगमेंट शेडर में करते हैं:

vec3 incident = mat3(view_right, view_up, view_forward) * normalize(o_pos);

सामान्य वेक्टर o_normal एक व्यू स्पेस वेक्टर भी है। तो इसे विश्व अंतरिक्ष में बदलना होगा:

vec3 wordlNormal = mat3(view_right, view_up, view_forward) * normalize(o_normal);

घटना वेक्टर और सामान्य वेक्टर को बदलने के बजाय, प्रतिबिंब के बाद परिणामी वेक्टर को बदलना संभव है।
अपनी समस्या को हल करने के लिए आपको ऑब्जेक्ट टुकड़ा शेडर बदलना होगा:

#version 330 core

in vec3 o_pos;
in vec3 o_normal;

out vec4 fragColor;

uniform vec3 view_up;
uniform vec3 view_right;
uniform vec3 view_forward;
uniform samplerCube cubeTex;

void main()
{
    mat3 invNormalM      = mat3(view_right, view_up, view_forward);

    vec3 viewIncident    = normalize(o_pos);
    vec3 viewNormal      = normalize(o_normal);
    vec3 worldReflection = invNormalM * reflect(viewIncident, viewNormal);

    fragColor            = vec4(texture(cubeTex, worldReflection).rgb, 1.0);
}

मैं व्यू मैट्रिक्स को सीधे टुकड़े टुकड़े करने के लिए पास करता हूं।

mat3(view_right, view_up, view_forward) व्यू मैट्रिक्स नहीं है। यह कैमरे का ओरिएंटेशन मैट्रिक्स है। तो यह उलटा दृश्य (सामान्य) मैट्रिक्स है।

1
Rabbid76 3 मार्च 2019, 12:15