Need a starting aid with 2d matrices(world and projection) with vertexshader

Hi, I try to understand this project where an image is slightly moved horizontally while the bottom vertices remain in place (at least so I understand the article):

https://www.indie-dev.at/2019/05/03/wind-shader/

Everytime I run the project, the sprites are not appearing or at least not at the correct position.
So I have read several articles about world, view and projection matrices to understand the problem, but I didn’t succeeded.

For the projection matrix I used Matrix.CreateOrthographic(…) and for view matrix I called Matrix.CreateLookAt(new Vector3(400, 300, -1), new Vector3(400, 300, 0), Vector3.Up) but the sprites were still not drawn on screen. After that I tried to use a world matrix as view matrix like shown in the code below, but no success either.(with several different inputs)

Here the shader:

//#pragma enable_d3d11_debug_symbols

#if OPENGL
#define SV_POSITION POSITION
#define VS_SHADERMODEL vs_3_0
#define PS_SHADERMODEL ps_3_0
#else
#define VS_SHADERMODEL vs_4_0_level_9_1
#define PS_SHADERMODEL ps_4_0_level_9_1
#endif

Texture2D SpriteTexture;
sampler2D SpriteTextureSampler = sampler_state
{
	Texture = <SpriteTexture>;
};

float4x4 projectionMatrix;
float4x4 viewMatrix;

float gameTime = 1.0;
float bendEnd = 0.5;
float minValue = 0.1;
float strength = 0.005;

struct PixelShaderOutput
{
	float4 Color: COLOR0;
};

struct VertexShaderOutput
{
	float4 Position : SV_POSITION;
	float2 TexCoord : TEXCOORD0;
	float4 Color: COLOR0;
};

VertexShaderOutput VertexShaderLogic(float4 position : SV_POSITION, float4 color : COLOR0, float2 texCoord : TEXCOORD0)
{
	VertexShaderOutput output = (VertexShaderOutput)0;

	output.Position = position;

	
	if (texCoord.y < 1)
		output.Position.x += minValue + sin(gameTime) * strength;

	output.Position = mul(output.Position, viewMatrix);
	output.Position = mul(output.Position, projectionMatrix);
	

	output.TexCoord = texCoord;
	output.Color = color;

	return output;
}

PixelShaderOutput PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
	PixelShaderOutput output = (PixelShaderOutput)0;

	output.Color = tex2D(SpriteTextureSampler, input.TexCoord) * input.Color;

	return output;
}

technique SpriteDrawing
{
	pass P0
	{
		VertexShader = compile VS_SHADERMODEL VertexShaderLogic();
		PixelShader = compile PS_SHADERMODEL PixelShaderFunction();
	}
};

Here the cs

 private Matrix WhatHelp() {
            return Matrix.CreateTranslation(0, 0, 0) * Matrix.CreateRotationZ(0) * Matrix.CreateScale(1, 1, 1);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

          
            WaveEffect.Parameters["projectionMatrix"].SetValue(Matrix.CreateOrthographic(800, 600, -1, 1));

            WaveEffect.Parameters["viewMatrix"].SetValue(WhatHelp());

            WaveEffect.Parameters["gameTime"].SetValue(GameTT);
            WaveEffect.Parameters["bendEnd"].SetValue(0.5f);
            WaveEffect.Parameters["strength"].SetValue(2f);
            WaveEffect.Parameters["minValue"].SetValue(15f);

            spriteBatch.Begin(SpriteSortMode.Deferred, effect: WaveEffect, transformMatrix: WhatHelp());
            
            spriteBatch.Draw(Tree, new Vector2(100, 200), Color.White);
            spriteBatch.Draw(Tree, new Vector2(400, 200), Color.White);
            spriteBatch.End();


            base.Draw(gameTime);
        }

WaveEffect.Parameters[“projectionMatrix”].SetValue(Matrix.CreateOrthographic(800, 600, -1, 1));
WaveEffect.Parameters[“viewMatrix”].SetValue(WhatHelp());

Which value would work for the desired screen output or is the problem elsewhere?

Hey Zynganugi! To see what kind of problem you are having add to the spriteBatch.Begin this rasterizerState: RasterizerState.CullNone. To quickly fix your problem instead of CreateOrthographic use CreateOrthographicOffCenter. In your case CreateOrthographicOffCenter(0, 800, 600, 0, -1, 1).

I lack knowledge about CreateOrthographic, but I believe inverting height (600 to -600 in your case) is the correct way to do it.

1 Like

To give some more information why this fixes it if it does what I assume here…

To speed up rendering the triangles facing away from the camera are being culled meaning not rendered. If you have 3D objects for example this avoids that the backside of objects get rendered which is often the wanted behavior. The way the front side is defined for each triangle is the ordering of the vertices that make it up: Clockwise or Counter Clockwise.

1 Like

Thanks @Einis, that was exactly what i needed. Now the projects runs as i desire.
Thanks @Kwyrky for the additional contribution.

So for anybody who come by.
Place the “if” to under the two matrix mul lines. Dunno why its was so in the first place even in the original post.
Should be so:

 VertexShaderOutput VertexShaderLogic(float4 position : SV_POSITION, float4 color : COLOR0, float2 texCoord : TEXCOORD0)
    {
    	VertexShaderOutput output = (VertexShaderOutput)0;

    	output.Position = position;

    	output.Position = mul(output.Position, viewMatrix);
    	output.Position = mul(output.Position, projectionMatrix);
    	
    	if (texCoord.y < 1)
    		output.Position.x += minValue + sin(gameTime) * strength;

    	output.TexCoord = texCoord;
    	output.Color = color;

    	return output;
    }

And with a now changed Draw:

protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
        
            WaveEffect.Parameters["projectionMatrix"].SetValue(Matrix.CreateOrthographicOffCenter(0, 800, 600, 0, -1, 1));

            WaveEffect.Parameters["viewMatrix"].SetValue(Matrix.CreateTranslation(0, 0, 0) * Matrix.CreateRotationZ(0) * Matrix.CreateScale(1, 1, 1));

            WaveEffect.Parameters["gameTime"].SetValue(GameTT);
            WaveEffect.Parameters["bendEnd"].SetValue(0.5f);
            WaveEffect.Parameters["strength"].SetValue(.1f);
            WaveEffect.Parameters["minValue"].SetValue(.1f);

            spriteBatch.Begin(SpriteSortMode.Deferred, effect: WaveEffect, transformMatrix: WhatHelp());
            
            spriteBatch.Draw(Tree, new Vector2(100, 200), Color.White);
            spriteBatch.Draw(Tree, new Vector2(400, 200), Color.White);
            spriteBatch.End();


            base.Draw(gameTime);
        }