2025-05-21 12:14:57 +08:00

62 lines
2.6 KiB
GLSL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// shaders/phong.frag
#version 330 core
// 从顶点着色器插值传入的变量
in vec3 Position_worldspace;
in vec3 Normal_cameraspace;
in vec3 EyeDirection_cameraspace;
in vec3 LightDirection_cameraspace;
in vec2 UV;
// 输出颜色
out vec3 color;
// Uniform 变量
uniform sampler2D myTextureSampler; // 纹理采样器
uniform vec3 lightColor; // 光源颜色
uniform float lightPower; // 光照强度
uniform vec3 viewPos_worldspace; // 观察者位置(世界空间)
uniform vec3 lightPos_worldspace; // 光源位置(世界空间)
// 材质属性 (可以作为uniform传入这里为了简单硬编码)
vec3 materialDiffuseColor = vec3(1.0, 1.0, 1.0); // 从纹理获取
vec3 materialAmbientColor = vec3(0.1, 0.1, 0.1);
vec3 materialSpecularColor = vec3(0.5, 0.5, 0.5);
float materialShininess = 32.0;
void main(){
// 环境光
vec3 AmbientLighting = materialAmbientColor * lightColor * 0.2; // 环境光强度通常较低
// 漫反射光
vec3 Normal_normalized = normalize(Normal_cameraspace);
vec3 LightDirection_normalized = normalize(LightDirection_cameraspace);
float cosTheta = clamp(dot(Normal_normalized, LightDirection_normalized), 0, 1); // clamp 避免负值
vec3 DiffuseLighting = materialDiffuseColor * lightColor * cosTheta;
// 镜面反射光
vec3 EyeDirection_normalized = normalize(EyeDirection_cameraspace);
vec3 ReflectionDirection = reflect(-LightDirection_normalized, Normal_normalized);
float cosAlpha = clamp(dot(EyeDirection_normalized, ReflectionDirection), 0, 1);
vec3 SpecularLighting = materialSpecularColor * lightColor * pow(cosAlpha, materialShininess);
// 如果法线和光线方向相反(背面),则不应有镜面反射和漫反射
if(dot(Normal_normalized, LightDirection_normalized) < 0.0){
SpecularLighting = vec3(0,0,0);
DiffuseLighting = vec3(0,0,0); // 可选,取决于是否做双面光照
}
// 从纹理采样颜色,并与漫反射材质颜色混合 (这里直接用纹理作为漫反射颜色)
vec3 textureColor = texture(myTextureSampler, UV).rgb;
DiffuseLighting = textureColor * lightColor * cosTheta;
// 最终颜色 (光照强度衰减)
float distance = length(lightPos_worldspace - Position_worldspace); // 实际光源与片元距离
float attenuation = lightPower / (distance * distance); // 简单平方反比衰减
color = AmbientLighting + (DiffuseLighting + SpecularLighting) * attenuation;
// 不带衰减的简单版本(如果上面的衰减不工作,可以尝试这个)
//color = AmbientLighting + DiffuseLighting + SpecularLighting;
}