Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I was wondering how does the stars in night time in minecraft work, are they point sprites? And are they placed on a texture or just randomly placed on some far away location.

EDIT 1:

OK, well, with the imformation gathered concerning the minecraft skybox I now know that the stars are not directly textured onto a sphere but are individial quads placed some set distance (the radius of the sphere) from the player.

The problem is now I will I go about getting a random position on that sphere (not in it and not too far out of it). And how will I get rotation for it to face the player? One user suggested normalising a random Vector3 then multiplying it by the spheres radius which I think, simply won't work. Also another suggested that I use the formular: "1 = x^2+y^2+z^2", I don't know how I would use this to find a random position on a sphere either.

EDIT 2:

OK, I haven't tested this or anything but from all the imformation gathered from PrinceCharles anwser it should be something like this:

            float x = (float)random.NextDouble() * 2 - 1;
            float y = (float)random.NextDouble() * 2 - 1;
            float z = (float)Math.Sqrt((double)(1f - x * x - y * y));

            Vector3 randomPoint = new Vector3(x, y, z);

            if (randomPoint.Length() != 0)
            {
                randomPoint.Normalize();
                Vector3 pointOnSphere = randomPoint * radius;

                                  // Position     Rotation
                stars.Add(new Star(pointOnSphere, new Vector3(0, 0, 0)));
            }

The reason for the "* 2 - 1" is to give the random a range of -1 to 1. I think that is correct...

EDIT 3:

One side of the map:

enter image description here

The other:

enter image description here

Any ideas?

Thanks :)

share|improve this question

3 Answers 3

up vote 3 down vote accepted

You want hemisphere point picking, which is not trivial to get right.

It is incorrect to pick uniform x, y and z coordinates and normalise them.

It is also incorrect to pick uniform angle values.

I believe the less computationally expensive method is derived from Marsaglia’s sphere point picking algorithm:

float x1, x2, p, q;
do
{
    x1 = (float)random.NextDouble() * 2.0f - 1.0f;
    x2 = (float)random.NextDouble() * 2.0f - 1.0f;
    p = x1 * x1 + x2 * x2;
} while (p > 1.0f);
q = 2.0f * sqrt(1.0f - p);

return Vector3(x1 * q, x2 * q, abs(1.0f - 2.0f * p));

Note: if you get rid of the abs() you get full sphere picking, which might be useful, too.

share|improve this answer
    
Are you sure you got the formula right? I think for q you would have to use q = 2.0f * sqrt(1.0f - x1 * x1 MINUS x2 * x2); –  PrinceCharles Jan 22 '12 at 7:13
    
@PrinceCharles: you are right, but that is precisely 2.0f * sqrt(1.0f - p). –  Sam Hocevar Jan 22 '12 at 12:06
    
p = x1 * x1 PLUS x2 * x2 PLUS != MINUS ;-) –  PrinceCharles Jan 22 '12 at 20:06
    
@PrinceCharles 1 - (A + B) is 1 - A - B. –  Sam Hocevar Jan 23 '12 at 1:22
    
Darn, math is a bitch sometimes... my deepest apologies! thx for pointing out! Can you explain why points with p > 1 in algorithm above are ruled out? –  PrinceCharles Jan 23 '12 at 6:52

They're not point sprites because of:

  • Minecraft doesn't used GLSL, and you can't easily do variable sized (or rotated) point sprites without shaders.

  • Point sprites can't be partially clipped at the edge of a screen, while Minecraft's stars can be.

They're just boring old white polygons placed camera facing as if on the inside of a sphere with a bit of blending. Nice effect.

share|improve this answer
    
Wow, really? So then how did he texture them on to a sphere, it is curved O_O. Also I thought shaders had to be used for the lighting... –  Darestium Dec 24 '11 at 4:38
2  
They're not textured, each star is an independent white coloured quad. Placing them on a sphere is just a matter of choosing random points that match the equation for the surface of a sphere: wolframalpha.com/input/?i=x%5E2%2By%5E2%2Bz%5E2%3D1 . Shaders don't have to be used for lighting, the old OpenGL fixed pipeline supports a handful of lighting modes, and up to 8 lights. –  Michael Dec 24 '11 at 5:07
    
So how would i check if an object fails on the bounds of a circle? –  Darestium Dec 24 '11 at 6:58
5  
I'm horrible at math ( and programming :) ) so this may be incorrect, but couldn't just make Vector3 of the x, y and z values and then normalize it. After that you could multiply that normalized vector by the radius of the sphere you want those stars/whatever to be in. –  Jaakko Lipsanen Dec 24 '11 at 16:02
1  
@JaakoLipsanen That approach will work, but will result in fewer stars near the axes than in the corners, and it'll be quite noticeable if you have a lot of stars. You'll get a more uniform distribution if you randomise the angles used to generate positions, instead of the explicit position. –  Trevor Powell Jan 18 '12 at 9:36

Probably just part of your question:

The mathematical definition of a unit sphere (e.g. 1 unit radius) is 1 = x² + y² + z²

Therefore to find a random point on a sphere you can choose any two of the variables in that equation and calculate the third. What's important here is, that x,y,z must be in the range of -1 to 1 - As mentioned the sphere has radius 1.

So lets say i randomly chose x = 0.5 and y = -0.75 then to calculate z we have to solve:
z = SQRT(1 - x² - y²)
z = SQRT(1 - 0.5² - 0.75²)
z = SQRT(1 - 0.25 - 0.5625)
z = SQRT(0.1875)
z = 0.4330

This vector (0.5, 0.75, 0.433) lies on a sphere with radius 1 and can then be multiplied by any scaling factor to get a point on a bigger/smaller sphere.

Hope that helps!

EDIT 1:

I haven't tested this either but from what Kevin Reid and BiAiB mentioned this will give you a uniformed distribution (over a whole sphere):

        float x = (float)random.NextDouble() * 2 - 1;
        float y = (float)random.NextDouble() * 2 - 1;
        float z = (float)random.NextDouble() * 2 - 1;

        Vector3 randomPoint = new Vector3(x, y, z);
        if(randomPoint.Length() != 0)
          Vector3 pointOnSphere = randomPoint.Normalize();

To find a point on a half sphere (depending on your orientation of the world) choose one coordinate from 0 to 1:

        float z = (float)random.NextDouble();

To get a bigger/smaller sphere multiply the Vector3 with the desired sphereRadius

          Vector3 pointOnSphere = randomPoint.Normalize() * sphereRadius;
share|improve this answer
1  
This will not produce a uniform distribution of points — the sphere will have an ‘equator’ of fewer points. The way to do it right is this: pick x, y, z randomly between -1 and 1; if they are all 0 or if x² + y² + z² > 1 then try again, else normalize (divide by √(x² + y² + z²)). –  Kevin Reid Jan 19 '12 at 18:37
    
Why would there be an equator? Of course you would have to pick which two of x,y,z to calculate the third at random as well. But picking 3 random coords (which basically lie on a sphere with radius √(x² + y² + z²) and normalizing them is probably an even better method! –  PrinceCharles Jan 20 '12 at 6:10
    
there would be an equator, It's easier to figure out on 2d half circle: pick equally distant points on diameter, project them on the circle: the distance between projections will be closer over the "middle" of the diameter and more far around the diameter circle intersection. You can solve this with normalization like Kevin Reid suggested or using random spherical coordinates. –  BiAiB Jan 20 '12 at 10:37
    
but when we thought about it, our earth sky has more the equator distribution that the uniform –  BiAiB Jan 20 '12 at 10:39
    
I added some code based on your idea in the main post, hope it is correct :) –  Darestium Jan 21 '12 at 4:16

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.