more resource docs
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
eaa901893b
commit
a9b29023d0
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
title: "Framebuffer"
|
||||
date: 2021-01-26T17:58:24-08:00
|
||||
weight: 6
|
||||
---
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
title: "Render Pass"
|
||||
date: 2021-01-26T17:55:09-08:00
|
||||
weight: 7
|
||||
---
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
---
|
||||
title: "Render Target"
|
||||
date: 2021-01-26T17:59:45-08:00
|
||||
weight: 5
|
||||
---
|
||||
|
||||
When you write rendering code, you might intuitively think we are just drawing to the screen, but you would be wrong! In MoonWorks, we are always drawing to an object called a render target. You can think of a render target like a canvas. It can be whatever size we want and whatever color format, and we can composite them together to get our final render.
|
||||
|
||||
To create a render target, we need a multisample count and a texture slice.
|
||||
|
||||
Multisampling is a technique which can produce higher-quality images at a processing cost. You should probably read more about multisampling elsewhere if you're interested, but know that it's an option. If you don't want multisampling, simply use `SampleCount.One` or omit the sample count argument.
|
||||
|
||||
```cs
|
||||
var myRenderTarget = new RenderTarget(
|
||||
GraphicsDevice,
|
||||
myTextureSlice
|
||||
);
|
||||
```
|
||||
|
||||
When we use a texture slice to create a render target, we say that the render target is "backed" by the texture slice. This code will create a render target that is backed by `myTextureSlice`. In order to use a texture as a backing texture, you need to make sure you create it with the `TextureUsageFlags.RenderTarget` flag.
|
||||
|
||||
A lot of the time you will be creating render targets and textures at the same time. We have a nice shortcut for that.
|
||||
|
||||
```cs
|
||||
var myRenderTarget = RenderTarget.CreateBackedColorTarget2D(
|
||||
GraphicsDevice,
|
||||
1280,
|
||||
720,
|
||||
TextureFormat.R8G8B8A8,
|
||||
false
|
||||
);
|
||||
```
|
||||
|
||||
This code creates a 1280x720 color render target, and creates the backing texture alongside it.
|
||||
|
||||
Another important kind of render target is a "depth buffer". Depth buffers are used so that the graphics card can know to skip rendering on pixels that will be obscured by other objects. This can be a major optimization.
|
||||
|
||||
To create a depth buffer, you must use one of the depth texture formats.
|
||||
|
||||
```cs
|
||||
var textureCreateInfo = new TextureCreateInfo
|
||||
{
|
||||
Width = 1280,
|
||||
Height = 720,
|
||||
Depth = 1,
|
||||
Format = TextureFormat.D32,
|
||||
IsCube = false,
|
||||
LevelCount = 1,
|
||||
SampleCount = SampleCount.One,
|
||||
UsageFlags = TextureUsageFlags.RenderTarget
|
||||
};
|
||||
|
||||
var depthTexture = new Texture(GraphicsDevice, textureCreateInfo);
|
||||
|
||||
var depthBuffer = new RenderTarget(
|
||||
GraphicsDevice,
|
||||
new TextureSlice(depthTexture)
|
||||
);
|
||||
```
|
||||
|
||||
This sets up a 1280x720 32-bit depth buffer.
|
|
@ -0,0 +1,31 @@
|
|||
---
|
||||
title: "Shader Module"
|
||||
date: 2021-01-26T17:41:14-08:00
|
||||
weight: 4
|
||||
---
|
||||
|
||||
Shaders are, to perhaps oversimplify a bit, the procedures that are used in rendering. A shader is a parallel program that your GPU will run thousands or tens of thousands of times simultaneously to process your data.
|
||||
|
||||
Explaining everything about shaders is beyond the scope of this documentation and there are plenty of resources for learning shader programming out there, so I will stick to a simple explanation and you can take it from there.
|
||||
|
||||
Vertex shaders are programs that transform vertex data. A vertex shader runs once per vertex and outputs some vertex-related data.
|
||||
|
||||
The graphics pipeline "rasterizes" your vertex data to produce pixel data, and this pixel data is then further transformed by your pixel, or "fragment" shader.
|
||||
|
||||
We'll talk more about this when we get to graphics pipelines. For now, let's explain how to create a MoonWorks shader module.
|
||||
|
||||
MoonWorks shader modules expect input in a format called "SPIR-V bytecode." Unlike the bad old days where you were locked into whatever shader language your engine required, SPIR-V is an intermediate representation. That means it can compile from higher level shader languages like GLSL or HLSL. Personally I prefer GLSL, but you can use any shader language you want that outputs SPIR-V!
|
||||
|
||||
To compile a GLSL shader into SPIR-V, you can use the [glslangValidator](https://github.com/KhronosGroup/glslang) program like this:
|
||||
|
||||
```sh
|
||||
glslangValidator -V myCoolShader.frag -o myCoolShaderFrag.spv
|
||||
```
|
||||
|
||||
This will output a file named "myCoolShaderFrag.spv". Now we can put that shader module into MoonWorks.
|
||||
|
||||
```cs
|
||||
var myShaderModule = new ShaderModule(GraphicsDevice, "myCoolShaderFrag.spv");
|
||||
```
|
||||
|
||||
Shader modules don't do anything on their own - you use them as part of a graphics pipeline. We'll get into that later.
|
|
@ -14,7 +14,7 @@ var textureCreateInfo = new TextureCreateInfo
|
|||
Width = 128,
|
||||
Height = 128,
|
||||
Depth = 1,
|
||||
Format = ColorFormat.R8G8B8A8,
|
||||
Format = TextureFormat.R8G8B8A8,
|
||||
IsCube = false,
|
||||
LevelCount = 1,
|
||||
SampleCount = SampleCount.One,
|
||||
|
@ -39,9 +39,9 @@ myTexture.SetData(pixels);
|
|||
Of course, having to fill in all this data every time is kind of cumbersome, so we have some shortcut methods for common texture usages.
|
||||
|
||||
```cs
|
||||
var my2DTexture = Texture.CreateTexture2D(GraphicsDevice, 128, 128, ColorFormat.R8G8B8A8, TextureUsageFlags.Sampler);
|
||||
var my3DTexture = Texture.CreateTexture3D(GraphicsDevice, 128, 128, ColorFormat.R8G8B8A8, TextureUsageFlags.Sampler);
|
||||
var myCubeTexture = Texture.CreateTextureCube(GraphicsDevice, 128, ColorFormat.R8G8B8A8, TextureUsageFlags.Sampler);
|
||||
var my2DTexture = Texture.CreateTexture2D(GraphicsDevice, 128, 128, TextureFormat.R8G8B8A8, TextureUsageFlags.Sampler);
|
||||
var my3DTexture = Texture.CreateTexture3D(GraphicsDevice, 128, 128, TextureFormat.R8G8B8A8, TextureUsageFlags.Sampler);
|
||||
var myCubeTexture = Texture.CreateTextureCube(GraphicsDevice, 128, TextureFormat.R8G8B8A8, TextureUsageFlags.Sampler);
|
||||
```
|
||||
|
||||
There is also a built-in PNG loader that creates a 2D R8G8B8A8 texture and fills it with pixel data.
|
||||
|
@ -49,3 +49,15 @@ There is also a built-in PNG loader that creates a 2D R8G8B8A8 texture and fills
|
|||
```cs
|
||||
var myPNGTexture = Texture.LoadPNG(GraphicsDevice, "coldsteel_the_hedgehog.png");
|
||||
```
|
||||
|
||||
One last concept we should discuss before moving on is texture slicing.
|
||||
|
||||
Texture slices are a very commonly used concept in MoonWorks. You don't have to do texture operations on an entire texture - you can instead use a subsection of the texture for whatever your operation is.
|
||||
|
||||
```cs
|
||||
var myTexture = Texture.Load(GraphicsDevice, "myTexture.png");
|
||||
var mySliceRect = new Rect(0, 0, 16, 16);
|
||||
var myTextureSlice = new TextureSlice(myTexture, mySliceRect);
|
||||
```
|
||||
|
||||
This code produces a texture slice which is a 16x16 square in the top left corner of the image. You can create slices of 3D textures and cube textures as well! We'll talk more about where to use texture slices later.
|
||||
|
|
|
@ -20,6 +20,6 @@ MoonWorks provides nine different kinds of graphics resources that you use to co
|
|||
|
||||
`Framebuffer` is essentially a collection of `RenderTarget`s.
|
||||
|
||||
`RenderPass` is essentially a link that tells the `GraphicsPipeline` how it should use a `Framebuffer`.
|
||||
`RenderPass` is a structure that tells the `GraphicsPipeline` how it should use a `Framebuffer`.
|
||||
|
||||
This is all pretty abstract. Let's get into some more detail.
|
||||
|
|
Loading…
Reference in New Issue