pissang / clay-viewer

3D model viewer with high quality rendering and glTF2.0/GLB export
https://pissang.github.io/clay-viewer/editor/
BSD 3-Clause "New" or "Revised" License
767 stars 97 forks source link

SSAO的半球采样方法 #108

Open shawn0326 opened 2 years ago

shawn0326 commented 2 years ago

https://github.com/pissang/clay-viewer/blob/86456edc4b28494e5facbe75fc4f009fe8cf3f3e/src/graphic/SSAOPass.js#L45

这里phi代表的是方位角吧,如果半球采样的话,theta 最大是 Math.PI,phi最大应该始终是2 * Math.PI。 另外,参考babylon的实现,建议处理一下theta角,避免因过于接近水平面而出现z-fight

pissang commented 2 years ago

这里phi代表的是方位角吧,如果半球采样的话,theta 最大是 Math.PI,phi最大应该始终是2 * Math.PI。

这个半球是在 z 轴方向上的

shawn0326 commented 2 years ago

这个半球是在 z 轴方向上的

抱歉,刚刚也发现了这个问题,重新整理了下写法:

  1. 整理了xyz的上传方式,明确是在tbn空间下的xyz坐标,感觉更好理解一些。这两种写法的xyz在值域上是一样的。
  2. 引入了Babylon对theta角的优化(不过目前还没有证明该优化有效的例子)
var phi = halton(i + offset, 2) * Math.PI * 2;

// rejecting samples that are close to tangent plane to avoid z-fighting artifacts
var cosTheta = 1.0 - (halton(i + offset, 3) * 0.85 + 0.15);
var sinTheta = Math.sqrt(1.0 - cosTheta * cosTheta);

var r = Math.random();
// for tbn space
var x = Math.cos(phi) * sinTheta * r;
var y = Math.sin(phi) * sinTheta * r;
var z = cosTheta * r;
pissang commented 2 years ago

@shawn0326 嗯一时想象不到这个效果怎么样,现在 clay-viewer 里是通过一个 bias 来控制的