Showing posts with label Essentials. Show all posts
Showing posts with label Essentials. Show all posts

Saturday, July 16, 2022

Primer:Lighting

Overview 
Lighting is an important factor to consider while rendering realistic 3D shapes.  The following discusses adapting lighting conditions while rendering 3D images.

Details
According to physics, visible light is made up of a band of different wavelengths. Each segment has a designated color that human eye can detect.


When light is shone on an object, it absorbs some wavelengths and reflects some giving out the color based on the material property of the object. 
The reflection is different based on its proximity to the light source and the angle between its position and  the light source. Therefore light calculations should factor these.

The calculations primarily considers three kinds of light sources.

Ambient
Ambient light means that light always existed in absence of a light source. Imagine a unlit room next to the street where light is coming in from a street lamp through the window bouncing off the walls onto curtains, furniture etc. It's dark, yet curtains, furnitures etc are visible albeit not clearly.
This pictorially represented as below

To calculate the amount of ambient reflection (I) on a surface,  the formula below is used.
I = Ka  ∑ Ia

Ka  is the ambient reflection coefficient that ranges from 0 to 1. Higher the value stronger is the reflection.

Ia  is global ambient intensity of the individual light source.

Example:
In this example, the Red light falls on Gray object. Here the 3rd image shows ambient lighting of the the back face of the sphere where lighting is same everywhere.


Diffused Light
Diffused light means that directional light that is reflected equally irrespective of user view point. 


The effectiveness of the reflection depends on the angle of incidence and the surface normal. In other words, the cross product of both. The lesser the value, higher is the reflection.
This pictorially represented as below. 



To calculate the amount of diffuse reflection (I) on a surface,  the formula below is used.
I = Kd Id (n.L)

Kd  is the diffuse reflection coefficient that ranges from 0 to 1. Higher the value stronger is the reflection.

Id  is the diffuse intensity of the light source.

(n.L) is the cross product of the surface normal n and light incident on the surface.

Example:
In this example, the red light falls on Gray object. Here the 3rd image represents the back face of the sphere where lighting is poor because of angle of incidence.
Specular Light
Specular light applies to smooth and polished surfaces that readily reflect light. When light hits the shiny surface it forms bright highlights.Here the reflection is targeted and is perpendicular to the angle of incidence in the opposite direction. A viewer can see only if in exactly the right position, somewhere along the path of the reflection r. 
Specular reflection from a very shiny surface produces very narrow cones of reflected light;
specular highlights on such a material are small and sharp. A duller surface will produce wider
cones of reflected light.


Specular reflection can be calculated as follows.
I = Ks  Imax(0,(v⋅r))ᵖ
Ks is the specular reflection coefficient to determine how strong or weak the specular reflection appears.
I is the brightness of the light source illuminating the surface.
is (2 (l . n) n) - l
(v⋅r) is the cross product between the observer's line of view and the direction of the reflected light.
p is known as the Phong Exponent. As p increases, the light cone becomes narrower (because r⋅e ≤ 1), the highlighted spot becomes smaller.
max(0,(v⋅r))ᵖ controls the size and sharpness of the specular highlight, making it more or less focused depending on the value of p.  The max returns 0 is returned if the v.r is negative.

Example
In this example, the White light source falls on Gray object. The 3rd image shows the specular reflection. 


Emissive Light
Some surfaces such as ovens, TV screens etc may emit light. It's independent and can be directly factored. Emissive lighting represents a self-luminous glow that is additive, meaning it is added on top of the results of ambient, diffuse, and specular lighting.

I = KeIe
Ke is emissive light value.
Ke is emissive light intensity.

The following example shows a sphere with emissive lighting.
Material
As discussed earlier materials absorb some light wavelengths and reflect back remaining. Illumination models should also consider these in the calculations of ambient, diffuse and specular. In other words, three separate material reflection color, one each for ambient, diffuse and specular should be used for realistic renderings.

Phong Lighting Model
This combines all the three models discussed above - Ambient, Diffuse,Specular and attenuation.
The combined formula combines  all the three
I = KaIa  +  KdId(n.L)KsIs(max(0,v⋅r)ᵖ)KeIe

The image below combines ambient,diffuse and specular reflections resulting in highlight and the curvature.

Blinn Phong Lighting Model
This combines all the three models discussed above - Ambient, Diffuse and Specular same as Phong lighting model except specular component is calculated using the halfway vector h.

The combined formula combines  all the three
I = Ka∑Ia + KdId(n.L) + KsIs(max(0,v⋅h)ᵖ)
h is (l+v) / |l+v|   




The image below combines ambient,diffuse and specular reflections resulting in highlight and the curvature.

These are the other light sources used to create realistic rendering.

Directional Light
Directional light refer to light sources such as sun where light reaches the objects irrespective of their location. Here the light source is assumed to be infinitely distant and intensity is same. Also the light rays are parallel to each other and are unidirectional.
In other words, Directional lights have only color and direction, not position. 


The following example displays an directional light such as tubelight.


Point Light
Point light emits light equally in all directions and also they have a position. Point lights have color and position within a scene, but no single direction.
However they suffer from attenuation where light gets waker over the distance. 
Attenuation reduces light intensity based on distance, making objects further from a light source appear dimmer. Attenuation has no impact on ambient light. Attenuation is calculated as below.

d: Distance between the light source and the point on the surface.
Kc: Constant attenuation (usually 1.0) to prevent division by zero or small numbers.
Kl: Linear attenuation (reduces intensity proportionally to distance).
Kq: Quadratic attenuation (reduces intensity proportionally to the square of the distance, simulating physical reality).

The light bulb below illustrates a point light.


Spot Light
A spotlight is a light source that radiates light in a cone shape from a single point in a specific direction, designed to simulate real-world lights like flashlights or stage spotlights. This effect is achieved through a two-cone system that defines the intensity, producing a bright center and a soft, fading edge.
Spotlights have color, position, and direction in which they emit light.


Notice that color is brightest in the center and gradually fades outwards.

In order to calculate the fading, cosine value of the directional vector of the light and the vertex under the cone is used. Naturally as angle increases the cosine value decreases.


The below spot light illustrates it.





Sunday, July 10, 2022

Primer: Graphics Pipeline

Overview
Modern OpenGL supports many different primitives  such as Points(GL_POINTS), Triangle(GL_TRIANGLE)  and Line Strip (GL_LINE_STRIP) etc. as shown below.


A scene consists of one or more 3D objects.  The shapes of these 3D objects are typically described using primitives.  For example, the 3D wire frame of a rabbit below is represented as hundreds of triangles.
These triangles are in turn are defined by their vertices. A vertex is the corner of the triangle where two edges meet, and thus every triangle is composed of three vertices. 

Note that this tutorial focuses only on 3D shapes rendered as  triangles.

Details
In OpenGL, the Graphics pipeline is responsible for rendering 3D objects. The following gives a brief overview without over burdening with the complex  details. As you get familiar, this can be revisited to gain a deeper understanding.

FrameBuffer
The output of graphics pipeline ends up in Framebuffer. Framebuffer is piece of memory within the graphics card that maps to the display. For simplicity, you can assume that it's like a bitmap covering entire viewport. Double framebuffers are used to avoid screen tearing while rendering the scene. For example, after the first frame of a scene is written by the pipeline into framebuffer, it's drawn on the screen while the framebuffer2 is filled with the second frame of the scene. Then it's swapped with the first so that  the screen now displays the second frame while third frame is written in to the framebuffer etc.

OpenGL  Graphics pipeline
OpenGL provides a multi-stage graphics pipeline that is partially programmable using a language called GLSL (OpenGL Shading Language) as shown below. Each of these programmable units are called shaders.


To kick off this chain, the C++ application supplies vertex data consisting of  vertices. 
The vertex data for each vertex maps to the following information:

Position
This is a mandatory input. It represents the X, Y, Z coordinate of the vertex.  As discussed earlier it contains double values.
Each position is represented as a vector of 3 doubles.

Color
This is an optional input. It represents RGBA color of the vertex. RGBA stands of Red Green Blue Alpha. The values are double values. The range goes from 0 to 1. 
To generate different colors such as fuchsia, violet etc, an unique different values are supplied to the RGB components.
However, the Alpha component represents transparency.  A value of 1 makes the vertex completely opaque and replaces background vertex. Similarly, a values 0 makes it completely transparent. Intermediate values makes the vertex blend with background. 
Each color is represented as a vector of 4 doubles. However in practise, only RGB values are sent. The alpha component is hardcoded in the Fragment shader.

Normal
This is an optional input. It represents the normal vector of the vertex. Normals are used in the lighting calculations. 
Just like Position, Normals are represented as X,Y,Z coordinates and hence represented as a vector of 3 doubles.

Texture
This is an optional input. It represents 2D texture coordinates of the vertex. 
Texture coordinates are represented as UV coordinates and hence represented as a vector of 2 doubles.

The vertex data is first fed to the vertex shader.

Vertex Shader
This stage is mandatory. A vertex shader is a graphics processing function used to add special effects to objects in a 3D environment by performing mathematical operations on the  vertex's data. Vertex Shaders don't actually change the type of data; they simply change the values of the data, so that a vertex emerges with a different color, different textures, or a different position in 3D space.

Tessellation Shader
This stage is optional and not available to OpenGL release 3.3.  After the vertex shader has processed each vertex’s associated data, the tessellation shader stage will continue processing those data, if it has been activated. Tessellation uses patches to describe an object’s shape, and allows relatively simple collections of patch geometry to be tessellated to increase the number of geometric primitives providing better-looking models. The tessellation shading stage can potentially use two shaders to manipulate the patch data and generate the final shape.

Geometry Shader
This stage is optional. Allows additional processing of individual geometric primitives, including creating new ones, before rasterization. This shading stage is also optional, but very powerful.

Rasterization
The primitive assembly stage organizes the vertices into their associated geometric primitives in preparation for clipping and rasterization. Clipping removes all pixels outside of the viewport.
After clipping, the updated primitives are sent to the rasterizer for fragment generation. Consider a fragment a candidate pixel, in that pixels have a home in the framebuffer, while a fragment still can be rejected and never update its associated pixel location. Processing of fragments occurs in the next two stages, fragment shading and per-fragment operations.

Fragment Shader
This stage is necessary for the practical reasons. Fragment shader determines the fragment’s final color , and potentially its depth value. Fragment shaders are very powerful as they often employ texture mapping to augment the colors provided by the vertex processing stages. A fragment shader may also terminate processing a fragment if it determines the fragment shouldn’t be drawn; this process is called fragment discard.

Pixel Operations
A fragment’s visibility is determined using depth testing (also commonly known as Z-buffering) and stencil testing. If a fragment successfully makes it through all of the enabled tests, it may
be written directly to the framebuffer, updating the color (and possibly depth value) of its pixel, or if blending is enabled, the fragment’s color will be combined with the pixel’s current color to generate a new color that is written into the framebuffer.

In the next post we will discuss the nitty gritty of rendering a cube.

Saturday, July 9, 2022

Primer: Matrices and Affine transformations

Overview 
OpenGL uses matrix operations for a lot of purposes. For example, translations, scaling, rotations. Also computing of projection matrices, view matrices etc. The following discusses it in detail.

Details
Cartesian Coordinate System
OpenGL uses Right hand side coordinate system where +Z is pointing towards you.
In OpenGL, the position values of x,y,z coordinates are represented as doubles. The origin is centered at 0,0,0. The ranges of x,y,z axes goes from -1 to +1.  
For example, the left top corner would be represented as -1,+1,-1 and so on. In other words, a value 0.5 would be halfway between the origin and positive maximum of the axis. Similarly a value -0.5 would be halfway between the origin and negative maximum of the axis

Pitch, Yaw and Roll
A 3D object can rotate along all the three axes as shown below. 
Rotation along X Axis is called Pitch. Rotation along Y Axis is called Yaw. Rotation along Z Axis is called Roll

The following diagram shows how the positive rotation happens in Counter clockwise direction.
        Pitch(X Axis)                                    Yaw (Y Axis)                                  Roll (Z Axis)


Homogeneous coordinate system 
OpenGL uses 4x4 matrix used in homogeneous coordinate system as shown below.
Each coordinate is represented as [x,y,z,w].Where w=1 for the affine transformations such as  translations, scaling, rotations. W can be any floating point number in the range -1.0 to 1.0 for projection matrices. During rasterization x, y, z coordinates are computed as  x/w, y/w and z/w. This is known as perspective divide.

OpenGL uses columnar matrix multiplication as shown below.

Identity Matrix
A special matrix having all elements along diagonal as 1 as shown below. 
It is associative, I*M = M*I = M. It's used in the computation of rotation, translation and scaling as discussed below.
Affine transformations
Affine transformations are applied to 3D objects to perform operations such as Translation, Scaling or Rotation on the X,Y,Z axes. Note that  rotation happens independently  on three cardinal axes X, Y, and Z. This can be calculated from this link.

Unlike projective transformation which may distort the shape, affine transformations preserve Lines, Parallelism and Ratio of Distances. 
The following affine transformations are discussed.

Translation 
Translation matrix is used for moving around 3D objects.

Example:
Let's say there is a point [1,2,3] and want to translate by [4,5,6]. It can be accomplished as below. Resulting in  [5,7,9].


Scaling
Scaling operation can be performed to Shrinking or Expanding 3d objects.

Example:
Let's say there is a point [1,2, 3] and want to  scale by [2,2,2]. It can be accomplished as below. Resulting in  [2,4,6].


Pitch or Rotation on X axis
The following matrix represents rotation matrix on X axis.

Example:
Let's say there is a point [1,2, 3] and want to  rotate by 90 degrees in X axis. It can be accomplished as below. Resulting in  [1,-3,2].


Yaw or Rotation on Y axis
The following matrix represents rotation matrix on Y axis.

Example:
Let's say there is a point [1,2, 3] and want to  rotate by 90 degrees in Y axis. It can be accomplished as below. Resulting in  [3,2,-1].


Roll or Rotation on Z  axis
The following matrix represents rotation matrix on Z axis.

Example:
Let's say there is a point [1,2, 3] and want to  rotate by 90 degrees in Z axis. It can be accomplished as below. Resulting in  [-2,1,3].












Primer: Vectors

Overview 
vectors are widely used  in 3D calculations. The following discusses it in detail.

Details
A 3D vector is represented as [Vx, Vy,  Vz] where  Vx, Vy and Vz represent numbers in 3D cartesian space. Vectors are attributed with a direction represented by its head  and a magnitude computed as square root of the squared sums of its components.

Unary negation and scalar multiplication 
The  negation and multiplication is done on all the components.
For example consider a vector
v=[1,2,3] so  2*v results in [2,4,6]. Similarly -v results in [-1,-2,-3].

Addition and Subtraction
Vectors can be added or subtracted. Here the individual components are added or subtracted. 
For example consider two vectors  A[1,2,3] and B[4,5,6]. 
A+B = [(1+4), (2+5), (3+6)] = [5, 7, 9].
A-B =  [(1-4), (2-5), (3-6)] = [-3, 3, -3].
Graphically represented as below, Note that the direction has changed  when arguments are reversed.
Unary Vectors
Also known as normalized vectors are represented as V^  have magnitude of 1. 

For Example V = [3,2,1]. It's normalized vector is calculated as
[2,3,1]/sqrt(4+9+1) = [3/3.74, 2/3.74, 1/3.74]=[0.8, 0.53, 0,27]




Dot Product
Dot Product of  two vectors is equal to the product of their magnitudes and the cosine of the angle between them. The notation used is a.b where a and b are vectors. It's mathematically represented as
a ·b = |a| x |b| x cos(θ).
It's graphically represented as 




To compute angle between two unit vectors, mathematically it can be represented as

The dot product may be a positive  or a negative or a zero based on the direction of the vectors.

Cross Product
Cross Product of  two vectors is equal to the product of their magnitudes and the sine of the angle between them. The notation used is axb where a and b are vectors.
Mathematically it's represented as

Cross product yields a vector that is perpendicular to the plane of two vectors a and b. Graphically it's represented as



The cross product of two vector is equal to area of their parallelogram.