跳到主要内容
← Advanced Rendering

Advanced Rendering

Linear Fog

shader-learning 自学第 11 课:Linear Fog

实时渲染 · 纹理 GLSL

第 11 课:Linear Fog

实现

uniform float iTime;
uniform vec2 iResolution;
uniform mat4 inverseViewMatrix;

uniform sampler2D iRTBuffer0;
uniform sampler2D iRTBuffer1;
uniform sampler2D iRTBuffer2;
uniform sampler2D iDepthBuffer;

out vec4 FragColor;

vec3 getViewPos() {
  return (inverseViewMatrix * vec4(0.0, 0.0, 0.0, 1.0)).xyz;
}

void main() {
  vec2 uv = gl_FragCoord.xy / iResolution.xy;

  vec4 fragColor  = texture(iRTBuffer0, uv);
  vec3 fragNormal = normalize(texture(iRTBuffer1, uv).xyz);
  float fragSpec  = texture(iRTBuffer1, uv).w;
  vec3 fragPos    = texture(iRTBuffer2, uv).xyz;
  vec3 viewPos    = getViewPos();
  vec3 lightPos    = vec3(0.0, 4.0, 0.0);
  vec3 lightClr    = vec3(1.0, 0.9, 0.8);

  vec3 lightDir = normalize(lightPos - fragPos);
  float diffuse = max(0.0, dot(fragNormal, lightDir));

  vec3 viewDir = normalize(viewPos - fragPos);
  vec3 halfwayDir = normalize(lightDir + viewDir);
  float specular = max(dot(fragNormal, halfwayDir), 0.0);
  specular = pow(specular, fragSpec);

  vec3 fogColor    = vec3(0.4, 0.4, 0.3);
  float fragDistance = distance(viewPos, fragPos);
  float fogEnd = 13.0;
  float fogStart = 8.0;
  float fogFactor = 1.0 - (fogEnd - fragDistance)/(fogEnd - fogStart);
  fogFactor = clamp(fogFactor, 0.0, 1.0);

  vec3 result = lightClr * (0.7 + diffuse + specular) * fragColor.rgb;
  result = mix(result, fogColor, fogFactor);

  FragColor = vec4(result.rgb, 1.0);
}