我一直在尝试理解着色器的坐标如何与SpriteKit一起工作。下面是我的测试程序。我创造了一个精灵,然后加载并运行一个着色器(作为一个字符串)在这个精灵上。着色器应在白色背景上创建蓝色矩形。我需要的矩形接近精灵的大小(等于0。9或其大小的90%),并且无论精灵在屏幕上的位置如何,都保持在精灵的中心。然而,我观察到:
- 蓝色矩形明显小于精灵
- 蓝色矩形似乎是粘在屏幕上,而不是来与精灵。这意味着它可能会“跑”出来的精灵时,我把精灵到其他位置。我猜这是由于使用gl_FragCoord造成的,但是当我用v_tex_coor替换它时,它仍然不起作用
有人能给我解释一下在使用SpriteKit时着色器的协调以及如何解决这些问题吗?谢谢。
import SpriteKit
class ViewController: UIViewController {
// Shader as a string
let shaderSource =
"""
// the center point of the rectangle, not really center vec2(0.0) but just for testing
constant vec2 center = vec2(0.5, 0.5);
constant vec2 rectSz = vec2(0.9, 0.9); // size of the rectangle
void main()
{
/// uv from -1 to 1 in Y height
vec2 uv = (gl_FragCoord.xy - u_sprite_size.xy * 0.5) / u_sprite_size.y;
vec2 sz = rectSz / 2.0; // half size to the center point
vec2 d = abs(uv - center);
bool inside = d.x <= sz.x && d.y <= sz.y;
// draw blue rectangle, white background
gl_FragColor = inside ? vec4(0.0, 0.0, 1.0, 1.) : vec4(1.0);
}
"""
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let sceneView = SKView(frame: view.bounds)
print("view.bounds = \(view.bounds)")
self.view.addSubview(sceneView)
let scene = SKScene(size: view.bounds.size)
sceneView.presentScene(scene)
// sprite in yellow if shader is not working
let sprite = SKSpriteNode(color: UIColor.yellow, size: CGSize(width: 300, height: 300))
sprite.position = CGPoint(x: 150, y: view.bounds.height - 150)
scene.addChild(sprite)
let spriteSize = vector_float2(Float(sprite.frame.size.width),
Float(sprite.frame.size.height))
let shader = SKShader(source: shaderSource,
uniforms: [
SKUniform(name: "u_sprite_size", vectorFloat2: spriteSize)
])
sprite.shader = shader
}
}
1条答案
按热度按时间hrysbysz1#
在某些情况下,将子画面大小作为均匀值传递是有用的。但你想多了如果你想让着色器坐标在0-1的数字空间中与精灵的大小齐平,那么你只要把坐标取为
vec2 st = v_tex_coord.xy;
就足够了,然后简单地使用它们而不需要缩放它们。下面是一个例子,在两个不同大小的精灵中绘制一个圆。