跳到主要内容
← Lighting Basics

Lighting Basics

Normal Map

shader-learning 自学第 9 课:Normal Map

实时渲染 · 纹理 GLSL

第 9 课:Normal Map

实现

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.5), 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 objectDiffuse = texture2D(iChannel0, uv).rgb;
  vec3 objectSpecular = texture2D(iChannel1, uv).rgb;
  vec3 normalMap = texture2D(iChannel2, uv).rgb;

  vec3 fragNormal = normalize(normalMap * 2.0 - 1.0);
  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);

  float ambientFactor = 0.1;
  float diffuseFactor = dot(fragNormal, lightDir);

  vec3 viewDir = normalize(viewPos - fragPos);
  vec3 reflectDir = reflect(-lightDir, fragNormal);
  float specularFactor = pow(max(dot(viewDir, reflectDir), 0.0), 32.0);

  vec3 result = vec3(0.0);
  result += ambientFactor * objectDiffuse;
  result += diffuseFactor * objectDiffuse;
  result += specularFactor * objectSpecular;
  result *= lightColor;

  gl_FragColor = vec4(result, 1.0);
}