Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
OpenGL-不现实的每片段点光源_Opengl_Glsl - Fatal编程技术网

OpenGL-不现实的每片段点光源

OpenGL-不现实的每片段点光源,opengl,glsl,Opengl,Glsl,在这里,您可以看到由点光源照亮的平面组成的场景。在自然界中,每个“碎片”的亮度在很大程度上取决于它与光源的距离,我希望在这里看到从一面墙到另一面墙的平滑过渡 唯一的可变因素是顶点法线,毫无疑问,它们导致了颜色的急剧变化。怎样才能更真实地照亮房间 顶点着色器 #version 330 precision highp float; uniform mat4 projection_matrix; uniform mat4 model_matrix; uniform mat4 view_matri

在这里,您可以看到由点光源照亮的平面组成的场景。在自然界中,每个“碎片”的亮度在很大程度上取决于它与光源的距离,我希望在这里看到从一面墙到另一面墙的平滑过渡

唯一的可变因素是顶点法线,毫无疑问,它们导致了颜色的急剧变化。怎样才能更真实地照亮房间

顶点着色器

#version 330

precision highp float;

uniform mat4 projection_matrix;
uniform mat4 model_matrix;
uniform mat4 view_matrix;

in vec3 vert_position;
in vec2 vert_texcoord;
in vec3 vert_normal;

out vec3 frag_normal;
out vec2 frag_texcoord;

uniform vec3 LightPosition;

out vec3 toLightVector;

void main(void)
{
    vec4 world_position = model_matrix * vec4(vert_position, 1);
    frag_texcoord = vert_texcoord;

    frag_normal = (model_matrix * vec4(vert_normal, 0)).xyz;
    toLightVector = LightPosition - world_position.xyz;

    gl_Position = projection_matrix * view_matrix * world_position;
}
片段着色器

#version 330

precision highp float;

in vec3 frag_normal;
in vec2 frag_texcoord;
in vec3 toLightVector;

uniform sampler2D MyTexture0;
uniform vec3 LightColour;
uniform vec3 LightAttenuation;

out vec4 finalColor;

void main(void)
{
        float distance = length(toLightVector);
        float attFactor = LightAttenuation.x + (LightAttenuation.y * distance) + (LightAttenuation.z * distance * distance);

        vec3 unitNormal = normalize(frag_normal);
        vec3 unitLightVector = normalize(toLightVector);

        float nDot1 = dot(unitNormal, unitLightVector);
        float brightness = max(nDot1, 0);

        vec3 diffuse = (brightness * LightColour) / attFactor;

        finalColor = vec4(diffuse, 1.0) * texture(MyTexture0, frag_texcoord);
}

只需将更多的权重放在距离上,而将更少的权重放在法线上。使光衰减看起来更像(0,0,1)。

您的问题在于您对照明模型的期望

照明模型的行为与预期完全一致。但这只是现实的一个模型,一个近似值

真实照明远比简单的点积和衰减复杂得多。这是一个高度复杂的相互作用之间的许多和许多小光源等。这就解释了为什么在现实生活中你(通常)看不到照明的这种不连续性


解决此问题的正确方法不是更改衰减或法线。这是为了研究更精确的照明模型。

你不会喜欢这个Nicol Bolas,但会简化计算,使其完全取决于距离,提供的正是我想要的效果

在设计和美学上轻描淡写会毁掉任何一件艺术品,但我要说的是,我不是在写《末日4》,我是在写一个无赖

片段着色器

#version 330

precision highp float;

in vec2 frag_texcoord;
in vec3 toLightVector;

uniform sampler2D MyTexture0;
uniform vec3 LightColour;
uniform vec3 LightAttenuation;

out vec4 finalColor;

void main(void)
{
        float distance = length(toLightVector);
        float attFactor = LightAttenuation.x + (LightAttenuation.y * distance) + (LightAttenuation.z * distance * distance);
        vec3 diffuse = (LightColour) / attFactor;

        finalColor = vec4(diffuse, 1.0) * texture(MyTexture0, frag_texcoord);
}

可能与此无关,但值得一提:你用模型矩阵的值变换法线吗?不,我没有,我只是为每个顶点传递一个标准化的方向向量。我有一个向量3数组,每个平面有4个相同的法线,我如何用逆模型矩阵来转换它?”每个碎片的亮度由它与源的距离决定“不,不是。这可能是决定的一部分,但法线和光线方向的点积也非常重要。如果你的正常是不连续的,没有理由期望灯光也会这样。我的问题是修辞,我真正的意思是:这是另一件需要考虑的事情。我不知道你的代码出了什么问题,但正如尼科尔指出的那样,当心被现实生活中的光学所欺骗,你没有光能传递或环境遮挡,光线非常强烈。我明白了,正是法线的急剧变化造成了颜色的急剧变化。将每个顶点朝向其父平面的中心45°是否会创建平滑过渡?我很感激你的建议,但我正在寻找一个永久的解决方案。你能推荐一个更精确的模型吗?最终目标是在预处理过程中将每面墙的照明信息写入光照贴图,如果这样做会产生影响的话。@livin_amuk:如果这是你的目标,那么OpenGL可能是错误的工具。你想要的是某种基于光能传递的照明系统。在CPU上生成结果需要很长时间,但这是一个离线过程。我不是使用着色器生成光照贴图,而是在CPU上使用与着色器相同的算法生成光照贴图。这样,静态环境将具有与动态照明对象相同的亮度。因此。。。你的问题是你的照明模型看起来不真实。因此,答案是去掉照明模型的实际照明模型部分,将其转换为一个值乘以一个距离?怎么会有人认为让事情变得不那么现实是一个有效的答案呢?你知道,战争并不总是必须的。我的问题清楚地表明了哪些方面困扰着我。无论如何,感谢你的投入,你是明智的,是这个社区的宝贵资源。