2013-10-06 46 views
0

标题说明了所有..使用在照明系统中构建的opengls,specularlight不会随着距离物体的距离而增加或减少,而是由着色器实现。opengl着色器定向灯镜头反射距离增加

顶点着色器:

#version 330 

layout (location = 0) in vec3 position; 
layout (location = 1) in vec2 texCoord; 
layout (location = 2) in vec3 normal; 

out vec2 texCoord0; 
out vec3 normal0; 
out vec3 worldPos0; 

uniform mat4 transform; 
uniform mat4 normalRotation; 
uniform mat4 transformProjected; 

void main() 
{ 
    gl_Position = transformProjected * vec4(position, 1.0); 
    texCoord0 = texCoord; 

    normal0 = normalize((normalRotation * vec4(normal, 0.0))).xyz; 
    worldPos0 = (transform * vec4(position, 1.0)).xyz; 
} 

片段着色器:

#version 330 

in vec2 texCoord0; 
in vec3 normal0; 
in vec3 worldPos0; 

out vec4 fragColor; 

struct BaseLight 
{ 
    vec3 colorDiffuse; 
    vec3 colorSpecular; 
    float intensityDiffuse; 
}; 
struct DirectionalLight 
{ 
    BaseLight base; 
    vec3 direction; 
}; 

uniform vec3 tint; 
uniform sampler2D sampler; 

uniform vec3 eyePos; // camera pos 

uniform vec3 ambientLight; 
uniform vec3 emissiveLight; 

//material 
uniform float specularIntensity; 
uniform float specularPower; 

uniform DirectionalLight directionalLight; 

vec4 calcLight(BaseLight base,vec3 direction, vec3 normal) 
{ 
    float diffuseFactor = dot(normal, -direction); 

    vec4 diffuseColorFinal = vec4(0,0,0,0); 
    vec4 specularColorFinal = vec4(0,0,0,0); 

    if(diffuseFactor > 0) 
    { 
     diffuseColorFinal = vec4(base.colorDiffuse,1) * diffuseFactor * base.intensityDiffuse; 

     vec3 directionToEye = normalize(eyePos - worldPos0); 
     vec3 reflectDirection = normalize(reflect(direction, normal)); 

     float specularFactor = dot(directionToEye, reflectDirection); 
     specularFactor = pow(specularFactor, specularPower); 

     if(specularFactor > 0) 
      specularColorFinal = vec4(base.colorSpecular,1) * specularFactor * specularIntensity; 
    } 
    // 
    return diffuseColorFinal + specularColorFinal; 
} 



void main() 
{ 
    vec4 colorD = texture(sampler, texCoord0.xy) * vec4(tint,1); 
    vec3 normal = normal0; 
    vec4 totalLight = vec4(ambientLight,1) + vec4(emissiveLight,1); 

    totalLight += calcLight(directionalLight.base,-directionalLight.direction,normal); 


    fragColor = colorD * totalLight; 
} 

enter image description here enter image description here

正如可以从2个图像的镜面光占据了更大的表面区域越远见摄像头从飞机上起飞。在我使用内置照明的opengls进行的测试中,这没有发生。有没有办法来解决这个问题?即时通讯新的照明,也许这是正常的定向光源?谢谢您的帮助!

我也设置我的eyePos统一到我的cameraPos。我不知道这是否有帮助。

+0

这种情况以前也发生在我身上,但我以为这是因为表面是完全平坦的。我可能是错的,但我认为从相机位置到每个片段的角度已经减小,并且来自片段着色器的结果表面颜色现在几乎完全在镜面范围内。我不知道我是否已经解释清楚了。我知道我脑子里的意思,而不是如何解释得很好。我发现在线查看一些与BRDF相关的东西,并且[实时渲染](http://books.google.co.uk/books/about/Real_time_Rendering.html?id=zMAFmQEACAAJ&redir_esc=y)书帮助。 – finlaybob

回答

1

基本上你需要在片段和光线之间有距离dist。这对定向光来说可能是一个问题,因为你只有方向而远处被认为是无限的。也许切换到指向灯?

时优尔有 'DIST' 您使用公式

att = 1.0/(Kc + Kl*dist + Kq*dist^2) 
Kc - constant attenuation 
Kl - linear attenuation 
Kq - quadratic attenuation 

简单的版本(仅KQ使用的,尽可设定为1.0):

float attenuation = 1.0/(1.0 + light.attenuation * pow(distanceToLight, 2)); 

则照明方程中你基本上乘法计算色彩这个att因素:

vec4 finalColor = ambient + (diffuseColorFinal + specularColorFinal)*att 

http://www.ozone3d.net/tutorials/glsl_lighting_phong_p4.php#part_4

http://tomdalling.com/blog/modern-opengl/07-more-lighting-ambient-specular-attenuation-gamma/