sholloway / agents-playground

MIT License
4 stars 0 forks source link

3D Lightning Models #117

Open sholloway opened 11 months ago

sholloway commented 11 months ago

There are a variety of 3D shading models. Create a small collection of models that can be applied to a rendering pipeline. Working through this should help establish the best practices for the shading pipeline (packing geometry, normals, lightning, etc). Ultimately I need a shading model that works for the 2D agent simulations.

Shading Algorithms

Building Blocks

Diffuse Reflection

Models that describe the perceived brightness due to diffuse reflection.

Specular Reflection

Models that describe the perceived brightness due to specular reflection.

Subsurface Scattering

Artistic

Physically Based Rendering (PBR)

TBD

Key Resources

sholloway commented 11 months ago

Flat Shading

Shading alters the colors of faces in a 3D model based on the angle of the surface to a light source or light sources. With flat shading the lighting is evaluated only once for each polygon (usually for the first vertex in the polygon, but sometimes for the centroid for triangle meshes), based on the polygon's surface normal and on the assumption that all polygons are flat. The computed color is used for the whole polygon, making the corners look sharp.

Resources

Algorithm

Calculate the amount of light on an entire face. For my needs a face is a triangle.

  1. Determine a normal vector to use for the entire face.
  2. Use normal to determine the amount of light for the entire face. At this point, different lightning algorithms could be used.

Calculating the Normal

There are a few options regarding getting the triangle's normal.

  1. Calculate surface normals in the fragment shader. vec3 normal = normalize(cross(dpdx(pos), dpdy(pos))); Notice that this is taking the cross product of the rate of change of the position in X and Y dimension.

  2. Pre-calculate the normal for the triangle and pass it in.

  3. Leverage the vertex normal for the first vertex (this may be incorrect) and pass it across the triangle's fragments using interpolate flat annotation.

sholloway commented 11 months ago

General Lightning Algorithm

There are 3 components to the general shading calculation

Ambient Light As ambient light is directionless, it interacts uniformly across all surfaces, with its intensity determined by the strength of the ambient light sources and the properties of objects' surface materials, namely their ambient reflection coefficients. Ambient light represents the light in an area that isn't direct. This prevents totally black shadows.

Diffuse Light The direct illumination of an object by an even amount of light interacting with a light-scattering surface. After light strikes an object, it is reflected as a function of the surface properties of the object as well as the angle of incoming light. This interaction is the primary contributor to the object's brightness and forms the basis for its color

Specular Light The specular lighting component gives objects shine and highlights. This is distinct from mirror effects because other objects in the environment are not visible in these reflections. Instead, specular lighting creates bright spots on objects based on the intensity of the specular lighting component and the specular reflection coefficient of the surface.

The final color is ambient + diffuse + specular.

Key Components

The angles between these vectors are the basis for computing light intensities. These angles typically need to be calculated in world coordinates because perspective transformations do not preserve the angles.

Key Properties

Calculating Diffuse Light Intensity

The general diffusion intensity D can be calculated as: Given:

Diffuse Intensity (D) = I d max(dot(s, m)/(|s| * |m|), 0)

If s and m are both unit vectors, then this can be simplified to: Diffuse Intensity (D) = I p max(dot(s, m), 0)

Calculating Specular Intensity

Diffuse spreads evenly across a surface but that isn't how things are lit in real life. A specular highlight component is added for realism. The different shading models take different approaches to calculating the specular highlight.

Putting it all Together

The final fragment light intensity L is calculated as follows. Given:

L = A a + D d lambert + S s * pow(phong, f)

Where,

lambert = max(0, dot(s, m)/(len(s) len(m))) phong = max(0, dot(h, m)/(len(h) len(m)))

sholloway commented 11 months ago

Phong Shading

In Phone shading the amount of light reflected is greatest in the direction of a perfect mirror reflection, the vector r. The vector r is the direction where all light would travel if the surface were a perfect mirror. The angle between r and the vector from the facet to the camera v is the angle of reflection.

The specular intensity S can be calculated as follows. Given:

First find the reflection vector r. r = -s + 2 dot(s, m)/square(len(m)) m

Then, use r to calculate the specular intensity. S = I q power(dot(unit(r), unit(v)), f)

Note: If the dot product of r and v are less than zero then the specular intensity is 0.

sholloway commented 11 months ago

Blinn-Phong Shading

Computing the vector reflection r is expensive. The Blinn-Phong approach is an optimization. Instead of using the cosine of the angle between r and v, one finds a vector h that is half-way between vectors s and v.

The half-way vector h can be calculated as follows. Given: s: The vector from the facet to the light source. v: The vector to the camera.

h = s + v

The angle between h and the normal vector m is used to measure the falloff of the specular intensity. This angle is larger than the angle between Phong's reflection vector r and the vector to the camera v. This can be compensated for by using a different value for the specular falloff parameter f.

Given all this, the specular intensity can be calculated as: S = I q max(0, power(dot(unit(h), unit(m)), f))

sholloway commented 11 months ago

Emissive Lightning

TBD

sholloway commented 11 months ago

Real-Time Ray Tracing

The Nvidia RTX chips now have dedicated hardware for raytracing.

Resources

VK_KHR_ray_tracing (https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#VK_KHR_ray_tracing)