A topic that came up again for me - how do i properly implement sampler states?
I want to have a Texture, and a seperate Sampler, which can be used for multiple input textures. But these are super unreliable and I want to know what i am doing wrong.
Here is a quick example:
If I change the light type from volumetric to normal it will change the sampler state of a whole different shader (the directional light shader in that case) and the shadows look broken now.
First a recap
The monogame framework has some of these:
Texture2D Texture: register(t0);
sampler Sampler : register(s0);
The old XNA way was
sampler2d Sampler : register(s0);
In this guide (porting from dx9 to dx11) link
it says
this is the way now:
Texture2D texture;
SamplerState g_samLinear
{
Filter = MIN_MAG_MIP_LINEAR;
AddressU = Wrap;
AddressV = Wrap;
};
I use the xna semantics so it looks like this
SamplerState blurSamplerPoint
{
AddressU = CLAMP;
AddressV = CLAMP;
MagFilter = POINT;
MinFilter = POINT;
Mipfilter = POINT;
};
The way to sample a texture then is
myTexture.Sample(mySamplerState, uv);
Now the problem
However, this doesn’t work. It will sample the texture, yes, but not with the filters specified in the sampler.
A way to make it work is, ironically, to use the old xna way of specifying a texture inside the sampler.
SamplerState texSampler
{
Texture = ;
AddressU = CLAMP;
AddressV = CLAMP;
MagFilter = POINT;
MinFilter = POINT;
Mipfilter = POINT;
};
Which obviously defeats the purpose of specifying a few universal samplers.
Now that would be fine, BUT more problems come our way - sometimes, if another sampler is used by some other shader (so 2 seperate fx files, 2 seperate samplerstates, textures etc.) the next sampler willl be overwritten by the values of the previous one.
For example if I use one technique of a light shader, which reads the shadow map more than once, another shader will be broken.
Example 1:
Two different shaders, one does the depth map reading for ao and the other one samples the skybox
Texture2D DepthMap;
SamplerState texSampler
{
Texture = < DepthMap >; // if this is disabled the sampling won’t work fast, the shader takes about 80% more time, if it is enabled the sky is wrong
AddressU = CLAMP;
AddressV = CLAMP;
MagFilter = POINT;
MinFilter = POINT;
Mipfilter = POINT;
};
DepthMap.SampleLevel(texSampler, texCoord, 0).r;
TextureCube SkyboxTexture;
SamplerState CubeMapSampler
{
AddressU = CLAMP;
AddressV = CLAMP;
MagFilter = LINEAR;
MinFilter = LINEAR;
Mipfilter = LINEAR;
};
SkyboxTexture.Sample(CubeMapSampler, normal.xyz);
So if I don’t use the DepthMap, my skybox is fine (it is drawn after the ao, which uses the depthmap).
If i use it, my Skycube will also use a point filter, which i don’t want.