Search code examples
math3dgeometrypseudocodelighting

Simple spherical lighting


Take a look at the sphere below, which we can assume is made up of polygons arranged in a sphere. Each polygon has an 'x' axis rotation, and a 'y' axis rotation, based on where it occurs on the sphere.

enter image description here

Imagine that there is a single light source. For the sake of demonstration that light source is casting light on the sphere at the indicated x and y axis rotation.

If the light 'amount' being received by any polygon was between 0-1 (1 being the 'brightest' point) How would one determine the brightness of any given polygon?

I had assumed that we take the y-axis-offset (how many degrees away the light source is from a polygon, compressed into a 0-1 value) and the x-axis-offset (as before), and use the average value to determine the brightness, but imagining this in my head it feels like this would cause a 'diamond' shaped light. Perhaps my assumption is wrong, and this is the correct understanding of lighting this sphere, but if not...

What is the correct process for determining the brightness of these polygons given this scenario?

I apologize if this question has already been asked, I was not able to find another example which articulates the question I have asked, particularly in simple terms. It's possible I am not using the right terms when searching, so perhaps that would be a sufficient answer?

Thanks in advance for any assistance

Edit: before I receive a selection of confusing, high-level mathematical formulas, please remember that I am not a maths major. a practical example, such as pseudo-code would be far more useful and relevant for readers on stackoverflow. thanks again


Solution

  • Any light formula I saw use dot product between normal to surface and light source direction.

    • if booth vectors are unit then the dot product will give you number <-1,+1>
    • which is also the cos(a) value where a is the shortest angle between vectors in N-D
    • 3D example:
    • normal: n(nx,ny,nz)
    • light direction d(dx,dy,dz)
    • cos(a)=dot(n,d)=(n.d)=(nx*dx+ny*dy+nz*dz)
    • now you can use the cos(a) to get the lighting information directly

    Illumination i of surface from cos(a)

    • i=cos(a);
    • if (i<0.0) i=0.0; // ignore negative result because light is in opposite direction
    • if you want non linear intensity change with light vs normal dot
    • then you can add:
    • i=a0+a1*i+a2*i*i+a3*i*i*i+...
    • a0 is ambient lighting (minimal illumination is bigger then zero)
    • a1 is linear coefficient
    • a2 is quadratic coefficient ,end so on
    • but you have to ensure that a0+a1+a2+...=1

    Illumination i of surface from a

    • a=acos(cos(a))=acos(n.d)
    • this gives you angle <0,2*PI>
    • so you need to shift the interval a bit
    • if (a>PI) a-=2*PI;
    • if (a<0.0) a=-a;
    • now you have abs angle between normal and light direction <0,PI>
    • i=1.0-(2.0*a/PI);
    • if (i<0.0) i=0.0;
    • now you have illumination index linear to normal to light direction angle
    • you can also add the coefficients now:
    • i=a0+a1*i+a2*i*i+a3*i*i*i+...

    Distance

    • some light formulas use dampening of light with traveled distance
    • so compute distance l between surface(rendered point) and light source
    • and add:
    • b=(b0+b1*l+b2*l*l+...)/I0
    • if (b<0.0) b=0.0;
    • if (b>1.0) b=1.0;
    • b is dampening coefficient 0 means no dampening, 1 means 100% light is removed
    • I0 is the light source strength
    • i*=(1.0-b);
    • there are many other ways to implement this ...

    Your case:

    • it is not clear if the light is in the center of sphere or in the outside
    • or what direction it has
    • for omni directional light source in the center the illumination will be 1 for whole inside surface without dampening of coarse
    • for generic light source position you can compute light direction (for omni directional sources)
    • just by substracting the light source and surface point positions
    • do not forget to make that vector unit
    • for directional sources the light vector is already given
    • normal can be obtained from surface polygon by cross product of any two non parallel vertices
    • the order affect the sign of vector so use the one you need (according to polygon winding)
    • in sphere the normal vector is also the surface position relative to sphere center so you can skip the above cross computation