Swiftorial Logo
Home
Swift Lessons
Matchups
CodeSnaps
Tutorials
Career
Resources

Lighting and Shading in 3D

1. Introduction

Lighting and shading are crucial elements in 3D game development that define the look and feel of a scene. They help create mood, define space, and enhance realism.

2. Types of Lighting

Understanding different types of lighting is essential for effective 3D rendering. The main types include:

  • Ambient Light: Provides a base level of illumination, simulating indirect light.
  • Directional Light: Simulates sunlight, casting parallel light rays in a specific direction.
  • Point Light: Emits light in all directions from a single point, similar to a light bulb.
  • Spotlight: Emits light in a specific cone shape, often used for focused lighting effects.
Note: Each type of light has unique properties and uses, affecting performance and visual quality.

3. Shading Techniques

Shading techniques determine how surfaces interact with light. Common techniques include:

  • Flat Shading: A simple technique where each polygon has a single color and normal.
  • Gouraud Shading: Calculates vertex colors and interpolates them across the surface.
  • Phong Shading: Computes pixel colors based on the light source position and surface normals, providing a more realistic appearance.
Tip: Phong shading is more computationally intensive but yields better visual quality.

4. Implementation

Here’s a basic example of a Phong shading implementation using GLSL (OpenGL Shading Language):


                #version 330 core
                in vec3 FragPos;  
                in vec3 Normal;  
                out vec4 color;

                uniform vec3 lightPos;  
                uniform vec3 viewPos;  
                uniform vec3 lightColor;  
                uniform vec3 objectColor;  

                void main() {
                    // Ambient
                    float ambientStrength = 0.1;
                    vec3 ambient = ambientStrength * lightColor;

                    // Diffuse
                    vec3 norm = normalize(Normal);
                    vec3 lightDir = normalize(lightPos - FragPos);
                    float diff = max(dot(norm, lightDir), 0.0);
                    vec3 diffuse = diff * lightColor;

                    // Specular
                    float specularStrength = 0.5;
                    vec3 viewDir = normalize(viewPos - FragPos);
                    vec3 reflectDir = reflect(-lightDir, norm);
                    float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
                    vec3 specular = specularStrength * spec * lightColor;  

                    vec3 result = (ambient + diffuse + specular) * objectColor;
                    color = vec4(result, 1.0);
                }
                

5. Best Practices

To achieve optimal results in lighting and shading:

  • Use a balanced combination of light types to create depth.
  • Optimize the number of lights in a scene to enhance performance.
  • Experiment with different shading models to find what fits your art style.
  • Utilize baked lighting for static objects to improve rendering speed.

6. FAQ

What is the difference between real-time and baked lighting?

Real-time lighting adjusts dynamically as objects move and change, while baked lighting is pre-calculated and stored in textures, which improves performance but lacks flexibility.

How can I improve performance when using multiple light sources?

Use techniques such as light culling, limiting the number of dynamic lights, and employing baked lighting for static elements in your scene.