🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

What is a Sun in game engines?

Started by
15 comments, last by Gnollrunner 3 years, 3 months ago

Hey,

so I started to make my own engine and right now I'm at the point where I would like to add a sun. I can load .obj files and use different shaders. I know how to do basic phong lightning and want to expand on that later on. Now this might be obvious but what is a sun inside an engine? In my mind the sun has to rotate around something. It also has to be visible even tho it's very far away. So the visibility depending how far away an object is has to be different for the sun compared to, say the world mesh. Is the sun an object (sphere) just like any other game object with a texture? Trying to google this has been a pain so I hope to get some information here.

Advertisement

Hi, for me, sun is a directional light source. The user of the engine can place directional lights just like any other light type, light point light, spotlight, area lights, etc. It has no mesh whatsoever. To visualize the "sun", I run a full screen shader when rendering the sky, and the sun on top of it is like a "specular highlight". The specular highlight is computed as if the sky was a sphere with normals facing inwards. Because this is a full screen shader drawn as a full screen triangle so there is no geometry information coming from vertex shader (although you could use a sphere geometry and interpolated normals too), the sphere normals are simply the per pixel view direction. There is a slight difference to specular highlights, as the sun disk will have a sharper edge, that is achieved by using smoothtep. Code for the sun disk only (pixel shader):

float2 clipspace : input from vertex shader, the position in clip space

float4 unprojected = mul(xInverseViewProjection, float4(clipspace, 0.0f, 1.0f));
unprojected.xyz /= unprojected.w;

float3 V = normalize(unprojected.xyz - xCameraPosition); // view direction
float sunAmount = distance(V, sunDirection); // sun falloff descreasing from mid point
float3 sun = smoothstep(0.03, 0.026, sunAmount) * sunColor * 50.0; // sun disc

The full screen effect is rendered in a pixel shader, because you also want to depth test the sky and only draw it for pixels that are behind all your geometry.

There is only 1 triangle rendered here, that covers the whole screen.

@turanszkij Thanks for this insigthful information. I have undersood most of what you said but I have a few questions if you don't mind.

Does this work for FPS cameras? I'm assuming you use a bigger texture and calculate what to show based on the view direction. I have seen an example of a “skyquad” but can't wrap my head around what happens when you look around in the sky. Especially when looking straight up, then turning 180° and looking down again. Is this a classic use case for a skybox?

The Idea of the sun being a “specular highlight” is very cool. It looks very nice btw, this is a beatiful sky.

This works perfectly for an FPS camera. I don't know what you mean by “I'm assuming you use a bigger texture and calculate what to show based on the view direction”. I am using a screen sized texture as the output (the render target). There is no input texture.

Don't you want to show different parts of the texture based on how you turn your camera? Otherwise the sky is always the same or do I missunderstand something? Like when you look north you see the sun but when you look south the sun is behind you.

All that you mentioned above just works when you provide the correct camera position (xCameraPosition) and camera matrices (xInverseViewProjection) to the shader. The sky I showed above is all procedural, so there are no textures involved.

I see. Thanks for the help I'll try to implement a cubemap as my sky and use this “specular highlight” to create my sun. This has been very helpful, again thanks.

Good luck with the implementation! If you are using a cubemap, you could use the “float3 V” value from my code above to sample the textureCube.

Going to high jack this thread somewhat since I'm working on the very same thing. I have a sube 1x1x1 with depth disabled. Here is my current code which does nothing:

float3 viewDirection = normalize(input.pos - input.cameraPos);
float sunAmount = distance(direction, input.pos);
float3 sun = smoothstep(0.03f, 0.026f, sunAmount) * radiance * 50.0f;

float3 skycolor = skybox.SampleLevel(sampleType, normalize(input.pos), textureLOD).rgb * environmentStrength;

float3 finalColor = sun * sunAmount + skycolor * (1.0f - sunAmount);

return float4(finalColor, 1.0f);

Right now it seems that where the sun disk is supose to be I see the skybox texture, but all other places it is just pitch black

Toastmastern said:

but all other places it is just pitch black

There are many different things.

There's a display object that hangs in the sky.

There's ambient lighting, often used to avoid pitch black displays or in simple lighting systems. Looks like you missed this.

There's the universal directional light applied to things that are lit in simple models. It looks like you forgot this part too.

There's cast shadows, used in more complex lighting systems.

There's darkness when indoors or underground.

There's also point light and spotlights, and more advanced surface lights and “cookie” shapes (named from real world cutouts over spotlights). But these usually aren't used as ‘the sun’.

This topic is closed to new replies.

Advertisement