From ef00dc22b3b2cfee71fb8321e64527abcea8ea8e Mon Sep 17 00:00:00 2001 From: _Redstone_c_ Date: Sun, 31 Jan 2021 14:34:46 +0800 Subject: [PATCH] GPU Function Library - Done! --- Assets/Scenes/SampleScene.unity | 2 +- Assets/Script/FunctionLibrary.compute | 126 +++++++++++++++++++++++++- Assets/Script/FunctionLibrary.cs | 2 + Assets/Script/GPUGraph.cs | 11 ++- 4 files changed, 133 insertions(+), 8 deletions(-) diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity index 43b781f..64ca789 100644 --- a/Assets/Scenes/SampleScene.unity +++ b/Assets/Scenes/SampleScene.unity @@ -171,7 +171,7 @@ MonoBehaviour: function: 4 transitionMode: 1 functionDuration: 1 - transitionDuration: 0 + transitionDuration: 1 --- !u!1 &705507993 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/Script/FunctionLibrary.compute b/Assets/Script/FunctionLibrary.compute index ef8a549..7caea58 100644 --- a/Assets/Script/FunctionLibrary.compute +++ b/Assets/Script/FunctionLibrary.compute @@ -1,4 +1,32 @@ -#pragma kernel FuncationKernel +#pragma kernel WaveKernel +#pragma kernel WaveToMultiWaveKernel +#pragma kernel WaveToRippleKernel +#pragma kernel WaveToSphereKernel +#pragma kernel WaveToTorusKernel + +#pragma kernel MultiWaveToWaveKernel +#pragma kernel MultiWaveKernel +#pragma kernel MultiWaveToRippleKernel +#pragma kernel MultiWaveToSphereKernel +#pragma kernel MultiWaveToTorusKernel + +#pragma kernel RippleToWaveKernel +#pragma kernel RippleToMultiWaveKernel +#pragma kernel RippleKernel +#pragma kernel RippleToSphereKernel +#pragma kernel RippleToTorusKernel + +#pragma kernel SphereToWaveKernel +#pragma kernel SphereToMultiWaveKernel +#pragma kernel SphereToRippleKernel +#pragma kernel SphereKernel +#pragma kernel SphereToTorusKernel + +#pragma kernel TorusToWaveKernel +#pragma kernel TorusToMultiWaveKernel +#pragma kernel TorusToRippleKernel +#pragma kernel TorusToSphereKernel +#pragma kernel TorusKernel RWStructuredBuffer _Positions; @@ -6,6 +34,7 @@ uint _Resolution; float _Step; float _Time; +float _TransitionProgress; float2 GetUV(uint3 id) { @@ -31,9 +60,96 @@ float3 Wave(float u, float v, float t) return p; } -[numthreads(8, 8, 1)] -void FuncationKernel(uint3 id : SV_DISPATCHTHREADID) +float3 MultiWave(float u, float v, float t) { - float2 uv = GetUV(id); - SetPositions(id, Wave(uv.x, uv.y, _Time)); + float3 p; + p.x = u; + p.y = sin(PI * (u + 0.5 * t)); + p.y += 0.5 * sin(2.0 * PI * (v + t)); + p.y += sin(PI * (u + v + 0.25 * t)); + p.y *= 1.0 / 2.5; + p.z = v; + return p; } + +float3 Ripple(float u, float v, float t) +{ + float d = sqrt(u * u + v * v); + float3 p; + p.x = u; + p.y = sin(PI * (4.0 * d - t)); + p.y /= 1.0 + 10.0 * d; + p.z = v; + return p; +} + +float3 Sphere(float u, float v, float t) +{ + float r = 0.9 + 0.1 * sin(PI * (6.0 * u + 4.0 * v + t)); + float s = r * cos(0.5 * PI * v); + float3 p; + p.x = s * sin(PI * u); + p.y = r * sin(0.5 * PI * v); + p.z = s * cos(PI * u); + return p; +} + +float3 Torus(float u, float v, float t) +{ + float r1 = 0.7 + 0.1 * sin(PI * (6.0 * u + 0.5 * t)); + float r2 = 0.15 + 0.05 * sin(PI * (8.0 * u + 4.0 * v + 2.0 * t)); + float s = r1 + r2 * cos(PI * v); + float3 p; + p.x = s * sin(PI * u); + p.y = r2 * sin(PI * v); + p.z = s * cos(PI * u); + return p; +} + +#define KERNEL_FUNCTION(function) \ + [numthreads(8, 8, 1)] \ + void function##Kernel(uint3 id : SV_DISPATCHTHREADID) \ + { \ + float2 uv = GetUV(id); \ + SetPositions(id, function(uv.x, uv.y, _Time)); \ + } + +KERNEL_FUNCTION(Wave) +KERNEL_FUNCTION(MultiWave) +KERNEL_FUNCTION(Ripple) +KERNEL_FUNCTION(Sphere) +KERNEL_FUNCTION(Torus) + +#define KERNEL_MOPH_FUNCTION(functionA, functionB) \ + [numthreads(8, 8, 1)] \ + void functionA##To##functionB##Kernel(uint3 id : SV_DISPATCHTHREADID) \ + { \ + float2 uv = GetUV(id); \ + float3 position = lerp(functionA(uv.x, uv.y, _Time), functionB(uv.x, uv.y, _Time), _TransitionProgress); \ + SetPositions(id, position); \ + } + +KERNEL_MOPH_FUNCTION(Wave, MultiWave) +KERNEL_MOPH_FUNCTION(Wave, Ripple) +KERNEL_MOPH_FUNCTION(Wave, Sphere) +KERNEL_MOPH_FUNCTION(Wave, Torus) + +KERNEL_MOPH_FUNCTION(MultiWave, Wave) +KERNEL_MOPH_FUNCTION(MultiWave, Ripple) +KERNEL_MOPH_FUNCTION(MultiWave, Sphere) +KERNEL_MOPH_FUNCTION(MultiWave, Torus) + +KERNEL_MOPH_FUNCTION(Ripple, Wave) +KERNEL_MOPH_FUNCTION(Ripple, MultiWave) +KERNEL_MOPH_FUNCTION(Ripple, Sphere) +KERNEL_MOPH_FUNCTION(Ripple, Torus) + +KERNEL_MOPH_FUNCTION(Sphere, Wave) +KERNEL_MOPH_FUNCTION(Sphere, MultiWave) +KERNEL_MOPH_FUNCTION(Sphere, Ripple) +KERNEL_MOPH_FUNCTION(Sphere, Torus) + +KERNEL_MOPH_FUNCTION(Torus, Wave) +KERNEL_MOPH_FUNCTION(Torus, MultiWave) +KERNEL_MOPH_FUNCTION(Torus, Ripple) +KERNEL_MOPH_FUNCTION(Torus, Sphere) diff --git a/Assets/Script/FunctionLibrary.cs b/Assets/Script/FunctionLibrary.cs index 6205c92..8f87d72 100644 --- a/Assets/Script/FunctionLibrary.cs +++ b/Assets/Script/FunctionLibrary.cs @@ -9,6 +9,8 @@ public static class FunctionLibrary private static Function[] functions = { Wave, MultiWave, Ripple, Sphere, Torus }; + public static int functionCount => functions.Length; + public static Function GetFunction(FunctionName name) { return functions[(int)name]; diff --git a/Assets/Script/GPUGraph.cs b/Assets/Script/GPUGraph.cs index 1c6fbee..a5ce1a3 100644 --- a/Assets/Script/GPUGraph.cs +++ b/Assets/Script/GPUGraph.cs @@ -42,6 +42,7 @@ public class GPUGraph : MonoBehaviour static readonly int resolutionId = Shader.PropertyToID("_Resolution"); static readonly int stepId = Shader.PropertyToID("_Step"); static readonly int timeId = Shader.PropertyToID("_Time"); + static readonly int transitionProgressId = Shader.PropertyToID("_TransitionProgress"); private void OnEnable() { @@ -89,11 +90,17 @@ public class GPUGraph : MonoBehaviour computeShader.SetInt(resolutionId, resolution); computeShader.SetFloat(stepId, step); computeShader.SetFloat(timeId, Time.time); + if (transitioning) + { + computeShader.SetFloat(transitionProgressId, Mathf.SmoothStep(0f, 1f, duration / transitionDuration)); + } - computeShader.SetBuffer(0, positionsId, positionsBuffer); + var kernelIndex = (int)function + + (int)(transitioning ? transitionFunction : function) * FunctionLibrary.functionCount; + computeShader.SetBuffer(kernelIndex, positionsId, positionsBuffer); var groups = Mathf.CeilToInt(resolution / 8f); - computeShader.Dispatch(0, groups, groups, 1); + computeShader.Dispatch(kernelIndex, groups, groups, 1); material.SetBuffer(positionsId, positionsBuffer); material.SetFloat(stepId, step);