Specular lighting in LWJGL 3 not working [Phong Shading]

huangapple go评论69阅读模式
英文:

Specular lighting in LWJGL 3 not working [Phong Shading]

问题

我在我的引擎中实现了光照,但存在一些问题,物体未正确地发光。Specular lighting in LWJGL 3 not working [Phong Shading] 镜面光照根本不起作用。

以下是顶点着色器:

#version 330

layout (location = 0) in vec3 position;
layout (location = 1) in vec2 tex_coords;
layout (location = 2) in vec3 normals;

uniform mat4 projectionMatrix;
uniform mat4 worldMatrix;
uniform mat4 viewMatrix;

out vec2 coords;
out vec3 vertexNormals;
out vec3 vertexPos;

void main() {
	vec4 mVerPos = worldMatrix * vec4(position, 1.0);
	gl_Position = projectionMatrix * viewMatrix * worldMatrix * vec4(position, 1.0);
	coords = tex_coords;
	vertexNormals = normalize(worldMatrix * vec4(normals, 0.0)).xyz;
	vertexPos = mVerPos.xyz;
}

以下是片段着色器:

#version 330

// 结构体和函数的定义...

void main() {

	setUpColor(material, coords);
	vec4 diffuseSpecularComp = calcDirLight(dirLight, vertexPos, vertexNormals);
	diffuseSpecularComp += calcPointLight(pointLight, vertexPos, vertexNormals);
	fragColor = ambientC * vec4(ambientColor, 1) + diffuseSpecularComp;
	
}

源代码在这里:https://www.dropbox.com/scl/fo/hwlnz913jm6c9xli2dsb6/h?dl=0&rlkey=b2zj0w6kttwu3b1di9rejwnq3

当我将 float diffuseFactor = max(dot(normal, to_light_dir ), 0.0);float specularFactor = max(dot(camera_direction, reflected_light), 0.0); 中的0.0 更改为大于0.1时,我得到以下结果Specular lighting in LWJGL 3 not working [Phong Shading],但镜面光照根本不起作用。

英文:

I implemented lighting in my engine. But there is some problem the object does not lights up properly
Specular lighting in LWJGL 3 not working [Phong Shading] The specular lighting does not work at all

Here is the vertex shader :

#version 330

layout (location = 0) in vec3 position;
layout (location = 1) in vec2 tex_coords;
layout (location = 2) in vec3 normals;

uniform mat4 projectionMatrix;
uniform mat4 worldMatrix;
uniform mat4 viewMatrix;

out vec2 coords;
out vec3 vertexNormals;
out vec3 vertexPos;

void main() {
	vec4 mVerPos = worldMatrix * vec4(position, 1.0);
	gl_Position = projectionMatrix * viewMatrix * worldMatrix * vec4(position, 1.0);
	coords = tex_coords;
	vertexNormals = normalize(worldMatrix * vec4(normals, 0.0)).xyz;
	vertexPos = mVerPos.xyz;
}

Here is the fragment shader :

#version 330

struct Material {
	vec4 ambient;
	vec4 diffuse;
	vec4 specular;
	int hasTexture;
	float reflectance;
};

struct PointLight {
	vec3 color;
	vec3 position;
	float intensity;
	float constant;
	float linear;
	float exponent;
};

struct DirLight {
	vec3 position;
	vec3 color;
	float intensity;
};

out vec4 fragColor;

in vec2 coords;
in vec3 vertexNormals;
in vec3 vertexPos;

uniform sampler2D sampler;
uniform	vec3 ambientColor;
uniform Material material;
uniform PointLight pointLight;
uniform float specularPower;
uniform DirLight dirLight;

vec4 ambientC;
vec4 diffuseC;
vec4 specularC;

void setUpColor(Material material, vec2 coords) {
	if (material.hasTexture == 1) {
		ambientC = texture(sampler, coords);
		diffuseC = ambientC;
		specularC = ambientC;
	}
	else {
		ambientC = material.ambient;
		diffuseC = material.diffuse;
		specularC = material.specular;
	}
}

vec4 calcLightColor(vec3 lightColor, float lightIntensity, vec3 position, vec3 to_light_dir, vec3 normal) {
	vec4 diffuseColour = vec4(0, 0, 0, 0);
    vec4 specColour = vec4(0, 0, 0, 0);

    // Diffuse Light
    float diffuseFactor = max(dot(normal, to_light_dir ), 0.0);
    diffuseColour = diffuseC * vec4(lightColor, 1.0) * lightIntensity * diffuseFactor;

    // Specular Light
    vec3 camera_direction = normalize(-position);
    vec3 from_light_dir = -to_light_dir;
    vec3 reflected_light = normalize(reflect(from_light_dir, normal));
    float specularFactor = max(dot(camera_direction, reflected_light), 0.0);
    specularFactor = pow(specularFactor, specularPower);
    specColour = specularC * lightIntensity * specularFactor * material.reflectance * vec4(lightColor, 1.0);
    
    return (diffuseColour + specColour);
};


vec4 calcPointLight(PointLight light, vec3 position, vec3 normal)
{
    vec3 light_direction = light.position - position;
    vec3 to_light_source  = normalize(light_direction);
    vec4 lightColor = calcLightColor(light.color, light.intensity, position, to_light_source, normal);

    // Attenuation
    float distance = length(light_direction);
    float attenuationInv = light.constant + light.linear * distance +
        light.exponent * distance * distance;
    return lightColor / attenuationInv;
}

vec4 calcDirLight(DirLight light, vec3 position, vec3 normal) {
	return calcLightColor(light.color, light.intensity, position, normalize(light.position), normal);
}

void main() {

	setUpColor(material, coords);
	vec4 diffuseSpecularComp = calcDirLight(dirLight, vertexPos, vertexNormals);
	diffuseSpecularComp += calcPointLight(pointLight, vertexPos, vertexNormals);
	fragColor = ambientC * vec4(ambientColor, 1) + diffuseSpecularComp;
	
}

Here is the source code : https://www.dropbox.com/scl/fo/hwlnz913jm6c9xli2dsb6/h?dl=0&rlkey=b2zj0w6kttwu3b1di9rejwnq3

When I changed the value of zero at float diffuseFactor = max(dot(normal, to_light_dir ), 0.0); and at float specularFactor = max(dot(camera_direction, reflected_light), 0.0); the to something above like 0.1
this what I get Specular lighting in LWJGL 3 not working [Phong Shading] but the specular does not work at all.

答案1

得分: 0

你的代码存在一些问题,但我不确定是什么导致了这个问题。

问题

  • 在顶点着色器中,你没有正确计算 vertexNormals。这在你的特定情况下可能不是问题,因为你似乎没有非均匀缩放网格,但值得一提,因为这是一个常见错误。你将对象空间法线与世界矩阵相乘,但应该改为与世界矩阵的逆转置相乘。
  • 在片段着色器中直接使用了 vertexNormals,但这是不正确的。虽然你在顶点着色器中对法线进行了归一化,但片段着色器得不到那个特定向量。它得到三个 vertexNormals 的线性插值(基本上是加权平均值),结果不一定是归一化的。因此,你应该在片段着色器中也进行归一化。
  • setUpColor 函数中,为什么将相同的值分配给 ambientCdiffuseCspecularC?通常,这些有不同的纹理,但至少对于漫反射和镜面反射来说是这样。

其他随机观察

  • 在顶点着色器中,你将 positionworldMatrix 相乘两次,但为什么?这似乎是浪费性能(也许编译器会优化它)。
  • DirLight 结构中,你有一个 position 成员,但定向光没有位置,它们只有一个方向。我看到你从位置计算方向,但这似乎不寻常。
  • 同样的,相机始终位于原点,定向光的方向始终指向原点。如果这是有意的,没问题,只是看起来不寻常。
  • Material 结构中(以及其他地方),你使用 vec4 而不是 vec3,但我猜最后的分量总是 1。这是对内存的浪费,你可以在 main 的末尾将 alpha 值设为 1.0f
英文:

There are a couple of problems in your code, but I'm not entirely sure which causes the problem.

Problems

  • In the vertex shader, you don't calculate vertexNormals correctly. It shouldn't be a problem in your specific case, because seemingly you don't scale your mesh nonuniformly, but it's worth mentioning because it's a common mistake. You multiply the object space normal with the world matrix, but you should instead multiply it with the inverse transposed of the world matrix.
  • In the fragment shader you use directly the vertexNormals, but it's not correct. Although you normalized the normal in the vertex shader, but the fragment shader doesn't get that specific vector. It gets the linear interpolation (basically a weighted average) of the 3 vertexNormals and the result is not necessarily normalized. So you should normalize it in the fragment shader as well.
  • In the setUpColor function, why do you assign the same value to ambientC, diffuseC, and specularC? Usually, there are different textures for these, but at least for diffuse and specular.

Other random observations

  • In the vertex shader, you multiply the position twice with worldMatrix, but why? It seems like wasted performance (maybe the compiler optimizes it).
  • In the DirLight struct you have a position member, but directional lights don't have a position, they just have a direction. I see that you compute the direction from the position, but it seems unusual.
  • In the same vein the camera is always at the origin and the directional light's direction always points to the origin. If it's intentional, it's okay, it just seems unusual.
  • In the Material struct (and in other places) you use vec4s instead of vec3s, but I guess, the last components are always ones. It's a waste of memory, you could just set the alpha value to 1.0f at the end of main.

Joey de Vries has amazing tutorials, including the Phong shading (using C++). In the One last thing section he also explains why it's important to use the inverse transposed matrix to transform the normal.

huangapple
  • 本文由 发表于 2023年6月30日 00:20:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/76582897.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定