您的位置:首页 > 运维架构

OpenGL4.0 GLSL 实现逐片元光照模型 提高场景真实性

2014-02-12 10:48 316 查看
当计算光照模型(如ADS模型)的时候,通常是在vertex shader中计算每个顶点的颜色值,然后通过这些顶点插值 传入fragment shader中,这些被称为Gouraud shading.

Gouraud shading.模型有一些不尽人意的地方,例如,高光(bright specular highlight)可能在一个polygon的中间,这样通过这种模型计算就会影响高光显示效果。

为了提高渲染结果的准确性,我们可以把计算光照模型的计算 放到fragment shader 中进行,我们通过插值物体表面的顶点和发向 而不是每个顶点的颜色,传递到fragment shader 中进行光照模型计算,这项技术程为:Phong shader 或者是 Phong interpolation 。这样通过phong shader 光照模型可以大大提高场景的真实性,但也会有一些小的瑕疵。

如图:Gouraud and Phong shading 对比



左边是Gouraud (per-vertex) shading,右边是Phong(per-fragment)shading。 在途中可以看出 右边的效果要比左边的效果更真实些。

顶点shader

#version 430

layout (location = 0) in vec3 VertexPosition;
layout (location = 1) in vec3 VertexNormal;

out vec3 Position;
out vec3 Normal;

uniform mat4 ModelViewMatrix;
uniform mat3 NormalMatrix;
uniform mat4 ProjectionMatrix;
uniform mat4 MVP;

void main()
{
    Normal = normalize( NormalMatrix * VertexNormal);
    Position = vec3( ModelViewMatrix * vec4(VertexPosition,1.0) );

    gl_Position = MVP * vec4(VertexPosition,1.0);
}


片元shader

#version 430

in vec3 Position;
in vec3 Normal;

uniform vec4 LightPosition;
uniform vec3 LightIntensity;

uniform vec3 Kd;            // Diffuse reflectivity
uniform vec3 Ka;            // Ambient reflectivity
uniform vec3 Ks;            // Specular reflectivity
uniform float Shininess;    // Specular shininess factor

layout( location = 0 ) out vec4 FragColor;

vec3 ads( )
{
    vec3 s = normalize( vec3(LightPosition) - Position );
    vec3 v = normalize(vec3(-Position));
    vec3 r = reflect( -s, Normal );

    return
        LightIntensity * ( Ka +
          Kd * max( dot(s, Normal), 0.0 ) +
          Ks * pow( max( dot(r,v), 0.0 ), Shininess ) );
}

void main() {
    FragColor = vec4(ads(), 1.0);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: