├── .config └── dotnet-tools.json ├── .gitignore ├── Content ├── Effect.fx ├── Public Sans.ttf ├── ShaderSampleDX.mgcb ├── ShaderSampleGL.mgcb └── TextFont.spritefont ├── Directory.Build.props ├── Game.cs ├── Program.cs ├── README.md ├── Screenshots ├── ComputeCircles.jpg ├── ComputeGeometryParticles.jpg ├── ComputeParticles.jpg ├── EdgeRounding.jpg ├── EditMesh.jpg ├── ObjectCulling.jpg ├── ParticlesIndirectDraw.jpg ├── PixelSort.jpg ├── TesselationGeometry.jpg └── Texture3D.jpg ├── ShaderSampleDX.csproj └── ShaderSampleGL.csproj /.config/dotnet-tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "isRoot": true, 4 | "tools": { 5 | "dotnet-mgcb-compute": { 6 | "version": "3.8.3", 7 | "commands": [ 8 | "mgcb-compute" 9 | ] 10 | }, 11 | "dotnet-mgcb-editor-compute": { 12 | "version": "3.8.3", 13 | "commands": [ 14 | "mgcb-editor-compute" 15 | ] 16 | }, 17 | "dotnet-mgcb-editor-compute-linux": { 18 | "version": "3.8.3", 19 | "commands": [ 20 | "mgcb-editor-compute-linux" 21 | ] 22 | }, 23 | "dotnet-mgcb-editor-compute-windows": { 24 | "version": "3.8.3", 25 | "commands": [ 26 | "mgcb-editor-compute-windows" 27 | ] 28 | }, 29 | "dotnet-mgcb-editor-compute-mac": { 30 | "version": "3.8.3", 31 | "commands": [ 32 | "mgcb-editor-compute-mac" 33 | ] 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #OS junk files 2 | [Tt]humbs.db 3 | *.DS_Store 4 | 5 | #Output Linux Installer 6 | Installers/Linux/tmp_deb/ 7 | Installers/Linux/tmp_run/ 8 | *.run 9 | *.deb 10 | 11 | #Visual Studio files 12 | *.pidb 13 | *.userprefs 14 | *.[Oo]bj 15 | *.exe 16 | *.pdb 17 | *.user 18 | *.aps 19 | *.pch 20 | *.vspscc 21 | *.vssscc 22 | *_i.c 23 | *_p.c 24 | *.ncb 25 | *.suo 26 | *.tlb 27 | *.tlh 28 | *.bak 29 | *.[Cc]ache 30 | *.ilk 31 | *.log 32 | *.lib 33 | *.sbr 34 | *.sdf 35 | *.csproj.csdat 36 | ipch/ 37 | obj/ 38 | [Bb]in 39 | [Dd]ebug*/ 40 | [Rr]elease*/ 41 | Ankh.NoLoad 42 | .vs/ 43 | project.lock.json 44 | /MonoGame.Framework/MonoGame.Framework.Net.WindowsUniversal.project.lock.json 45 | /MonoGame.Framework/MonoGame.Framework.WindowsUniversal.project.lock.json 46 | artifacts/ 47 | 48 | # JetBrains Rider 49 | .idea/ 50 | 51 | #Tooling 52 | _ReSharper*/ 53 | *.resharper 54 | [Tt]est[Rr]esult* 55 | 56 | #Visual Studio Rebracer extension, allows the user to automatically change the style configuration by project 57 | rebracer.xml 58 | 59 | #Subversion files 60 | .svn 61 | 62 | # Office Temp Files 63 | ~$* 64 | 65 | #monodroid private beta 66 | monodroid*.msi 67 | 68 | #Unix temporary files 69 | *~ 70 | 71 | # Output docs 72 | Documentation/Output/ 73 | 74 | #Mac Package Files 75 | *.pkg 76 | *.mpack 77 | **/packages 78 | 79 | #Nuget Packages 80 | **/*.nupkg 81 | 82 | #Zip files 83 | *.zip 84 | 85 | Installers/MacOS/Scripts/Framework/postinstall 86 | IDE/MonoDevelop/MonoDevelop.MonoGame/templates/Common/MonoGame.Framework.dll.config 87 | 88 | # CAKE 89 | .cake/** 90 | 91 | # docfx 92 | _* 93 | /ShaderTest.sln 94 | -------------------------------------------------------------------------------- /Content/Effect.fx: -------------------------------------------------------------------------------- 1 | //============================================================================== 2 | // Vertex shader 3 | //============================================================================== 4 | struct VertexIn 5 | { 6 | float3 Position : POSITION0; 7 | }; 8 | 9 | struct VertexOut 10 | { 11 | float4 Position : SV_POSITION; 12 | }; 13 | 14 | VertexOut VS(in VertexIn input) 15 | { 16 | VertexOut output; 17 | 18 | output.Position = float4(input.Position, 1); 19 | 20 | return output; 21 | } 22 | 23 | //============================================================================== 24 | // Pixel shader 25 | //============================================================================== 26 | float4 PS(VertexOut input) : SV_TARGET 27 | { 28 | return float4(1,1,1,1); 29 | } 30 | 31 | //============================================================================== 32 | // Techniques 33 | //============================================================================== 34 | technique Tech0 35 | { 36 | pass P0 37 | { 38 | VertexShader = compile vs_4_0 VS(); 39 | PixelShader = compile ps_4_0 PS(); 40 | } 41 | }; -------------------------------------------------------------------------------- /Content/Public Sans.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cpt-max/MonoGame-Shader-Samples/7ee68d492657b8ace3f46dab0c8af5ccb16685f6/Content/Public Sans.ttf -------------------------------------------------------------------------------- /Content/ShaderSampleDX.mgcb: -------------------------------------------------------------------------------- 1 | 2 | #----------------------------- Global Properties ----------------------------# 3 | 4 | /outputDir:../bin/$(Configuration)/.net8.0-windows/Content 5 | /intermediateDir:../obj/$(Configuration)/.net8.0-windows/Content 6 | /platform:Windows 7 | /config:Debug 8 | /profile:HiDef 9 | /compress:False 10 | 11 | #-------------------------------- References --------------------------------# 12 | 13 | 14 | #---------------------------------- Content ---------------------------------# 15 | 16 | #begin Effect.fx 17 | /importer:EffectImporter 18 | /processor:EffectProcessor 19 | /processorParam:DebugMode=Auto 20 | /build:Effect.fx 21 | 22 | -------------------------------------------------------------------------------- /Content/ShaderSampleGL.mgcb: -------------------------------------------------------------------------------- 1 | 2 | #----------------------------- Global Properties ----------------------------# 3 | 4 | /outputDir:../bin/$(Configuration)/.net8.0/Content 5 | /intermediateDir:../obj/$(Configuration)/.net8.0/Content 6 | /platform:DesktopGL 7 | /config:Debug 8 | /profile:HiDef 9 | /compress:False 10 | 11 | #-------------------------------- References --------------------------------# 12 | 13 | 14 | #---------------------------------- Content ---------------------------------# 15 | 16 | #begin Effect.fx 17 | /importer:EffectImporter 18 | /processor:EffectProcessor 19 | /processorParam:DebugMode=Auto 20 | /build:Effect.fx 21 | 22 | -------------------------------------------------------------------------------- /Content/TextFont.spritefont: -------------------------------------------------------------------------------- 1 |  2 | 8 | 9 | 10 | 11 | 14 | Public Sans 15 | 16 | 20 | 24 21 | 22 | 26 | 0 27 | 28 | 32 | true 33 | 34 | 38 | 39 | 40 | 44 | 45 | 46 | 53 | 54 | 55 | 56 | ~ 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | obj\Nuget.$(MSBuildProjectName) 5 | 6 | -------------------------------------------------------------------------------- /Game.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using Microsoft.Xna.Framework; 4 | using Microsoft.Xna.Framework.Graphics; 5 | using Microsoft.Xna.Framework.Input; 6 | 7 | namespace ShaderSample 8 | { 9 | public class ShaderGame : Game 10 | { 11 | const int ResolutionX = 1280; 12 | const int ResolutionY = 720; 13 | 14 | GraphicsDeviceManager graphics; 15 | Effect effect; 16 | 17 | public ShaderGame() 18 | { 19 | Content.RootDirectory = "Content"; 20 | graphics = new GraphicsDeviceManager(this); 21 | graphics.GraphicsProfile = GraphicsProfile.HiDef; 22 | graphics.IsFullScreen = false; 23 | } 24 | 25 | protected override void Initialize() 26 | { 27 | graphics.PreferredBackBufferWidth = ResolutionX; 28 | graphics.PreferredBackBufferHeight = ResolutionY; 29 | graphics.ApplyChanges(); 30 | 31 | base.Initialize(); 32 | } 33 | 34 | protected override void LoadContent() 35 | { 36 | effect = Content.Load("Effect"); 37 | } 38 | 39 | protected override void Update(GameTime gameTime) 40 | { 41 | if (Keyboard.GetState().IsKeyDown(Keys.Escape)) 42 | Exit(); 43 | 44 | base.Update(gameTime); 45 | } 46 | 47 | protected override void Draw(GameTime gameTime) 48 | { 49 | graphics.GraphicsDevice.Clear(Color.CornflowerBlue); 50 | 51 | var triangle = new VertexPositionTexture[] { 52 | new VertexPositionTexture(new Vector3( 0, 0.1f, 0), new Vector2(0, 0)), 53 | new VertexPositionTexture(new Vector3( 0.1f, -0.1f, 0), new Vector2(0, 1)), 54 | new VertexPositionTexture(new Vector3(-0.1f, -0.1f, 0), new Vector2(1, 1)), 55 | }; 56 | 57 | foreach (var pass in effect.CurrentTechnique.Passes) 58 | { 59 | pass.Apply(); 60 | GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, triangle, 0, 1); 61 | } 62 | 63 | base.Draw(gameTime); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ShaderSample 4 | { 5 | public static class Program 6 | { 7 | static void Main() 8 | { 9 | using (var game = new ShaderGame()) 10 | game.Run(); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MonoGame Shader Samples Overview 2 | 3 | Each sample is in a separate branch of this repository, so don't use this branch here, pick a sample from below first.
4 | The samples are based on a [custom MonoGame fork](https://github.com/cpt-max/MonoGame), that adds tesselation, geometry and compute shaders.
5 | You don't need to build the fork in order to run the samples, as they use prebuilt NuGet packages. As long as .Net 8 is installed, they should just launch.
6 | 7 | [Equivalent Android Samples](https://github.com/cpt-max/MonoGame-Shader-Samples-Mobile)
8 | [Compute Shader Guide for MonoGame](https://github.com/cpt-max/Docs/blob/master/MonoGame%20Compute%20Shader%20Guide.md)
9 | [NuGet Packages, Platform Support and Build Requirements](https://github.com/cpt-max/Docs/blob/master/Build%20Requirements.md)
10 | [Pull Request for main MonoGame Repo](https://github.com/MonoGame/MonoGame/pull/7533)
11 | [MonoGame Forum Post](https://community.monogame.net/t/compute-tessellation-geometry-shader/16676)
12 | [Download Prebuilt Executables](https://www.dropbox.com/s/v4gg77pzbniykha/Monogame.Shader.Samples.zip?dl=1) (win-x64, linux-x64, requires .Net 5+) 13 |

14 | 15 | ## [Simple Tessellation & Geometry Shader](https://github.com/cpt-max/MonoGame-Shader-Samples/tree/tesselation_geometry) 16 | [](https://github.com/cpt-max/MonoGame-Shader-Samples/tree/tesselation_geometry) 17 | This sample uses a very simple hull and domain shader to tessellate a single input triangle into many sub triangles. Each sub triangle is then passed into a geometry shader to generate even more triangles along it's edges, which creates a wireframe-like effect. 18 |

19 | 20 | ## [Edge-rounding Tessellation Shader](https://github.com/cpt-max/MonoGame-Shader-Samples/tree/edgerounding) 21 | [](https://github.com/cpt-max/MonoGame-Shader-Samples/tree/edgerounding) 22 | This sample uses a hull and domain shader to round off the edges of a mesh. The mesh is created out of quad patches. The rounding radius and tesselltation factor can be changed dynamically. 23 |

24 | 25 | ## [Particle Compute Shader](https://github.com/cpt-max/MonoGame-Shader-Samples/tree/compute_gpu_particles) 26 | [](https://github.com/cpt-max/MonoGame-Shader-Samples/tree/compute_gpu_particles) 27 | This sample uses a compute shader to update particles on the GPU. The particle buffer is used directly by the vertex shader that draws the particles. Since no data needs to be downloaded to the CPU, this method is very fast. 28 |

29 | 30 | ## [Collision Test Compute Shader](https://github.com/cpt-max/MonoGame-Shader-Samples/tree/compute_cpu) 31 | [](https://github.com/cpt-max/MonoGame-Shader-Samples/tree/compute_cpu) 32 | This sample uses a compute shader to do brute-force collision checks between circles. The buffer containing the collision results is then downloaded to the CPU, in order to color the circles according to how many collisions they are involved in. 33 |

34 | 35 | ## [Pixel-Sort Compute Shader](https://github.com/cpt-max/MonoGame-Shader-Samples/tree/compute_write_to_texture) 36 | [](https://github.com/cpt-max/MonoGame-Shader-Samples/tree/compute_write_to_texture) 37 | This sample uses a compute shader to sort pixels in a texture horizontally by hue. 38 | For each pair of pixels a compute thread is launched, that swaps the pixels (if neccessary) like a bubble sort. 39 |

40 | 41 | ## [Edit Mesh Compute Shader](https://github.com/cpt-max/MonoGame-Shader-Samples/tree/compute_write_to_vertex_buffer) 42 | [](https://github.com/cpt-max/MonoGame-Shader-Samples/tree/compute_write_to_vertex_buffer) 43 | This sample uses a compute shader to modify a vertex and an index buffer directly on the GPU. 44 |

45 | 46 | ## [Texture3D Compute Shader](https://github.com/cpt-max/MonoGame-Shader-Samples/tree/compute_write_to_3d_texture) 47 | [](https://github.com/cpt-max/MonoGame-Shader-Samples/tree/compute_write_to_3d_texture) 48 | This sample uses a compute shader to update a 3D texture on the GPU.
49 | The texture is initialized with a bunch of randomly colored pixels. The pixel's color represents a velocity, so pixels move through the volume. 50 |

51 | 52 | ## [Object Culling with Indirect Draw](https://github.com/cpt-max/MonoGame-Shader-Samples/tree/object_culling_indirect_draw) 53 | [](https://github.com/cpt-max/MonoGame-Shader-Samples/tree/object_culling_indirect_draw) 54 | This sample uses a compute shader to determine the visibility of objects directly on the GPU. 55 | A structured buffer is filled up with all the visible objects, which are then draw using indirect draw. This has the advantage that no data has to be downloaded from the GPU to the CPU.
56 | There is a [converted version of this sample using an append buffer](https://github.com/cpt-max/MonoGame-Shader-Samples/tree/object_culling_indirect_draw_append), which slightly simplifies the code. 57 |

58 | 59 | ## [Particles with Indirect Draw](https://github.com/cpt-max/MonoGame-Shader-Samples/tree/indirect_draw_instances) 60 | [](https://github.com/cpt-max/MonoGame-Shader-Samples/tree/indirect_draw_instances) 61 | This sample uses a compute shader to spawn, destroy and update particles.
62 | Since the spawn and destroy logic is done on the GPU, the CPU doesn't know how many particles to draw.
63 | Using indirect draw makes it possible to draw and update the correct number of particles, without the need to download that data to the CPU. 64 |

65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /Screenshots/ComputeCircles.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cpt-max/MonoGame-Shader-Samples/7ee68d492657b8ace3f46dab0c8af5ccb16685f6/Screenshots/ComputeCircles.jpg -------------------------------------------------------------------------------- /Screenshots/ComputeGeometryParticles.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cpt-max/MonoGame-Shader-Samples/7ee68d492657b8ace3f46dab0c8af5ccb16685f6/Screenshots/ComputeGeometryParticles.jpg -------------------------------------------------------------------------------- /Screenshots/ComputeParticles.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cpt-max/MonoGame-Shader-Samples/7ee68d492657b8ace3f46dab0c8af5ccb16685f6/Screenshots/ComputeParticles.jpg -------------------------------------------------------------------------------- /Screenshots/EdgeRounding.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cpt-max/MonoGame-Shader-Samples/7ee68d492657b8ace3f46dab0c8af5ccb16685f6/Screenshots/EdgeRounding.jpg -------------------------------------------------------------------------------- /Screenshots/EditMesh.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cpt-max/MonoGame-Shader-Samples/7ee68d492657b8ace3f46dab0c8af5ccb16685f6/Screenshots/EditMesh.jpg -------------------------------------------------------------------------------- /Screenshots/ObjectCulling.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cpt-max/MonoGame-Shader-Samples/7ee68d492657b8ace3f46dab0c8af5ccb16685f6/Screenshots/ObjectCulling.jpg -------------------------------------------------------------------------------- /Screenshots/ParticlesIndirectDraw.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cpt-max/MonoGame-Shader-Samples/7ee68d492657b8ace3f46dab0c8af5ccb16685f6/Screenshots/ParticlesIndirectDraw.jpg -------------------------------------------------------------------------------- /Screenshots/PixelSort.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cpt-max/MonoGame-Shader-Samples/7ee68d492657b8ace3f46dab0c8af5ccb16685f6/Screenshots/PixelSort.jpg -------------------------------------------------------------------------------- /Screenshots/TesselationGeometry.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cpt-max/MonoGame-Shader-Samples/7ee68d492657b8ace3f46dab0c8af5ccb16685f6/Screenshots/TesselationGeometry.jpg -------------------------------------------------------------------------------- /Screenshots/Texture3D.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cpt-max/MonoGame-Shader-Samples/7ee68d492657b8ace3f46dab0c8af5ccb16685f6/Screenshots/Texture3D.jpg -------------------------------------------------------------------------------- /ShaderSampleDX.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | WinExe 4 | .net8.0-windows 5 | false 6 | false 7 | true 8 | ShaderSample 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ShaderSampleGL.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | WinExe 4 | .net8.0 5 | false 6 | false 7 | ShaderSample 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | --------------------------------------------------------------------------------