跳到主要内容
← Advanced Rendering

Advanced Rendering

Camera Height Based Fog

shader-learning 自学第 14 课:Camera Height Based Fog

实时渲染 · 纹理 GLSL

第 14 课:Camera Height Based 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 fogColor    = vec3(0.4, 0.4, 0.3);

  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);

  float distanceY = distance(viewPos.y, fragPos.y);
  float fogFar = 10.0;
  float density = 4.605 / (fogFar * fogFar);
  float fogFactor = 1.0 - exp(-density * distanceY * distanceY);
  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);
}