【发布时间】:2017-01-15 17:11:16
【问题描述】:
我正在尝试使用下面的代码复制 Unity3D 的自动双线性过滤算法:
fixed4 GetBilinearFilteredColor(float2 texcoord)
{
fixed4 s1 = SampleSpriteTexture(texcoord + float2(0.0, _MainTex_TexelSize.y));
fixed4 s2 = SampleSpriteTexture(texcoord + float2(_MainTex_TexelSize.x, 0.0));
fixed4 s3 = SampleSpriteTexture(texcoord + float2(_MainTex_TexelSize.x, _MainTex_TexelSize.y));
fixed4 s4 = SampleSpriteTexture(texcoord);
float2 TexturePosition = float2(texcoord)* _MainTex_TexelSize.z;
float fu = frac(TexturePosition.x);
float fv = frac(TexturePosition.y);
float4 tmp1 = lerp(s4, s2, fu);
float4 tmp2 = lerp(s1, s3, fu);
return lerp(tmp1, tmp2, fv);
}
fixed4 frag(v2f IN) : SV_Target
{
fixed4 c = GetBilinearFilteredColor(IN.texcoord) * IN.color;
c.rgb *= c.a;
return c;
}
我认为我使用了正确的算法,因为这是我见过的唯一一种双线性算法。但我尝试使用统一的相同纹理复制:
- 1º 纹理:在点过滤中并使用自定义双线性着色器(由默认精灵着色器制成)。
- 2º 纹理:在双线性过滤器中使用默认精灵着色器
结果如下:
您可以看到它们是不同的,而且我的自定义着色器中存在一些位移,这使得精灵在 Z 轴上旋转时会偏离中心。
知道我做错了什么吗? 知道 Unity3D 有什么不同吗? 是否有其他算法适合 Unity3D 默认过滤?
解决方案
更新了完整的代码解决方案,其中包含 Nico 的代码,供在此处搜索的其他人使用:
fixed4 GetBilinearFilteredColor(float2 texcoord)
{
fixed4 s1 = SampleSpriteTexture(texcoord + float2(0.0, _MainTex_TexelSize.y));
fixed4 s2 = SampleSpriteTexture(texcoord + float2(_MainTex_TexelSize.x, 0.0));
fixed4 s3 = SampleSpriteTexture(texcoord + float2(_MainTex_TexelSize.x, _MainTex_TexelSize.y));
fixed4 s4 = SampleSpriteTexture(texcoord);
float2 TexturePosition = float2(texcoord)* _MainTex_TexelSize.z;
float fu = frac(TexturePosition.x);
float fv = frac(TexturePosition.y);
float4 tmp1 = lerp(s4, s2, fu);
float4 tmp2 = lerp(s1, s3, fu);
return lerp(tmp1, tmp2, fv);
}
fixed4 frag(v2f IN) : SV_Target
{
fixed4 c = GetBilinearFilteredColor(IN.texcoord - 0.498 * _MainTex_TexelSize.xy) * IN.color;
c.rgb *= c.a;
return c;
}
以及带有结果的图像测试:
为什么不准确减去 0.5?
如果您对其进行测试,您会看到一些边缘情况,它会跳转到 (pixel - 1)。
【问题讨论】:
标签: opengl unity3d shader fragment-shader