# HLSL sine/cosine

Discussion in 'Shaders' started by Cherubim79, Aug 26, 2018.

1. ### Cherubim79

Joined:
May 3, 2014
Posts:
55
Is there a way to get doubles to work with sine and cosine on GPU compute shaders? I suppose you could roll your own functions to support doubles, but I just wonder if they're using anything faster than a Taylor series or CORDIC on the GPU for calculation of sine/cosine?

I discovered a new mathematical formula based on the Discrete Fourier transform that lets you output any array size of frequency domain for a given input array of time based samples, allowing me to get music frequencies based on piano pitches rather than an even distribution that the DFT/FFT normally produces, especially with the FFT requiring powers of 2, for complex number analysis of music.

So I'm basically rebuilding Unity's FFT on the GPU, and it works, but I want to test with doubles. The sine and cosine operations on HLSL intrinsic functions only output floats though.

2. ### Przemyslaw_Zaworski

Joined:
Jun 9, 2017
Posts:
195
Cherubim79 likes this.
3. ### Cherubim79

Joined:
May 3, 2014
Posts:
55
Ah thank you, seems to me like the best method may still be to go with the Taylor series, but I just wanted to sanity check first.

4. ### Przemyslaw_Zaworski

Joined:
Jun 9, 2017
Posts:
195
Code (CSharp):
1. double mod(double a,double b)
2. {
3.     return (a>0) ? a-(((int)(a/b))*b) : -a+(((int)(a/b))*b);
4. }
5.
6. double sinus(double theta)
7. {
8.     double PI = 3.14159265358979323846;
9.     theta = mod(theta+PI/2.0, PI*2.0)-PI/2.0;
10.     if (theta > PI/2.0)
11.         theta = PI - theta;
12.     double x3 = (theta*theta*theta);
13.     double x5 = (x3*theta*theta);
14.     return theta - x3/6.0 + x5/120.0;
15. }

Cherubim79 likes this.
5. ### Przemyslaw_Zaworski

Joined:
Jun 9, 2017
Posts:
195
Fix for mod function:
Code (CSharp):
1. double mod(double a,double b)
2. {
3.     return (a>0)?a-b*((int)(a/b)):-(-a+b*(((int)(a/b))));
4. }

Cherubim79 likes this.
6. ### Cherubim79

Joined:
May 3, 2014
Posts:
55
This is wonderful thank you very much Przemyslaw_Zaworski!

7. ### Przemyslaw_Zaworski

Joined:
Jun 9, 2017
Posts:
195
It seems there is an inconsistency between C++ fmod and GLSL mod. So next fix and there is the final code :

Code (CSharp):
1. double sinus(double theta)
2. {
3.     double PI = 3.14159265358979323846;
4.     double a = theta+PI/2.0, b = PI*2.0;
5.     theta = ((a>0)?a-b*((int)(a/b)):(-a+b*(((int)(a/b)))))-PI/2.0;
6.     if (theta > PI/2.0)
7.         theta = PI - theta;
8.     double x3 = (theta*theta*theta);
9.     double x5 = (x3*theta*theta);
10.     return theta - x3/6.0 + x5/120.0;
11. }
12.
13. double cosinus(double x)
14. {
15.     return sinus(x+1.57079632679489661923);
16. }

unityunity