首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GLSL法线贴图照明暗区域和朝向奇数方向的灯光

GLSL法线贴图照明暗区域和朝向奇数方向的灯光
EN

Stack Overflow用户
提问于 2014-09-23 11:27:02
回答 1查看 1.1K关注 0票数 0

我似乎不明白为什么我的碎片和顶点着色器不能工作。我想我要么是我的视图/透视图错了,要么是我的法线贴图有负值(因为黑色亮起了)。不管怎样,我已经这样做了好几天了,我似乎不能让它变得有吸引力。

我复制到我的项目中的照明系统来自这里:https://github.com/mattdesl/lwjgl-basics/wiki/ShaderLesson6

唯一具有法线贴图的纹理是建筑物,它似乎可以正常照亮,但仅从左下角开始。我也会想,其他的一切都会是一片漆黑。我也认为我的灯光应该是圆形的,而不是方向性的。

https://www.dropbox.com/s/pd8und7xbqz0kfh/Screenshot%202014-09-22%2023.17.22.png?dl=0

编辑:一些研究表明,如果我将法线贴图的r,g,b值设置为.5,如果它们小于片段着色器中的.5,那么至少那些没有法线贴图的图像不会变亮,这表明问题的一部分可能与负的法线贴图值有关。

另一个编辑:我在顶点着色器中使用ftransform()。即使我做了上面的修复来使所有没有法线贴图的东西变暗,我也不知道为什么我的光源是有角度的。除非我将NdotL设置为max(点(N,L),1.0);,否则乱七八糟的值不会让我的光源变成圆形。这使我相信我的坐标系没有被正确转换,或者我的法线贴图中有奇怪的/负值,这会导致问题。我不能很好地理解这个数学,不知道哪里出了问题。

还有一件事,因为我只为一个建筑创建了法线,所以我传入-1作为其他图像的法线贴图的textureId。这会是一个问题吗?

这是我的顶点着色器:

代码语言:javascript
复制
attribute vec4 Color;

varying vec2 vTexCoord;
varying vec4 vColor;

void main() {

    vColor = Color;
    vTexCoord = gl_MultiTexCoord0;
    gl_Position = ftransform();
}

和我的片段着色器:

代码语言:javascript
复制
struct Light{
    //float intensity;
    vec4 color;
    vec3 position;
    //vec3 direction;
};

//attributes from vertex shader
varying vec4 vColor;
varying vec2 vTexCoord;

//our texture samplers
uniform sampler2D u_texture;   //diffuse map
uniform sampler2D u_normals;   //normal map


//values used for shading algorithm...
uniform vec2 Resolution;      //resolution of screen
uniform Light Lights[50];        //light position, normalized
uniform vec4 AmbientColor;    //ambient RGBA -- alpha is intensity 
uniform vec3 Falloff;         //attenuation coefficients

uniform int LightCount;

void main() {
    vec3 Sum = vec3(0.0);


    //RGBA of our diffuse color
    vec4 DiffuseColor = texture2D(u_texture, vTexCoord);

    //set our defuse color to whatever color the image actually is.
    //vec4 vColor = DiffuseColor;

    //RGB of our normal map
    vec3 NormalMap = texture2D(u_normals, vTexCoord).rgb;

    //pre-multiply ambient color with intensity
    vec3 Ambient = AmbientColor.rgb * AmbientColor.a;

    int i = 0;
    while(i < LightCount){
        vec3 ThisLightPosition = Lights[i].position;
        vec4 ThisLightColor = Lights[i].color;

        //The delta position of light
        vec3 LightDir = vec3(ThisLightPosition.xy - (gl_FragCoord.xy / Resolution.xy), ThisLightPosition.z);

        //Correct for aspect ratio
        LightDir.x *= Resolution.x / Resolution.y;

        //Determine distance (used for attenuation) BEFORE we normalize our LightDir
        float D = length(LightDir);

        //normalize our vectors
        vec3 N = normalize(NormalMap * 2.0 - 1.0);
        vec3 L = normalize(LightDir);
        float NdotL = max(dot(N, L), 0.0);
        //Pre-multiply light color with intensity
        //Then perform "N dot L" to determine our diffuse term
        vec3 Diffuse = (ThisLightColor.rgb * ThisLightColor.a) * NdotL;

        //calculate attenuation
        float Attenuation = 1.0 / ( Falloff.x + (Falloff.y*D) + (Falloff.z*D*D));

        //the calculation which brings it all together
        vec3 Intensity = Ambient + Diffuse * Attenuation;
        vec3 FinalColor = DiffuseColor.rgb * Intensity;
        Sum += FinalColor;
        i++;
    }

    gl_FragColor = vColor * vec4(Sum, DiffuseColor.a);
}
EN

回答 1

Stack Overflow用户

发布于 2014-09-24 12:27:05

问题出在我的法线贴图上。我使用基础rbg(0,0,0)作为空白法线,而实际上空白法线贴图应该是(128,128,255) (即(.5,.5,1))。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25986373

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档