62 lines
2.6 KiB
GLSL
62 lines
2.6 KiB
GLSL
// 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;
|
||
}
|
||
|