A question on texture sampling

Started by
4 comments, last by oggs91 9 years, 2 months ago

Hello everyone, I am currently teaching myself some graphics programming with HLSL, which my current knowledge has been learned almost exclusively from post processing mods like ENB, SweetFX, and ReShade.

Now for my question, is there a way to use custom filters in the sampler or bypass the sampler altogether/create a custom sampler?

As I understand it, textures are declared towards the beginning of a file, then the samplers are what make it so a pixel shader can read the texture.

Here is an example if my sentence above didn't make sense.


// My declared texture
texture texExample 
{
  width = 1920; 
  height = 1080;
};

// The sampler that makes it readable by a pixel shader

sampler samplerExample
{
  Texture = texExample;
  MinFilter = LINEAR;
  MagFilter = LINEAR;
  MipFilter = NONE;
  AddressU = Clamp;
  AddressV = Clamp;
  SRGBTexture=FALSE;
  MaxMipLevel=0;
  MipMapLodBias=0;
};

// Then a pixel shader that uses the sampler to get the texture information

float4 ExamplePS(in float4 pos : SV_POSITION, in float2 texcoord : TEXCOORD0) : SV_Target
{
  float4 example = tex2D(samplerExample, texcoord);
  return example;
}

// Then the technique and stuff...

The reason I want to know this is so that I can play around with mipmapping which I don't fully understand yet either.

Advertisement

essentially the sampler is what brings your texture from a raster image to a 2d parameterized texture space, so you can index your texture in the shader not with pixel positions but with a continuous floating point value in 2 axis in range [0,1]

ok, nice, but how do we determine what color is on position [0.234, 0.789] ? first of all we need the texture size lets assume it's [512, 512]

[0.234, 0.789] * [512, 512] = [119.808, 403.968] okay ... but at this exact position is obviously no pixel

going the simple way we can just use the NEAREST pixel position [120, 404]

well but that looks pretty crappy, especially if we zoom into the texture ... another possibility would be to interpolate between the 4 surrounding pixels

[119, 403], [120, 403], [119, 404], [120, 404]

this method is called bilinear interpolation

BilinearInterpolation_fig001.jpg

filterings.png

i already mentioned zooming into the texture ... this is called the magnification filter and this case can be perfectly handled with bilinear interpolation ... but now imagine the shown texture covers less pixels than in the original texture

texles.jpg

if we use nearest we only get the one pixel marked on the right, if we use bilinear interpolation we get 4 pixels ... but actually we need the pixels of the whole patch .. and somehow combine the colors

fig25-01a.jpg

on the left you can see the result with linear interpolation, pretty ugly because we dont use enough information from our texture, this effect is called aliasing

and finally this is where mipmapping steps in

the mipmaps of a texture are downsampled versions of the original textures ( original is the bottom one )

each mip level has half it's size of the previous level

0.jpg

resume to the image from before, we have a big area in texel space we have to cover ... we can now choose an appropriate mip level from our texture pyramid depending on the size of the area in texture domain ... choosing colors from appropriate mipmaps leaves us with image (b) from before

texles.jpg

but wait there is more! if two pixels in screenspace are now textured from two different mipmap levels we can get artifacts,

compare bilinear mipmap with trilinear mipmap

pic06.jpg

trilinear filtering solves our problem, it samples a second mipmap level and interpolates again linearily between the sampled colors from the two chosen mipmap levels

but wait ... there is even more biggrin.png

if you still have not enough from this subject look into ripmapping and anisotropic filtering

Wow that was a wealth of information, I'm sure I will refer back to it often, but one more question. Is it possible to pick a specific mip level of a texture and output that to the screen through a pixel shader? Like the 8th mip level which should be much blurrier than the first?

You absolutely can. One such way would be to use SampleLevel.


You absolutely can. One such way would be to use SampleLevel.

FYI, the D3D9 version of that function is tex2dlod.

Wow that was a wealth of information, I'm sure I will refer back to it often, but one more question. Is it possible to pick a specific mip level of a texture and output that to the screen through a pixel shader? Like the 8th mip level which should be much blurrier than the first?

for example tonemapping shaders use this functionality to read the average luminance from the smallest mipmap level which is only 1x1 pixel

This topic is closed to new replies.

Advertisement