无需查找即可快速但不准确的 sin 函数

发布于 2024-12-01 01:01:15 字数 229 浏览 1 评论 0原文

对于海洋着色器,我需要一个快速函数来计算 sin(x) 的非常近似的值。唯一的要求是它是周期性的,并且大致类似于正弦波。

sin 的泰勒级数太慢,因为我需要计算 x 的 9 次方才能得到完整的周期。

有什么建议吗?

编辑:抱歉我没有提到,我无法使用查找表,因为它位于顶点着色器上。查找表将涉及纹理样本,该样本在顶点着色器上比内置的 sin 函数慢。 它不必以任何方式准确,它只需看起来不错即可。

For an ocean shader, I need a fast function that computes a very approximate value for sin(x). The only requirements are that it is periodic, and roughly resembles a sine wave.

The taylor series of sin is too slow, since I'd need to compute up to the 9th power of x just to get a full period.

Any suggestions?

EDIT: Sorry I didn't mention, I can't use a lookup table since this is on the vertex shader. A lookup table would involve a texture sample, which on the vertex shader is slower than the built in sin function.
It doesn't have to be in any way accurate, it just has to look nice.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

丑丑阿 2024-12-08 01:01:15

根据您需要的数量使用切比雪夫近似值。如果您的输入角度被限制为良好行为(-π .. +π 或 0 .. 2π),那么这会特别容易,因此您不必首先将参数减少到合理的值。您可以使用 2 或 3 个术语而不是 9 个。

Use a Chebyshev approximation for as many terms as you need. This is particularly easy if your input angles are constrained to be well behaved (-π .. +π or 0 .. 2π) so you do not have to reduce the argument to a sensible value first. You might use 2 or 3 terms instead of 9.

千柳 2024-12-08 01:01:15

您可以为某些值创建一个包含 sin 值的查找表,并在这些值之间使用线性插值。

You can make a look-up table with sin values for some values and use linear interpolation between that values.

素手挽清风 2024-12-08 01:01:15

sin(x) 的有理代数函数近似值(从零到 π/2 有效)为:

f = (C1 * x) / (C2 * x^2 + 1.) 

具有常数:

c1 =   1.043406062 
c2 =  .2508691922 

这些常数是通过最小二乘曲线拟合找到的。 (使用子程序 DHFTI,作者:Lawson & Hanson)。

如果输入在 [0, 2π] 之外,则需要采用 x mod 2 π。
要处理负数,您需要编写如下内容:

t = MOD(t, twopi)
IF (t < 0.) t = t + twopi

然后,要将范围扩展到 0 到 2π,请使用以下内容减少输入:

IF (t  < pi) THEN
  IF (t < pi/2) THEN
    x = t
  ELSE
      x = pi - t
   END IF
 ELSE 
   IF (t < 1.5 * pi) THEN
     x = t - pi
  ELSE
     x = twopi - t
   END IF
END IF

然后计算:

f = (C1 * x) / (C2 * x*x + 1.0)
IF (t > pi) f = -f

结果应在真实正弦值的 5% 左右。

A rational algebraic function approximation to sin(x), valid from zero to π/2 is:

f = (C1 * x) / (C2 * x^2 + 1.) 

with the constants:

c1 =   1.043406062 
c2 =  .2508691922 

These constants were found by least-squares curve fitting. (Using subroutine DHFTI, by Lawson & Hanson).

If the input is outside [0, 2π], you'll need to take x mod 2 π.
To handle negative numbers, you'll need to write something like:

t = MOD(t, twopi)
IF (t < 0.) t = t + twopi

Then, to extend the range to 0 to 2π, reduce the input with something like:

IF (t  < pi) THEN
  IF (t < pi/2) THEN
    x = t
  ELSE
      x = pi - t
   END IF
 ELSE 
   IF (t < 1.5 * pi) THEN
     x = t - pi
  ELSE
     x = twopi - t
   END IF
END IF

Then calculate:

f = (C1 * x) / (C2 * x*x + 1.0)
IF (t > pi) f = -f

The results should be within about 5% of the real sine.

剑心龙吟 2024-12-08 01:01:15

好吧,你没有说你需要它有多准确。正弦可以通过区间 [0, pi/2]、[pi/2, 3*pi/2]、[3*pi/2, 2*pi 上的斜率 2/pi 和 -2/pi 的直线来近似]。在减少角度 mod 2*pi 后,可以通过乘法和加法的成本获得该近似值。

Well, you don't say how accurate you need it to be. The sine can be approximated by straight lines of slopes 2/pi and -2/pi on intervals [0, pi/2], [pi/2, 3*pi/2], [3*pi/2, 2*pi]. This approximation can be had for the cost of a multiplication and an addition after reducing the angle mod 2*pi.

最丧也最甜 2024-12-08 01:01:15

使用查找表可能是控制速度和准确性之间权衡的最佳方法。

Using a lookup table is probably the best way to control the tradeoff between speed and accuracy.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文