HLSL – Как настроить фильтры Min/Mag/Mip семплера, чтобы отключить всю фильтрацию/сглаживание?
Вопрос
У меня есть сэмплер tex2D, и я хочу возвращать только те цвета, которые присутствуют в моей текстуре.Я использую Shader Model 3, поэтому не могу использовать нагрузка.
В случае, если тексель перекрывает несколько цветов, я хочу, чтобы он выбрал один и чтобы весь тексель был этого цвета.
Думаю для этого надо отключить мипмэппинг или хотя бы трилинейную фильтрацию мипов.
sampler2D gColourmapSampler : register(s0) = sampler_state {
Texture = <gColourmapTexture>; //Defined above
MinFilter = None; //Controls sampling. None, Linear, or Point.
MagFilter = None; //Controls sampling. None, Linear, or Point.
MipFilter = None; //Controls how the mips are generated. None, Linear, or Point.
//...
};
Моя проблема в том, что я не совсем понимаю фильтрацию Min/Mag/Mip, поэтому не уверен, какую комбинацию мне нужно установить, и действительно ли это то, что мне нужно.
Как выглядит часть моей исходной текстуры;
Снимок экрана, на котором показано, как выглядит соответствующая область после того, как на мою сферу была наложена полная текстура;
Артефакты сглаживания/смешивания/фильтрации четко видны;Я не хочу этого.
MSDN имеет это сказать;
D3DSAMP_MAGFILTER:Увеличительный фильтр типа ТИП ФИЛЬТРА D3DТЕКСТУРЫ
D3DSAMP_MINFILTER:Минимизирующий фильтр типа ТИП ФИЛЬТРА D3DТЕКСТУРЫ.
D3DSAMP_MIPFILTER:Mipmap-фильтр, используемый во время минификации.Видеть ТИП ФИЛЬТРА D3DТЕКСТУРЫ.
D3DTEXF_NONE:При использовании с D3DSAMP_MIPFILTER отключает мипмэппинг.
Еще одна хорошая ссылка на понимание особенностей hlsl.
РЕШЕНО
Это вообще не проблема HLSL!Извините все.Кажется, я задаю много вопросов, на которые невозможно ответить.Ogre переопределил вышеуказанные настройки.Это было исправлено с помощью;
Ogre::MaterialManager::getSingleton().setDefaultTextureFiltering(Ogre::FO_NONE , Ogre::FO_NONE, Ogre::FO_NONE);
Решение
Мне кажется, что вы получаете значения из MIP-карты более низкого уровня (нефильтрованной), чем самая высокая детализация, которую вы показываете.
MipFilter = None
должен предотвратить это, если только что-то в коде не переопределяет это.Поэтому ищите вызовы SetSamplerState.
Другие советы
То, что вы сделали, должно отключить фильтрацию.Однако есть две потенциальные проблемы, о которых я могу подумать.
1) В любом случае, водитель просто игнорирует вас и фильтры (если это происходит, вы ничего не можете сделать) 2) У вас есть какая-то форма краевых анти-алистов.
Глядя на полученное изображение, которое мне не очень похоже на билинейную фильтрацию, я думаю, что вы страдаете от того, что где-то включено сглаживание.Вы установили флаг сглаживания при создании текстуры устройства/рендеринга?
Если вы хотите иметь только один тексель, используйте load
вместо sample
. load
занимает (насколько я знаю) int2
в качестве аргумента, указывающего фактические координаты массива в текстуре. load
Затем ищет запись в вашей текстуре по заданным координатам массива.
Итак, просто масштабируйте свой float2
, напримериспользуя ceil(float2(texCoord.x*textureWidth, texCoord.y*textureHeight))
.
MSDN для загрузки: http://msdn.microsoft.com/en-us/library/bb509694(VS.85).aspx
Используя только модель шейдера 3, вы можете немного взломать, чтобы добиться этого:Опять же, давайте предположим, что вы знаете textureWidth
и textureHeight
.
// compute floating point stride for texture
float step_x = 1./textureWidth;
float step_y = 1./textureHeight;
// compute texel array coordinates
int target_x = texCoord.x * textureWidth;
int target_y = texCoord.y * textureHeight;
// round to values, such that they're multiples of step_x and step_y
float2 texCoordNew;
texCoordNew.x = target_x * step_x;
texCoordNew.y = target_y * step_y;
Я не проверял, но думаю, что это может сработать.