You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: articles/tutorials/advanced/2d_shaders/07_sprite_vertex_effect/index.md
+39-32Lines changed: 39 additions & 32 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -123,7 +123,15 @@ Now that you understand the default vertex shader being used by `SpriteBatch`, w
123
123
1. convert the vertices from world-space to clip-space
124
124
2. provide the input semantics required for the pixel shader.
125
125
126
-
To experiment with this, create a new Sprite Effect called `3dEffect` in the _MonoGameLibrary_'s shared content effects folder. We need to add a vertex shader function. To do that, we need a new `struct` that holds all the input semantics passed from `SpriteBatch`:
126
+
To experiment with this, create a new Sprite Effect called `3dEffect` in the _MonoGameLibrary_'s shared content effects folder.
127
+
128
+
||
1. We need to add a vertex shader function. To do that, we need a new `struct` that holds all the input semantics passed from `SpriteBatch`:
127
135
128
136
> [!tip]
129
137
> Use a struct for inputs and outputs.
@@ -132,45 +140,44 @@ To experiment with this, create a new Sprite Effect called `3dEffect` in the _Mo
132
140
133
141
[!code-hlsl[](./snippets/snippet-7-09.hlsl)]
134
142
135
-
Now add the stub for the vertex shader function:
143
+
2.Now add the stub for the vertex shader function:
136
144
137
145
[!code-hlsl[](./snippets/snippet-7-10.hlsl)]
138
146
139
-
And finally modify the `technique` to _include_ the vertex shader function. Until now, the `MainVS()` function is just considered as any average function in your shader, and since it wasn't used from the `MainPS` pixel shader, it would be compiled out of the shader. When you specify the `MainVS()` function as the vertex shader function, you are overriding the default `SpriteBatch` vertex shader function:
147
+
3.And finally modify the `technique` to _include_ the vertex shader function. Until now, the `MainVS()` function is just considered as any average function in your shader, and since it wasn't used from the `MainPS` pixel shader, it would be compiled out of the shader. When you specify the `MainVS()` function as the vertex shader function, you are overriding the default `SpriteBatch` vertex shader function:
140
148
141
149
[!code-hlsl[](./snippets/snippet-7-11.hlsl)]
142
150
143
-
The shader will not compile yet, because the `VertexShaderOutput` has not been completely initialized. We need to replicate the `MatrixTransform` step to convert the vertices from world-space to clip-space.
144
-
145
-
Add the `MatrixTransform` shader parameter:
151
+
4. The shader will not compile yet, because the `VertexShaderOutput` has not been completely initialized. We need to replicate the `MatrixTransform` step to convert the vertices from world-space to clip-space.
152
+
Add the `MatrixTransform` shader parameter:
146
153
147
154
[!code-hlsl[](./snippets/snippet-7-12.hlsl)]
148
155
149
-
And then assign all of the output semantics in the vertex shader:
156
+
5.And then assign all of the output semantics in the vertex shader:
150
157
151
158
[!code-hlsl[](./snippets/snippet-7-13.hlsl)]
152
159
153
-
To validate this is working, we should try to use the new effect. For now, we will experiment in the `TitleScene`. Create a class member for the new `Material`:
160
+
6.To validate this is working, we should try to use the new effect. For now, we will experiment in the `TitleScene`. Create a class member for the new `Material`:
154
161
155
162
[!code-csharp[](./snippets/snippet-7-14.cs)]
156
163
157
-
Load the shader using the hot reload system:
164
+
7.Load the shader using the hot reload system:
158
165
159
166
[!code-csharp[](./snippets/snippet-7-15.cs)]
160
167
161
-
And then use the effect when drawing the title text:
168
+
8.And then use the effect when drawing the title text:
162
169
163
170
[!code-csharp[](./snippets/snippet-7-16.cs)]
164
171
165
-
When the game runs, the text will be missing. This is because we never created a projection matrix to assign to the `MatrixTransform` shader parameter. Add this code when loading the material:
172
+
9.When the game runs, the text will be missing. This is because we never created a projection matrix to assign to the `MatrixTransform` shader parameter. Add this code when loading the material:
166
173
167
174
[!code-csharp[](./snippets/snippet-7-17.cs)]
168
175
169
-
And now you should see the text normally again.
176
+
10.And now you should see the text normally again.
170
177
171
-
||
178
+
||
|**Figure 7-4: We can control the vertex positions**|
196
+
|**Figure 7-5: We can control the vertex positions**|
190
197
191
198
It is important to build intuition for the different coordinate systems involved. Instead of adding the `DebugOffset`_after_ the clip-space conversion, if you try to add it _before_, like in the code below:
192
199
193
200
[!code-hlsl[](./snippets/snippet-7-20.hlsl)]
194
201
195
202
Then you will not see much movement at all. This is because the `DebugOffset` values only go from `0` to `1`, and in world space, this really only amounts to a single pixel. In fact, exactly how much an addition of _`1`_ happens to make is entirely defined _by_ the conversion to clip-space. The `projection` matrix we created treats world space coordinates with an origin around the screen's center, where 1 unit maps to 1 pixel. Sometimes this is exactly what you want, and sometimes it can be confusing.
196
203
197
-
||
204
+
||
The text disappears for half of the rotation. That happens because as the vertices are rotated, the triangle itself started to point _away_ from the camera. By default, `SpriteBatch` will cull any faces that point away from the camera. Change the `rasterizerState` to `CullNone` when beginning the sprite batch:
247
254
248
255
[!code-csharp[](./snippets/snippet-7-26.cs)]
249
256
250
257
And voilà, the text no longer disappears on its flip side.
251
258
252
-
||
259
+
||
|**Figure 7-8: A spinning text with reverse sides with smaller fov**|
267
+
|**Figure 7-9: A spinning text with reverse sides with smaller fov**|
261
268
262
269
As a final touch, we should remove the hard-coded `screenSize` variable from the shader, and extract it as a shader parameter. While we are at it, clean up and remove the debug parameters as well:
263
270
@@ -271,9 +278,9 @@ And instead of manually controlling the spin angle, we can make the title spin g
271
278
272
279
[!code-csharp[](./snippets/snippet-7-29.cs)]
273
280
274
-
||
281
+
||
@@ -359,9 +366,9 @@ And then apply all of the parameters to the single material:
359
366
360
367
Any place where the old `_colorSwapMaterial` is being referenced should be changed to use the `_gameMaterial` instead. Now, if you run the game, the color swap controls are still visible, but we can also manually control the tilt of the map.
361
368
362
-
||
369
+
||
0 commit comments