Add different texture per draw call for billboard

This commit is contained in:
Benau 2022-09-18 10:54:22 +08:00
parent 50c22a5837
commit 4d79ccdea5
3 changed files with 41 additions and 34 deletions

View File

@ -3,42 +3,50 @@ layout(binding = 0) uniform sampler2D f_mesh_textures[SAMPLER_SIZE * TOTAL_MESH_
vec4 sampleMeshTexture0(int material_id, vec2 uv)
{
return texture(f_mesh_textures[(TOTAL_MESH_TEXTURE_LAYER * material_id) + 0], uv);
int id = (TOTAL_MESH_TEXTURE_LAYER * material_id) + 0;
return texture(f_mesh_textures[GE_SAMPLE_TEX_INDEX(id)], uv);
}
vec4 sampleMeshTexture1(int material_id, vec2 uv)
{
return texture(f_mesh_textures[(TOTAL_MESH_TEXTURE_LAYER * material_id) + 1], uv);
int id = (TOTAL_MESH_TEXTURE_LAYER * material_id) + 1;
return texture(f_mesh_textures[GE_SAMPLE_TEX_INDEX(id)], uv);
}
vec4 sampleMeshTexture2(int material_id, vec2 uv)
{
return texture(f_mesh_textures[(TOTAL_MESH_TEXTURE_LAYER * material_id) + 2], uv);
int id = (TOTAL_MESH_TEXTURE_LAYER * material_id) + 2;
return texture(f_mesh_textures[GE_SAMPLE_TEX_INDEX(id)], uv);
}
vec4 sampleMeshTexture3(int material_id, vec2 uv)
{
return texture(f_mesh_textures[(TOTAL_MESH_TEXTURE_LAYER * material_id) + 3], uv);
int id = (TOTAL_MESH_TEXTURE_LAYER * material_id) + 3;
return texture(f_mesh_textures[GE_SAMPLE_TEX_INDEX(id)], uv);
}
vec4 sampleMeshTexture4(int material_id, vec2 uv)
{
return texture(f_mesh_textures[(TOTAL_MESH_TEXTURE_LAYER * material_id) + 4], uv);
int id = (TOTAL_MESH_TEXTURE_LAYER * material_id) + 4;
return texture(f_mesh_textures[GE_SAMPLE_TEX_INDEX(id)], uv);
}
vec4 sampleMeshTexture5(int material_id, vec2 uv)
{
return texture(f_mesh_textures[(TOTAL_MESH_TEXTURE_LAYER * material_id) + 5], uv);
int id = (TOTAL_MESH_TEXTURE_LAYER * material_id) + 5;
return texture(f_mesh_textures[GE_SAMPLE_TEX_INDEX(id)], uv);
}
vec4 sampleMeshTexture6(int material_id, vec2 uv)
{
return texture(f_mesh_textures[(TOTAL_MESH_TEXTURE_LAYER * material_id) + 6], uv);
int id = (TOTAL_MESH_TEXTURE_LAYER * material_id) + 6;
return texture(f_mesh_textures[GE_SAMPLE_TEX_INDEX(id)], uv);
}
vec4 sampleMeshTexture7(int material_id, vec2 uv)
{
return texture(f_mesh_textures[(TOTAL_MESH_TEXTURE_LAYER * material_id) + 7], uv);
int id = (TOTAL_MESH_TEXTURE_LAYER * material_id) + 7;
return texture(f_mesh_textures[GE_SAMPLE_TEX_INDEX(id)], uv);
}
#else
layout(binding = 0) uniform sampler2D f_mesh_texture_0;

View File

@ -187,17 +187,9 @@ void GEVulkanDrawCall::addBillboardNode(irr::scene::IBillboardSceneNode* node)
if (m_culling_tool->isCulled(bb))
return;
irr::video::SMaterial m = node->getMaterial(0);
std::array<const irr::video::ITexture*, 8> textures =
{{
m.TextureLayer[0].Texture,
m.TextureLayer[1].Texture,
m.TextureLayer[2].Texture,
m.TextureLayer[3].Texture,
m.TextureLayer[4].Texture,
m.TextureLayer[5].Texture,
m.TextureLayer[6].Texture,
m.TextureLayer[7].Texture
}};
TexturesList textures = {};
if (!GEVulkanFeatures::supportsDifferentTexturePerDraw())
textures = getTexturesList(m);
if (m_billboard_buffers.find(textures) == m_billboard_buffers.end())
m_billboard_buffers[textures] = new GEVulkanBillboardBuffer(m);
GESPMBuffer* buffer = m_billboard_buffers.at(textures);
@ -265,20 +257,9 @@ void GEVulkanDrawCall::generate()
unsigned accumulated_instance = 0;
for (auto& p : visible_nodes)
{
irr::video::SMaterial& m = p.first->getMaterial();
std::array<const irr::video::ITexture*, 8> textures =
{{
m.TextureLayer[0].Texture,
m.TextureLayer[1].Texture,
m.TextureLayer[2].Texture,
m.TextureLayer[3].Texture,
m.TextureLayer[4].Texture,
m.TextureLayer[5].Texture,
m.TextureLayer[6].Texture,
m.TextureLayer[7].Texture
}};
TexturesList textures = getTexturesList(p.first->getMaterial());
const irr::video::ITexture** list = &textures[0];
const int material_id = m_texture_descriptor->getTextureID(list);
int material_id = m_texture_descriptor->getTextureID(list);
if (!GEVulkanFeatures::supportsBindMeshTexturesAtOnce())
m_materials[p.first] = material_id;
@ -299,6 +280,13 @@ void GEVulkanDrawCall::generate()
irr::scene::ISceneNode* node = r.first;
if (r.second == BILLBOARD_NODE)
{
if (GEVulkanFeatures::supportsDifferentTexturePerDraw())
{
const irr::video::SMaterial& m = node->getMaterial(0);
TexturesList textures = getTexturesList(m);
const irr::video::ITexture** list = &textures[0];
material_id = m_texture_descriptor->getTextureID(list);
}
m_visible_objects.emplace_back(
static_cast<irr::scene::IBillboardSceneNode*>(
node), material_id, m_billboard_rotation);

View File

@ -1,6 +1,7 @@
#ifndef HEADER_GE_VULKAN_DRAW_CALL_HPP
#define HEADER_GE_VULKAN_DRAW_CALL_HPP
#include <array>
#include <functional>
#include <map>
#include <string>
@ -84,10 +85,12 @@ struct DrawCallData
class GEVulkanDrawCall
{
private:
typedef std::array<const irr::video::ITexture*,
_IRR_MATERIAL_MAX_TEXTURES_> TexturesList;
const int BILLBOARD_NODE = -1;
std::map<std::array<const irr::video::ITexture*, 8>, GESPMBuffer*>
m_billboard_buffers;
std::map<TexturesList, GESPMBuffer*> m_billboard_buffers;
irr::core::quaternion m_billboard_rotation;
@ -152,6 +155,14 @@ private:
VK_SHADER_STAGE_ALL_GRAPHICS, 0, size, data);
}
}
// ------------------------------------------------------------------------
TexturesList getTexturesList(const irr::video::SMaterial& m)
{
TexturesList textures;
for (unsigned i = 0; i < textures.size(); i++)
textures[i] = m.TextureLayer[i].Texture;
return textures;
}
public:
// ------------------------------------------------------------------------
GEVulkanDrawCall();