我试图在我的spritekit 2d像素艺术游戏中应用调色板交换功能,并且在应用SKShader时,似乎忽略了SKSpriteNode纹理上的filteringMode。
因此,我认为我需要首先应用最近邻居着色,然后再进行调色板交换逻辑。
基于在着色器玩具上找到的一些代码我已经做了这个尝试,这看起来像是正确的方向,如果坐标被标准化并且(0.0,0.0)是左下角(&( 1.0,1.0)右上角,但结果太明显了。
https://www.shadertoy.com/view/MllSzX
我对shader.fsh
文件的改编:
void main() {
float texSize = 48.0;
vec2 pixel = v_tex_coord * texSize;
float c_onePixel = 1.0 / texSize;
pixel = (floor(pixel) / texSize);
gl_FragColor = texture2D(u_texture, pixel + vec2(c_onePixel/2.0));
}
在进行调色板交换之前,如何让最近邻居在我的SKShader上工作?
答案 0 :(得分:0)
不是我自己的完美答案,但我设法通过在我的info.plist中将PrefersOpenGL
添加到YES
来防止此问题,但我知道在ios上尽可能使用Metal < / p>
答案 1 :(得分:0)
我遇到了类似的问题。我想在像素周围创建轮廓,同时保持其像素化,但是它模糊了现有像素,使其看起来很糟糕。我最终实现了最近的邻居,然后在计算了最近的邻居位置之后检查了邻居像素,以查看该像素的alpha是否大于0。如果是,我将填写该像素。这是我的操作方式:
Outline.fsh:
vec2 nearestNeighbor(vec2 loc, vec2 size) {
vec2 onePixel = vec2(1.0, 1.0) / size;
vec2 coordinate = floor(loc * size) / size;
return coordinate + onePixel / 2.0;
}
void main() {
vec2 onePixel = vec2(1.0, 1.0) / a_sprite_size;
vec4 texture = texture2D(u_texture, nearestNeighbor(v_tex_coord, a_sprite_size)); // Nearest neighbor for the current pixel
if (texture.a == 0.0) {
// Pixel has no alpha, check if any neighboring pixels have a non 0 alpha
vec4 outlineColor = vec4(0.9, 0.9, 0.0, 1.0);
if (texture2D(u_texture, nearestNeighbor(v_tex_coord + vec2(onePixel.x, 0), a_sprite_size)).a > 0.0) {
// Right neighbor has an alpha > 0
gl_FragColor = outlineColor;
} else if (texture2D(u_texture, nearestNeighbor(v_tex_coord + vec2(-onePixel.x, 0), a_sprite_size)).a > 0.0) {
// Left neighbor has an alpha > 0
gl_FragColor = outlineColor;
} else if (texture2D(u_texture, nearestNeighbor(v_tex_coord + vec2(0, onePixel.y), a_sprite_size)).a > 0.0) {
// Top neighbor has an alpha > 0
gl_FragColor = outlineColor;
} else if (texture2D(u_texture, nearestNeighbor(v_tex_coord + vec2(0, -onePixel.y), a_sprite_size)).a > 0.0) {
// Bottom neighbor has an alpha > 0
gl_FragColor = outlineColor;
} else {
// No neighbors with an alpha > 0, don't change the color
gl_FragColor = texture;
}
} else {
// Pixel has an alpha > 0
gl_FragColor = texture;
}
}
然后,您需要将着色器添加到精灵中,并在精灵和着色器上设置已定义的属性,以便可以使用着色器中定义的值。
spriteNode.setValue(SKAttributeValue(vectorFloat2: vector_float2(Float(spriteNode.size.width), Float(spriteNode.size.height))), forAttribute: "a_sprite_size")
let shader = SKShader(fileNamed: "Outline.fsh")
shader.attributes = [
SKAttribute(name: "a_sprite_size", type: .vectorFloat2)
]
spriteNode.shader = shader
希望这对其他遇到类似问题的人有所帮助!