跳到主要内容
← ShadowMap

ShadowMap

Shadow Map - PCF

shader-learning 自学第 7 课:Shadow Map - PCF

实时渲染 · 网格 GLSL

第 7 课:Shadow Map - PCF

实现

uniform vec2 iResolution;
uniform int iDepthPass;

attribute vec4 color;

varying vec3 vLightDir;
varying vec3 vNormal;
varying vec4 vColor;
varying vec4 vPos;
varying vec4 vPosLight;
varying vec2 shadowResolution;


mat4 getLightProjection() {
  float ratio = iResolution.x / iResolution.y;
  float size = 4.0;
  float left = -size * ratio;
  float right = size * ratio;
  float top = size;
  float bottom = -size;
  float far = 8.0;
  float near = 0.1;

  mat4 lightProjection;

  lightProjection[0][0] = 2.0 / (right - left);
  lightProjection[1][0] = 0.0;
  lightProjection[2][0] = 0.0;
  lightProjection[3][0] = -(right + left) / (right - left);

  lightProjection[0][1] = 0.0;
  lightProjection[1][1] = 2.0 / (top - bottom);
  lightProjection[2][1] = 0.0;
  lightProjection[3][1] = -(top + bottom) / (top - bottom);

  lightProjection[0][2] = 0.0;
  lightProjection[1][2] = 0.0;
  lightProjection[2][2] = -2.0 / (far - near);
  lightProjection[3][2] = -(far + near) / (far - near);

  lightProjection[0][3] = 0.0;
  lightProjection[1][3] = 0.0;
  lightProjection[2][3] = 0.0;
  lightProjection[3][3] = 1.0;

  return lightProjection;
}

void main() {

  vec3 lightDir = normalize(vec3(-0.5, -0.8, 0.0));
  vec3 lightPos = vec3(1.5, 2.4, 0.0);
 vec3 worldUp = vec3(0.0,1.0,0.0);
  vec3 vectorRight = normalize(cross(worldUp,-lightDir));
  vec3 vectorUp = normalize(cross(-lightDir, vectorRight));

  mat4 lightView = transpose(mat4(
    vec4(vectorRight, 0.0),
    vec4(vectorUp, 0.0),
    vec4(-lightDir, 0.0),
    vec4(vec3(0.0), 1.0)
  ));

  mat4 translate = transpose(mat4(
    vec4(1.0, 0.0, 0.0, -lightPos.x),
    vec4(0.0, 1.0, 0.0, -lightPos.y),
    vec4(0.0, 0.0, 1.0, -lightPos.z),
    vec4(vec3(0.0), 1.0)
  ));

  lightView *= translate;

  mat4 lightProjView = getLightProjection() * lightView;
  mat4 cameraProjView = projectionMatrix * viewMatrix;
  mat4 projView = (iDepthPass == 1) ? lightProjView : cameraProjView;
  vec4 worldPos = modelMatrix * vec4(position, 1.0);
  vec4 pos = projView * worldPos;
  gl_Position = pos;

  vLightDir = lightDir;
  vNormal = mat3(modelMatrix) * normal;
  vColor = color;
  vPos = pos;
  vPosLight = lightProjView * worldPos;
  shadowResolution = iResolution;
}