[英]“SceneKit: error, missing buffer [-1/2]” when trying to pass uniforms to a metal shader
我已經將SCNProgram附加到SceneKit的幾何體上,我試圖將制服傳遞給片段着色器。 在我的簡單代碼片段中,我只是將輸出顏色作為一個統一體傳遞給片段着色器,它將其作為輸出值返回。
我已經測試了着色器並且它們工作,從某種意義上說,我可以成功地旋轉頂點着色器中的對象,或者在片段着色器中繪制不同顏色的對象等等......但問題是當我通過時制服。 這是我的片段着色器:
struct Uniforms
{
float4 color;
};
fragment float4 myFragment(MyVertexOutput in [[ stage_in ]],
constant Uniforms& uniforms [[buffer(2)]])
{
return uniforms.color;
}
這就是我嘗試在SceneKit + Swift代碼中傳遞制服的方法:
SCNTransaction.begin()
cube.geometry?.setValue(NSValue(SCNVector4:SCNVector4(0.0,1.0,0.0,1.0)), forKey: "uniforms.color")
SCNTransaction.commit()
但我的對象(它是一個立方體)甚至沒有繪制(它是黑色的),我得到這個錯誤:
2016-04-01 01:00:34.485 Shaded Cube [30266:12687154] SceneKit:錯誤,缺少緩沖區[-1/0]
編輯我試圖按照@lock的建議,但我仍然得到同樣的錯誤。 這是完整的項目存儲庫: https : //github.com/ramy89/Shaded-Cube.git
你的着色器代碼看起來很好,你穿着制服的方式接近於工作。
着色器制服的名稱必須與setValue
使用的名稱相匹配。 在這種情況下,您的Metal變量名稱是uniforms
,您在setValue
使用的值是uniforms.color
。 這些不匹配,因此您看到的錯誤。 建議更改swift代碼,只需在setValue
調用中使用uniforms
即可。
接下來,您需要確保傳入的數據,因為setValue
的值在Metal和Swift中都是相同的。 SCNVector4
是四個64位雙精度(CGFloats)的結構,而Metal的float4
是四個32位浮點數的結構。 文檔似乎表明您可以將SCNVector作為NSValue傳遞,但我從來沒有讓它工作。
在你的swift代碼中,我創建了一個包含你想要傳入的制服的結構。在vector_float4
結構上沒有很多文檔,但它與Metal float4
結構相匹配,因為它是四個32位浮點數。
struct Uniforms {
var color:vector_float4
}
將此值作為NSData
傳遞給setValue
函數。
let myColor = vector_float4(0,1,0,1)
var myUniforms = Uniforms(color:myColor)
var myData = NSData(bytes:&myUniforms, length:sizeof(Uniforms))
cube.geometry?.setValue(myData, forKey: "uniforms")
我不確定你是否需要SCNTransaction
電話,我過去不需要它們,而且它們可能SCNTransaction
。
更新
在查看Ramy的代碼之后,當應用於幾何體時,似乎存在setValue和SCNPrograms的問題。 我不能告訴你為什么,但是將自定義着色器設置為材料似乎可以解決這個問題,例如;
func makeShaders()
{
let program = SCNProgram()
program.vertexFunctionName = "myVertex"
program.fragmentFunctionName = "myFragment"
//cube.geometry?.program = program
cube.geometry?.firstMaterial?.program = program
var uniforms = Uniforms(color: vector_float4(0.0,1.0,0.0,1.0))
let uniformsData = NSData(bytes: &uniforms, length: sizeof(Uniforms))
//cube.geometry?.setValue(uniformsData, forKey: "uniforms")
cube.geometry?.firstMaterial?.setValue(uniformsData, forKey: "uniforms")
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.