Целочисленные текстурные координаты HLSL - PullRequest
0 голосов
/ 03 декабря 2018

Я пытаюсь интерполировать между целочисленными пиксельными координатами, а не между 0-1, потому что я использую точечную выборку, поэтому меня не интересуют доли пикселей, но координаты текстуры все еще поступают в пиксельный шейдеркак float2, хотя тип данных int2.

pixelSize равен 1, деленному на размер текстуры

matrix WorldViewProjection;

float2 pixelSize;

Texture2D SpriteTexture;

sampler2D SpriteTextureSampler = sampler_state
{
    Texture = <SpriteTexture>;
    AddressU = clamp;
    AddressV = clamp;
    magfilter = POINT;
    minfilter = POINT;
    mipfilter = POINT;
};

struct VertexShaderOutput
{
    float4 Position : SV_POSITION;
    float4 Color : COLOR0;
    int2 TextureCoordinates : TEXCOORD0;
};

VertexShaderOutput SpriteVertexShader(float4 position : POSITION0, float4 color : COLOR0, float2 texCoord : TEXCOORD0)
{
    VertexShaderOutput output;
    output.Position = mul(position, WorldViewProjection);
    output.Color = color;
    output.TextureCoordinates = texCoord * (1 / pixelSize);
    return output;
}

float4 SpritePixelShader(VertexShaderOutput input) : COLOR
{
    float2 texCoords = input.TextureCoordinates * pixelSize;
    return tex2D(SpriteTextureSampler, texCoords) * input.Color;
}

technique SpriteDrawing
{
    pass P0
    {
        VertexShader = compile vs_2_0 SpriteVertexShader();
        PixelShader = compile ps_2_0 SpritePixelShader();
    }
};

1 Ответ

0 голосов
/ 13 декабря 2018

Насколько я понимаю, вам нужно взять диапазон 0-1 и изменить его размер до 0-w:h, а затем вернуться к 0-1 позже.Очень полезный метод для этого называется масштабирование объектов :

Масштабирование объектов - это метод, используемый для стандартизации диапазона независимых переменных или функций данных.При обработке данных это также называется нормализацией данных и обычно выполняется на этапе предварительной обработки данных.

Существует несколько подходов к этому, но я остановлюсь на подходе масштабирования .Первоначально этот подход фокусируется на взятии диапазона, такого как 200-300, и масштабировании его до 0-1.Математика просто:

Rescaling

Где x - исходное значение, а x' - нормализованное значение.


В нашем случае мы хотим перейти в противоположном направлении и в масштабе от 0-1 обратно до 200-300, поэтому мы должны переработать его;но в то время как мы находимся, почему бы не сделать это, где мы можем пойти в любом направлении, чтобы удовлетворить ваши требования:

customizable rescaling

Перевод этого в HLSLпростая задача, и я бы рекомендовал использовать ее для повторного использования позже:

float RescaleInRange(float value, float oldMin, float oldMax, float newMin, float newMax) {
    if (value < oldMin) value = oldMin;
    else if (value > oldMax) value = oldMax;
    return ((value - oldMin) / (oldMax - oldMin)) * (newMax - newMin) + newMin;
}

Я бы оставил ваш TextureCoordinates как float2, чтобы он оставался в соответствии с отраслевыми стандартами, где большинство примененийfloat2 за это.Затем в вашем вершинном шейдере просто присвойте ему texCoord, который был предоставлен.Позже, в вашем пиксельном шейдере вы можете использовать масштабирование, предоставленное выше, чтобы обрабатывать единицы TextureCoordinates индивидуально (в моем коде ниже UV):

float w = textureSize.x;
float h = textureSize.y;
float x = RescaleInRange(UV.x, 0, 1, 0, w);
float y = RescaleInRange(UV.y, 0, 1, 0, h);
return tex2D(Sampler, float2(RescaleInRange(x, 0, w, 0, 1), RescaleInRange(y, 0, h, 0, 1))) * input.Color;
...