我正在尝试在整数像素坐标之间进行插值,而不是在0-1之间进行插值,因为我使用的是点采样,因此我对像素分数不感兴趣,但是纹理坐标仍在像素着色器中即使数据类型为int2,也仍为float2。
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();
}
};
答案 0 :(得分:0)
我的理解是,您需要采用0-1
范围并将其大小调整为0-w:h
,然后再返回到0-1
。一种非常有用的技术称为feature scaling:
特征缩放是一种用于标准化自变量或数据特征范围的方法。在数据处理中,这也称为数据规范化,通常在数据预处理步骤中执行。
有几种解决方法,但我将重点介绍rescaling approach。最初,此方法着重于采用200-300
之类的范围并将其缩放为0-1
。数学很简单:
其中x
是原始值,而x'
是归一化值。
在我们的情况下,我们想朝相反的方向从0-1
扩展到200-300
,因此我们必须对其进行重做;但是当我们选择它时,为什么不把它放在可以满足您要求的任何方向:
将其转换为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;