Setting up your own dome using Stellarium's spheric mirror distortion feature

From Stellarium Wiki
Jump to: navigation, search

People interested in building and operating their own planetarium can subscribe to a YahooGroup, and the related Small Planetarium Forums Site.

In the following section I want to describe how you can build your own planetarium using Stellarium’s spheric_mirror distortion feature.

What you need:

  1. A dome. The dome should have a spherical inside. I suppose you can have good results with any dome larger than 2m in diameter, perhaps even with smaller ones.
  2. A spherical security mirror. I recommenda 1/4 mirror, that is a quarter of a sphere. Something like 0.4 or 0.5m in diameter should be ok, for small domes you may need smaller mirrors, decide for yourself.
  3. A video projector
  4. A computer running a current verion of stellarium.

In the following example I assume a dome with 5m diameter and a spheric 1/4 mirror with radius 0.25m. I suggest the following config.ini settings:

projector_gamma = 0.45
projector_position_x = 0
projector_position_y = 1
projector_position_z = -0.2
mirror_position_x = 0
mirror_position_y = 2
mirror_position_z = 0
mirror_radius = 0.25
dome_radius = 2.5
zenith_y = 0.125
scaling_factor = 0.8
flip_horz = true
flip_vert = false
flag_gravity_labels            = true
flag_menu                      = false

You should be familiar with the keys because there will be no menu except the tui. When you start stellarium press "PgDown" to get maximum FOV and "CursorUp" in order to look at the zenith. Press "z" 2 times in order to display the azimuth grid. Press "1" in order to get the config window. In the video settings choose the spheric_mirror distortion.

Install the spheric mirror inside the dome. Imagine a coordinate system that is centered in the dome center. The z-axis points upward to the zenith and the y-axis points to some point on the horizon. Look into the direction of the y-axis. Now the x-axis points to a point on the horizon which is near your right hand. In the above config.ini example I suggest that the center of the spheric mirror is at (0,2,0) (I use meters, but feel free to use any units you like).

Install the projector approximately at (0,1,-0.2). Notice the z-coordinate -0.2: the projector is lower than the spheric mirror center so that it shall not occult parts of the image. In my implementation I assume that all light comes from one point, which in reality is not true. The projector_position in config.ini refers to this fictional point. It will lie somewhere inside your projector, I do not know, where.

Turn your projector on and project the image onto the mirror. The upper black curved border of the image should correspond to the upper part of the mirror. Use the projector zoom and the scaling_factor in order to match. Also shift and tilt your projector so that the image zenith and horizon is projected onto your dome zenith and horizon. The azimuth grid should be in place, you know what I mean. Play around with the geometry parameters. In order to get equal illumination throughout the dome, you must set the projector_gamma value to whatever your projector needs.

I keep getting inquiries about zenith_y, so here comes a short explanation. The optical axis of the projector does not go through the center of the mirror sphere, but it meets the mirror surface on some point in the upper half. With the zenith_y parameter you can configure, where this point is. With zenith_y=0 the zenith is right in the center of the stellarium window (y=0). With zenith_y>0 the zenith is above the center of the stellarium window, with zenith_y<0 the zenith is below the center of the stellarium window. There is no zenith_x parameter for moving the zenith to the left of right side of the stellarium window. Exercise: try zenith_y values of 0.0,0.3,-0.3.

You do not need to restart stellarium every time you make changes to the spheric mirror distortion parameters. While stellarium is running just change the parameters in config.ini with your favourite editor, and in the stellarium config window switch to a different projection type, and back to spheric mirror distortion.

Mr. Paul Bourke has explained to me that some users like the following setup: They configure their dual head graphic card to show the same image on both outputs. One of them is connected to the projector, the other to an ordinary monitor that is used by the operator only. The operator wants to read the texts left-to-right, and therefore there shall be no image flipping on the stellarium image. Of course the projector then must be capable of doing image flipping, and must be configured to do so. Therefore I have introduced two new config.ini options in the [spheric_mirror] section: flip_horz (default=true) and flip_vert (default=false). This feature is available in current svn, and will go into the 0.9.x release.

Mr. Paul Bourke was so nice to set up an own page describing in great detail how to setup stellariums spheric mirror distortion feature, please visit his page at:

I hope you will be satisfied with the results. Please send pictures of your new planetarium!

Yours, Johannes

New features in current svn, which will go into version 0.9:

1) Ability to control image flipping:

flip_horz  (horizontal image flipping, optional, default=true)
flip_vert  (vertical image flipping, optional, default=false)

2) distortion can also be based on other projections than fisheye, for example stereographic, equal area or cylinder

3) improved texturing with triangles, image width and height need not be multiples of 16 any more:

texture_triangle_base_length  (how fine the grid shall be, optional, default=16)

4) make use of the OpenGL EXT_framebuffer_object extension for increasing the resolution of the image that shall be distorted. The image is then rendered to an off-screen buffer with configurable layout. You can disable ext_framebuffer_object if it does not work on your hardware/driver.

flag_use_ext_framebuffer_object  (optional, default autodetect: true, when extension is available)

Warning: when your video card/driver supports the OpenGL EXT_framebuffer_object extension, but does not support the OpenGL EXT_packed_depth_stencil extension, you can still use the EXT_framebuffer_object extension, but you will have no stencil buffer in viewport distortion mode. This results in bad drawing of the earth shadow during lunar eclipses. Currently only NVidia cards support EXT_packed_depth_stencil.

5) make the layout of the not yet distorted image configurable

distorter_max_fov     (maximum FOV value of the not yet distorted image, optional, default=175)
viewport_width        (width of the not yet distorted image, optional, default=screen_w)
viewport_height       (height of the not yet distorted image, optional, default=screen_h)
viewport_center_x     (center of the FOV-disk in the not yet distorted image, optional, default = 0.5*viewport_width)
viewport_center_y     (center of the FOV-disk in the not yet distorted image, optional, default = 0.5*viewport_height)
viewport_fov_diameter (diameter of the FOV-disk in pixels, optional, default=min(viewport_width,viewport_height))

6) The current set of parameters work well for configuration of a standard dome setup (where zenith, projector, dome center, mirror center and projector optical axis lie in a single plane). Yet I received lots of questions and even complaints about the parameters zenith_y and scaling_factor. Perhaps it was to not easy enough to understand their meaning and importance. Therefore I have decided to introduce additional parameters:

projector_alpha   (optional, default = 0)
projector_delta   (optional, default = whatever your zenith_y parameter implied)
projector_phi     (optional, default = 0)
image_distance_div_height (optional, default = whatever your scaling_factor implied)

projector_alpha, projector_delta specifies the direction of the projectors optical axis in degrees, projector_phi specifies how much the projector is turned around its optical axis. image_distance_div_height is focal length of the projector divided by the height of the projectors video chip, which is the same as the distance to the projected image divided by the projected images height. Because of the default values, your previous setup with zenith_y and scaling_factor will continue to work as usual. Yet I encourage migrating to the new parameters, which is easy, because the needed values are printed to stdout (you can read them in your xterm window). Windows users - if there are any - have some special file where they can read the standard output, I think it is called cout.txt, stdout.txt or similar.

7) With the above described parameters you can setup stellariums distortion feature for any planetarium with a spheric dome and a spheric mirror. The only restriction is that both the mirror and the dome have spheric shape. But even when the dome and/or the mirror are aspheric, you can use stellariums distortion feature by supplying a custom distortion grid using the parameter

custom_distortion_file  (optional, default="")

custom_distortion_file is not for the faint of heart. Only people who know what they are doing are supposed to use it. I will not support requests from people who do not understand what is going on.

When custom_distortion_file is supplied, the parameters projector_gamma, projector_position_x, projector_position_y, projector_position_z, mirror_position_x, mirror_position_y, mirror_position_z, mirror_radius, dome_radius, zenith_y, scaling_factor, flip_horz, flip_vert, texture_triangle_base_length, projector_alpha, projector_delta, projector_phi, image_distance_div_height have no influence on the distortion process any more. Instead the distortion is controlled by the contents of the given file.

The syntax of the custom_distortion_file is as follows: It contains integers or floats in decimal notation seperated by whitespaces. The first and second numbers are max_x, max_y (both integer). They discribe the dimension of the triangular distortion grid:

   const double step_x = screen_w / (double)(max_x-0.5);
   const double step_y = screen_h / (double)max_y;
   for (int j=0;j<=max_y;j++) for (int i=0;i<=max_x;i++) {
       vertex_x = (i == 0)
                ? 0.0
                : (i == max_x)
                ? screen_w
                : ((i-0.5*(j%2))*step_x);
       vertex_y = j*step_y;

vertex_x, vertex_y are the coordinates in the destination image. After max_x, max_y come (max_y+1)*(max_x+1) tuples of 5 numbers each. The 5 numbers are: x, y, r, g, b, all of them float. These are the texture coordinates and colors of the vertices given above. The texture coordianates are the coordinates in the fisheye image. The ranges are:

0 <= x <= viewport_width
0 <= y <= viewport_height
0 <= r,g,b <= 1

Remember that the bottom left corner has coordinates (0,0). Example custom_distortion_file for a 1024x768 viewport:

2 1
   0   0 1 1 1
 900   0 1 1 1
1024   0 1 0 0
   0 768 0 0 1
 100 768 1 1 1
1024 768 1 1 1

Related parameters when spheric mirror distortion is disabled. When these parameters are not supplied, you get the old behaviour:

fisheye_max_fov       (maximum fisheye FOV, optional, try 360)
cylinder_max_fov      (maximum cylinder FOV, optional)
viewport_width        (width of the image, optional, default=screen_w)
viewport_height       (height of the image, optional, default=screen_h)
viewport_center_x     (center of the FOV-disk, optional, default = 0.5*viewport_width)
viewport_center_y     (center of the FOV-disk, optional, default = 0.5*viewport_height)
viewport_fov_diameter (diameter of the FOV-disk in pixels, optional, default=min(viewport_width,viewport_height))
viewport_x            (offset of the viewport within the screen, default = 0.5*(screen_w-viewport_width)
viewport_y            (offset of the viewport within the screen, default = 0.5*(screen_h-viewport_height)
Personal tools
in this wiki
other languages