Tuesday, May 21, 2019

c# - Monogame shader not working


I'm trying to use this this tutorial in monogame, but the effect does not work, only renders a black screen. Everyhing by itself renders just fine, I looked at the render targets if they get drawn to, but when I try to apply the effect to them it only renders a black screen.


I converted the .fx file using 2MGFX, also tried loading it with the following code:


BinaryReader Reader = new BinaryReader(File.Open(@"Content\\Lighting.mgfx", FileMode.Open));
lightingEffect = new Effect(GraphicsDevice, Reader.ReadBytes((int)Reader.BaseStream.Length));

also with



lightingEffect = content.Load("Lighting.mgfx");

and also with


byte[] bytecode = File.ReadAllBytes("Content\\Lighting.mgfx");
lightingEffect = new Effect(graphics.GraphicsDevice, bytecode);

They did not make a difference.


The .fx file contains the following:


sampler s0;
texture lightMask;

sampler lightSampler = sampler_state { Texture = ; };

float4 PixelShaderFunction(float2 coords: TEXCOORD0) : COLOR0
{
float4 color = tex2D(s0, coords);
float4 lightColor = tex2D(lightSampler, coords);
return color * lightColor;
}

technique Technique1

{
pass Pass1
{
PixelShader = compile ps_4_0_level_9_1 PixelShaderFunction();
}
}

And the monogame version of the game1.cs(Only the important stuff):


public class Game1 : Game
{

GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;

Texture2D lightMask;
Texture2D SquareGuy;

RenderTarget2D lightsTarget;
RenderTarget2D mainTarget;

Effect lightingEffect;



public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
IsMouseVisible = true;
}



protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
lightMask = Content.Load("lightmask");
SquareGuy = Content.Load("SquareGuy");
// lightingEffect = content.Load("Lighting.mgfx");
/*
byte[] bytecode = File.ReadAllBytes("Content\\Lighting.mgfx");
lightingEffect = new Effect(graphics.GraphicsDevice, bytecode);
*/

BinaryReader Reader = new BinaryReader(File.Open(@"Content\\Lighting.mgfx", FileMode.Open));
lightingEffect = new Effect(GraphicsDevice, Reader.ReadBytes((int)Reader.BaseStream.Length));

var pp = GraphicsDevice.PresentationParameters;
// pp.BackBufferHeight = 1024;
// pp.BackBufferWidth = 1024;
lightsTarget = new RenderTarget2D(
GraphicsDevice, pp.BackBufferWidth, pp.BackBufferHeight);
mainTarget = new RenderTarget2D(
GraphicsDevice, pp.BackBufferWidth, pp.BackBufferHeight);

}

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

// TODO: Add your drawing code here
GraphicsDevice.SetRenderTarget(lightsTarget);
GraphicsDevice.Clear(Color.Black);
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Additive);

spriteBatch.Draw(lightMask, new Vector2(0, 0), Color.White);
spriteBatch.Draw(lightMask, new Vector2(100, 0), Color.White);
spriteBatch.Draw(lightMask, new Vector2(200, 200), Color.White);
spriteBatch.Draw(lightMask, new Vector2(300, 300), Color.White);
spriteBatch.Draw(lightMask, new Vector2(500, 200), Color.White);
spriteBatch.End();

// Draw the main scene to the Render Target
GraphicsDevice.SetRenderTarget(mainTarget);
GraphicsDevice.Clear(Color.CornflowerBlue);

spriteBatch.Begin();
spriteBatch.Draw(SquareGuy, new Vector2(100, 0), Color.White);
spriteBatch.Draw(SquareGuy, new Vector2(250, 250), Color.White);
spriteBatch.Draw(SquareGuy, new Vector2(550, 225), Color.White);
spriteBatch.End();

// Draw the main scene with a pixel
GraphicsDevice.SetRenderTarget(null);
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);

lightingEffect.Parameters["lightMask"].SetValue(lightsTarget);
lightingEffect.CurrentTechnique.Passes[0].Apply();
spriteBatch.Draw(mainTarget, Vector2.Zero, Color.White);
spriteBatch.End();

base.Draw(gameTime);
}
}

So the question is what do I need to change to make the effect work in monogame?



I tried it in XNA with this code and worked perfectly. I know almost nothing about HLSL, so I don't know if theres something wrong with the effect. I only changed the version thingy from ps_2_0 to ps_4_0_level_9_1. If I change it to ps_4_0_level_9_3 it still doesn't work. I read something about assigning textures from outside of the .fx here, but since I know so little about shaders I don't know if this is the problem.



Answer



I had this same problem last week. You need to add all the parameters to your PixelShaderFunction, or monogame will map registers incorrectly. Change your PixelShaderFunction parameters to be like this:


PixelShaderFunction(float4 pos : SV_POSITION, float4 color1 : COLOR0, float2 coords: TEXCOORD0)

Here is a more detailed explanation, where I got the answer: http://www.software7.com/blog/pitfalls-when-developing-hlsl-shader/


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...