threejs交流群511163089
来看看这个shader。
shadow是实现思路就是传入灯光镜头下的矩阵,将点投影过去,对比深度。
累加起来除一下权值和, 可以柔和一下影子边缘。
里面有个没有学过的新东西就是这个对比采样器。
textureSampleCompare,有点意思 像是硬件帮你做计算。
第一个参数是纹理,第二个是采样器 这个采样器的类型sampler_comparison,第三个是uv,第四个是对比值,别的代码都很朴素 那个$符号是js的字符串替换
[[block]] struct Scene {
[[offset(0)]] lightViewProjMatrix : mat4x4<f32>;
[[offset(64)]] cameraViewProjMatrix : mat4x4<f32>;
[[offset(128)]] lightPos : vec3<f32>;
};
[[group(0), binding(0)]] var<uniform> scene : Scene;
[[group(0), binding(1)]] var shadowMap: texture_depth_2d;
[[group(0), binding(2)]] var shadowSampler: sampler_comparison;
[[location(0)]] var<in> shadowPos : vec3<f32>;
[[location(1)]] var<in> fragPos : vec3<f32>;
[[location(2)]] var<in> fragNorm : vec3<f32>;
[[location(0)]] var<out> outColor : vec4<f32>;
const albedo : vec3<f32> = vec3<f32>(0.9, 0.9, 0.9);
const ambientFactor : f32 = 0.2;
[[stage(fragment)]]
fn main() -> void {
// Percentage-closer filtering. Sample texels in the region
// to smooth the result.
var shadowFactor : f32 = 0.0;
for (var y : i32 = -1 ; y <= 1 ; y = y + 1) {
for (var x : i32 = -1 ; x <= 1 ; x = x + 1) {
const offset : vec2<f32> = vec2<f32>(
f32(x) * ${1 / shadowDepthTextureSize},
f32(y) * ${1 / shadowDepthTextureSize});
shadowFactor = shadowFactor + textureSampleCompare(
shadowMap, shadowSampler,
shadowPos.xy + offset, shadowPos.z - 0.007);
}
}
shadowFactor = ambientFactor + shadowFactor / 9.0;
const lambertFactor : f32 = abs(dot(normalize(scene.lightPos - fragPos), fragNorm));
const lightingFactor : f32 = min(shadowFactor * lambertFactor, 1.0);
outColor = vec4<f32>(lightingFactor * albedo, 1.0);
}