| … | … | @@ -1741,10 +1741,19 @@ RTViewportState *RenderRaytracing::build_tlas(const RenderDataRD *p_render_data, |
| 1741 | 1741 | uint16_t material_counter = material_storage->material_get_rt_invalidation_counter(material_rid); |
| 1742 | 1742 | RTMaterialData *mat_data = process_material(material_rid, material_counter); |
| 1743 | 1743 | |
| 1744 | | if (mat_data->rt_sbt_offset > 0 && |
| 1745 | | !rt_shader_singleton->is_hg_ready_in_bundle(mat_data->rt_sbt_offset, p_rt_flags)) { |
| 1746 | | surf = surf->next; |
| 1747 | | continue; |
| 1744 | // Custom hit groups compile on a worker thread, so a surface's HG is |
| 1745 | // typically not ready for the first frames after a material appears. |
| 1746 | // Dropping the surface from the TLAS meanwhile makes the geometry |
| 1747 | // INVISIBLE until the compile lands (seconds, for a large shader with |
| 1748 | // several pipeline variants). Fall back to the default hit group |
| 1749 | // instead: the surface renders immediately with standard material |
| 1750 | // shading and upgrades to its own shader once that is ready. |
| 1751 | // |
| 1752 | // A permanently-failed HG (HGState::Failed) never becomes ready, so |
| 1753 | // this also keeps such geometry visible rather than silently absent. |
| 1754 | uint32_t sbt_offset = mat_data->rt_sbt_offset; |
| 1755 | if (sbt_offset > 0 && !rt_shader_singleton->is_hg_ready_in_bundle(sbt_offset, p_rt_flags)) { |
| 1756 | sbt_offset = 0; |
| 1748 | 1757 | } |
| 1749 | 1758 | |
| 1750 | 1759 | // Compute or reuse cached final transform (instance * aabb_transform for compressed meshes). |
| … | … | @@ -1785,7 +1794,7 @@ RTViewportState *RenderRaytracing::build_tlas(const RenderDataRD *p_render_data, |
| 1785 | 1794 | } |
| 1786 | 1795 | #endif |
| 1787 | 1796 | |
| 1788 | | sbt_offsets.push_back(mat_data->rt_sbt_offset); |
| 1797 | sbt_offsets.push_back(sbt_offset); |
| 1789 | 1798 | material_data.push_back(mat_data->data); |
| 1790 | 1799 | |
| 1791 | 1800 | // Determine per-instance TLAS flags from material properties. |
| … | … | @@ -1807,10 +1816,12 @@ RTViewportState *RenderRaytracing::build_tlas(const RenderDataRD *p_render_data, |
| 1807 | 1816 | inst_flags |= RD::ACCELERATION_STRUCTURE_INSTANCE_TRIANGLE_FLIP_FACING_BIT; |
| 1808 | 1817 | } |
| 1809 | 1818 | |
| 1810 | | if (mat_data->rt_sbt_offset > 0) { |
| 1819 | // Uses the possibly-fallen-back offset: a surface shading through the |
| 1820 | // default hit group must take the standard-material branch below. |
| 1821 | if (sbt_offset > 0) { |
| 1811 | 1822 | // Custom shader: only enable any-hit if the shader uses alpha clip. |
| 1812 | 1823 | const SceneShaderRaytracing::CustomShaderEntry *cse = |
| 1813 | | rt_shader_singleton->get_custom_shader_entry(mat_data->rt_sbt_offset); |
| 1824 | rt_shader_singleton->get_custom_shader_entry(sbt_offset); |
| 1814 | 1825 | if (!cse || !cse->uses_alpha_clip) { |
| 1815 | 1826 | inst_flags |= RD::ACCELERATION_STRUCTURE_INSTANCE_FORCE_OPAQUE_BIT; |
| 1816 | 1827 | } |