www.xbdev.net xbdev - software development
Saturday December 15, 2018
home | about | contact | Donations

     
 

Slice of Java.

Its simple and its powerful...

 

 

 

Simple Lighting - Bring our world to life

by Ben Kenwright

 

Well adding a bit of a virtual light to our 3D demo's can make things look a lot more realistic and enticing :)  Won't be long now before your looking at this demo and rubbing your eyes in disbelief ... wondering how you can create such amazing demo's using such a simple thing as your browser and a bit of java.

 

A simple lighting model we can introduce, is the directional light model....and its really simple.  We'll have the light model, on top of our camera...so the light will be us, and as we move around, the light on the triangle faces will change...darker or lighter depending if where facing them.

 

 

 

Thats our simple picture we have...but just so we know, we'll go over other vectors that are involved here :)

 

Intensity=Ambient + Diffuse * (L N)

 

But I have to go into the various other models and possible lightings, else I wouldn't feel right.  As I think they make sense...well they did to me - its just a matter of looking at them long enough :)  If you don't get it after 3 hours of looking at it, I'd take a rest..hehe

 

We can expand the simple model above to include more vector's - more values such as the viewers location and refection of light off the surface.

 

Intensity=Ambient + Diffuse * (L N) + Specular * (R V)^n

 

 

 

 

But the true model is never usually used - instead some people came up with some relatively good approximations, which give a close representation to the original model.  its all by using the H vector.

 

Now we need to think of some optimisation tricks, as we can't go using the reflection vector R, as it takes to much to calculate.  So for our specular part, we could use (L dot N) instead of (R dot V)....which is an okay approximation, but not that realistic.

We can take it a bit further by adding H...which is the vector between Light (L) and View (V)....(e.g. L+V/2 ).

 

 

 

What H has in common isn't easy to see at first, but we notice that HV proportional to RV...in fact its a factor of 2!  Dang that's lucky isn't it....so we get this:

 

RV = (HV)*2

 

But then again, we can make a further little optimisation - as its a linear relationship, so we can make a quick fix, and take away the multiplication of 2, and modify our power n value to account for this.  Saving one extra calculation here and there soon adds up :)

 

We are really interested in that angle...the one between H and N ...which we get using our dot product again...so we have HN

 

Intensity=Ambient + Diffuse * (L N) + Specular * (H N)^n

 

 

Putting this into code - Ambient and Diffuse.

Well we'll only use a simple flat shaded model for our simple applet demo to start with.  We can always re-visit our lighting model later on...as we might add in the specular code later on...but basic lighting first I think :)

 

So we'll use this model for basics:

 

Intensity = Ambient + Diffuse*(LN)

 

And remember, we have a Red, Green and Blue intensity, so what you really have is this:

 

Ir = A + D*(LN)

Ig = A + D*(LN)

Ib = A + D*(LN)

 

I've chosen to use A - Ambient, and D - Diffuse, so its easier to type :)

 

When we go into code, we'll have to make sure of a number of things, as we want to clip our values, so they are limited to 0-255, as each colour part is only a 8 bit value.

 

 

So we choose A and D so that our Intensity value goes from 0 to 1.  Well make A = 0.3 (or 30%) and D = 0.7 (or 70%).

 

 

Flat Lighting - Download Applet Source Code
    ...

 

  void AddFlatLighting(Triangle t[], int iNumTris)

  {

      // Ideally:

      // Intensity=Ambient + Diffuse * (L N) + Specular * (R V)^n

     

      float PercentageAmbient = 0.3f;

      float PercentageDiffuse = 0.7f;

     

      for(int i=0; i<iNumTris; i++)

      {

         Color origColour = t[i].c;

         float red   = origColour.getRed();

         float green = origColour.getGreen();

         float blue  = origColour.getBlue();

        

         Vector3 vLight = new Vector3(0,0,1);

         vLight = Vector3.normalize(vLight);

         Vector3 vTriNormal = t[i].tn;

         float fDiffuse = Vector3.dot( vLight, vTriNormal );

        

         if( fDiffuse < 0.0f ) fDiffuse = 0.0f;

        

         int newred   = (int)(red*PercentageAmbient    + red*PercentageDiffuse*fDiffuse);

         int newgreen = (int)(green*PercentageAmbient  + green*PercentageDiffuse*fDiffuse);

         int newblue  = (int)(blue*PercentageAmbient   + blue*PercentageDiffuse*fDiffuse);

 

         t[i].tc = new Color(newred, newgreen, newblue);

      }// End for loop i

 

  }// End AddFlatLighting(..)

 

  ...

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 
 Visitor: 9534626  { 209.237.238.175 } Copyright (c) 2002-2017 xbdev.net - All rights reserved.
Designated tutorial and software are the property of their respective owners.