开发者

Large, slowly rotating planet graphics for game

开发者 https://www.devze.com 2023-01-31 07:34 出处:网络
For a computer game I\'m developing, I\'d like to draw very large (~500 px) graphics of planets slowly rotating. These graphics are meant to impress.开发者_开发问答 What\'s the best way of doing this?

For a computer game I'm developing, I'd like to draw very large (~500 px) graphics of planets slowly rotating. These graphics are meant to impress.开发者_开发问答 What's the best way of doing this?

  • I could pre-render each frame, but at 500px and a rotation period of 10 seconds, that's a ludicrous amount of data per planet.
  • I could use a 3D engine and map the planet's texture onto a mesh approaching a sphere, but at 500px, I fear the polygon count would have to be huge to make it look good.
  • I could write a kind of custom 3D engine that does nothing but efficiently render a textured sphere, by converting the x/y coordinate of each view pixel into the coordinate space of the sphere's texture - but this is involved, and couldn't benefit from graphics acceleration.
  • Something else I haven't thought of?

Here's an example animated GIF of what I mean. (At 100x100 px and 60 frames, it's already pretty huge, sorry.) Imagine this much, much bigger, rotating much slower, and animated more smoothly:

Large, slowly rotating planet graphics for game

But if this were 500x500 px and 10 x 25 = 250 frames, we'd be talking about hundreds of MB of data, so this straightforward approach doesn't work.


Fracplanet can save out "spheremap" texture maps (and bump maps); see the images towards the bottom of the gallery. These are intended to be subsequently read into an app and mapped onto relatively low resolution sphere geometry to achieve the very effect I think you're looking for. This approach will use less memory than the pre-rendered animation approach or using the original full resolution polygon model.

Yes this is basically your second bullet point but I wouldn't be so quick to rule that approach out and I think you'll find you can get away with a lower resolution sphere than you anticipate; the eye notices the fine detail in the texture far more than it notices the low resolution of the geometry it's draped over. Modern tessellation hardware means you can probably get the GPU to easily generate and render a ridiculous number of polygons for a sphere for you anyway.

Alternative idea: render a single square quad polygon sufficiently large to cover the planet. For each pixel within that, execute a pixel-shader which computes the screen-ray-sphere intersection point (if any). Look up the colour from the planet texture (taking time and planet rotation into account). Avoids the need for a lot of polygons and gets you an exact sphere.


If you want graphics acceleration, then polygons are cheap -- a fairly large number of polygons is not a problem.

I recommend a cube map texture, and a corresponding cube-like triangle grid: start with a vertex grid in the shape of (the surface of) a cube about the origin, and normalize each 3D coordinate to unit radius. This will make computing your texture coordinates easy.

Keep in mind that you need to choose the right projection for your texture: in the above case, you will want a tangent projection for each cube face, to match your grid.


The archaic way of doing this would be to pre-create an image of a sphere but instead of storing the colors of the surface texture in each pixel you store the texture UV as a lookup table. Now you can render the sphere by drawing the pre-rendered image but look up the corresponding texel in a planet surface texture from the UV found in the image. In order to make the planet rotate you can add an offset to the uv coordinate found in the lookup table image. Make sure you use a modulus addition so the texture wraps nicely. If you want shading on the planet you can add that as a separate pass on top of the texture.

This approach would most likely be much faster than a textured polygon version on hardware without built in graphics acceleration and you would also be able to render it with as many polygons as you want since the rendering is a pre-process.


If you go for pre-rendering, how about an algorithm that will render the required frames as the game is running, based on how likely the player is to actually see them - ranging from 'certain' going down through increasingly improbable based on where the game engine could permit the player to possibly be in x seconds time versus which frame should be in view at that time, down to 'impossible' and therefore not rendered?


If your planets will always be rotating orthogonal to the screen just have a single planet texture that scrolls and is masked off by a circle.

If you want an arbitrary rotation axis you'll want to ask yourself which is easier, the 3D solution or using a couple compressed textures to hold all the frames. If you already have an easy to work with 3D pipeline use that.

If you make a frame 256x256 you could fit 16 on a 1024 texture so 60 frames would only take 4 textures. Using DXT3 compression you could expect this to be about 1 MB per texture (pretty reasonable).


You can either move the camera about the object (that really only works if all your stuff is centered), or transform the object. The latter is commonly done.

I can recommend looking at sf.net/projects/a3d which has been easy to study. draw_asteroids uses a glRotate call, so that's it.

Furthermore, if I heard correctly, the Doom3 engine introduced bezier lines, so that a rounded corner in a game — or a sphere, to apply it to this case — would not need to be composed of quantized points (producing the ugly mesh network that you are thinking of).


Large, slowly rotating planet graphics for game

Turns out using perlin noise and a shader gives pretty good results.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号