これは床面にトレイルを作成するために使用するサーフェスシェーダです。配列データをOpenGLシェーダの一様配列に渡しているときに、Scenekitがバッファサイズエラーを返す
#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))
エラー消え去るが、配列の最初のメンバーだけがシェーダに渡される。
ので、問題は、私はシェーダにすべてのアレイメンバーを渡すことができますどのように、
のですか?
は 'カウントされません:myValueArray.countの*のはsizeof(するfloat2を)':myValueArray.count'は 'カウントする必要がありますか? – solidpixel
@solidpixelいいえ、すべてここで良いです。この高水準APIは、一様配列をサポートしていないようです。 NSDataオブジェクトには40バイト(10 32ビット浮動小数点数)が含まれていますが、エラーは8バイトを必要とするレポートを観察しているキー値から来ているようです。trailPointsをvec2として保存していると仮定するだけで2フロート(32ビット)バイト。私はこのAPIを純粋なOpenGLよりも使用することは考えていませんが、それを調べる限り、より低いレベルでシェーダ入力を操作する方法はありません。 –
ありがとうMatic。私はあなたが言及した理由を疑ったが、わからなかった。どうやら、ScenekitのShader Modifier Entry Pointsを使ってシェーダーに配列を渡す機会はありません。 私はSCNProgramを純粋な希望で試してみます。 – ytur