2014-12-02 87 views
0

我的镜面照明有一些问题,我有环境和漫反射,但我现在正在寻找镜面反射来尝试制作漂亮的模型。OpenGL中的高光照明问题

我在vertexShader如下:

#version 330 

layout (location = 0) in vec3 Position; 
layout (location = 1) in vec3 Normal; 

out vec4 Colour0; 

// Transforms 
uniform mat4 gModelToWorldTransform; 
uniform mat4 gWorldToViewToProjectionTransform; 

// Ambient light parameters 
uniform vec3 gAmbientLightIntensity; 

// Directional light parameters 
uniform vec3 gDirectionalLightIntensity; 
uniform vec3 gDirectionalLightDirection; 

// Material constants 
uniform float gKa; 
uniform float gKd; 
uniform float gKs; 
uniform float gKsStrength; 


void main() 
{ 
    // Transform the vertex from local space to homogeneous clip space 
    vec4 vertexPositionInModelSpace = vec4(Position, 1); 
    vec4 vertexInWorldSpace = gModelToWorldTransform * vertexPositionInModelSpace; 
    vec4 vertexInHomogeneousClipSpace = gWorldToViewToProjectionTransform * vertexInWorldSpace; 
    gl_Position = vertexInHomogeneousClipSpace; 

    // Calculate the directional light intensity at the vertex 
    // Find the normal in world space and normalise it 
    vec3 normalInWorldSpace = (gModelToWorldTransform * vec4(Normal, 0.0)).xyz; 
    normalInWorldSpace = normalize(normalInWorldSpace); 

    // Calculate the ambient light intensity at the vertex 
    // Ia = Ka * ambientLightIntensity 
    vec4 ambientLightIntensity = gKa * vec4(gAmbientLightIntensity, 1.0); 

    // Setup the light direction and normalise it 
    vec3 lightDirection = normalize(-gDirectionalLightDirection); 

    //lightDirection = normalize(gDirectionalLightDirection); 
    // Id = kd * lightItensity * N.L 
    // Calculate N.L 
    float diffuseFactor = dot(normalInWorldSpace, lightDirection); 
    diffuseFactor = clamp(diffuseFactor, 0.0, 1.0); 

    // N.L * light source colour * intensity 
    vec4 diffuseLightIntensity = gKd * vec4(gDirectionalLightIntensity, 1.0f) * diffuseFactor; 

    vec3 lightReflect = normalize(reflect(gDirectionalLightDirection, Normal)); 

    //Calculate the specular light intensity at the vertex 
    float specularFactor = dot(normalInWorldSpace, lightReflect); 
    specularFactor = pow(specularFactor, gKsStrength); 
    vec4 specularLightIntensity = gKs * vec4(gDirectionalLightIntensity, 1.0f) * specularFactor; 

    // Final vertex colour is the product of the vertex colour 
    // and the total light intensity at the vertex 

    vec4 colour = vec4(0.0, 1.0, 0.0, 1.0); 
    Colour0 = colour * (ambientLightIntensity + diffuseLightIntensity + specularLightIntensity); 
} 

然后在我main.cpp中我有一些代码,试图让这一起工作,镜面光肯定是做什么的,只是,而不是使模型看起来有光泽,这似乎加剧了光线,直到我看不到任何细节。

创建下列变量:

// Lighting uniforms location 

GLuint gAmbientLightIntensityLoc; 
GLuint gDirectionalLightIntensityLoc; 
GLuint gDirectionalLightDirectionLoc; 
GLuint gSpecularLightIntensityLoc; 

// Materials uniform location 
GLuint gKaLoc; 
GLuint gKdLoc; 
GLuint gKsLoc; 
GLuint gKsStrengthLoc; 

然后我把我的变量,像这样在renderSceneCallBack()功能被称为主:

// Set the material properties 
glUniform1f(gKaLoc, 0.2f); 
glUniform1f(gKdLoc, 0.9f); 
glUniform1f(gKsLoc, 0.5f); 
glUniform1f(gKsStrengthLoc, 0.5f); 

我然后创建一个initLights()功能,我想处理所有的照明,这也是主要的:

static void initLights() 
{ 
    // Setup the ambient light 
    vec3 ambientLightIntensity = vec3(0.2f, 0.2f, 0.2f); 
    glUniform3fv(gAmbientLightIntensityLoc, 1, &ambientLightIntensity[0]); 

    // Setup the direactional light 
    vec3 directionalLightDirection = vec3(0.0f, 0.0f, -1.0f); 
    normalize(directionalLightDirection); 
    glUniform3fv(gDirectionalLightDirectionLoc, 1, &directionalLightDirection[0]); 

    vec3 directionalLightIntensity = vec3(0.8f, 0.8f, 0.8f); 
    glUniform3fv(gDirectionalLightIntensityLoc, 1, &directionalLightIntensity[0]); 

    //Setup the specular Light 
    vec3 specularLightIntensity = vec3(0.5f, 0.5f, 0.5f); 
    glUniform3fv(gSpecularLightIntensityLoc, 1, &specularLightIntensity[0]); 
} 

任何人都可以看到我可能做错了什么,我可能有一些calculatiuons错了,我只是没有看到它。环境/漫射照明工作正常。这张照片展示了当前正在发生的事情,左侧的环境,中间的漫反射以及右侧强度设置为30的镜面反射。

enter image description here

回答

我忘了这个值传递到主:

gKsStrengthLoc = glGetUniformLocation(shaderProgram, "gKsStrength"); 
    //assert(gDirectionalLightDirectionLoc != 0xFFFFFFFF); 

一切正常,现在使用的答案选择

+1

还有一点评论 - 通常,镜面反射光不会乘以物体的颜色,而是会随着光线颜色与镜面反射强度的乘积而增加到最终颜色上。因此,对于白光,镜面高光应该是白色的,而不是绿色的。 – vesan 2014-12-02 22:20:01

回答

3

您的gKsStrength值看起来方式太小:

glUniform1f(gKsStrengthLoc, 0.5f); 

该值控制对象的闪亮程度,更高的值使其更加闪亮。这是有道理的,如果你看一下在着色器计算:

specularFactor = pow(specularFactor, gKsStrength); 

较大的指数,更快的价值脱落,这意味着镜面高光变得更窄。

典型值可能是10.0f,比如中等闪亮,30.0f比较闪亮,而对于非常闪亮的材料,其值可能更高。

随着您的值为0.5f,您会得到非常宽的高光“高光”。您的镜面反射强度值也相当高(0.5),因此高光将覆盖大部分物体,并使大部分的颜色饱和。

+0

感谢您的参与,我玩过这个价值,它似乎让对象更有活力而不是闪亮,这是正确的效果吗?我已经添加了一张照片来演示我的照明 – user2757842 2014-12-02 17:33:01

+0

我的错,我忘了参考main中的gksStrengthLoc,您是正确的,先生,谢谢,我已经更新了我的错误 – user2757842 2014-12-02 17:52:45