DecalComponent.cpp 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  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. loadDiffuseImageResource("EngineAssets/DefaultDecal.png", 0.9f);
  16. m_defaultDecalImage = m_layers[LayerType::kDiffuse].m_image;
  17. }
  18. DecalComponent::~DecalComponent()
  19. {
  20. }
  21. void DecalComponent::setLayer(CString fname, F32 blendFactor, LayerType type)
  22. {
  23. Layer& l = m_layers[type];
  24. ImageResourcePtr rsrc;
  25. if(ResourceManager::getSingleton().loadResource(fname, rsrc))
  26. {
  27. ANKI_SCENE_LOGE("Failed to load image");
  28. return;
  29. }
  30. m_dirty = true;
  31. l.m_image = std::move(rsrc);
  32. l.m_bindlessTextureIndex = l.m_image->getTexture().getOrCreateBindlessTextureIndex(TextureSubresourceDesc::all());
  33. l.m_blendFactor = clamp(blendFactor, 0.0f, 1.0f);
  34. }
  35. void DecalComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
  36. {
  37. updated = m_dirty || info.m_node->movedThisFrame();
  38. if(!updated) [[likely]]
  39. {
  40. return;
  41. }
  42. m_dirty = false;
  43. const Vec3 halfBoxSize = info.m_node->getWorldTransform().getScale().xyz();
  44. // Calculate the texture matrix
  45. Transform trf = info.m_node->getWorldTransform();
  46. trf.setScale(Vec3(1.0f));
  47. const Mat4 viewMat = Mat4(trf).invert();
  48. const Mat4 projMat = Mat4::calculateOrthographicProjectionMatrix(halfBoxSize.x(), -halfBoxSize.x(), halfBoxSize.y(), -halfBoxSize.y(),
  49. -halfBoxSize.z(), halfBoxSize.z());
  50. 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);
  51. const Mat4 biasedProjViewMat = biasMat4 * projMat * viewMat;
  52. // Upload to the GPU scene
  53. GpuSceneDecal gpuDecal;
  54. gpuDecal.m_diffuseTexture = m_layers[LayerType::kDiffuse].m_bindlessTextureIndex;
  55. gpuDecal.m_roughnessMetalnessTexture = m_layers[LayerType::kRoughnessMetalness].m_bindlessTextureIndex;
  56. gpuDecal.m_diffuseBlendFactor = m_layers[LayerType::kDiffuse].m_blendFactor;
  57. gpuDecal.m_roughnessMetalnessFactor = m_layers[LayerType::kRoughnessMetalness].m_blendFactor;
  58. gpuDecal.m_textureMatrix = biasedProjViewMat;
  59. gpuDecal.m_sphereCenter = info.m_node->getWorldTransform().getOrigin().xyz();
  60. gpuDecal.m_sphereRadius = halfBoxSize.length();
  61. m_gpuSceneDecal.uploadToGpuScene(gpuDecal);
  62. }
  63. } // end namespace anki