跳到主要内容
← Lighting Basics

Lighting Basics

Metallic

用 PBR 的材质参数(F0, Metallic, Roughness/Shininess),去套用老式的 Blinn-Phong 光照公式。

实时渲染 · 纹理 GLSL

第 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 光照公式。
    1. kS = Coefficient of Specular全称:Coefficient of Specular Reflection(镜面反射系数)含义:代表光线打到物体表面后,直接反弹(镜面反射) 的比例。代码中的角色:它通常等于菲涅尔项(F)。
    1. kD = Coefficient of Diffuse全称:Coefficient of Diffuse Reflection(漫反射系数)含义:代表光线打到物体表面后,折射进入物体内部(漫反射) 的比例。代码中的角色:它通常等于 1.0 - kS。
  • ![[Pasted image 20251204205752.png]]