我在网上找到的教程中创建了以下GLSL着色器,但位置照明似乎根本不起作用。
另外,我的整个场景光线不足,我不确定我有什么错误才能使用这个二进制文件" on,off"照明效果。
这是一张只有位置照明的场景照片:
当我按照着色器代码启用方向照明时;我从正确的方向得到了光,但它基本上是作为一个"开,关"事情。你会看到我突出显示了下图中的区域,其中物体基本上变亮,然后在下一个像素中右边没有光线:
为了向人们展示我正在加载法线,我在着色器代码中做了一个简单的finalColor = NormalColor
着色器。
以下是相同角度的场景结果图像:
这是我的顶点着色器:
#version 330 core
#extension GL_ARB_explicit_attrib_location : require
layout(location = 0) in vec3 vPosition;
layout(location = 1) in vec3 vNormal;
layout(location = 2) in vec2 vUV;
layout (std140) uniform Sunlight
{
vec4 SunlightPosition;
vec4 SunlightDiffuse;
vec4 SunlightSpecular;
vec4 SunlightDirection;
float constantAttenuation, linearAttenuation, quadraticAttenuation;
float spotCutoff, spotExponent;
float EnableLighting;
float EnableSun;
float ExtraValue;
};
out vec4 worldSpacePosition; // position of the vertex (and fragment) in world space
out vec3 vertexNormalDirection; // surface normal vector in world space
out vec2 TextureCoordinates;
out vec3 NormalColor;
uniform mat4 MVP;
uniform mat4 ModelMatrix;
uniform mat4 ViewMatrix;
uniform mat4 ViewModelMatrix;
uniform mat4 InverseViewMatrix;
uniform mat3 NormalMatrix;
void main()
{
gl_Position = MVP * vec4(vPosition, 1.0);
TextureCoordinates = vUV;
worldSpacePosition = ModelMatrix * vec4(vPosition, 1.0);
vertexNormalDirection = normalize(NormalMatrix * vNormal);
NormalColor = vNormal;
}
这是我的片段着色器代码:
#version 330
#extension GL_ARB_explicit_attrib_location : require
precision highp float;
uniform mat4 MVP;
uniform mat4 ModelMatrix;
uniform mat4 ViewMatrix;
uniform mat4 ViewModelMatrix;
uniform mat4 InverseViewMatrix;
uniform mat3 NormalMatrix;
//
// These values vary per Mesh
//
uniform vec4 AmbientMeshColor;
uniform vec4 EmissiveMeshColor;
uniform vec4 DiffuseMeshColor;
uniform vec4 SpecularMeshColor;
uniform vec4 SceneBrightnessColor;
uniform float MeshShininess;
uniform float ObjectHasTextureFile;
//
// Sunlight Settings.
//
layout (std140) uniform Sunlight
{
vec4 SunlightPosition;
vec4 SunlightDiffuse;
vec4 SunlightSpecular;
vec4 SunlightDirection;
float constantAttenuation, linearAttenuation, quadraticAttenuation;
float spotCutoff, spotExponent;
float EnableLighting;
float EnableSun;
float ExtraValue;
};
uniform vec4 SceneAmbient;
//
// Whether Materials are enabled at all.
//
uniform float IfEnableTextures;
//
// If we are just simply drawing the skybox.
//
uniform float DrawingSkyBox;
uniform float DrawNormals;
uniform float EnableWireframe;
uniform vec4 WireframeColor;
uniform float TextureCoordinateDebug;
uniform sampler2D MainTextureSampler;
in vec4 worldSpacePosition;
in vec3 vertexNormalDirection;
in vec2 TextureCoordinates;
in vec3 NormalColor;
vec4 finalDiffuseColor;
out vec4 finalColor;
void DrawSkyBox() {
finalColor = texture(MainTextureSampler, TextureCoordinates);
}
void DrawWireFrame() {
finalColor = WireframeColor;
}
void main()
{
if (DrawingSkyBox != 1.0) {
if (DrawNormals == 1.0) {
finalColor = vec4(NormalColor, 1.0);
} else {
vec3 normalDirection = normalize(vertexNormalDirection);
vec3 viewDirection = normalize(vec3(InverseViewMatrix * vec4(0.0, 0.0, 0.0, 1.0) - worldSpacePosition));
vec3 lightDirection;
float attenuation;
if (SunlightPosition.w == 0.0) // directional light?
{
attenuation = 1.0; // no attenuation
lightDirection = normalize(vec3(SunlightPosition));
}
else // point light or spotlight (or other kind of light)
{
vec3 positionToLightSource = vec3(SunlightPosition - worldSpacePosition);
float distance = length(positionToLightSource);
lightDirection = normalize(positionToLightSource);
attenuation = 1.0 / (constantAttenuation
+ linearAttenuation * distance
+ quadraticAttenuation * distance * distance);
if (spotCutoff <= 90.0) // spotlight?
{
float clampedCosine = max(0.0, dot(-lightDirection, vec3(SunlightDirection)));
if (clampedCosine < cos(radians(spotCutoff))) // outside of spotlight cone?
{
attenuation = 0.0;
}
else
{
attenuation = attenuation * pow(clampedCosine, spotExponent);
}
}
}
vec4 ambientLighting = SceneAmbient * AmbientMeshColor;
vec3 diffuseReflection;
if (ObjectHasTextureFile == 1.0) {
diffuseReflection = attenuation * vec3(SunlightDiffuse) * vec3(texture(MainTextureSampler, TextureCoordinates)) * max(0.0, dot(normalDirection, normalDirection));
} else {
diffuseReflection = attenuation * vec3(SunlightDiffuse) * vec3(DiffuseMeshColor) * max(0.0, dot(normalDirection, normalDirection));
}
vec3 specularReflection;
if (dot(normalDirection, lightDirection) < 0.0) // light source on the wrong side?
{
specularReflection = vec3(0.0, 0.0, 0.0); // no specular reflection
}
else // light source on the right side
{
specularReflection = attenuation * vec3(SunlightSpecular) * vec3(SpecularMeshColor) * pow(max(0.0, dot(reflect(-lightDirection, normalDirection), viewDirection)), MeshShininess);
}
finalColor = vec4(vec3(ambientLighting) + diffuseReflection + specularReflection, DiffuseMeshColor.a);
}
} else {
DrawSkyBox();
}
}
编辑(1):
根据BWG的评论,我简化了顶点和片段着色器:
顶点着色器:
#version 330 core
#extension GL_ARB_explicit_attrib_location : require
layout(location = 0) in vec3 vPosition;
layout(location = 1) in vec3 vNormal;
layout(location = 2) in vec2 vUV;
layout (std140) uniform Sunlight
{
vec4 SunlightPosition;
vec4 SunlightDiffuse;
vec4 SunlightSpecular;
vec4 SunlightDirection;
float constantAttenuation, linearAttenuation, quadraticAttenuation;
float spotCutoff, spotExponent;
float EnableLighting;
float EnableSun;
float ExtraValue;
};
out vec4 worldSpacePosition; // position of the vertex (and fragment) in world space
out vec3 vertexNormalDirection; // surface normal vector in world space
out vec2 TextureCoordinates;
uniform mat4 MVP;
uniform mat4 ModelMatrix;
uniform mat4 ViewMatrix;
uniform mat4 ViewModelMatrix;
uniform mat4 InverseViewMatrix;
uniform mat3 NormalMatrix;
void main()
{
gl_Position = MVP * vec4(vPosition, 1.0);
TextureCoordinates = vUV;
worldSpacePosition = ModelMatrix * vec4(vPosition, 1.0);
vertexNormalDirection = normalize(NormalMatrix * vNormal);
}
Fragment Shader:
#version 330
#extension GL_ARB_explicit_attrib_location : require
precision highp float;
uniform mat4 MVP;
uniform mat4 ModelMatrix;
uniform mat4 ViewMatrix;
uniform mat4 ViewModelMatrix;
uniform mat4 InverseViewMatrix;
uniform mat3 NormalMatrix;
//
// These values vary per Mesh
//
uniform vec4 AmbientMeshColor;
uniform vec4 EmissiveMeshColor;
uniform vec4 DiffuseMeshColor;
uniform vec4 SpecularMeshColor;
uniform vec4 SceneBrightnessColor;
uniform float MeshShininess;
uniform float ObjectHasTextureFile;
//
// Sunlight Settings.
//
layout (std140) uniform Sunlight
{
vec4 SunlightPosition;
vec4 SunlightDiffuse;
vec4 SunlightSpecular;
vec4 SunlightDirection;
float constantAttenuation, linearAttenuation, quadraticAttenuation;
float spotCutoff, spotExponent;
float EnableLighting;
float EnableSun;
float ExtraValue;
};
uniform vec4 SceneAmbient;
uniform sampler2D MainTextureSampler;
in vec4 worldSpacePosition;
in vec3 vertexNormalDirection;
in vec2 TextureCoordinates;
out vec4 finalColor;
void main()
{
vec3 normalDirection = normalize(vertexNormalDirection);
vec3 viewDirection = normalize(vec3(InverseViewMatrix * vec4(0.0, 0.0, 0.0, 1.0) - worldSpacePosition));
vec3 lightDirection;
float attenuation;
if (SunlightPosition.w == 0.0) // directional light?
{
attenuation = 1.0; // no attenuation
lightDirection = normalize(vec3(SunlightPosition));
}
else // point light or spotlight (or other kind of light)
{
vec3 positionToLightSource = vec3(SunlightPosition - worldSpacePosition);
float distance = length(positionToLightSource);
lightDirection = normalize(positionToLightSource);
attenuation = 1.0 / (constantAttenuation
+ linearAttenuation * distance
+ quadraticAttenuation * distance * distance);
if (spotCutoff <= 90.0) // spotlight?
{
float clampedCosine = max(0.0, dot(-lightDirection, vec3(SunlightDirection)));
if (clampedCosine < cos(radians(spotCutoff))) // outside of spotlight cone?
{
attenuation = 0.0;
}
else
{
attenuation = attenuation * pow(clampedCosine, spotExponent);
}
}
}
vec4 ambientLighting = SceneAmbient * AmbientMeshColor;
vec3 diffuseReflection;
if (ObjectHasTextureFile == 1.0) {
diffuseReflection = attenuation * vec3(SunlightDiffuse) * vec3(texture(MainTextureSampler, TextureCoordinates)) * max(0.0, dot(normalDirection, lightDirection));
} else {
diffuseReflection = attenuation * vec3(SunlightDiffuse) * vec3(DiffuseMeshColor) * max(0.0, dot(normalDirection, lightDirection));
}
vec3 specularReflection;
if (dot(normalDirection, lightDirection) < 0.0) // light source on the wrong side?
{
specularReflection = vec3(0.0, 0.0, 0.0); // no specular reflection
}
else // light source on the right side
{
specularReflection = attenuation * vec3(SunlightSpecular) * vec3(SpecularMeshColor) * pow(max(0.0, dot(reflect(-lightDirection, normalDirection), viewDirection)), MeshShininess);
}
finalColor = vec4(vec3(ambientLighting) + diffuseReflection + specularReflection, DiffuseMeshColor.a);
}
我还更改了导入实用程序的导入器设置,用于使网格数据(ASSIMP)无法生成平滑法线。
这摆脱了三角测量,但
现在,如果我只是将鼠标移动一点点,那么地面会变黑。没有褪色。