Yes — this is very doable, and you’re thinking about it the right way (Unity “RenderTexture” mental model maps to Unreal “Render Target”).
There are two sane ways to drive tile scale from a BW heatmap in Unreal:
- CPU sampling (Blueprint reads the texture and sets each tile’s scale)
- GPU-driven (material displaces/animates visuals from the texture; tiles stay static as geometry)
Because you want to actually scale 180 separate tile components, you’re in CPU sampling land (at least for now). For 180 tiles this is fine.
Below is the clean “static BW texture → scale” approach, and I’ll also tell you what texture type you should use later for live camera feedback.
- Use a normal Texture2D (grayscale).
- Use a Texture Render Target 2D (
TextureRenderTarget2D).
- Later you can write into it via:
- SceneCapture2D
- Drawing materials to the render target
- C++/plugin
- Media texture pipeline, etc.
✅ So: design your pipeline around a Render Target 2D, but for now you can plug in a Texture2D.
For each tile:
- Convert tile world position → UV (0–1) in heatmap space
- Sample heatmap value (0–1) at that UV
- Use that value to drive scale (lerp between MinScale/MaxScale)
That replaces your “distance to influencer” logic.
Create these variables:
- HeatmapTexture :
Texture (or Texture2D / TextureRenderTarget2D)
- ProjectionOrigin :
Vector (world-space bottom-left of the projection)
- ProjectionSize :
Vector2D (world width/height covered by the texture)
- bFlipV : bool (optional; textures often come in upside down)
(These replace influencer position/distance)
Inside your tile loop (where you currently compute distance):
TileComp → GetWorldLocation → Pos
Offset = Pos - ProjectionOrigin
U = Offset.X / ProjectionSize.X
V = Offset.Y / ProjectionSize.Y
- Clamp each 0..1
Depending on your ground plane orientation you might use X/Y or X/Z.
Most ground planes in UE are X/Y, but if your tiles lie on X/Z, swap accordingly.
Add Clamp (float) for U and V.
Optional:
Here’s the key: Blueprints can’t “just sample a Texture2D” cheaply like a shader. You have a few approaches:
If you use TextureRenderTarget2D (even for a static image you can copy into it once), you can sample in BP.
Nodes (Blueprint):
Read Render Target Pixel (or “Read Render Target Raw UV” depending on version)
- Target = your RenderTarget
- X,Y pixel coordinates
To do that you convert UV → pixel coords:
X = floor(U * (Width-1))
Y = floor(V * (Height-1))
Then the node returns a LinearColor.
Use .R as the grayscale value.
✅ This is the closest match to Unity RenderTexture workflows.
Blueprint can’t efficiently read Texture2D pixels every frame without plugins/C++. So for static Texture2D, the sane approach is:
- At BeginPlay: read it once (C++ or editor utility), store array
- At runtime: index into the array
If you want to stay Blueprint-only, use a Render Target.
Recommendation: start with a RenderTarget now, even for a static BW image.
Let:
Heat = SampledValue (0..1)
Then:
Scale = Lerp(MinScale, MaxScale, Heat)
(or invert if white should mean small)
Then apply SetRelativeScale3D.
This replaces all your distance math.
For each tile component:
Pos = GetWorldLocation(Tile)
UV = (Pos - ProjectionOrigin) / ProjectionSize (component-wise)
- Clamp UV 0..1
PixelXY = UV * (RTSize - 1)
Color = ReadRenderTargetPixel(RenderTarget, PixelXY)
Heat = Color.R
FinalScale = Lerp(MinScale, MaxScale, Heat)
SetRelativeScale3D(Tile, (FinalScale, FinalScale, FinalScale))
Don’t sample the texture every Tick if you can avoid it.
For 180 tiles it may be okay at low frequency, but reading render target pixels can still be expensive.
Use your existing UpdateInterval and run this on a timer (e.g. 0.05–0.2s).
Later, if you need 60Hz and it becomes heavy, you move to:
- C++ bulk read (ReadPixels once per frame)
- Or GPU approach (material displacement instead of component scaling)
- Create a TextureRenderTarget2D asset (e.g. 512×512, R8 or RGBA8).
- Create a simple material that outputs your BW texture into Emissive.
- At BeginPlay:
Draw Material to Render Target once to copy the BW texture into the RT.
- Then sample the RT in your tile scaler.
This gives you the same pipeline you’ll later use for live heatmaps.
Are your tiles laid out on X/Y (typical plane) or X/Z (common “ground” in some workflows)?
If you don’t know: tell me what axis is “up” for your scene (usually Z-up in Unreal).
Even without your answer, you can try:
- Use X and Y first
- If the mapping looks rotated, swap to X/Z
If you want, I can sketch the exact nodes to replace your “Distance(Vector)” section with “World→UV→ReadRenderTargetPixel”.