Texture sample2D not loading custom image

Hello there,

I am currently learning HLSL and shaders to bascially do billboard grass using 2D images. Fairly new to this so I’m just trying it out.

I’ve been following the CatLikeCoding tutorials for rendering and currently trying it out with Monogame instead of Unity.

For some reason the texture isn’t loading in my .fx file. I have tried debugging with my texture coordinates and turns out they are fine in the fragment shader. (see image attached)

I have tried using the sampler2D for my image using registers(s0) and (t0).
Still nothing. Also here’s the grass texture I’m using attached.

Here’s my HLSL code and the C# code if anyone knows what’s missing here :

#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

matrix WorldViewProjection;

extern float4 TintColor;

extern Texture2D SpriteTexture : register(t0);

sampler2D SpriteSampler : register(s0)
{
	Texture = <SpriteTexture>;
};

struct VertexInput
{
	float4 Position : POSITION0;
};

struct VertexOutput
{
	float4 Position : SV_POSITION;
	float2 TextureCoordinates : TEXCOORD0;
};

float4 MyFragmentProgram(VertexOutput i) : SV_Target
{
    // debug line for texture coordinates
	return float4(i.TextureCoordinates, 1, 1);
 
	//return tex2D(SpriteSampler, i.TextureCoordinates);
}

VertexOutput MyVertexProgram(VertexOutput v)
{
    VertexOutput output;
    output.Position = mul(WorldViewProjection, v.Position);
    output.TextureCoordinates = v.TextureCoordinates;
    return output;

}

technique BasicColorDrawing
{
	pass P0
	{
        //VertexShader = compile VS_SHADERMODEL MyVertexProgram();
		PixelShader = compile PS_SHADERMODEL MyFragmentProgram();
	}
};

Game.cs :


        private Camera camera;
        private Effect _basicShader;
        public Texture2D _basicTexture;

      protected override void LoadContent()
      {
          _spriteBatch = new SpriteBatch(GraphicsDevice);

          playerTexture = Content.Load<Texture2D>("square"); // Load your cell texture

          _basicTexture = Content.Load<Texture2D>("billboardGrass");

          _basicShader = Content.Load<Effect>("GrassShader");

      }

   protected override void Draw(GameTime gameTime)
   {
       GraphicsDevice.Clear(Color.CornflowerBlue);
   
       _basicShader.Parameters["SpriteTexture"]?.SetValue(_basicTexture);
 
// draw the shader
       _spriteBatch.Begin(effect: _basicShader);

       foreach (var element in gridRef.gridElements)
       {
         gridRef.Draw(_spriteBatch);
       }

       playerRef.Draw(_spriteBatch, playerRef.ballPosition);

       _spriteBatch.End();

       base.Draw(gameTime);
   }

I’m not sure, but I think the s0 contains the texture that is used in the spritebatch. Try use another sampler and texture index. s1 maybe…

When you call Draw methods under the hood spritebatch sets method’s texture to the register s0, therefore when you apply your texture to s0 it will be replaces by that texture from Draw method.

1 Like

No register to pass in Texture:

Texture SpriteTexture;

sampler SpriteSampler = sampler_state
{
	Texture = <SpriteTexture>;
};

Thank you that was it !
I changed the index and it worked immediately