├── .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 |
--------------------------------------------------------------------------------