Sponza рэндэрлэх оролдлого 12, Point Light буруу гэрэлтүүлэг

Өмнөх normal mapping хийгдсэн код маань хэдийгээр боломжийн хэмжээнд ажиллаж байсан боловч үр дүн нь нэг л санаан нийцэхгүй байлаа яагаад гэвэл point light гэрэлтүүлэг хийсэн атал ойролцоох орчингоо гэрэлтүүлж байгаа байдал нь нэг л буруу геометрийн хэлбэртэй байв.
Гэрэлтүүлэхдээ уртаашаа сунасан гэрэл гарч байлаа.



Vertex Shader -ээ дахин нягталбал normal вектор хувиргах TBN матриц маань view огторгуйд хэрэглэгдэхэд бэлэн болсон байхад аль хэдийн viewMatrix аар үржсэн утгыг TBN ашиглаж үржиж байв. Өөрөөр хэлбэл view-space оруулаад дахиад view-space-руу оруулахыг оролдсон байна гэсэн үг. Доор буруу ажиллагаатай кодыг тавьлаа.
#version 330
layout(location=0) in vec4 in_position; // model-space
layout(location=1) in vec3 in_normal;   // model-space
layout(location=2) in vec2 in_texcoord;
layout(location=3) in vec3 in_tangent;
layout(location=4) in vec3 in_bitangent;

out vec2 vTexcoord;
out vec3 vPosition; // view-space
out vec3 vNormal;   // view-space
out vec3 vEyeDir;   // view-space
out vec3 vLightDir; // view-space
out vec3 vLightPosition; // viewSpace
uniform mat4 mvpMatrix;
uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat3 normalMatrix;

uniform int hasNormalMap;
uniform vec3 lightPosition; // world-space

void main(void)
{
    gl_Position = mvpMatrix * in_position;
    
    vTexcoord = in_texcoord;
    
    vPosition = (viewMatrix * modelMatrix * in_position).xyz;
    vLightPosition = (viewMatrix * vec4(lightPosition, 1.0)).xyz;
    
    vNormal = (normalMatrix * in_normal).xyz;
    
    vec3 tbnNormal    = normalize(vNormal);
    vec3 tbnTangent   = normalize(normalMatrix * in_tangent);
    //vec3 tbnBitangent = normalize(normalMatrix * in_bitangent);
    vec3 tbnBitangent  = normalize(cross(tbnNormal, tbnTangent));
    mat3 tbnMatrix = transpose(mat3(tbnTangent, tbnBitangent, tbnNormal));
    
    vec3 posInEyespace = (viewMatrix * modelMatrix * in_position).xyz;
    vEyeDir = vec3(0,0,0) - posInEyespace;

    vec3 lightPosInEyespace = (viewMatrix * vec4(lightPosition, 1.0)).xyz;
    vLightDir = lightPosInEyespace + vEyeDir;


    vLightDir = normalize(tbnMatrix * vLightDir);
    vNormal   = normalize(tbnMatrix * vNormal);
    
}

vLightDir болон vNormal хоёр аль хэдийн view-space дотор орсон байгаад энэ кодны алдаа байна. Тэгвэл энийг засая. Хэрэв shader маань normal texture-тэй байвал vLight, vNormal хоёрыг бүүр эхний хувиргагдаагүй model-space доторхи байх утгыг нь ашиглаж tbn матрицаараа үржин view-space доторхи normal болон гэрлийн утгуудаа гаргаж авая.
#version 330
layout(location=0) in vec4 in_position; // model-space
layout(location=1) in vec3 in_normal;   // model-space
layout(location=2) in vec2 in_texcoord;
layout(location=3) in vec3 in_tangent;
layout(location=4) in vec3 in_bitangent;

out vec2 vTexcoord;
out vec3 vPosition; // view-space
out vec3 vNormal;   // view-space
out vec3 vEyeDir;   // view-space
out vec3 vLightDir; // view-space
out vec3 vLightPosition; // viewSpace
uniform mat4 mvpMatrix;
uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat3 normalMatrix;

uniform int hasNormalMap;
uniform vec3 lightPosition; // world-space

void main(void)
{
    gl_Position = mvpMatrix * in_position;
    
    vTexcoord = in_texcoord;
    
    vPosition = (viewMatrix * modelMatrix * in_position).xyz;
    vLightPosition = (viewMatrix * vec4(lightPosition, 1.0)).xyz;
    
    vNormal = (normalMatrix * in_normal).xyz;
    
    vec3 tbnNormal    = normalize(vNormal);
    vec3 tbnTangent   = normalize(normalMatrix * in_tangent);
    //vec3 tbnBitangent = normalize(normalMatrix * in_bitangent);
    vec3 tbnBitangent  = normalize(cross(tbnNormal, tbnTangent));
    mat3 tbnMatrix = transpose(mat3(tbnTangent, tbnBitangent, tbnNormal));
    
    vec3 posInEyespace = (viewMatrix * modelMatrix * in_position).xyz;
    vEyeDir = vec3(0,0,0) - posInEyespace;

    vec3 lightPosInEyespace = (viewMatrix * vec4(lightPosition, 1.0)).xyz;
    vLightDir = lightPosInEyespace + vEyeDir;

    if (hasNormalMap==1) {
        vNormal = normalize(tbnMatrix * in_normal);
        vec3 tempLightPos = (tbnMatrix * lightPosition).xyz;
        vLightDir = tempLightPos + vEyeDir;
    }
}

Fragment Shader нь
#version 330
uniform sampler2D material_diffuse_texture;
uniform sampler2D material_normal_texture;
uniform sampler2D material_ambient_texture;
uniform sampler2D material_specular_texture;
uniform sampler2D material_opacity_texture;
uniform float     material_shininess; 
uniform vec4      material_diffuse_color;

uniform int hasOpacityMap;
uniform int hasAmbientMap;
uniform int hasNormalMap;
uniform int hasSpecularMap;

uniform float ambientIntensity;

//uniform vec3 lightPosition; // world-space
uniform vec3 spotDir;

in vec2 vTexcoord;
in vec3 vPosition; // world-space, view-space
in vec3 vNormal;   // view-space
in vec3 vEyeDir;   // view-space
in vec3 vLightDir; // view-space
in vec3 vLightPosition;
out vec4 out_color;

void main(void)
{
    vec3 lightColor = vec3(1.0, 1.0, 1.0);

    vec4 diffuseColor  = texture2D(material_diffuse_texture, vTexcoord);
    vec4 ambientColor  = texture2D(material_ambient_texture, vTexcoord);
    vec4 normalColor   = vec4(texture2D(material_normal_texture , vTexcoord).xyz, 1.0);
    vec4 specularColor = texture2D(material_specular_texture, vTexcoord);
    vec4 opacityColor  = texture2D(material_opacity_texture, vTexcoord);

    if (hasAmbientMap==0) {
        ambientColor = diffuseColor;
    }

    vec4 resAmbientColor  = vec4(0, 0, 0, 0);
    vec4 resDiffuseColor  = vec4(0, 0, 0, 0);
    vec4 resSpecularColor = vec4(0, 0, 0, 0);
    vec4 resultColor      = vec4(0, 0, 0, 0);

    // ambient calculation
    float ambientFraction = 0.25;
    resAmbientColor = vec4((ambientFraction * lightColor * ambientColor.xyz).xyz, 1.0);
    //resAmbientColor = vec4((ambientFraction * ambientColor.xyz).xyz, 1.0);
    
    vec3 normal = normalize(vNormal);
    if (hasNormalMap != 0) {
        vec3 nTex = normalColor.xyz;
        normal = nTex * 2.0 - 1.0;
        normal = normalize(normal);
    }
    vec3 lightDirection = normalize(vLightDir);

    // diffuse calculation, lambertian cosinus
    float lambertcos = max(0.0, dot(normal, lightDirection));
    resDiffuseColor = vec4((lightColor * diffuseColor.xyz).xyz, 1.0);

    // specular calculation, blinn-phong
    float lightDistance = length(vLightPosition-vPosition);
    vec3 halfVector = normalize(normalize(vEyeDir) + lightDirection);
    // Blinn-Phong needs shininiess about 4 * Phong shininess
    float specularcoeff = pow(max(0.0, dot(normal, halfVector)), 4.0 * material_shininess); 
    resSpecularColor = vec4((specularcoeff * lightColor * specularColor.xyz).xyz, 1.0);

    float attenuation = 0.0;
    if (lambertcos>0.0) {
        float constant = 1.0;
        float linear   = 0.0014;
        float quadric  = 0.000007;
        attenuation = 1.0 / (constant + linear*lightDistance + quadric*lightDistance*lightDistance);
    } 
    //attenuation = 1.0;
    if (hasSpecularMap!=1) {
        resSpecularColor = vec4(0.347, 0.347, 0.347, 1.0);
    }

    //resultColor = clamp(resAmbientColor + attenuation *(resDiffuseColor + resSpecularColor), 0.0, 1.0);

    if (lambertcos>0.0) {
        resultColor = clamp(resAmbientColor + attenuation * lambertcos *(resDiffuseColor + resSpecularColor), 0.0, 1.0);
    } else {
        resultColor = clamp(resAmbientColor + attenuation * (resDiffuseColor + resSpecularColor), 0.0, 1.0);
    }
    
    if (hasOpacityMap!=0){
        if (opacityColor.rgb==vec3(0,0,0))
            discard;
        else
            out_color = resultColor;
    } else {
        out_color = resultColor;
    }   
}

Ингээд зөв point light гэрэлтүүлэгтэй боллоо.

Мөн normal гэрэлтүүлэг маань ч гэсэн зөв талдаа сүүдэрлэлттэй болсон байна.
Normal map гадаргуун деталийг нь илүү тодотгож өгдөг болохоор илүү үнэмшилтэй гадаргуу үүсч байна.






Popular posts from this blog

Apache Spark + Cassandra. Hello World