DecalComponent.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <AnKi/Scene/Components/DecalComponent.h>
  6. #include <AnKi/Scene/SceneGraph.h>
  7. #include <AnKi/Resource/ResourceManager.h>
  8. #include <AnKi/Shaders/Include/ClusteredShadingTypes.h>
  9. #include <AnKi/GpuMemory/GpuSceneBuffer.h>
  10. namespace anki {
  11. DecalComponent::DecalComponent(SceneNode* node)
  12. : SceneComponent(node, kClassType)
  13. {
  14. m_gpuSceneDecal.allocate();
  15. setDiffuseImageFilename("EngineAssets/DefaultDecal.png");
  16. setDiffuseBlendFactor(0.9f);
  17. m_defaultDecalImage = m_layers[LayerType::kDiffuse].m_image;
  18. }
  19. DecalComponent::~DecalComponent()
  20. {
  21. }
  22. void DecalComponent::setImage(LayerType type, CString fname)
  23. {
  24. ImageResourcePtr rsrc;
  25. if(ANKI_EXPECT(type < LayerType::kCount && !ResourceManager::getSingleton().loadResource(fname, rsrc)))
  26. {
  27. Layer& l = m_layers[type];
  28. if(!l.m_image || rsrc->getUuid() != l.m_image->getUuid())
  29. {
  30. m_dirty = true;
  31. l.m_image = std::move(rsrc);
  32. l.m_bindlessTextureIndex = l.m_image->getTexture().getOrCreateBindlessTextureIndex(TextureSubresourceDesc::all());
  33. }
  34. }
  35. }
  36. void DecalComponent::setBlendFactor(LayerType type, F32 blendFactor)
  37. {
  38. if(ANKI_EXPECT(type < LayerType::kCount))
  39. {
  40. Layer& l = m_layers[type];
  41. blendFactor = saturate(blendFactor);
  42. if(l.m_blendFactor != blendFactor)
  43. {
  44. l.m_blendFactor = blendFactor;
  45. m_dirty = true;
  46. }
  47. }
  48. }
  49. void DecalComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
  50. {
  51. updated = m_dirty || info.m_node->movedThisFrame();
  52. if(!updated) [[likely]]
  53. {
  54. return;
  55. }
  56. m_dirty = false;
  57. const Vec3 halfBoxSize = info.m_node->getWorldTransform().getScale().xyz;
  58. // Calculate the texture matrix
  59. Transform trf = info.m_node->getWorldTransform();
  60. trf.setScale(Vec3(1.0f));
  61. const Mat4 viewMat = Mat4(trf).invert();
  62. const Mat4 projMat =
  63. Mat4::calculateOrthographicProjectionMatrix(halfBoxSize.x, -halfBoxSize.x, halfBoxSize.y, -halfBoxSize.y, -halfBoxSize.z, halfBoxSize.z);
  64. const Mat4 biasMat4(0.5f, 0.0f, 0.0f, 0.5f, 0.0f, -0.5f, 0.0f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
  65. const Mat4 biasedProjViewMat = biasMat4 * projMat * viewMat;
  66. // Upload to the GPU scene
  67. GpuSceneDecal gpuDecal;
  68. gpuDecal.m_diffuseTexture = m_layers[LayerType::kDiffuse].m_bindlessTextureIndex;
  69. gpuDecal.m_roughnessMetalnessTexture = m_layers[LayerType::kRoughnessMetalness].m_bindlessTextureIndex;
  70. gpuDecal.m_diffuseBlendFactor = m_layers[LayerType::kDiffuse].m_blendFactor;
  71. gpuDecal.m_roughnessMetalnessFactor = m_layers[LayerType::kRoughnessMetalness].m_blendFactor;
  72. gpuDecal.m_textureMatrix = biasedProjViewMat;
  73. gpuDecal.m_sphereCenter = info.m_node->getWorldTransform().getOrigin().xyz;
  74. gpuDecal.m_sphereRadius = halfBoxSize.length();
  75. m_gpuSceneDecal.uploadToGpuScene(gpuDecal);
  76. }
  77. Error DecalComponent::serialize(SceneSerializer& serializer)
  78. {
  79. Layer& diffuse = m_layers[LayerType::kDiffuse];
  80. Layer& roughnessMetalness = m_layers[LayerType::kRoughnessMetalness];
  81. ANKI_SERIALIZE(diffuse.m_image, 1);
  82. ANKI_SERIALIZE(roughnessMetalness.m_image, 1);
  83. ANKI_SERIALIZE(diffuse.m_blendFactor, 1);
  84. ANKI_SERIALIZE(roughnessMetalness.m_blendFactor, 1);
  85. if(!serializer.isInWriteMode() && diffuse.m_image)
  86. {
  87. diffuse.m_bindlessTextureIndex = diffuse.m_image->getTexture().getOrCreateBindlessTextureIndex(TextureSubresourceDesc::all());
  88. }
  89. if(!serializer.isInWriteMode() && roughnessMetalness.m_image)
  90. {
  91. roughnessMetalness.m_bindlessTextureIndex =
  92. roughnessMetalness.m_image->getTexture().getOrCreateBindlessTextureIndex(TextureSubresourceDesc::all());
  93. }
  94. return Error::kNone;
  95. }
  96. } // end namespace anki