我已经编写了GLSL着色器,以模拟老式街机游戏基于索引的彩色图块的图形。我制作了两个着色器,一个使用点精灵进行着色,另一个使用多边形。点精灵着色器将gl_PointCoord
转换为每个图块中的像素坐标,如下所示:
vec2 pixelFloat = gl_PointCoord * tileSizeInPixels;
ivec2 pixel = ivec2(int(pixelFloat.x), int(pixelFloat.y));
// pixel is now used in conjunction with a tile 'ID' uniform
// to locate indexed colors with a texture lookup from a
// large texture representing the game's ROM, with GL_NEAREST filtering.
// very clever ?
多边形着色器改为使用属性缓冲区传递像素坐标(例如,对于32像素的正方形图块,其范围为{0.0…32.0})。转换为int
后,图块中的每个片段都会看到x {0…31} y {0…31}范围内的像素坐标值,除了:
除了有时在某些分辨率下以较高编号的像素坐标显示在图块边缘的伪像外,此效果很好。我猜想这是由于片段位于gl_PointCoord
的最大值或顶点属性值32.0上的正确位置,导致该片段采样了错误的图块。
当我像这样夹紧像素ivec时,这些伪像消失了:
vec2 pixelFloat = gl_PointCoord * tileSizeInPixels;
ivec2 pixel = ivec2(
min(int(pixelFloat.x), tileSizeInPixels - 1),
min(int(pixelFloat.y), tileSizeInPixels - 1));
解决了这个问题,没有引入任何新的人工制品。
我的问题是:有没有办法控制gl_PointCoord
或我的像素坐标属性的插值,以便我们可以保证插值的范围?
minimum value <= interpolated value < maximum value
相对于
minimum value <= interpolated value <= maximum value
有什么办法可以避免在这里使用min()
?
NB:GL_CLAMP_*
在这里不是选项,因为像素坐标用于从更大的纹理中查找像素的索引颜色,该纹理实际上是游戏的精灵ROM加载到单个大纹理缓冲区中。