第 12 课:Metallic
实现:用 PBR 的材质参数(F0, Metallic, Roughness/Shininess),去套用老式的 Blinn-Phong 光照公式。
实现
uniform vec2 iResolution;
uniform float iTime;
uniform sampler2D iChannel0;
uniform sampler2D iChannel1;
uniform sampler2D iChannel2;
vec3 getLightPos(vec3 ratio) {
vec2 delta = vec2(cos(iTime * 1.0), 0.0);
return vec3(0.5, 0.5, 1.0) * ratio + vec3(delta, 0.0) * ratio;
}
void main() {
vec2 uv = gl_FragCoord.xy / iResolution.xy;
vec3 ratio = vec3(iResolution.x / iResolution.y, 1.0, 1.0);
vec3 viewPos = vec3(0.5, 0.5, 1.0) * ratio;
vec3 fragDiffuse = pow(texture2D(iChannel0, uv).rgb, vec3(2.2));
vec3 fragNormal = normalize(texture2D(iChannel1, uv).rgb * 2.0 - 1.0);
float fragMetallic = texture2D(iChannel2, uv).r;
vec3 F0 = vec3(0.04);
F0 = mix(F0, fragDiffuse, fragMetallic);
vec3 ks = F0;
vec3 kd = vec3(1.0) - ks;
kd *= 1.0 - fragMetallic;
vec3 fragPos = vec3(uv, 0.0) * ratio;
vec3 lightColor = vec3(1.0, 1.0, 0.75);
vec3 lightPos = getLightPos(ratio);
vec3 lightDir = normalize(lightPos - fragPos);
vec3 viewDir = normalize(viewPos - fragPos);
vec3 halfwayDir = normalize(viewDir + lightDir);
float diffuseFactor = dot(fragNormal, lightDir);
float specularFactor = pow(max(dot(fragNormal, halfwayDir), 0.0), 32.0) ;
vec3 specular = ks * specularFactor;
vec3 diffuse = kd * diffuseFactor * fragDiffuse;
vec3 result = (diffuse + specular) * lightColor;
gl_FragColor = vec4(result, 1.0);
}
复盘笔记
- 用 PBR 的材质参数(F0, Metallic, Roughness/Shininess),去套用老式的 Blinn-Phong 光照公式。
-
- kS = Coefficient of Specular全称:Coefficient of Specular Reflection(镜面反射系数)含义:代表光线打到物体表面后,直接反弹(镜面反射) 的比例。代码中的角色:它通常等于菲涅尔项(F)。
-
- kD = Coefficient of Diffuse全称:Coefficient of Diffuse Reflection(漫反射系数)含义:代表光线打到物体表面后,折射进入物体内部(漫反射) 的比例。代码中的角色:它通常等于 1.0 - kS。
- ![[Pasted image 20251204205752.png]]