├── Captures └── lbm.gif ├── Assets ├── LBM │ ├── Scenes │ │ ├── SimpleLBM.unity │ │ └── SimpleLBM.unity.meta │ ├── Scenes.meta │ ├── Scripts.meta │ ├── Shaders.meta │ ├── Shaders │ │ ├── LBM.meta │ │ └── LBM │ │ │ ├── Includes.meta │ │ │ ├── Compute.shader.meta │ │ │ ├── Copy.shader.meta │ │ │ ├── Init.shader.meta │ │ │ ├── Paint.shader.meta │ │ │ ├── Show.shader.meta │ │ │ ├── Step.shader.meta │ │ │ ├── BounceBack.shader.meta │ │ │ ├── Includes │ │ │ ├── compute.cginc.meta │ │ │ └── compute.cginc │ │ │ ├── Init.shader │ │ │ ├── Paint.shader │ │ │ ├── Copy.shader │ │ │ ├── Show.shader │ │ │ ├── Step.shader │ │ │ ├── BounceBack.shader │ │ │ └── Compute.shader │ └── Scripts │ │ ├── LBM.cs.meta │ │ └── LBM.cs └── LBM.meta ├── .gitignore └── README.md /Captures/lbm.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattatz/unity-lbm-fluid-simulation/HEAD/Captures/lbm.gif -------------------------------------------------------------------------------- /Assets/LBM/Scenes/SimpleLBM.unity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattatz/unity-lbm-fluid-simulation/HEAD/Assets/LBM/Scenes/SimpleLBM.unity -------------------------------------------------------------------------------- /Assets/LBM/Scenes/SimpleLBM.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 958ab5bf9bd5df94cae97cdecb53ae81 3 | timeCreated: 1433816822 4 | licenseType: Pro 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/LBM.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8aef6564c96bb34438883716be25b903 3 | folderAsset: yes 4 | timeCreated: 1432087571 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/LBM/Scenes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7281fa669fefe784085f57530acce53e 3 | folderAsset: yes 4 | timeCreated: 1433816813 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/LBM/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: eb883103c7458d44fb42956387cb533c 3 | folderAsset: yes 4 | timeCreated: 1432087575 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/LBM/Shaders.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bc7b8ec2b686a334f86bb487304d7124 3 | folderAsset: yes 4 | timeCreated: 1432087582 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/LBM/Shaders/LBM.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 84de8e6a8386d564eb6853782701a65c 3 | folderAsset: yes 4 | timeCreated: 1433817544 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/LBM/Shaders/LBM/Includes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8bc9d7c492f4240479e9292a7ea57d46 3 | folderAsset: yes 4 | timeCreated: 1433818984 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/LBM/Shaders/LBM/Compute.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e9bada50480218241977a7caf53a58ac 3 | timeCreated: 1433817600 4 | licenseType: Pro 5 | ShaderImporter: 6 | defaultTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/LBM/Shaders/LBM/Copy.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f16f6cf976bdb884f976f4094509a203 3 | timeCreated: 1433817604 4 | licenseType: Pro 5 | ShaderImporter: 6 | defaultTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/LBM/Shaders/LBM/Init.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d4f5b21648861c5429d8ee82aaecbefa 3 | timeCreated: 1433820953 4 | licenseType: Pro 5 | ShaderImporter: 6 | defaultTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/LBM/Shaders/LBM/Paint.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9450291e174ad4049ad158abc2d7d775 3 | timeCreated: 1433826100 4 | licenseType: Pro 5 | ShaderImporter: 6 | defaultTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/LBM/Shaders/LBM/Show.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bfc274ee32e4d8643b297e7944cd1312 3 | timeCreated: 1433823338 4 | licenseType: Pro 5 | ShaderImporter: 6 | defaultTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/LBM/Shaders/LBM/Step.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 58b4d86588c357a4f9ec8e0ad876f6e9 3 | timeCreated: 1433817595 4 | licenseType: Pro 5 | ShaderImporter: 6 | defaultTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/LBM/Shaders/LBM/BounceBack.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b40816aa56b6a9a42a588da07d8ead26 3 | timeCreated: 1433817629 4 | licenseType: Pro 5 | ShaderImporter: 6 | defaultTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/LBM/Shaders/LBM/Includes/compute.cginc.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7098d4431525f8542949d93b960a495d 3 | timeCreated: 1433819026 4 | licenseType: Pro 5 | ShaderImporter: 6 | defaultTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | [Ll]ibrary/ 2 | [Tt]emp/ 3 | [Oo]bj/ 4 | [Bb]uild/ 5 | [Pp]rojectSettings/ 6 | 7 | # Autogenerated VS/MD solution and project files 8 | *.csproj 9 | *.unityproj 10 | *.sln 11 | *.suo 12 | *.user 13 | *.userprefs 14 | *.pidb 15 | *.booproj 16 | 17 | # Unity3D Generated File On Crash Reports 18 | sysinfo.txt 19 | -------------------------------------------------------------------------------- /Assets/LBM/Scripts/LBM.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d2645df884c41b04f824227e27396fb2 3 | timeCreated: 1432087599 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | unity-lbm-fluid-simulation 2 | ===================== 3 | 4 | Lattice Boltzmann Method (LBM) fluid simulation for Unity. 5 | 6 | ![lbm](https://raw.githubusercontent.com/mattatz/unity-lbm-fluid-simulation/master/Captures/lbm.gif) 7 | 8 | ## Demo 9 | 10 | [Unity Web Player](https://mattatz.github.io/unity/lbm-fluid-simulation) 11 | -------------------------------------------------------------------------------- /Assets/LBM/Shaders/LBM/Init.shader: -------------------------------------------------------------------------------- 1 | Shader "LBM/Init" { 2 | 3 | CGINCLUDE 4 | 5 | #include "UnityCG.cginc" 6 | 7 | float4 frag(v2f_img IN) : SV_Target { 8 | return float4(0, 0, 0, 1); 9 | } 10 | 11 | ENDCG 12 | 13 | SubShader { 14 | Pass { 15 | Fog { Mode Off } 16 | CGPROGRAM 17 | #pragma target 3.0 18 | #pragma vertex vert_img 19 | #pragma fragment frag 20 | ENDCG 21 | } 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /Assets/LBM/Shaders/LBM/Paint.shader: -------------------------------------------------------------------------------- 1 | Shader "LBM/Paint" { 2 | 3 | Properties { 4 | _X ("X", Float) = 0.5 5 | _Y ("Y", Float) = 0.5 6 | _Radius ("Radius", Float) = 0.02 7 | } 8 | 9 | CGINCLUDE 10 | 11 | #include "UnityCG.cginc" 12 | 13 | uniform float _X; 14 | uniform float _Y; 15 | uniform float _Radius; 16 | 17 | float4 frag(v2f_img IN) : SV_Target { 18 | float2 uv = IN.uv; 19 | if(distance(uv, float2(_X, _Y)) < _Radius) { 20 | return float4(1, 0, 0, 1); 21 | } else { 22 | return float4(0, 0, 0, 1); 23 | } 24 | } 25 | 26 | ENDCG 27 | 28 | SubShader { 29 | 30 | Pass { 31 | Fog { Mode Off } 32 | CGPROGRAM 33 | #pragma target 3.0 34 | #pragma vertex vert_img 35 | #pragma fragment frag 36 | ENDCG 37 | } 38 | 39 | } 40 | 41 | FallBack "Diffuse" 42 | } 43 | -------------------------------------------------------------------------------- /Assets/LBM/Shaders/LBM/Copy.shader: -------------------------------------------------------------------------------- 1 | Shader "LBM/Copy" { 2 | 3 | Properties { 4 | _Diffuse1 ("Diffuse Texture", 2D) = "" {} 5 | _Diffuse2 ("Diffuse Texture", 2D) = "" {} 6 | _Diffuse3 ("Diffuse Texture", 2D) = "" {} 7 | } 8 | 9 | CGINCLUDE 10 | 11 | #include "UnityCG.cginc" 12 | 13 | uniform sampler2D _Diffuse1; 14 | uniform sampler2D _Diffuse2; 15 | uniform sampler2D _Diffuse3; 16 | 17 | float4 copy1(v2f_img IN) : SV_Target { 18 | return tex2D(_Diffuse1, IN.uv); 19 | } 20 | 21 | float4 copy2(v2f_img IN) : SV_Target { 22 | return tex2D(_Diffuse2, IN.uv); 23 | } 24 | 25 | float4 copy3(v2f_img IN) : SV_Target { 26 | return tex2D(_Diffuse3, IN.uv); 27 | } 28 | 29 | ENDCG 30 | 31 | SubShader { 32 | 33 | Pass { 34 | Fog { Mode Off } 35 | CGPROGRAM 36 | #pragma target 3.0 37 | #pragma vertex vert_img 38 | #pragma fragment copy1 39 | ENDCG 40 | } 41 | 42 | Pass { 43 | Fog { Mode Off } 44 | CGPROGRAM 45 | #pragma target 3.0 46 | #pragma vertex vert_img 47 | #pragma fragment copy2 48 | ENDCG 49 | } 50 | 51 | Pass { 52 | Fog { Mode Off } 53 | CGPROGRAM 54 | #pragma target 3.0 55 | #pragma vertex vert_img 56 | #pragma fragment copy3 57 | ENDCG 58 | } 59 | 60 | } 61 | 62 | FallBack "Diffuse" 63 | } 64 | -------------------------------------------------------------------------------- /Assets/LBM/Shaders/LBM/Includes/compute.cginc: -------------------------------------------------------------------------------- 1 | 2 | float2 uv = IN.uv; 3 | float t1 = 4.0 / 9.0; 4 | float t2 = 1.0 / 9.0; 5 | float t3 = 1.0 / 36.0; 6 | float c_squ = 1.0 / 3.0; 7 | 8 | float4 v1 = tex2D(_Diffuse1, uv); 9 | float4 v2 = tex2D(_Diffuse2, uv); 10 | float4 v3 = tex2D(_Diffuse3, uv); 11 | 12 | float f1 = v1.r; 13 | float f2 = v1.g; 14 | float f3 = v1.b; 15 | 16 | float f4 = v2.r; 17 | float f5 = v2.g; 18 | float f6 = v2.b; 19 | 20 | float f7 = v3.r; 21 | float f8 = v3.g; 22 | float f9 = v3.b; 23 | 24 | if (_T == 0.) { 25 | f1 = 1. / 9.; 26 | f2 = 1. / 9.; 27 | f3 = 1. / 9.; 28 | f4 = 1. / 9.; 29 | f5 = 1. / 9.; 30 | f6 = 1. / 9.; 31 | f7 = 1. / 9.; 32 | f8 = 1. / 9.; 33 | f9 = 1. / 9.; 34 | }; 35 | 36 | float density = f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9; 37 | float invDensity = 1./ density; 38 | float ux = invDensity * (f1 + f2 + f8 - f4 - f5 - f6); 39 | float uy = invDensity * (f2 + f3 + f4 - f6 - f7 - f8); 40 | 41 | /* 42 | // if (abs(uv.x - 0.5 / 512.) < 1e-6) { 43 | if (abs(uv.x - _Dx) < 1e-6) { 44 | ux = 0.25 * (uv.y - uv.y * uv.y); 45 | uy = 0.0; 46 | density = (1. / (1. - ux)) * (f3 + f7 + f9 + 2. * (f4 + f5 + f6) ); 47 | f1 = f5 + (2. / 3.) * density * ux; 48 | f2 = f6 + 0.5 * (f7 - f3) + 0.5 * density * uy + (1. / 6.) * density * ux; 49 | f8 = f4 + 0.5 * (f3 - f7) - 0.5 * density * uy + (1. / 6.) * density * ux; 50 | // } else if (abs(uv.x - ( 1. - 0.5/512. ) ) < 1e-6) { 51 | } else if (abs(uv.x - (1. - _Dx)) < 1e-6) { 52 | density = 1.; 53 | ux = -1. + (1. / density) * (f3 + f7 + f9 + 2. * (f1 + f2 + f8)); 54 | uy = 0.0; 55 | f5 = f1 - (2. / 3.) * density * ux; 56 | f6 = f2 + 0.5 * (f3 - f7) - 0.5 * density * uy - (1. / 6.) * density * ux; 57 | f4 = f8 + 0.5 * (f7 - f3) + 0.5 * density * uy - (1. / 6.) * density * ux; 58 | }; 59 | */ 60 | 61 | float usqu = ux * ux + uy * uy; // dot(u, u) 62 | float uc2 = ux + uy; // dot(vec2(1., 1.), u) 63 | float uc4 = -ux + uy; // dot(vec2(-1., 1.), u) 64 | float uc6 = -uc2; // dot(vec2(-1., -1.), u) 65 | float uc8 = -uc4; // dot(vec2(1., -1.), u) 66 | 67 | -------------------------------------------------------------------------------- /Assets/LBM/Shaders/LBM/Show.shader: -------------------------------------------------------------------------------- 1 | Shader "LBM/Show" { 2 | 3 | Properties { 4 | _Diffuse1 ("Diffuse Texture", 2D) = "" {} 5 | _Diffuse2 ("Diffuse Texture", 2D) = "" {} 6 | _Diffuse3 ("Diffuse Texture", 2D) = "" {} 7 | _Mask ("Mask Texture", 2D) = "" {} 8 | _Dx ("dx", float) = 0.001 9 | _Dy ("dy", float) = 0.001 10 | } 11 | 12 | CGINCLUDE 13 | 14 | #include "UnityCG.cginc" 15 | 16 | uniform sampler2D _Diffuse1; 17 | uniform sampler2D _Diffuse2; 18 | uniform sampler2D _Diffuse3; 19 | uniform sampler2D _Mask; 20 | uniform float _Dx; 21 | uniform float _Dy; 22 | 23 | void velocity (float4 v1, float4 v2, float4 v3, out float u, out float v) { 24 | u = (v1.r + v1.g + v3.g) - (v2.r + v2.g + v2.b); 25 | v = (v1.g + v1.b + v2.r) - (v2.b + v3.r + v3.g); 26 | } 27 | 28 | float4 frag(v2f_img IN) : SV_Target { 29 | float2 uv = IN.uv; 30 | float4 v1 = tex2D(_Diffuse1, uv); 31 | float4 v2 = tex2D(_Diffuse2, uv); 32 | float4 v3 = tex2D(_Diffuse3, uv); 33 | float ux, uy; 34 | velocity(v1, v2, v3, ux, uy); 35 | 36 | /* 37 | float uW, vW, uE, vE, uN, vN, uS, vS; 38 | 39 | v1 = tex2D(_Diffuse1, uv + float2( _Dx, 0)); 40 | v2 = tex2D(_Diffuse2, uv + float2( _Dx, 0)); 41 | v3 = tex2D(_Diffuse3, uv + float2( _Dx, 0)); 42 | velocity(v1, v2, v3, uE, vE); 43 | 44 | v1 = tex2D(_Diffuse1, uv + float2(-_Dx, 0)); 45 | v2 = tex2D(_Diffuse2, uv + float2(-_Dx, 0)); 46 | v3 = tex2D(_Diffuse3, uv + float2(-_Dx, 0)); 47 | velocity(v1, v2, v3, uW, vW); 48 | 49 | v1 = tex2D(_Diffuse1, uv + float2( 0, -_Dy)); 50 | v2 = tex2D(_Diffuse2, uv + float2( 0, -_Dy)); 51 | v3 = tex2D(_Diffuse3, uv + float2( 0, -_Dy)); 52 | velocity(v1, v2, v3, uN, vN); 53 | 54 | v1 = tex2D(_Diffuse1, uv + float2( 0, _Dy)); 55 | v2 = tex2D(_Diffuse2, uv + float2( 0, _Dy)); 56 | v3 = tex2D(_Diffuse3, uv + float2( 0, _Dy)); 57 | velocity(v1, v2, v3, uS, vS); 58 | float m = abs(10.0 * ((vE - vW) - (uN - uS))); 59 | */ 60 | 61 | float s = (abs(ux) + abs(uy)) * 5; 62 | return float4(s, s, s, 1.); 63 | } 64 | 65 | 66 | ENDCG 67 | 68 | SubShader { 69 | 70 | Pass { 71 | Fog { Mode Off } 72 | CGPROGRAM 73 | #pragma target 3.0 74 | #pragma vertex vert_img 75 | #pragma fragment frag 76 | ENDCG 77 | } 78 | 79 | } 80 | 81 | FallBack "Diffuse" 82 | } 83 | -------------------------------------------------------------------------------- /Assets/LBM/Shaders/LBM/Step.shader: -------------------------------------------------------------------------------- 1 | Shader "LBM/Step" { 2 | 3 | Properties { 4 | _Diffuse1 ("Diffuse Texture 1", 2D) = "" {} 5 | _Diffuse2 ("Diffuse Texture 2", 2D) = "" {} 6 | _Diffuse3 ("Diffuse Texture 3", 2D) = "" {} 7 | _Dx ("dx", float) = 0.001 8 | _Dy ("dy", float) = 0.001 9 | _T ("time", float) = 0.0 10 | } 11 | 12 | CGINCLUDE 13 | 14 | #include "UnityCG.cginc" 15 | 16 | uniform sampler2D _Diffuse1; 17 | uniform sampler2D _Diffuse2; 18 | uniform sampler2D _Diffuse3; 19 | uniform float _Dx; 20 | uniform float _Dy; 21 | uniform float _T; 22 | 23 | float4 step1(v2f_img IN) : SV_Target { 24 | float4 col = float4(1.0 / 9.0, 1.0 / 9.0, 1.0 / 9.0, 1.0); 25 | if(_T > 0.) { 26 | float2 uv = IN.uv; 27 | float f1 = tex2D(_Diffuse1, uv - float2(_Dx, 0)).r; 28 | float f2 = tex2D(_Diffuse1, uv - float2(_Dx, _Dy)).g; 29 | float f3 = tex2D(_Diffuse1, uv - float2( 0, _Dy)).b; 30 | col.rgb = float3(f1, f2, f3); 31 | } 32 | return col; 33 | } 34 | 35 | float4 step2(v2f_img IN) : SV_Target { 36 | float4 col = float4(1.0 / 9.0, 1.0 / 9.0, 1.0 / 9.0, 1.0); 37 | if(_T > 0.) { 38 | float2 uv = IN.uv; 39 | float f4 = tex2D(_Diffuse2, uv - float2(-_Dx, _Dy)).r; 40 | float f5 = tex2D(_Diffuse2, uv - float2(-_Dx, 0)).g; 41 | float f6 = tex2D(_Diffuse2, uv - float2(-_Dx, -_Dy)).b; 42 | col.rgb = float3(f4, f5, f6); 43 | } 44 | return col; 45 | } 46 | 47 | float4 step3(v2f_img IN) : SV_Target { 48 | float4 col = float4(1.0 / 9.0, 1.0 / 9.0, 1.0 / 9.0, 1.0); 49 | if(_T > 0.) { 50 | float2 uv = IN.uv; 51 | float f7 = tex2D(_Diffuse3, uv - float2( 0, -_Dy)).r; 52 | float f8 = tex2D(_Diffuse3, uv - float2( _Dx, -_Dy)).g; 53 | float f9 = tex2D(_Diffuse3, uv - float2( 0, 0)).b; 54 | col.rgb = float3(f7, f8, f9); 55 | } 56 | return col; 57 | } 58 | 59 | 60 | ENDCG 61 | 62 | SubShader { 63 | 64 | Pass { 65 | Fog { Mode Off } 66 | CGPROGRAM 67 | #pragma target 3.0 68 | #pragma vertex vert_img 69 | #pragma fragment step1 70 | ENDCG 71 | } 72 | 73 | Pass { 74 | Fog { Mode Off } 75 | CGPROGRAM 76 | #pragma target 3.0 77 | #pragma vertex vert_img 78 | #pragma fragment step2 79 | ENDCG 80 | } 81 | 82 | Pass { 83 | Fog { Mode Off } 84 | CGPROGRAM 85 | #pragma target 3.0 86 | #pragma vertex vert_img 87 | #pragma fragment step3 88 | ENDCG 89 | } 90 | 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /Assets/LBM/Shaders/LBM/BounceBack.shader: -------------------------------------------------------------------------------- 1 | Shader "LBM/BounceBack" { 2 | 3 | Properties { 4 | _Diffuse1 ("Diffuse Texture 1", 2D) = "" {} 5 | _Diffuse2 ("Diffuse Texture 2", 2D) = "" {} 6 | _Diffuse3 ("Diffuse Texture 3", 2D) = "" {} 7 | _Mask ("Mask Texture", 2D) = "black" {} 8 | _Threshold ("Mask Threshold", float) = 0.1 9 | _Strongness ("Strongness", float) = 1.1 10 | } 11 | 12 | CGINCLUDE 13 | 14 | #include "UnityCG.cginc" 15 | 16 | uniform sampler2D _Diffuse1; 17 | uniform sampler2D _Diffuse2; 18 | uniform sampler2D _Diffuse3; 19 | uniform sampler2D _Mask; 20 | uniform float _Threshold; 21 | uniform float _Strongness; 22 | 23 | // (W, NW, N) 24 | float4 bounceback1(v2f_img IN) : SV_Target { 25 | float4 col; 26 | if(tex2D(_Mask, IN.uv).r > _Threshold) { 27 | // (E, SE, S) to (W, NW, N) 28 | float4 v2 = tex2D(_Diffuse2, IN.uv); 29 | float4 v3 = tex2D(_Diffuse3, IN.uv); 30 | float f5 = v2.g; 31 | float f6 = v2.b; 32 | float f7 = v3.r; 33 | col = float4(f5, f6, f7, 1.) * _Strongness; 34 | } else { 35 | col = tex2D(_Diffuse1, IN.uv); 36 | } 37 | return col; 38 | } 39 | 40 | float4 bounceback2(v2f_img IN) : SV_Target { 41 | float4 col; 42 | if(tex2D(_Mask, IN.uv).r > _Threshold) { 43 | float4 v1 = tex2D(_Diffuse1, IN.uv); 44 | float4 v3 = tex2D(_Diffuse3, IN.uv); 45 | float f8 = v3.g; 46 | float f1 = v1.r; 47 | float f2 = v1.g; 48 | col = float4(f8, f1, f2, 1.) * _Strongness; 49 | } else { 50 | col = tex2D(_Diffuse2, IN.uv); 51 | } 52 | return col; 53 | } 54 | 55 | float4 bounceback3(v2f_img IN) : SV_Target { 56 | float4 col; 57 | if(tex2D(_Mask, IN.uv).r > _Threshold) { 58 | float4 v1 = tex2D(_Diffuse1, IN.uv); 59 | float4 v2 = tex2D(_Diffuse2, IN.uv); 60 | float4 v3 = tex2D(_Diffuse3, IN.uv); 61 | float f3 = v1.b; 62 | float f4 = v2.r; 63 | col = float4(f3, f4, v3.b, 1.) * _Strongness; 64 | } else { 65 | col = tex2D(_Diffuse3, IN.uv); 66 | } 67 | return col; 68 | } 69 | 70 | ENDCG 71 | 72 | SubShader { 73 | 74 | Pass { 75 | Fog { Mode Off } 76 | CGPROGRAM 77 | #pragma target 3.0 78 | #pragma vertex vert_img 79 | #pragma fragment bounceback1 80 | ENDCG 81 | } 82 | 83 | Pass { 84 | Fog { Mode Off } 85 | CGPROGRAM 86 | #pragma target 3.0 87 | #pragma vertex vert_img 88 | #pragma fragment bounceback2 89 | ENDCG 90 | } 91 | 92 | Pass { 93 | Fog { Mode Off } 94 | CGPROGRAM 95 | #pragma target 3.0 96 | #pragma vertex vert_img 97 | #pragma fragment bounceback3 98 | ENDCG 99 | } 100 | 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /Assets/LBM/Shaders/LBM/Compute.shader: -------------------------------------------------------------------------------- 1 | Shader "LBM/Compute" { 2 | 3 | Properties { 4 | _Diffuse1 ("Diffuse Texture 1", 2D) = "" {} 5 | _Diffuse2 ("Diffuse Texture 2", 2D) = "" {} 6 | _Diffuse3 ("Diffuse Texture 3", 2D) = "" {} 7 | _Dx ("dx", float) = 0.001 8 | _Dy ("dy", float) = 0.001 9 | __Omega ("_Omega", float) = 0.1 10 | _T ("time", float) = 0.0 11 | } 12 | 13 | CGINCLUDE 14 | 15 | #include "UnityCG.cginc" 16 | 17 | uniform sampler2D _Diffuse1; 18 | uniform sampler2D _Diffuse2; 19 | uniform sampler2D _Diffuse3; 20 | uniform float _Omega; 21 | uniform float _Dx; 22 | uniform float _Dy; 23 | uniform float _T; 24 | 25 | float4 compute1 (v2f_img IN) : SV_Target { 26 | 27 | #include "Includes/compute.cginc" 28 | 29 | float feq1 = t2 * density * (1. + ux / c_squ + 0.5 * (ux / c_squ) * (ux / c_squ)- usqu / (2. * c_squ)); 30 | float feq3 = t2 * density * (1. + uy / c_squ + 0.5 * (uy / c_squ) * (uy / c_squ) - usqu / (2. * c_squ)); 31 | float feq2 = t3 * density * (1. + uc2 / c_squ + 0.5 * (uc2 / c_squ) * (uc2 / c_squ)- usqu / (2. * c_squ)); 32 | float ff1 = _Omega * feq1 + (1. - _Omega) * f1; 33 | float ff2 = _Omega * feq2 + (1. - _Omega) * f2; 34 | float ff3 = _Omega * feq3 + (1. - _Omega) * f3; 35 | 36 | ff1 = clamp(ff1, 0.0, 1.0); 37 | ff2 = clamp(ff2, 0.0, 1.0); 38 | ff3 = clamp(ff3, 0.0, 1.0); 39 | 40 | return float4(ff1, ff2, ff3, 1.0); 41 | } 42 | 43 | float4 compute2(v2f_img IN) : SV_Target { 44 | 45 | #include "Includes/compute.cginc" 46 | 47 | float feq5 = t2 * density * (1. - ux / c_squ + 0.5 * (ux / c_squ) * (ux / c_squ) - usqu / (2. * c_squ)); 48 | float feq4 = t3 * density * (1. + uc4 / c_squ + 0.5 * (uc4 / c_squ) * (uc4 / c_squ) - usqu / (2. * c_squ)); 49 | float feq6 = t3 * density * (1. + uc6 / c_squ + 0.5 * (uc6 / c_squ) * (uc6 / c_squ) - usqu / (2. * c_squ)); 50 | 51 | float ff4 = _Omega * feq4 + (1. - _Omega) * f4; 52 | float ff5 = _Omega * feq5 + (1. - _Omega) * f5; 53 | float ff6 = _Omega * feq6 + (1. - _Omega) * f6; 54 | 55 | ff4 = clamp(ff4, 0.0, 1.0); 56 | ff5 = clamp(ff5, 0.0, 1.0); 57 | ff6 = clamp(ff6, 0.0, 1.0); 58 | 59 | return float4(ff4, ff5, ff6, 1.); 60 | } 61 | 62 | float4 compute3(v2f_img IN) : SV_Target { 63 | 64 | #include "Includes/Compute.cginc" 65 | 66 | float feq7 = t2 * density * (1. - uy / c_squ + 0.5 * (uy / c_squ) * (uy / c_squ) - usqu / (2. * c_squ)); 67 | float feq8 = t3 * density * (1. + uc8 / c_squ + 0.5 * (uc8 / c_squ) * (uc8 / c_squ) - usqu / (2. * c_squ)); 68 | float feq9 = t1 * density * (1. - usqu / (2. * c_squ)); 69 | float ff7 = _Omega * feq7 + (1. - _Omega) * f7; 70 | float ff8 = _Omega * feq8 + (1. - _Omega) * f8; 71 | float ff9 = _Omega * feq9 + (1. - _Omega) * f9; 72 | 73 | ff7 = clamp(ff7, 0.0, 1.0); 74 | ff8 = clamp(ff8, 0.0, 1.0); 75 | ff9 = clamp(ff9, 0.0, 1.0); 76 | 77 | return float4(ff7, ff8, ff9, 1.); 78 | } 79 | 80 | 81 | ENDCG 82 | 83 | SubShader { 84 | 85 | Pass { 86 | Fog { Mode Off } 87 | CGPROGRAM 88 | #pragma target 3.0 89 | #pragma vertex vert_img 90 | #pragma fragment compute1 91 | ENDCG 92 | } 93 | 94 | Pass { 95 | Fog { Mode Off } 96 | CGPROGRAM 97 | #pragma target 3.0 98 | #pragma vertex vert_img 99 | #pragma fragment compute2 100 | ENDCG 101 | } 102 | 103 | Pass { 104 | Fog { Mode Off } 105 | CGPROGRAM 106 | #pragma target 3.0 107 | #pragma vertex vert_img 108 | #pragma fragment compute3 109 | ENDCG 110 | } 111 | 112 | } 113 | 114 | FallBack "Diffuse" 115 | } 116 | -------------------------------------------------------------------------------- /Assets/LBM/Scripts/LBM.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | public class LBM : MonoBehaviour { 5 | 6 | [SerializeField] float omega = 1.0f; 7 | 8 | [SerializeField] Shader initShader; 9 | [SerializeField] Shader compShader; 10 | [SerializeField] Shader stepShader; 11 | [SerializeField] Shader copyShader; 12 | [SerializeField] Shader bounceBackShader; 13 | [SerializeField] Shader showShader; 14 | [SerializeField] Shader paintShader; 15 | 16 | Material initMat; 17 | Material compMat; 18 | Material stepMat; 19 | Material copyMat; 20 | Material bounceBackMat; 21 | Material paintMat; 22 | Material showMat; 23 | 24 | RenderTexture rt1; 25 | RenderTexture rt2; 26 | RenderTexture rt3; 27 | RenderTexture rt1c; 28 | RenderTexture rt2c; 29 | RenderTexture rt3c; 30 | RenderTexture rtMask; 31 | 32 | bool isDragging; 33 | 34 | void Start () { 35 | SetupRTs(); 36 | SetupMats(); 37 | 38 | Graphics.Blit(null, rtMask, initMat); 39 | Graphics.Blit(null, rt1, initMat); 40 | Graphics.Blit(null, rt2, initMat); 41 | Graphics.Blit(null, rt3, initMat); 42 | } 43 | 44 | void Update () { 45 | 46 | if(Input.GetMouseButtonDown(0)) { 47 | isDragging = true; 48 | } else if(Input.GetMouseButtonUp(0)) { 49 | Graphics.Blit (null, rtMask, initMat); 50 | isDragging = false; 51 | } 52 | 53 | if(isDragging) { 54 | Graphics.Blit (null, rtMask, initMat); 55 | 56 | Vector3 mousePos = Input.mousePosition; 57 | float mx = mousePos.x / Screen.width; 58 | float my = mousePos.y / Screen.height; 59 | paintMat.SetFloat("_X", mx); 60 | paintMat.SetFloat("_Y", my); 61 | Graphics.Blit (null, rtMask, paintMat); 62 | } 63 | 64 | Graphics.Blit(null, rt1c, compMat, 0); 65 | Graphics.Blit(null, rt2c, compMat, 1); 66 | Graphics.Blit(null, rt3c, compMat, 2); 67 | 68 | Graphics.Blit(null, rt1, copyMat, 0); 69 | Graphics.Blit(null, rt2, copyMat, 1); 70 | Graphics.Blit(null, rt3, copyMat, 2); 71 | 72 | Graphics.Blit(null, rt1c, bounceBackMat, 0); 73 | Graphics.Blit(null, rt2c, bounceBackMat, 1); 74 | Graphics.Blit(null, rt3c, bounceBackMat, 2); 75 | 76 | Graphics.Blit(null, rt1, copyMat, 0); 77 | Graphics.Blit(null, rt2, copyMat, 1); 78 | Graphics.Blit(null, rt3, copyMat, 2); 79 | 80 | Graphics.Blit(null, rt1c, stepMat, 0); 81 | Graphics.Blit(null, rt1, copyMat, 0); 82 | 83 | Graphics.Blit(null, rt2c, stepMat, 1); 84 | Graphics.Blit(null, rt2, copyMat, 1); 85 | 86 | Graphics.Blit(null, rt3c, stepMat, 2); 87 | Graphics.Blit(null, rt3, copyMat, 2); 88 | 89 | compMat.SetFloat("_Omega", omega); 90 | compMat.SetFloat("_T", Time.timeSinceLevelLoad); 91 | stepMat.SetFloat("_T", Time.timeSinceLevelLoad); 92 | } 93 | 94 | void OnGUI () { 95 | if(!Event.current.type.Equals(EventType.Repaint)) return; 96 | 97 | var tex = new Texture2D(1, 1); 98 | tex.SetPixel(0, 0, Color.white); 99 | Graphics.DrawTexture(new Rect(0, 0, Screen.width, Screen.height), tex, showMat); 100 | 101 | int size = 48; 102 | var r00 = new Rect(0, size * 0, size, size); 103 | var r01 = new Rect(0, size * 1, size, size); 104 | var r02 = new Rect(0, size * 2, size, size); 105 | var r03 = new Rect(0, size * 3, size, size); 106 | Graphics.DrawTexture(r00, rtMask); 107 | Graphics.DrawTexture(r01, rt1c); 108 | Graphics.DrawTexture(r02, rt2c); 109 | Graphics.DrawTexture(r03, rt3c); 110 | } 111 | 112 | void OnDestroy () { 113 | rt1.Release(); 114 | rt2.Release(); 115 | rt3.Release(); 116 | rt1c.Release(); 117 | rt2c.Release(); 118 | rt3c.Release(); 119 | rtMask.Release(); 120 | } 121 | 122 | void SetupRTs () { 123 | rt1 = CreateRenderTexture(Screen.width, Screen.height); 124 | rt2 = CreateRenderTexture(Screen.width, Screen.height); 125 | rt3 = CreateRenderTexture(Screen.width, Screen.height); 126 | rt1c = CreateRenderTexture(Screen.width, Screen.height); 127 | rt2c = CreateRenderTexture(Screen.width, Screen.height); 128 | rt3c = CreateRenderTexture(Screen.width, Screen.height); 129 | rtMask = CreateRenderTexture(Screen.width, Screen.height); 130 | } 131 | 132 | void SetupMats () { 133 | initMat = new Material(initShader); 134 | copyMat = new Material(copyShader); 135 | compMat = new Material(compShader); 136 | stepMat = new Material(stepShader); 137 | bounceBackMat = new Material(bounceBackShader); 138 | showMat = new Material(showShader); 139 | paintMat = new Material(paintShader); 140 | 141 | copyMat.SetTexture("_Diffuse1", rt1c); 142 | copyMat.SetTexture("_Diffuse2", rt2c); 143 | copyMat.SetTexture("_Diffuse3", rt3c); 144 | 145 | compMat.SetTexture("_Diffuse1", rt1); 146 | compMat.SetTexture("_Diffuse2", rt2); 147 | compMat.SetTexture("_Diffuse3", rt3); 148 | compMat.SetFloat("_Omega", omega); 149 | compMat.SetFloat("_Dx", 1f / Screen.width); 150 | compMat.SetFloat("_Dy", 1f / Screen.height); 151 | 152 | bounceBackMat.SetTexture("_Diffuse1", rt1); 153 | bounceBackMat.SetTexture("_Diffuse2", rt2); 154 | bounceBackMat.SetTexture("_Diffuse3", rt3); 155 | bounceBackMat.SetTexture("_Mask", rtMask); 156 | 157 | stepMat.SetTexture("_Diffuse1", rt1); 158 | stepMat.SetTexture("_Diffuse2", rt2); 159 | stepMat.SetTexture("_Diffuse3", rt3); 160 | stepMat.SetFloat("_Dx", 1f / Screen.width); 161 | stepMat.SetFloat("_Dy", 1f / Screen.height); 162 | 163 | showMat.SetTexture("_Diffuse1", rt1c); 164 | showMat.SetTexture("_Diffuse2", rt2c); 165 | showMat.SetTexture("_Diffuse3", rt3c); 166 | showMat.SetTexture("_Mask", rtMask); 167 | showMat.SetFloat("_Dx", 1f / Screen.width); 168 | showMat.SetFloat("_Dy", 1f / Screen.height); 169 | } 170 | 171 | RenderTexture CreateRenderTexture (int width, int height) { 172 | RenderTexture rt = new RenderTexture(width, height, 0); 173 | rt.format = RenderTextureFormat.ARGBFloat; 174 | rt.wrapMode = TextureWrapMode.Repeat; 175 | rt.filterMode = FilterMode.Point; 176 | rt.Create(); 177 | return rt; 178 | } 179 | 180 | } 181 | --------------------------------------------------------------------------------