I'm a non-astronomer, but I'm working on a project for which I need to produce CGI renderings of as complete a starfield as I can find. The latest Gaia catalogue release has an impressive 1.5 billion sources with photometry, so I'd like to use that. However, I'm struggling with figuring out how to convert the photometry data into rgb colour values. My understanding is that the sources are photographed through bandpass filters which each transmit a particular range of frequencies, and that this can be used to determine the colour temperature of the stars, but I don't know which pieces of data I need or what formula I need to convert them into colour values or temperatures.

I think that the following fields in the dataset are probably what I need:

  • phot_g_mean_mag: G-band mean magnitude (float, Magnitude[mag])
  • phot_bp_mean_mag: Integrated BP mean magnitude (float, Magnitude[mag])
  • phot_rp_mean_mag: Integrated RP mean magnitude (float, Magnitude[mag])
  • bp_rp : BP - RP colour (float, Magnitude[mag])
  • bp_g : BP - G colour (float, Magnitude[mag])
  • g_rp : G - RP colour (float, Magnitude[mag])

Is it as simple as stuffing the G mean magnitude into the green channel, the BP into the blue and the RP into the red?

I'd welcome any advice on how to go about doing this, or links to resources or code that does something similar. I don't need the results to be scientifically accurate, just visually plausible.

  • 1
    $\begingroup$ In this context, "G" means "Gaia", not "green". It's actually a "white light" band, meaning it's basically blue + green + yellow + orange + red + (a tiny bit of) near-infrared. $\endgroup$ Sep 9, 2021 at 9:32
  • $\begingroup$ @PeterErwin Thanks! I eventually figured that out after some more skimming of Gaia-related papers. So: G = white light (absolute visible magnitude) BP = Blue Photometry RP = Red Photometry ? $\endgroup$
    – Niall
    Sep 9, 2021 at 14:52

2 Answers 2


My other answer was probably unnecessarily complicated and not at all Straightforward. I suggest you use instead the Gaia DR2 database, which contains 161,497,595 sources with an estimate of the effective temperature, according to this documentation page.

From the effective temperature, you can obtain the RGB values of the black body spectrum directly from the software you are using, as you have said.

  • $\begingroup$ This would definitely be simpler, but I still appreciate the complete answer you originally posted! $\endgroup$
    – Niall
    Sep 10, 2021 at 15:35

Color is a difficult matter. I anticipate that there is no unique solution to your question, and that things can get arbitrarily complicated the deeper you dig into the problem.

In order to present the correct color of the stars in your rendering, you have to account for many different "layers" of representation of the color.

  1. The spectrum of the star, which is a continuum function of the wavelength.
  2. The Gaia filters, that transform the continuum spectrum in a finite set of magnitude values for some bands.
  3. The RGB color, that describes the color with three real numbers.
  4. The way a display converts an RGB color into an electromagnetic spectrum. Which will be utterly different than the original spectrum of the star.
  5. The way your eye perceives the color (with three different receptors) and the way your brain processes this information.

Each step encodes the color of the previous step in a different way. But each encoding loses information and you can't do anything about it. Additionally, you have direct control only on the step from 2 to 3. You can only (educately) guess what was the original spectrum of the star and guess what will be the perceived color at the end. Your task it to associate an RGB value to each Gaia filter measurement such that when a user looks at the monitor, they will perceive a similar color to the one they would have perceived if they had looked directly at the star. A daunting task! We'll have to make lots of approximations and assumptions.

Let's start by looking at Gaia's filters

Gaia filters passband Credits: ESA/Gaia/DPAC, P. Montegriffo, F. De Angeli, M. Bellazzini, E. Pancino, C. Cacciari, D. W. Evans, and CU5/PhotPipe team

This figure shows the transmissivity of the filters as a function of the wavelength. The green curve is the G filter. It encompasses all the visible range and also some near infrared (NIR). The blue curve is the BP filter, that covers all the visible range. The red curve is the RP filter, that covers the red part of the visible, but is mostly sensitive to near infrared. As you can see, G, BP and RP do not correspond to green, blue and red.

Let's compare this with the response function of the human cone cells:

normalized response of the human cone cells

Credits: BenRG

S (short) is usually associated with blue, M (medium) is often associated with green and L (long) with red. But as you can see this association is far from perfect. S actually peaks in the violet and both M and L span a large range from green to red.

They are totally different from Gaia's filters. This means that Gaia's "eyes" see color in a different way than human eyes. The two signals are not directly comparable.

What we could do instead, is estimate the shape of the original spectrum, from Gaia's data. Then we could calculate how such spectrum would be perceived by a human eye.

Estimating the original spectrum

The spectrum of a star can be complicated, full of absorption lines that depend on the temperature and composition. It can also be modified by radial motion (redshift), dust extinction and emission. I will ignore all the details and assume that the spectrum is a perfect black body. This is nice, because a black body spectrum is determined from its temperature $T$ only, so we need to estimate just one parameter.

Given a transmission function $t_W(\lambda)$ (the ones in the first picture) of a filter $W$, and the flux of a star $F(\lambda)$, the flux registered in the telescope through the filter will be

$$F_W = \frac{\int_0^\infty F(\lambda) t_W(\lambda)d\lambda}{\int_0^\infty t_W(\lambda)d\lambda}$$

From this page you can download a file that contains the shape of Gaia's transmission function. Or you can just approximate them with a constant value inside an interval and with zero outside.

As I said, you can use Planck law for the source flux, where $T$ is the temperature and $\epsilon$ is a normalization constant that depends on the brightness of the source.

$$F(\lambda; T, \epsilon) = {\epsilon \over \lambda^5} \frac{1}{\exp(\frac{hc}{\lambda k_B T})-1}$$

Let's say that a given filter $W$ measures a magnitude $m_W$ for a given star. You will first need to convert the magnitude to a flux $F_W$, and then you will need to find the values of $T$ and $\epsilon$ that minimize the function $$f_W(T,\epsilon) = \left| F_W - \frac{\int_0^\infty F(\lambda; T, \epsilon) t_W(\lambda)d\lambda}{\int_0^\infty t_W(\lambda)d\lambda} \right|$$

Feel free to use your favorite minimization algorithm :)

Actually, you have three values to minimize, not just one, because Gaia tells you the readings of three filters. At this point I suggest you keep it simple and just minimize the sum of the squares of the three function:

$$f_G(T,\epsilon)^2 + f_{BP}(T,\epsilon)^2 + f_{RP}(T,\epsilon)^2$$

If the result is not satisfactory, then you can start to mess with maximum likelihood or Bayesian inference, but I'd leave it for another time.

Finding the RGB values

Now that you have the spectrum, things could get difficult. With a generic spectrum, you'd have to calculate the values of the XYZ coefficients of the CIE 1931 color space, and then convert them to the RGB coefficients of the sRGB color space.

But I have suggested to work with black bodies for a reason. This conversion from the spectrum to the RGB has already been done for the black body, and the results are tabulated. You can find the values for example here, or in many other places on the web.

You can even use the $\epsilon$ coefficient that you have found to set the brightness of the stars in your CGI software.

All is left to do is hope that layers 4 and 5 work as intended: e.g. that the monitor of your final users will display sRGB colors correctly and that your users won't be color blind ;)

I hope that this explanation has not discouraged you to the point of deciding to use the following algorithm, instead

R = random.uniform(0,255)
G = random.uniform(0,255)
B = random.uniform(0,255)

If you want some clarifications, feel free to ask.

  • $\begingroup$ Thank you! The simulation and rendering software I use actually has a blackbody function that will convert a temperature in K to an RGB value. I've used it for rendering sparks, etc in the past, and it'll work perfectly for this. Unfortunately, the math in the "Estimating the original spectrum" section is a little bit beyond me, so any further clarification (or pointers to reference on the topic) you can provide there would be much appreciated! $\endgroup$
    – Niall
    Sep 9, 2021 at 17:52
  • $\begingroup$ @Niall I think that the easiest way could be to use the 161,497,595 sources that already have a computed effective temperature inside Gaia DR2 catalogue. I'm sorry, this answer was an overkill $\endgroup$
    – Prallax
    Sep 9, 2021 at 18:30
  • $\begingroup$ @Niall I have posted another answer, but I will keep this one, just in case I am trapped on a desert island with an hard drive filled only with EDR3 photometry data and no precalculated effective temperatures. (And also a pc, electricity and this SE page cached in my browser) $\endgroup$
    – Prallax
    Sep 9, 2021 at 18:48

You must log in to answer this question.

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