Saturday, August 23, 2014

Sponza рэндэрлэх оролдлого 18, Deferred rendering - final

Sponza цувралаа үргэлжлүүлэлгүй их удсан байна. Өмнөх хэсэгт deferred rendering арга хэрэглээд буруу үр дүнд хүрсэнээр зогссон байгаа. Энэ удаа гүйцэт болгосныгоо тэмдэглэж үлдээе гэж саналаа.

geometry pass vertex shader
#version 330

layout(location=0) in vec4 in_position;
layout(location=1) in vec3 in_normal;
layout(location=2) in vec2 in_texcoord;
layout(location=3) in vec3 in_tangent;
layout(location=4) in vec3 in_bitangent;

uniform mat4  u_Projection;
uniform mat4  u_View;
uniform mat4  u_World;

out vec3 v_NormalVS;
out vec3 v_TangentVS;
out vec3 v_BitangentVS;
out vec2 v_TexCoord;


void main(void)
{
    mat3 world3    = mat3(u_World);
    mat3 view3     = mat3(u_View);
    vec4 world_pos = u_World * in_position;
    vec4 view_pos  = u_View * world_pos;
    v_NormalVS     = view3 * world3 * in_normal;
    v_TangentVS    = view3 * world3 * in_tangent;
    v_BitangentVS  = view3 * world3 * in_bitangent;
    v_TexCoord     = in_texcoord;

    gl_Position = u_Projection * view_pos;
}

geometry pass fragment shader
#version 330

precision highp float;
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 vec3      material_diffuse_color;
uniform vec3      material_ambient_color;
uniform vec3      material_specular_color;
uniform vec3      material_emissive_color;
uniform int       hasDiffuseMap;
uniform int       hasNormalMap;
uniform int       hasAmbientMap;
uniform int       hasSpecularMap;
uniform int       hasOpacityMap;

in vec3 v_NormalVS;
in vec3 v_TangentVS;
in vec3 v_BitangentVS;
in vec2 v_TexCoord;

out vec4 out_color;  // albedo
out vec4 out_normal; // view space normal

vec4 encode(vec3 normal) 
{
    float p = sqrt(normal.z*8.0 + 8.0);
    return vec4(normal.xy/p + 0.5,0,0);
}

void main(void)
{
    vec3 diffuseColor  = texture2D(material_diffuse_texture , v_TexCoord).rgb;
    vec3 normal        = normalize(texture2D(material_normal_texture  , v_TexCoord).rgb*2.0 - 1.0);
    vec3 ambientColor  = texture2D(material_ambient_texture , v_TexCoord).rgb;
    vec3 specularColor = texture2D(material_specular_texture, v_TexCoord).rgb;
    vec3 opacityColor  = texture2D(material_opacity_texture , v_TexCoord).rgb;
    if (hasAmbientMap==0) ambientColor = diffuseColor;
    if (hasDiffuseMap==0) diffuseColor = material_diffuse_color;
    
    if (hasNormalMap != 0) {
        vec3 N = normalize(v_NormalVS);
        vec3 T = normalize(v_TangentVS);
        vec3 B = normalize(v_BitangentVS);
        mat3 TBN = mat3(T, B, N);
        normal = normalize(TBN * normal);
    } else {
        normal = v_NormalVS;
    }
   
    if (hasOpacityMap!=0){
        if (opacityColor==vec3(0,0,0))
            discard;
        else {
            out_color  = vec4(diffuseColor, 1.0);
            out_normal = encode(normal);
        }
    } else {
        out_color  = vec4(diffuseColor, 1.0);
        out_normal = encode(normal);       
    }
}

lighting pass vertex shader
#version 330
layout(location=0) in vec3 in_position;

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

lighting pass fragment shader
#version 330

precision highp float;

uniform sampler2D u_DiffuseTex;
uniform sampler2D u_NormalTex;
uniform sampler2D u_DepthTex;
uniform mat4      u_InvProj;
uniform vec2      u_Viewport;
uniform vec3      u_LightColor;
uniform vec3      u_LightPosition;
uniform float     u_LightSize;

out vec4 out_color;

vec3 decode(vec2 encoded)
{
    vec2 fenc = encoded*4.0 - 2.0;
    float f = dot(fenc, fenc);
    float g = sqrt(1.0 - f/4.0);
    vec3 normal;
    normal.xy = fenc*g;
    normal.z = 1.0 - f/2.0;
    return normal;
}

void main(void)
{
    vec2 tex_coord = vec2(gl_FragCoord.x, gl_FragCoord.y)/u_Viewport; // map to [0..1]
    
    vec3 albedo = texture2D(u_DiffuseTex, tex_coord).rgb;
    vec3 normal = decode(texture2D(u_NormalTex, tex_coord).rg);
    float depth = texture2D(u_DepthTex, tex_coord).r;
    
    // Calculate the pixel's position in view space
    vec4 view_pos = vec4(tex_coord*2.0-1.0, depth*2.0-1.0, 1.0);
    view_pos = u_InvProj * view_pos;
    view_pos /= view_pos.w;

    vec3 light_dir = u_LightPosition - view_pos.xyz;
    float dist = length(light_dir);
    float size = u_LightSize;
    float attenuation = 1.0 - pow(clamp(dist/size, 0.0, 1.0), 2.0);
    light_dir = normalize(light_dir);

    // diffuse lighting calculation
    float n_dot_l = clamp(dot(light_dir, normal), 0.0, 1.0);
    vec3 diffuse = u_LightColor * n_dot_l;

    vec3 final_lighting = attenuation * diffuse;

    out_color = vec4(final_lighting * albedo, 1.0);
}

Albedo
Depth
Normal
Deferred Rendering эхний үр дүн
Deferred Rendering. хөдлөж байгаа олон гэрэл
Одоогоор зөвхөн Lambert-ийн diffuse lighting хэрэглэсэн байгаа болохоор specular өнгө нь харагдахгүй байгаа болно. Цаашаагаа Phong-ийн алгоритм нэмж хэрэглээд specular өнгө нэмэгдсэн deferred shading хэрэгжүүлэлт хийнээ. Үр дүн нь яриангүй үнэмшилтэй харагдах нь дамжиггүй.