2
\$\begingroup\$

I'm currently developing a Universe Simulator for Android. I had a question regarding layering. I have a list of 100k 3DPoints each represent a stars co-ordinates. I have decided to break the cameras frustum into a number of chunks.enter image description here

Chunk[0]: This will be 3D space I will have any star inside here as this model.

Chunks[1-N]: The Chunk will be defined by 8 3DPoints which create that partition of the cameras frustum. These chunks will be rendered as 2D, any stars that appear will be represented as a single/multiple pixels.

enter image description here

How do I sell the illusion to the user that the star is smoothly growing bigger towards them? I hope to each an effect like this while keeping the workload to a minimal, I'm quite new to unity and I was wondering if anyone could point me towards the correct resources or has any insight! Cheers enter image description here

\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

Perspective projection will already make objects "twice as far" look "half as big". You need to one-up that scaling to make sure objects are dot-sized at the FARPLANE. You need two scale factors for each mesh. One of the factors, MinSize, will be shared by all of them and you can just experiment to find it. Place a mesh close to the farplane, then shrink it until it is "dot-sized". The other factor, MaxSize, is per-mesh, giving each mass their own dimensions.

A simplified example:

To be dot-sized at the FARPLANE, a MinSize of 0.01f looks good.

To be planet-sized at the NEARPLANE, a MaxSize of 50.0f looks good.

percentOfFrustumDepth = distanceFromCamera / FARPLANE;
//Using linear fall-off
//currentPlanetScale = lerp(MaxSize, MinSize, percentOfFrustumDepth);
currentPlanetScale = lerp(50.0f, 0.01f, percentOfFrustumDepth);

This makes the planet scale MaxSize (50.0f) at the NEARPLANE and MinSize (0.01f) at the FARPLANE. At 50% scene-depth, planet scale would be about 25.0005f.

You can adjust the fall-off any way you'd like, clamping it between X and Y, using different factors between DepthX and DepthY, etc., etc.

//Quadratic(?) fall-off
currentPlanetScale = lerp(MaxSize, MinSize, sqrt(percentOfFrustumDepth));

With this formula, at 50% scene-depth, the planet is about 1/4 of its' full size (71% between Max and Min). Around 25% scene-depth, the planet is half-sized.

//Don't lerp objects closer than 200-units
percentOfFrustumDepth = (distanceFromCamera - 200.0f) / (FARPLANE - 200.0f);
//(distanceFromCamera - 200.0f) might be negative so clamp
percentOfFrustumDepth = fmaxf(0.0f, percentOfFrustumDepth);

Experiment. To give a warp tunnel effect, you can also collapse the object's translations toward a single point, based on their scene-depth.

currentPlanetLocation = lerp(actualPlanetLocation, vanishingPoint, percentOfFrustumDepth);

With this formula, all incoming objects appear to originate from the same dot, spreading out to their actual positions as you get near. All out-going objects appear to collapse into the same dot, then vanish. To see what these two scaling and perspective effects might look like together, watch a few videos of ships warping in EVE Online.

A closeup of the "3D" partition:

enter image description here

\$\endgroup\$
2
  • \$\begingroup\$ Thank you for this answer @Jon ! So due to perspective projection the max from one mesh will be transformed onto the min of another with a smooth look? \$\endgroup\$
    – MarsYeti
    Commented Mar 5, 2016 at 19:45
  • \$\begingroup\$ @MarsYeti, I'm not sure what you mean. I modified the image from my answer to your other question to show the difference between normal projection and what you want to do. All you're doing is overriding the world matrix scale-factor of meshes beyond a certain distance, based on that distance. \$\endgroup\$
    – Jon
    Commented Mar 5, 2016 at 22:49
1
\$\begingroup\$

Unity's rendering engine is not designed for interstellar scales, so you need to fake it.

Place the game objects which represent far-away stars just at the edge of the view frustum in the direction where the star is relative to the camera. Represent the stars as sprites and add a script to them which always turns them towards the camera ("billboarding") and adjusts their size according to the square-root of the distance.

\$\endgroup\$
1
  • \$\begingroup\$ I got curious why you mention that Unity's engine is not designed for interstellar scales. I mean, all engines out there like Unreal or CryEngine or Lumberjack, all have that limitation, don't they? Also got curious why did specifically point out the rendering problem. Isn't that much more an issue of floating points causing jittering (so a positioning problem) than a proper rendering problem? \$\endgroup\$
    – Louis15
    Commented Mar 5, 2016 at 7:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .