跳到主要内容
← Advanced Rendering

Advanced Rendering

Deferred Shading

shader-learning 自学第 9 课:Deferred Shading

代码复盘 GLSL

第 9 课:Deferred Shading

本课需 多 pass / 后处理,暂以代码复盘呈现。

实现

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

uniform sampler2D iRTBuffer0; // color
uniform sampler2D iRTBuffer1; // normal + specular shininess
uniform sampler2D iRTBuffer2; // position

out vec4 FragColor;

struct TLight { vec3 position; vec3 color; };

TLight c_Lights[4] = TLight[4](
  TLight(vec3( 2.5, 0.5,  2.5), vec3(1.0, 0.2, 0.2)),
  TLight(vec3(-2.5, 0.5,  2.5), vec3(0.2, 1.0, 0.2)),
  TLight(vec3( 2.5, 0.5, -2.5), vec3(0.2, 0.2, 1.0)),
  TLight(vec3(-2.5, 0.5, -2.5), vec3(1.0, 1.0, 0.2))
);

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

mat3 rotationYMatrix(float angle) {
    float cosAngle = cos(angle);
    float sinAngle = sin(angle);
    return mat3(
      vec3(cosAngle, 0, -sinAngle),
      vec3(0, 1, 0),
      vec3(sinAngle, 0, cosAngle)
    );
}

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

  vec4 color = texture(iRTBuffer0, uv);
  vec4 normal = texture(iRTBuffer1, uv);
  vec4 position = texture(iRTBuffer2, uv);
  float specularShine = normal.w;

  vec3 viewPos = getViewPos();
  mat3 rotateY = rotationYMatrix(iTime * 1.57);

  float kc = 0.1;
  float kl = 0.1;
  float kq = 0.1;

  float ambient = 0.5;

  vec3 lights = vec3(0.0);

  for(int i = 0; i < 4; i++){
    vec3 lightColor = c_Lights[i].color;
    vec3 lightPos = rotateY * c_Lights[i].position;
    vec3 lightDir = normalize(position.xyz - lightPos);
    vec3 viewDir = normalize(viewPos - position.xyz);
    vec3 halfwayVec =  normalize(-lightDir + viewDir);
    float diffuse = max(dot(normal.xyz,-lightDir),0.0);
    float specular = max(dot(normal.xyz,halfwayVec),0.0);
    specular = pow(specular, specularShine);
    float Distance = distance(position.xyz, lightPos);
    float Attenuation = 1.0 / (kc + kl * Distance + kq * Distance * Distance);
    lights += color.xyz * lightColor * (ambient + diffuse + specular) * Attenuation;
  }



  FragColor =  vec4(lights, 1.0) ;
}