如何理解更简单的calcNormal函数



我在这里阅读shadertoy教程:https://inspirnathan.com/posts/52-shadertoy-tutorial-part-6

有一种计算球体法线的法线方法:

vec3 calcNormal(vec3 p) {
float e = 0.0005; // epsilon
float r = 1.; // radius of sphere
return normalize(vec3(
sdSphere(vec3(p.x + e, p.y, p.z), r) - sdSphere(vec3(p.x - e, p.y, p.z), r),
sdSphere(vec3(p.x, p.y + e, p.z), r) - sdSphere(vec3(p.x, p.y - e, p.z), r),
sdSphere(vec3(p.x, p.y, p.z  + e), r) - sdSphere(vec3(p.x, p.y, p.z - e), r)
));
}

然后,他得到了一个更简单的:

vec3 calcNormal(vec3 p) {
vec2 e = vec2(1.0, -1.0) * 0.0005; // epsilon
float r = 1.; // radius of sphere
return normalize(
e.xyy * sdSphere(p + e.xyy, r) +
e.yyx * sdSphere(p + e.yyx, r) +
e.yxy * sdSphere(p + e.yxy, r) +
e.xxx * sdSphere(p + e.xxx, r)
);
}

和sdSphere函数:

// p is the point location, r is radius, sdSphere calculate the distance of the point in the world and the origin point(0,0) with the radius of r.
float sdSphere(vec3 p, float r)
{
return length(p) - r; // p is the test point and r is the radius of the sphere
}

我能理解正常的方法,但更简单的方法,他怎么能做到,而且是正确的
我搜索了一段时间,找不到答案,需要一些帮助,谢谢。

我是本教程的作者。很抱歉对这个问题的答复太晚了😅.第二CCD_ 1函数是用于创建小梯度的替代方法。法向量可以通过求球体上两个闭合点之间的距离来近似。

用于实现CCD_ 2功能的第一种方法和第二种方法并不完全等同。我已经在我的博客上更新了这一点,以防止将来混淆。然而,这两个函数都能完成寻找小梯度的工作,因为它们都能在球体表面或球体表面附近找到两个闭合点。

我创建了一个小的JavaScript程序,它模拟GLSL代码的一些行为,以防您想比较每个calcFunction实现之间的差异。

const p = new Vector3(1, 2, 3);
console.log('calcNormal1:', calcNormal1(p));
console.log('calcNormal2:', calcNormal2(p));
/* OUTPUT:
calcNormal1: Vector3 {
x: 0.26726124089009934,
y: 0.534522482802048,
z: 0.8017837267599155
}
calcNormal2: Vector3 {
x: 0.26721624351172774,
y: 0.5345183943192493,
z: 0.8018014500721813
}
*/

正如我们所看到的,结果非常接近!😃

相关内容

  • 没有找到相关文章

最新更新