How to find position of a mesh in viewport x,y space

is there an elegant way to find out the position of a mesh in the viewport plane? I’ve got clicking-on-objects working using raycaster, so I could poll the whole grid to see what is at every x,y, but that seems horribly inefficient. The engine knows where the mesh is – it drew it there – are the coordinates available somehow? Ideally there’s something I just don’t know about, like MyMesh.engine.viewportdata.x and …y.

thank you

  1. CPU knows where anything is in the viewport similarly as billionaire mine stakeholders in US would know (or care) where miner #13284 found a specific vein of coal on Mars. WebGL just throws a bunch of vectors at the GPU, which then splits and hands out all these vectors and their associated shaders across 1.000.000 independent, parallel GPU cores - unless you render things back to a RenderTarget texture, CPU has no interest of what GPU rendered where.
  1. Depends on use-case and optimisation - raycasting against bounding spheres of only relevant objects (together with some octree or three-mesh-bvh) should be fast enough, if not faster than CPU 3D-to-2D projection.

  2. This is how you can project 3D world position into 2D viewport position (lines 10-29 only, it’s a simplified version of CSS2DRenderer does.)

3 Likes

well said and thank you

I was able to adapt your code to get the effect I want

for newcomers to OrbitControls, right-click and drag to get some change in the viewport position

FWIW i added distance from the camera, which was relatively simple, and successfully used that to adjust the size of the text in my floating label div, which kind of completes the effect of associating html text with a threejs object. Modified the codepen in my previous note to demonstrate.

1 Like

But looking at the example - if what you’re looking for is just positioning the DOM elements relative to 3D elements - is there any reason not to just use CSS2DRenderer (or CSS3DRenderer alternatively) :eyes: ?

1 Like

There’s only one of me and my goal is to have a working 3D game board, not to become a professional subject matter expert in Threejs. My game has 165 positions evenly distributed in a diamond cubic lattice, and as of yesterday the positions all have labels. Now that you’ve showed me the CSS2DRenderer example I might change it to use those in a future housekeeping phase – or maybe a threejs expert can take over the look and feel of it – but the current action item has to do with WebSockets. As of a couple hours ago I have a minimal pub/sub pattern working so the players can subscribe to each other and play. Yes, calling BoardPositionObject.add(BoardPositionLabel) and having two renderers running, instead of one renderer and a label mover-arounder that gets called every 300 ms, would probably look a lot smoother. And textures on the pieces instead of just colors would be cool too. I’m looking at a big board and I can only play so many stones in a day.

Again, yes, that’s a cleaner solution (assuming sizing the labels will be easy-peasy and isn’t a feature that’s demonstrated in that example) but I’m also learning dynamic HTML from Javascript in this project; I’ve been doing Extract/Transform/Load for years and haven’t needed these features that didn’t exist back in the day.