Intro
Back to the basics. The function for lambertian reflectance is
Basically, final result equals the dot product of light normal(L) and surface normal(N), multiply by diffuse color(C), multiply by color of light(IL). I'll write the simplest diffuse shader that doesn't get into light loops and getting light information.
MI Source
declare shader
color "jc_simple_diffuse" (
color "diffuse" default 1 1 1,
vector "light_dir" default 0 0 0)
version 1
apply material
end declare
C Source
#include "shader.h"
DLLEXPORT
struct jc_simple_diffuse {
miColor diffuse;
miVector lightdir;
};
DLLEXPORT
int jc_simple_diffuse_version(void) {return(1);}
DLLEXPORT
miBoolean jc_simple_diffuse(
miColor *result,
miState *state,
struct jc_simple_diffuse *params) {
miScalar dot_nl;
miColor *diff = mi_eval_color(¶ms->diffuse);
miVector *dir = mi_eval_vector(¶ms->lightdir);
dot_nl = -mi_vector_dot(&state->normal, dir);
result->r = diff->r * dot_nl;
result->g = diff->g * dot_nl;
result->b = diff->b * dot_nl;
result->a = 1.0;
return(miTRUE);
}
Conclusions
The only inputs are diffuse color and a light vector. Inputing -1 -1 -1 in light direction gives it a light looking like in fig 1.
|
Fig 1: simple diffuse |
|
Fig 2: simple diffuse attribute editor |
Since light dir is expressed as vectors, by connecting transforms of x, y, z to Light Dir we can change the light direction of this particular diffuse shader.
|
Fig 3: demo 01 |
In fig 3, I connected the translation of xyz of a cube to the light dir, as well as created a direction light and aim constraint it to the cube to better illustrate. When I move the cube.z to 1, the light points left.
|
Fig 4: demo 02 |
In fig 4, when i move the cube.z to 5, the falloff becomes really harsh. This is due to dot product of the surface normal and light dir becoming smaller and smaller as the light dir moves further away.
|
Fig 5: demo 03 |
In fig 5, basic 45 degree angle light. Harsh falloff could be fixed by normalizing light dir to unit vectors.
0 comments:
Post a Comment