GAMES202 作业1-part2
应老师要求不会直接放上作业答案,会记录整体思路和核心代码
PCF
主要步骤
- 获取shadow map和对应的坐标
- 设置filter和随机采样的数目
- 使用泊松分布采样
- 判断每个采样点的shadow map值
- 进行累加求平均
1 2 3 4 5
| float PCF(sampler2D shadowMap, vec4 coords, float filter_size)
|
接着使用泊松分布
1 2
| poissonDiskSamples(coords.xy);
|
然后通过每个对采样点进行判断累加结果
1 2 3 4 5 6 7 8 9
| for(int i = 0;i < PCF_NUM_SAMPLES; i++){ vec2 temp = poissonDisk[i] * filter_size + coords.xy; float depth_decode = (unpack(texture2D(shadowMap, temp))); if(depth_decode>coords.z - bias) depth_sum += 1.0; else depth_sum += 0.0; }
|
得到效果如下
PCSS
PCSS主要步骤:
- blocker search
- 进行泊松分布采样
- 和当前uv的深度进行对比、
- 判断是否有遮挡
- 计算比值
- 通过PCF创建软阴影
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| for(int i=0;i<NUM_SAMPLES; i ++){ vec2 simpleUV = uv +poissonDisk[i] * (zReceiver-0.01)/zReceiver; float shadowMapDepth = unpack(texture2D(uShadowMap,simpleUV)); if(zReceiver > (shadowMapDepth+EPS)){ average_depth += shadowMapDepth; count +=1; } }
if(count == 0){ return 0.3; }
average_depth /= float(count);
|
1 2 3 4 5 6 7 8 9
| float PCSS(sampler2D shadowMap, vec4 coords){ float blocker_depth = findBlocker(shadowMap, coords.xy, coords.z); float penumbra = (coords.z-blocker_depth)*LIGHT_WIDTH/blocker_depth; return PCF(shadowMap, coords, 1.0/2048.0 * 5.0 * penumbra); }
|
优化效果
开始的时候PCF和PCSS效果如下,可以看得出特别糊
通过修改NUM_SAMPLES进行优化,从20调到了60