From c12ec892f391e5c6077fa6fa250d7a7ad6e21b7d Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Thu, 3 Jul 2025 11:52:50 +0800 Subject: [PATCH] add bbCenter to outline material --- materials/outline.mat | 82 +++++++++++++++++++ .../components/OverlayComponentManager.hpp | 10 +++ 2 files changed, 92 insertions(+) create mode 100644 materials/outline.mat diff --git a/materials/outline.mat b/materials/outline.mat new file mode 100644 index 00000000..2331fb85 --- /dev/null +++ b/materials/outline.mat @@ -0,0 +1,82 @@ +material { + name : Highlight, + requires : [ position ], + parameters : [ + { + type : sampler2d, + name : depth, + precision: high + }, + { + type : float, + name : scale + }, + { + type : float3, + name : bbCenter + }, + { + type : float3, + name : color + } + ], + depthWrite : true, + depthCulling : true, + shadingModel : unlit, + blending: transparent, + culling: none, + instanced: false, + vertexDomain: object, +} + +vertex { + void materialVertex(inout MaterialVertexInputs material) { + vec3 position = getPosition().xyz; + mat4 transform = getWorldFromModelMatrix(); + vec4 bbCenter = mulMat4x4Float3(transform, materialParams.bbCenter); + // Transform position to world space first + vec4 worldPos = mulMat4x4Float3(transform, position); + + // Translate to bbCenter, scale, then translate back + vec3 relativePos = worldPos.xyz - bbCenter.xyz; + vec3 scaledPos = relativePos * materialParams.scale; + material.worldPosition = vec4(bbCenter.xyz + scaledPos, worldPos.w); + } +} + +fragment { + void material(inout MaterialInputs material) { + float2 vp = uvToRenderTargetUV( getNormalizedViewportCoord().xy ); + prepareMaterial(material); + + float depth = texture( materialParams_depth, vp ).r; + float dDepthDx = dFdx(depth); + float dDepthDy = dFdy(depth); + + vec2 texelSize = 1.0f / float2(textureSize(materialParams_depth, 0)); + + float depth_up = texture(materialParams_depth, vp + vec2(0.0, texelSize.y)).r; + float depth_down = texture(materialParams_depth, vp - vec2(0.0, texelSize.y)).r; + float depth_left = texture(materialParams_depth, vp - vec2(texelSize.x, 0.0)).r; + float depth_right = texture(materialParams_depth, vp + vec2(texelSize.x, 0.0)).r; + + // Check if any neighbor is background (edge detection) + bool isEdge = (depth_up >= 1.0) || (depth_down >= 1.0) || + (depth_left >= 1.0) || (depth_right >= 1.0); + + if (isEdge) { + material.baseColor.rgb = materialParams.color; + material.baseColor.a = 1.0f; + } else { + // Interior pixel - discard or make transparent + discard; + } + + //if(depth == 1.0f) { + // material.baseColor = vec4(depth, 0.0f, 0.0f, 1.0f); + //} else { + // discard; + //} + } +} + diff --git a/thermion_dart/native/include/components/OverlayComponentManager.hpp b/thermion_dart/native/include/components/OverlayComponentManager.hpp index 19284fc8..c0eb1d9d 100644 --- a/thermion_dart/native/include/components/OverlayComponentManager.hpp +++ b/thermion_dart/native/include/components/OverlayComponentManager.hpp @@ -64,9 +64,19 @@ namespace thermion void addOverlayComponent(utils::Entity target, filament::MaterialInstance *materialInstance) { std::lock_guard lock(mMutex); + + auto &rm = mEngine->getRenderableManager(); + auto ri = rm.getInstance(target); + + if(!ri.isValid()) { + return; + } + + auto bb = rm.getAxisAlignedBoundingBox(ri); auto *color = mRenderTarget->getTexture(filament::RenderTarget::AttachmentPoint::COLOR); materialInstance->setParameter("depth", color, mDepthSampler); + materialInstance->setParameter("bbCenter", bb.center); if (!hasComponent(target)) { utils::EntityInstanceBase::Type componentInstance = addComponent(target);