MonoGame/HLSL Seperate Texture from sampler

Started by
4 comments, last by -XM- 9 years, 7 months ago

For the platform I'm targeting with MonoGame, I'm needing to replace all tex2d calls with a call to Sample from a Texture2D object.

Right now I'm trying to update my shaders in the PC/XNA4 version of my game. I'm trying to update the BloomCombine.fx shader from the XNA Bloom sample but all I'm seeing right now is a black screen.

The culprit is these lines:

float4 bloom = bloomTexture.Sample(BloomSampler, texCoord);
float4 base = baseTexture.Sample(BaseSampler, texCoord

I had to make new Texture2D objects, seperate from the samplers, but do I need to set these from my XNA code? I'm setting them to a register, so to my understanding it should work fine, just like how the samplers are set to a register.

Here's what I have so far:


// Pixel shader combines the bloom image with the original
// scene, using tweakable intensity levels and saturation.
// This is the final step in applying a bloom postprocess.
SamplerState BloomSampler : register(s0);
SamplerState BaseSampler : register(s1);

Texture2D<float4> bloomTexture : register(t0); 
Texture2D<float4> baseTexture : register(t1);

float BloomIntensity;
float BaseIntensity;

float BloomSaturation;
float BaseSaturation;

// Helper for modifying the saturation of a color.
float4 AdjustSaturation(float4 color, float saturation)
{
    // The constants 0.3, 0.59, and 0.11 are chosen because the
    // human eye is more sensitive to green light, and less to blue.
    float grey = dot(color, float4(0.3, 0.59, 0.11, 1));

    return lerp(grey, color, saturation);
}

float4 PixelShaderFunction(float2 texCoord : TEXCOORD0) : COLOR0
{
    // Look up the bloom and original base image colors.
    //float4 bloom = tex2D(BloomSampler, texCoord);
    //float4 base = tex2D(BaseSampler, texCoord); << Old code
	float4 bloom = bloomTexture.Sample(BloomSampler, texCoord);
	float4 base = baseTexture.Sample(BaseSampler, texCoord);
    
    // Adjust color saturation and intensity.
    bloom = AdjustSaturation(bloom, BloomSaturation) * BloomIntensity;
    base = AdjustSaturation(base, BaseSaturation) * BaseIntensity;
    
    // Darken down the base image in areas where there is a lot of bloom,
    // to prevent things looking excessively burned-out.
    base *= (1 - saturate(bloom));
    
    // Combine the two images.
    return base + bloom;
}

technique BloomCombine
{
    pass Pass1
    {
#if SM4
        PixelShader = compile ps_4_0_level_9_1 PixelShaderFunction();
#elif SM3
        PixelShader = compile ps_3_0 PixelShaderFunction();
#else
        PixelShader = compile ps_2_0 PixelShaderFunction();
#endif
    }
}

Advertisement

You seem to be missing DX9-style (SM3.0) and DX11-style (SM4.0+) shader code here. I'm not really familiar with MonoGame...does that use DX11? XNA4 is definitely limited to DX9, so you will have to use the old DX9-style syntax for sampling textures (tex2D(), sampler, etc.). You should consult the XNA samples for examples on how to set up the old-style shaders, and bind textures.

If are trying to use the same shaders for DX9 and DX11, let me warn you that it's rather difficult. You typically need to use a lot of macros to hide the different syntax.

As for XNA it is indeed limited to DX9.

Monogame on the other hand is like an inofficial progress of XNA since it is not being developed anymore. So it is not limited to DX9 only but also can use DX11.

But MonoGame has some problems.

As it its made for multiplatform it uses either Open-Stuff or DX for rendering so the Shader-Language is NOT HLSL (though I read that you can compile .fx files like effects.fx to the needed MGFX-Format). I might be wrong on this, but thats what I've seen so far.

The second thing is the content-pipeline. It has to use the one of XNA, so there might be also problems caused by a higher shader-level.

As you are using XNA right now that should be not a problem unless you use any shader_level higher than 3.x.

It is not much of help, I know. But I thought this might lead to something (hehe)

Yeah I'm converting .fx to MGFX, but when I run the game on the MonoGame platform, I see nothing but a clear color.... it said my shaders were converted properly, so I tried to see what this code was doing in XNA4 because I can't debug on the MonoGame platform.

I thought the Sample function was available in DX9, it doesn't throw any compiler errors, maybe it's just a fluke that it's running. If I put the ted2d calls back, everything works fine.

So, let's assume all of this is valid DX9 code, attaching that Texture2D to that register should give me data right? And theoretically I should be able to call sample like I'm doing without any changes to my C# code?

Well I can't say for sure, as I was searching desperatly for MonoGame Shader Tutorials on the web but never found one really in-depth so I can't say which difference there are in the actual code.

I saw a thread stating about a similar issue, but can't find it. There the problem was the compiling, even it said that every file was compiled correctly.

Maybe have a look at that:

https://github.com/mono/MonoGame/wiki/Getting-Effect-.fx-files-to-compile-and-run---Hints,-Tips-and-Gotchas

It is an article to get the shaders run on MonoGame. Maybe it helps you.

Ok, I had a few problems.

1. I was trying to mix DX9 and DX10 syntax. Use SamplerState for all of your samplers in DX10, sampler for DX9... http://msdn.microsoft.com/en-us/library/windows/desktop/bb509644%28v=vs.85%29.aspx

2. My shaders were post process only, no vertex shaders. In DX10 this is a problem because it expects the input of the pixel shader to be the same as the output of the vertex shader. Since I have no custom vertex shader it was defaulting to SpriteBatch's vertex output. Here's what your pixel shader function should look like to match that:

float4 CombinedPixelShader(float4 pos : S_POSITION, float4 color : COLOR0, float2 texCoords : TEXCOORD0) : S_TARGET_OUTPUT

This topic is closed to new replies.

Advertisement