【发布时间】:2017-06-02 12:13:49
【问题描述】:
这是我用来在地板表面制作轨迹的表面着色器。
#pragma arguments
uniform vec2 trailPoints[5];
uniform float count;
#pragma body
float trailRadius = 10.0;
float x = _surface.diffuseTexcoord.x;
float x100 = float(x * 100);
float y = _surface.diffuseTexcoord.y;
float y100 = float(y * 100);
for (int i = 0; i < int(count); i++) {
vec2 position = trailPoints[i];
if ((x100 > position.x - trailRadius && x100 < position.x + trailRadius) && (y100 > position.y - trailRadius && y100 < position.y + trailRadius)) {
_surface.diffuse.rgb = vec3(0.0, 10.0 ,0.0);
}
}
这是我用来将矢量数据传递给表面着色器的快速侧代码。
if let geometry = self.floorNode.geometry {
if let material = geometry.firstMaterial {
// this is the temporary data which I use to find the problem.
// this data will be dynamic later on.
let myValueArray:[float2] = [float2(x:80, y:80),float2(x:60, y:60),float2(x:40, y:40),float2(x:20, y:20),float2(x:0, y:0)]
// Passing array count to shader. There is no problem here.
var count = Float(myValueArray.count)
let countData = Data(buffer: UnsafeBufferPointer(start: &count, count: 1))
material.setValue(countData, forKey: "count")
// and here is the problem start.
// myValueArray converted to data with its size.
let valueArrayData = Data(buffer: UnsafeBufferPointer(start: myValueArray, count: myValueArray.count))
material.setValue(valueArrayData, forKey: "trailPoints")
}
}
当我构建和运行项目时,出现以下错误,并且没有数据传递到着色器中的“trailPoints”。
错误:参数 trailPoints : NSData 和缓冲区大小不匹配 40 != 8
当我在将数组转换为数据时将数组计数更改为 1,
let valueArrayData = Data(buffer: UnsafeBufferPointer(start: myValueArray, count: 1))
错误消失了,但只有数组的第一个成员会传递给着色器。
所以,问题是,
如何将所有数组成员传递给着色器?
【问题讨论】:
-
count: myValueArray.count不需要是count: myValueArray.count * sizeof(float2)? -
@solidpixel 不,这里一切都很好。这个高级 API 似乎不支持统一数组。 NSData 对象包含 40 个字节(即 10 个 32 位浮点数),但错误似乎来自一些关键值观察报告它需要 8 个字节,我只能假设它将 trailPoints 保存为 vec2 所以 2 个浮点数(32 位)是 8字节。我永远不会考虑在纯 openGL 上使用这个 API,但据我研究,没有任何方法可以在较低级别上操作着色器输入。
-
感谢 Matic。我怀疑你提到的原因,但我不确定。显然没有机会在 Scenekit 中使用着色器修改器入口点将数组传递给着色器。我会满怀希望地尝试 SCNProgram。
-
GLES API 确实支持按元素上传,但我不确定它是否通过 swift 支持公开。您可以通过遍历数组并使用
material.setValue(valueArrayData, forKey: "trailPoints[0]"),然后使用material.setValue(valueArrayData, forKey: "trailPoints[1]")等来进行组件上传吗? -
感谢solidpixel。我以前在网上看到过你的建议。它看起来有点难看,但我又试了一次,没有任何改变。而且我也尝试过这种看起来更“明智”的方式,material.setValue(NSValue(cgPoint: CGPoint(x: 80, y: 80)), forKey: "trailPoints[0]") material.setValue (NSValue(cgPoint: CGPoint(x: 60, y: 60)), forKey: "trailPoints[1]")...等没有。没有用。
标签: arrays swift opengl-es shader scenekit