2017-02-20 14 views
-1

パーティクルエフェクトをレンダリングするためにジオメトリシェーダーにビルボード付きクワッドを実装しようとしています。ジオメトリシェーダ入力は点(vec3)で、出力は位置とUV座標(vec3、vec2)を持つ三角形ストリップです。私は、頂点入力バインディングの2つのバリエーションを試しましたが、どちらも機能しません。Vulkan:VkVertexInputBindingDescriptionジオメトリシェイダーで常に間違っています

私はこのような結合の頂点に設定した場合:

VkVertexInputBindingDescription binding_desc[2] = {}; 
binding_desc[0].binding = 0; 
binding_desc[0].stride = sizeof(glm::vec3); 
binding_desc[0].inputRate = VK_VERTEX_INPUT_RATE_VERTEX; 

binding_desc[1].binding = 1; 
binding_desc[1].stride = sizeof(glm::vec2); 
binding_desc[1].inputRate = VK_VERTEX_INPUT_RATE_VERTEX; 

VkVertexInputAttributeDescription attribute_desc[2] = {}; 
attribute_desc[0].location = 0; 
attribute_desc[0].binding = binding_desc[0].binding; 
attribute_desc[0].format = VK_FORMAT_R32G32B32_SFLOAT; 
attribute_desc[0].offset = offsetof(vert_shader_vertex, pos); 

attribute_desc[1].location = 1; 
attribute_desc[1].binding = binding_desc[1].binding; 
attribute_desc[1].format = VK_FORMAT_R32G32_SFLOAT; 
attribute_desc[1].offset = offsetof(vert_shader_vertex, uv); 

vkCmdDrawを呼び出すときに、私は次のエラーを取得する:

ERROR [デフォルト] DS:(OBJECT 0)(CODE 24)パイプライン状態オブジェクト (0x3c)は、このコマンドバッファの頂点バインディングインデックス1 をvkCmdBindVertexBuffersで設定する必要があります。 pVertexBindingDescriptionsのインデックス1の VkVertexInputBindingDescription構造体は、しかし、1

の結合値を持っているので、私はこのようにそれを設定する場合、これは、次のとおりです。

VkVertexInputBindingDescription binding_desc[1] = {}; 
binding_desc[0].binding = 0; 
binding_desc[0].stride = sizeof(glm::vec3); 
binding_desc[0].inputRate = VK_VERTEX_INPUT_RATE_VERTEX; 

VkVertexInputAttributeDescription attribute_desc[1] = {}; 
attribute_desc[0].location = 0; 
attribute_desc[0].binding = binding_desc[0].binding; 
attribute_desc[0].format = VK_FORMAT_R32G32B32_SFLOAT; 
attribute_desc[0].offset = offsetof(vert_shader_vertex, pos); 

vkCreateGraphicsPipelinesを呼び出すときに、私はこのエラーを取得します:

ERROR [デフォルト] SC:(OBJECT 0)(コード3)頂点シェーダは、位置1での入力 を消費するが、設けられていない

  • VkVertexInputBindingDescriptionは、ジオメトリシェーダ、または頂点シェーダへの入力を説明していますか?
  • プレースホルダとして頂点バッファに「ダミー」UV座標が必要ですか?
  • ジオメトリシェーダがアクティブ化されていない可能性があります。どのように確認できますか?
  • 2つのアプローチのどちらが正しいかは、どのように対応するエラーに対処するのですか?
  • 私はVulkanを初めて使っているので、シェーダのコメントを歓迎します。

ジオメトリシェーダ

#version 450 

#extension GL_ARB_separate_shader_objects : enable 
#extension GL_ARB_shading_language_420pack : enable 

layout (points) in; 
layout (triangle_strip, max_vertices = 4) out; 

layout (location = 0) in vec3 inPos[]; 

layout (location = 0) out vec3 outPos; 
layout (location = 1) out vec2 outUV; 

layout (push_constant) uniform constants_t { 
    vec3 up; 
    vec3 right; 
    mat4x4 world; 
    mat4x4 projection; 
} constants; 

void main(void) 
{ 
    const vec3 pos = gl_in[0].gl_Position.xyz; 
    const vec3 up = constants.up; 
    const vec3 right = constants.right; 

    outPos = pos + up - right; 
    outUV = vec2(0, 0); 
    EmitVertex(); 

    outPos = pos + up + right; 
    outUV = vec2(1, 0); 
    EmitVertex(); 

    outPos = pos - up - right; 
    outUV = vec2(0, 1); 
    EmitVertex(); 

    outPos = pos - up + right; 
    outUV = vec2(1, 1); 
    EmitVertex(); 

    EndPrimitive(); 
} 

頂点シェーダ

#version 450 

#extension GL_ARB_separate_shader_objects : enable 
#extension GL_ARB_shading_language_420pack : enable 

layout (location = 0) in vec3 inPos; 
layout (location = 1) in vec2 inUV; 

layout (location = 0) out vec4 outPos; 
layout (location = 1) out vec2 outUV; 

layout (push_constant) uniform constants_t { 
    vec3 up; 
    vec3 right; 
    mat4x4 world; 
    mat4x4 projection; 
} constants; 

void main(void) { 
    outUV = inUV; 
    outPos = vec4(inPos.xyz, 1.0) * constants.world * constants.projection; 
} 

vkCmdBindVertexBuffers

VkBuffer vertex_buffers[1] = {vertexBuffer}; 
VkDeviceSize vertex_offset[1] = {0}; 
vkCmdBindVertexBuffers(commandBuffer, 0, 1, vertex_buffers, vertex_offset); 
+0

"* vkCmdDrawを呼び出すときに次のエラーが発生します:*"何が起こっているのかを知るためには、レンダリングする前に送る*実際のコマンドを見る必要があります。 –

+0

私はvkCmdBindVertexBuffersは最初の亜種にとって非常に重要だと思います –

+0

@NicolBolas本当ですか?私の投稿には、かなり一般的な、弾丸で指摘された質問が含まれています。また、私はあなたが見るためにどこかのコードをすべてダンプする権限を持っていません。 – Brent

答えて

2
vkCmdBindVertexBuffers(commandBuffer, 0, 1, vertex_buffers, vertex_offset); 

これは、1つのバッファをインデックス0にバインドしていることを示しています。しかし、パイプラインに2つのバッファがバインドされていることを指定しました。

Vulkanには嘘をつけないでください。 それは常に(検証レイヤーを使用している場合)を知っています))。

どちらの頂点属性にもと同じバッファオブジェクトを使用することを意図している可能性があります。私は、あなたがoffsetofを使ってそれらの相対的なオフセットを計算したことから、このことを推測します。それがあなたの意図ならば、同じバッファバインディングを使用する2つの頂点属性が必要です。

VkVertexInputBindingDescriptionは、ジオメトリシェーダ、または頂点シェーダへの入力を説明していますか?

第1のパイプラインシェーダステージは、頂点シェーダあるのでGSへの入力を記述することはできません。また、VSなしでグラフィックスパイプラインを作成することはできません。

関連する問題