From 15afab09cb6f8bedd38df3e0b21494795064c918 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Teemu=20J=C3=A4rvisalo?= Date: Sat, 19 Jul 2025 18:38:36 +0300 Subject: [PATCH] aaltogeneraattori(wip) --- leviathan.vcxproj | 2 + leviathan.vcxproj.filters | 2 + src/main.cpp | 28 ++++++ src/shaders/fragment.frag | 70 +++++++++++--- src/shaders/fragment.inl | 187 ++++++++++++++++++++++---------------- src/waveGenerator.cpp | 87 ++++++++++++++++++ src/waveGenerator.h | 7 ++ 7 files changed, 293 insertions(+), 90 deletions(-) create mode 100644 src/waveGenerator.cpp create mode 100644 src/waveGenerator.h diff --git a/leviathan.vcxproj b/leviathan.vcxproj index 45d71f4..1126a45 100644 --- a/leviathan.vcxproj +++ b/leviathan.vcxproj @@ -606,6 +606,7 @@ shader_minifier.exe -v -o src\shaders\post.inl src\shaders\post.frag true true + @@ -621,6 +622,7 @@ shader_minifier.exe -v -o src\shaders\post.inl src\shaders\post.frag true true + diff --git a/leviathan.vcxproj.filters b/leviathan.vcxproj.filters index 1a02fb0..1a4a55f 100644 --- a/leviathan.vcxproj.filters +++ b/leviathan.vcxproj.filters @@ -5,6 +5,7 @@ + @@ -19,6 +20,7 @@ + diff --git a/src/main.cpp b/src/main.cpp index 208b136..97ed18b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -30,6 +30,7 @@ #endif #include "fft.h" +#include "waveGenerator.h" #pragma data_seg(".pids") // static allocation saves a few bytes @@ -127,6 +128,9 @@ int __cdecl main(int argc, char* argv[]) static float fft_output[FFT_SIZE / 2]; // Magnitudes static float fft_uniform[FFT_SIZE / 4]; + static float wave[WAVE_SIZE]; + static float wave_uniform[WAVE_SIZE]; + do { direct_sound_buffer->GetCurrentPosition((DWORD*)&playCursor, NULL); @@ -206,6 +210,24 @@ int __cdecl main(int argc, char* argv[]) glUniform1fvProc(0, SU_NUMSYNCS + 1, syncs); glUniform1fvProc(8, FFT_SIZE / 4, fft_uniform); + /****************** + * WAVE GENERATOR + *******************/ + + waveGenerator(syncs[4], wave); + for (int i = 0; i < (WAVE_SIZE); i++) + { + float gain = 1.2f; + float alpha = 0.15f; // "Hidastaa" FFT:n piikkejä + float threshhold = 0.1f; // Alin arvo mikä päästetään shaderille (vähentää "noisea") + float x_t = wave[i] * gain; + // Exponential smoothing kaava + // s(t) = alpha*x(t)+(1-alpha)*s(t-1) + wave_uniform[i] = (x_t < threshhold) ? 0.f : alpha * (x_t)+(1 - alpha) * wave_uniform[i]; + } + + glUniform1fvProc(1000, WAVE_SIZE, wave); + glRects(-1, -1, 1, 1); //syncs[0] = -syncs[0]; @@ -243,5 +265,11 @@ int __cdecl main(int argc, char* argv[]) lastPlayCursor = playCursor; } while(!GetAsyncKeyState(VK_ESCAPE)); + + + ExitProcess(0); } + + + diff --git a/src/shaders/fragment.frag b/src/shaders/fragment.frag index 78359b1..03c57ee 100644 --- a/src/shaders/fragment.frag +++ b/src/shaders/fragment.frag @@ -6,11 +6,13 @@ const float TAU = (2. * PI); const float PHI = sqrt(5.) * 0.5 + 0.5; layout(location = 0) uniform float syncs[7]; layout(location = 8) uniform float fft_output[512]; // FFT_SIZE / 4 +layout(location = 1000) uniform float wave[512]; // FFT_SIZE / 4 float u_time = syncs[0]; -vec2 getUV() { - const vec2 scale = vec2(0.00104166667, 0.00185185185); - return gl_FragCoord.xy * scale - 1.0; +vec2 getUV(vec2 offset) { + vec2 uv = 2.0 * ((gl_FragCoord.xy + offset *0.5) / vec2(1920,1080) - 0.5); + uv.x *= 1920/1080; + return uv; } float noise(in vec2 xy, in float seed) { @@ -30,12 +32,21 @@ float sdHex(vec3 pos, float i, float angle) { return d1; } +float sdSphere(vec3 p, float r) { + return length(p)-r; +} + +mat2 rot2D(float angle) { + float s = sin(angle), c = cos(angle); + return mat2(c, -s, s, c); +} + float getScaledFFT(int index, float scale, float offset) { // Clamp index to valid range index = clamp(index, 0, 511); // Get raw FFT value - float raw = fft_output[index]; + float raw = wave[index]; // Apply logarithmic scaling: log(1 + value * scale) + offset return log(1.0 + raw * scale) + offset; @@ -52,6 +63,39 @@ vec2 mapScene(in vec3 p) { float rippleFreq = 1.0; float rippleDecay = 0.25; + // big sphere + a = sdSphere(vec3(p.x, p.y - 16., p.z - 10.), 2.); + d = min(d,a); + if (d==a) { + mat = 1.; + } + + // rotating spheres + vec3 q = vec3(p.x, p.y - 16., p.z - 10.); + q.xy = rot2D(u_time*2.)*q.xy; + float smallSphereDist = 4.; + float smallSphereSize = 0.2; + + a = sdSphere(vec3(q.x + smallSphereDist, q.y, q.z), smallSphereSize), + d = min(d,a); + if (d==a) mat = 1.0; + + a = sdSphere(vec3(q.x - smallSphereDist, q.y, q.z), smallSphereSize), + d = min(d,a); + if (d==a) mat = 1.0; + + a = sdSphere(vec3(q.x, q.y + smallSphereDist, q.z), smallSphereSize), + d = min(d,a); + if (d==a) mat = 1.0; + + a = sdSphere(vec3(q.x, q.y - smallSphereDist, q.z), smallSphereSize), + d = min(d,a); + if (d==a) mat = 1.0; + + + + + // Hexagonal grid float hexGap = 0.2; @@ -98,7 +142,7 @@ vec3 castRay(vec3 ro, vec3 rd, inout vec3 pos) { pos = ro + rd * t; vec2 res = mapScene(pos); // Increase step size multiplier for faster marching - t += res.x; + t += res.x * 1.2; mat = res.y; if(t > 100.) { // Reduced max distance break; @@ -247,7 +291,7 @@ vec3 postProcess(vec3 col) { //col += 0.075*clamp(vec3(0.5*random, 0.5*random2, 0.5*random), 0.02, 1.); // dither // Normalized pixel coordinates (from 0 to 1) - vec2 screenCoord = getUV(); + vec2 screenCoord = getUV(vec2(0., 0.)); //gl_FragCoord.xy / u_resolution.xy; // Vignette float radius = 0.8; @@ -278,7 +322,7 @@ vec3 getCameraRay(vec2 uv, vec3 camPos, vec3 camTarget, float fov) { vec3 camRight = normalize(cross(vec3(0.0, 1.0, 0.0), camForward)); vec3 camUp = normalize(cross(camForward, camRight)); - vec3 rayDir = normalize(uv.x * camRight + uv.y * camUp + camForward * fov); + vec3 rayDir = normalize(uv.x * camRight + uv.y * camUp + camForward); return rayDir; } @@ -286,11 +330,11 @@ vec3 getCameraRay(vec2 uv, vec3 camPos, vec3 camTarget, float fov) { // Camera positioning function vec3 getCameraPosition(float time, int cameraMode) { vec3 camPos; - camPos = vec3(0.0, 30.0, -10.0); + camPos = vec3(0.0, 10.0, -10.0); if(cameraMode == 1) { // Orbiting camera - vec3 camTarget = vec3(0.0, 0.0, -20.0); + vec3 camTarget = vec3(0.0, 50.0, -20.0); float orbitRadius = 20.0; float orbitSpeed = 0.2; float orbitHeight = 10.0; @@ -304,6 +348,8 @@ vec3 getCameraPosition(float time, int cameraMode) { // First person style movement float walkSpeed = 2.0; camPos = vec3(sin(time * walkSpeed) * 0.1, 8.0 + sin(time * walkSpeed * 2.0) * 0.05, time * 0.5); + } else if(cameraMode == 4) { + camPos = vec3(0., 30., 25.); } return camPos; @@ -312,7 +358,7 @@ vec3 getCameraPosition(float time, int cameraMode) { // Main camera function that combines everything vec3 setupCamera(vec2 uv, float time, int positionMode) { vec3 camPos = getCameraPosition(time, positionMode); - vec3 camTarget = vec3(0.0, -1.0, 10.0); // Adjust target as needed + vec3 camTarget = vec3(0.0, 10.0, 10.0); // Adjust target as needed float fov = 1.; return getCameraRay(uv, camPos, camTarget, fov); @@ -323,7 +369,7 @@ vec3 render(vec2 uv) { // Choose camera modes: // Position: 0=static, 1=orbit, 2=smooth, 3=walk // Ray: 0=standard, 1=zoom, 2=dof - int positionMode = 2; // Static + int positionMode = 4; // Static vec3 rayDir = setupCamera(uv, u_time, positionMode); vec3 camPos = getCameraPosition(u_time, positionMode); @@ -342,7 +388,7 @@ vec3 render(vec2 uv) { void main() { - vec3 finalColor = render(getUV()); + vec3 finalColor = render(getUV(vec2(0., 0.))); //finalColor = postProcess(finalColor); diff --git a/src/shaders/fragment.inl b/src/shaders/fragment.inl index bcae441..0fe190d 100644 --- a/src/shaders/fragment.inl +++ b/src/shaders/fragment.inl @@ -1,43 +1,79 @@ // Generated with Shader Minifier 1.5.1 (https://github.com/laurentlb/Shader_Minifier/) #ifndef FRAGMENT_INL_ # define FRAGMENT_INL_ -# define VAR_fft_output "n" -# define VAR_o "f" +# define VAR_fft_output "l" +# define VAR_o "i" # define VAR_syncs "m" +# define VAR_wave "n" const char *fragment_frag = "#version 460\n" "precision mediump float;" - "out vec4 f;" - "const float i=2.*acos(-1.),v=sqrt(5.)*.5+.5;" + "out vec4 i;" + "const float f=2.*acos(-1.),v=sqrt(5.)*.5+.5;" "layout(location=0)uniform float m[7];" - "layout(location=8)uniform float n[512];" - "float c=m[0];" + "layout(location=8)uniform float l[512];" + "layout(location=1000)uniform float n[512];" + "float x=m[0];" + "vec2 t()" + "{" + "vec2 i=2.*((gl_FragCoord.xy+vec2(0)*.5)/vec2(1920,1080)-.5);" + "i.x*=1;" + "return i;" + "}" "float t(vec3 v,vec2 i)" "{" "v=abs(v);" "return max(v.y-i.y,max(v.x*sqrt(3.)*.5+v.z*.5,v.z)-i.x);" "}" - "float t(int v)" + "float t(vec3 v,float i)" + "{" + "return length(v)-i;" + "}" + "mat2 e()" + "{" + "float v=x*2.,i=sin(v);" + "v=cos(v);" + "return mat2(v,-i,i,v);" + "}" + "float e(int v)" "{" "v=clamp(v,0,511);" "float i=n[v];" "return log(1.+i*15.);" "}" - "vec2 t(vec3 v)" + "vec2 e(vec3 v)" "{" "float i=0.,f=1e9,m=0.;" "vec2 n=vec2(7);" - "for(float r=0.;r<16.;r++)" + "m=t(vec3(v.x,v.y-16.,v.z-10.),2.);" + "f=min(f,m);" + "if(f==m)" + "i=1.;" + "vec3 l=vec3(v.x,v.y-16.,v.z-10.);" + "l.xy=e()*l.xy;" + "m=t(vec3(l.x+4.,l.yz),.2),f=min(f,m);" + "if(f==m)" + "i=1.;" + "m=t(vec3(l.x-4.,l.yz),.2),f=min(f,m);" + "if(f==m)" + "i=1.;" + "m=t(vec3(l.x,l.y+4.,l.z),.2),f=min(f,m);" + "if(f==m)" + "i=1.;" + "m=t(vec3(l.x,l.y-4.,l.z),.2),f=min(f,m);" + "if(f==m)" + "i=1.;" + "for(float l=0.;l<16.;l++)" "{" - "vec3 c=v+vec3(1.8*8,-5,-2.08*10)+vec3(0,0,2.08*r);" + "vec3 x=v+vec3(1.8*8,-5,-2.08*10)+vec3(0,0,2.08*l);" "for(float v=0.;v<16.;v++)" "{" - "c=mod(v,2.)==0.?" - "c-vec3(1.8,0,1):" - "c+vec3(-1.8,0,1);" - "int y=int(length(vec2(v,r)-n.xy));" - "m=t(c,vec2(.86,1.+t(y)*2.));" + "x=mod(v,2.)==0.?" + "x-vec3(1.8,0,1):" + "x+vec3(-1.8,0,1);" + "int y=int(length(vec2(v,l)-n.xy));" + "m=t(x,vec2(.86,1.+e(y)*2.));" "f=min(f,m);" "if(f==m)" "i=1.;" @@ -45,108 +81,103 @@ const char *fragment_frag = "}" "return vec2(f,i);" "}" - "vec3 t(vec3 v,vec3 i,inout vec3 f)" + "vec3 e(vec3 v,vec3 i,inout vec3 f)" "{" - "float r=0.,m=0.,y=0.;" - "for(int c=0;c<30;c++)" + "float m=0.,l=0.,y=0.;" + "for(int r=0;r<30;r++)" "{" - "f=v+i*r;" - "vec2 n=t(f);" - "r+=n.x;" - "m=n.y;" - "if(r>1e2)" + "f=v+i*m;" + "vec2 n=e(f);" + "m+=n.x*1.2;" + "l=n.y;" + "if(m>1e2)" "break;" - "if(n.x<.001*r)" + "if(n.x<.001*m)" "{" "y=1.;" "break;" "}" "}" - "if(r>1e2)" - "r=0.;" - "return vec3(r,m,y);" + "if(m>1e2)" + "m=0.;" + "return vec3(m,l,y);" "}" - "float t(vec3 v,vec3 i,float y)" + "float e(vec3 v,vec3 m,float i)" "{" - "float f=1.,r=.02;" - "for(int c=0;c<6;c++)" + "float f=1.,l=.02;" + "for(int r=0;r<6;r++)" "{" - "if(r>y)" + "if(l>i)" "break;" - "float m=t(v+r*i).x;" - "f=min(f,m/(4.*r));" - "r+=clamp(m,.1,.8);" + "float x=e(v+l*m).x;" + "f=min(f,x/(4.*l));" + "l+=clamp(x,.1,.8);" "if(f<-1.)" "break;" "}" "f=max(f,-1.);" "return.25*(1.+f)*(1.+f)*(2.-f);" "}" - "vec3 e(vec3 v)" + "vec3 t(vec3 v)" "{" "vec2 i=vec2(.01,0);" - "return normalize(vec3(t(v+i.xyy).x-t(v-i.xyy).x,t(v+i.yxy).x-t(v-i.yxy).x,t(v+i.yyx).x-t(v-i.yyx).x));" + "return normalize(vec3(e(v+i.xyy).x-e(v-i.xyy).x,e(v+i.yxy).x-e(v-i.yxy).x,e(v+i.yyx).x-e(v-i.yyx).x));" "}" - "vec3 e(vec3 v,vec3 i,vec3 f,vec3 r,vec3 c,float m)" + "vec3 e(vec3 v,vec3 f,vec3 m,vec3 i,vec3 x,float l)" "{" - "v-=f;" - "float y=length(v);" + "v-=m;" + "float r=length(v);" "v=normalize(v);" - "float n=3./(1.+.09*y+.032*y*y),p=max(dot(c,v),0.);" - "r=normalize(v-r);" - "vec3 e=vec3(.04);" - "e+=(1.-e)*pow(clamp(1.-max(dot(r,v),0.),0.,1.),5.);" - "y=t(f+c*.01,v,y);" - "return(i*p*n+i*pow(max(dot(c,r),0.),mix(128.,8.,m))*n*e)*y;" + "float n=3./(1.+.09*r+.032*r*r),y=max(dot(x,v),0.);" + "i=normalize(v-i);" + "vec3 z=vec3(.04);" + "z+=(1.-z)*pow(clamp(1.-max(dot(i,v),0.),0.,1.),5.);" + "r=e(m+x*.01,v,r);" + "return(f*y*n+f*pow(max(dot(x,i),0.),mix(128.,8.,l))*n*z)*r;" "}" - "vec3 e(vec3 v,vec3 f,vec3 i,float y)" + "vec3 e(vec3 v,vec3 f,vec3 i,float m)" "{" - "float m=.01;" - "vec3 c=vec3(0);" - "if(y==0.)" - "c=vec3(.8314,.2941,.2941),m=.1;" - "else if(y==1.)" - "c=vec3(.6196,.6118,.6118),m=.7;" - "else if(y==2.)" - "c=vec3(.3255,.4784,.3255),m=.2;" - "else if(y==3.)" - "c=vec3(.2471,.3059,.6314),m=1.;" - "else if(y==4.)" - "c=vec3(.9961,1,.9922),m=.1;" - "else if(y==5.)" - "c=vec3(.9961,1,.9922),m=.3;" - "v=vec3(0)+e(vec3(-10,10,0),vec3(.77,.26,.73),v,i,f,m)+e(vec3(0,10,-5),vec3(.08,.62,.75),v,i,f,m)+e(vec3(0,25,0),vec3(.5137,.1961,.7725),v,i,f,m)+vec3(.08,.62,.75)*clamp(dot(f,normalize(vec3(0,1,-3)*vec3(0,-1,-2))),0.,1.)*.8;" - "return c*max(vec3(0),v);" + "float l=.01;" + "vec3 x=vec3(0);" + "if(m==0.)" + "x=vec3(.8314,.2941,.2941),l=.1;" + "else if(m==1.)" + "x=vec3(.6196,.6118,.6118),l=.7;" + "else if(m==2.)" + "x=vec3(.3255,.4784,.3255),l=.2;" + "else if(m==3.)" + "x=vec3(.2471,.3059,.6314),l=1.;" + "else if(m==4.)" + "x=vec3(.9961,1,.9922),l=.1;" + "else if(m==5.)" + "x=vec3(.9961,1,.9922),l=.3;" + "v=vec3(0)+e(vec3(-10,10,0),vec3(.77,.26,.73),v,i,f,l)+e(vec3(0,10,-5),vec3(.08,.62,.75),v,i,f,l)+e(vec3(0,25,0),vec3(.5137,.1961,.7725),v,i,f,l)+vec3(.08,.62,.75)*clamp(dot(f,normalize(vec3(0,1,-3)*vec3(0,-1,-2))),0.,1.)*.8;" + "return x*max(vec3(0),v);" "}" "vec3 e(vec2 v,vec3 f)" "{" - "f=normalize(vec3(0,-1,10)-f);" + "f=normalize(vec3(0,10,10)-f);" "vec3 m=normalize(cross(vec3(0,1,0),f));" "return normalize(v.x*m+v.y*normalize(cross(f,m))+f);" "}" - "vec3 e()" + "vec3 d()" "{" - "vec3 f;" - "{" - "float v=c*.06;" - "f=vec3(sin(v)*15.,30.+cos(v*.5)*5.,cos(v)*15.);" - "}" - "return f;" + "return vec3(0,30,25);" "}" - "vec3 e(vec2 v)" + "vec3 d(vec2 v)" "{" - "vec3 f=e(v,e()),m=vec3(.102,.2431,.3412),y=vec3(0),i=t(e(),f,y);" - "if(i.x>0.)" + "vec3 f=e(v,d()),i=vec3(.102,.2431,.3412),m=vec3(0),l=e(d(),f,m);" + "if(l.x>0.)" "{" - "vec3 v=e(y);" - "m=e(y,v,f,i.y);" + "vec3 v=t(m);" + "i=e(m,v,f,l.y);" "}" - "return m;" + "return i;" "}" "void main()" "{" - "vec3 v=e(gl_FragCoord.xy*vec2(.00104166667,.00185185185)-1.);" - "f=vec4(v,1);" + "vec3 v=d(t());" + "i=vec4(v,1);" "}"; #endif // FRAGMENT_INL_ diff --git a/src/waveGenerator.cpp b/src/waveGenerator.cpp new file mode 100644 index 0000000..35f0cd1 --- /dev/null +++ b/src/waveGenerator.cpp @@ -0,0 +1,87 @@ +#include "waveGenerator.h" +#include + +const float DECAY_FACTOR = 0.80f; // Amplitude decay per iteration +const float PI = 3.14159265f; + +const float WAVE_LENGTH = 3.0f; +const float WAVE_SPEED = 0.5f; +const int speed = 1; + +float waveOffset = 0.0f; +float temp[WAVE_SIZE] = { 0.0f }; // Temp buffer for propagation + +//float wave[WAVE_SIZE] = { 0.0f }; // Wave buffer +float clamp(float value) { + if (value > 4.f) { + value = 4.f; + } + + if (value < 0.f) { + value = 0.f; + } + return value; +} + +// Generate a sine wave into the beginning of the array +void generateSineWave(float amplitude, float* wave) { + for (int i = 0; i < WAVE_SIZE; ++i) { + float sine = std::sin(2.0f * PI * i / WAVE_LENGTH); + float sample = 1.0f + sine; + wave[i] = clamp(sample * amplitude); + } +} + +// Shift wave and apply decay +void propagateWave(float* wave) { + + + for (int i = WAVE_SIZE - 1; i >= speed; --i) { + wave[i] = wave[i - speed] * DECAY_FACTOR; + } + + // Decay the front section that no longer receives new values + for (int i = 0; i < speed; ++i) { + wave[i] = wave[i] * DECAY_FACTOR; + } +} + + +/* +void propagateWave(float* wave) { + waveOffset += WAVE_SPEED; + + for (int i = 0; i < WAVE_SIZE; ++i) { + float srcIndex = i - waveOffset; + + if (srcIndex < 0 || srcIndex >= WAVE_SIZE - 1) { + temp[i] = 0.0f; + } + else { + int index0 = srcIndex - (srcIndex < 0 && srcIndex != (int)srcIndex); + int index1 = index0 + 1; + float t = srcIndex - index0; + + float value = (1.0f - t) * wave[index0] + t * wave[index1]; + temp[i] = clamp(value * DECAY_FACTOR); + } + } + + //// Copy temp back to wave + for (int i = 0; i < WAVE_SIZE; ++i) { + wave[i] = temp[i]; + } + + //// Prevent offset overflow + if (waveOffset >= 1.0f) { + waveOffset -= waveOffset - (waveOffset < 0 && srcIndex != (int)srcIndex); + } +} +*/ + +void waveGenerator(float sound, float* wave) { + generateSineWave(sound, wave); + propagateWave(wave); +} + + diff --git a/src/waveGenerator.h b/src/waveGenerator.h new file mode 100644 index 0000000..b753843 --- /dev/null +++ b/src/waveGenerator.h @@ -0,0 +1,7 @@ +#pragma once +#include + +#define WAVE_SIZE 512 +void generateSineWave(float amplitude, float* wave); +void propagateWave(float* wave); +void waveGenerator(float sound, float* wave); \ No newline at end of file