Italian community request: Area light fix!
http://peach.blender.org/index.php/area-light-fix-light-not-shadow/ Now, for every possible shadow sample, an area light calculation is done from that position.
This commit is contained in:
parent
448a423288
commit
4ba215478f
@ -2940,8 +2940,13 @@ static void initshadowbuf(Render *re, LampRen *lar, float mat[][4])
|
||||
|
||||
static void area_lamp_vectors(LampRen *lar)
|
||||
{
|
||||
float xsize= 0.5*lar->area_size, ysize= 0.5*lar->area_sizey;
|
||||
float xsize= 0.5*lar->area_size, ysize= 0.5*lar->area_sizey, multifac;
|
||||
|
||||
/* make it smaller, so area light can be multisampled */
|
||||
multifac= 1.0f/sqrt((float)lar->ray_totsamp);
|
||||
xsize *= multifac;
|
||||
ysize *= multifac;
|
||||
|
||||
/* corner vectors */
|
||||
lar->area[0][0]= lar->co[0] - xsize*lar->mat[0][0] - ysize*lar->mat[1][0];
|
||||
lar->area[0][1]= lar->co[1] - xsize*lar->mat[0][1] - ysize*lar->mat[1][1];
|
||||
@ -3076,6 +3081,7 @@ static GroupObject *add_render_lamp(Render *re, Object *ob)
|
||||
}
|
||||
|
||||
area_lamp_vectors(lar);
|
||||
init_jitter_plane(lar); // subsamples
|
||||
}
|
||||
else lar->ray_totsamp= 0;
|
||||
|
||||
|
@ -579,6 +579,9 @@ void init_jitter_plane(LampRen *lar)
|
||||
float *fp;
|
||||
int x, iter=12, tot= lar->ray_totsamp;
|
||||
|
||||
/* test if already initialized */
|
||||
if(lar->jitter) return;
|
||||
|
||||
/* at least 4, or max threads+1 tables */
|
||||
if(BLENDER_MAX_THREADS < 4) x= 4;
|
||||
else x= BLENDER_MAX_THREADS+1;
|
||||
|
@ -421,17 +421,21 @@ static double saacos_d(double fac)
|
||||
}
|
||||
|
||||
/* Stoke's form factor. Need doubles here for extreme small area sizes */
|
||||
static float area_lamp_energy(float *co, float *vn, LampRen *lar)
|
||||
static float area_lamp_energy(float (*area)[3], float *co, float *vn)
|
||||
{
|
||||
double fac;
|
||||
double vec[4][3]; /* vectors of rendered co to vertices lamp */
|
||||
double cross[4][3]; /* cross products of this */
|
||||
double rad[4]; /* angles between vecs */
|
||||
|
||||
VECSUB(vec[0], co, lar->area[0]);
|
||||
VECSUB(vec[1], co, lar->area[1]);
|
||||
VECSUB(vec[2], co, lar->area[2]);
|
||||
VECSUB(vec[3], co, lar->area[3]);
|
||||
/* extra test for dot */
|
||||
if ( INPR(co, vn) <= 0.0f)
|
||||
return 0.0f;
|
||||
|
||||
VECSUB(vec[0], co, area[0]);
|
||||
VECSUB(vec[1], co, area[1]);
|
||||
VECSUB(vec[2], co, area[2]);
|
||||
VECSUB(vec[3], co, area[3]);
|
||||
|
||||
Normalize_d(vec[0]);
|
||||
Normalize_d(vec[1]);
|
||||
@ -467,7 +471,35 @@ static float area_lamp_energy(float *co, float *vn, LampRen *lar)
|
||||
fac+= rad[3]*(vn[0]*cross[3][0]+ vn[1]*cross[3][1]+ vn[2]*cross[3][2]);
|
||||
|
||||
if(fac<=0.0) return 0.0;
|
||||
return pow(fac*lar->areasize, lar->k); // corrected for buttons size and lar->dist^2
|
||||
return fac;
|
||||
}
|
||||
|
||||
static float area_lamp_energy_multisample(LampRen *lar, float *co, float *vn)
|
||||
{
|
||||
/* corner vectors are moved around according lamp jitter */
|
||||
float *jitlamp= lar->jitter, vec[3];
|
||||
float area[4][3], intens= 0.0f;
|
||||
int a= lar->ray_totsamp;
|
||||
|
||||
|
||||
while(a--) {
|
||||
vec[0]= jitlamp[0];
|
||||
vec[1]= jitlamp[1];
|
||||
vec[2]= 0.0f;
|
||||
Mat3MulVecfl(lar->mat, vec);
|
||||
|
||||
VECADD(area[0], lar->area[0], vec);
|
||||
VECADD(area[1], lar->area[1], vec);
|
||||
VECADD(area[2], lar->area[2], vec);
|
||||
VECADD(area[3], lar->area[3], vec);
|
||||
|
||||
intens+= area_lamp_energy(area, co, vn);
|
||||
|
||||
jitlamp+= 2;
|
||||
}
|
||||
intens /= (float)lar->ray_totsamp;
|
||||
|
||||
return pow(intens*lar->areasize, lar->k); // corrected for buttons size and lar->dist^2
|
||||
}
|
||||
|
||||
static float spec(float inp, int hard)
|
||||
@ -1057,10 +1089,10 @@ float lamp_get_visibility(LampRen *lar, float *co, float *lv, float *dist)
|
||||
/* area type has no quad or sphere option */
|
||||
if(lar->type==LA_AREA) {
|
||||
/* area is single sided */
|
||||
if(INPR(lv, lar->vec) > 0.0f)
|
||||
visifac= 1.0f;
|
||||
else
|
||||
visifac= 0.0f;
|
||||
//if(INPR(lv, lar->vec) > 0.0f)
|
||||
// visifac= 1.0f;
|
||||
//else
|
||||
// visifac= 0.0f;
|
||||
}
|
||||
else {
|
||||
switch(lar->falloff_type)
|
||||
@ -1206,7 +1238,7 @@ static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int
|
||||
/* this complex construction screams for a nicer implementation! (ton) */
|
||||
if(R.r.mode & R_SHADOW) {
|
||||
if(ma->mode & MA_SHADOW) {
|
||||
if(lar->type==LA_HEMI);
|
||||
if(lar->type==LA_HEMI || lar->type==LA_AREA);
|
||||
else if((ma->mode & MA_RAYBIAS) && (lar->mode & LA_SHAD_RAY) && (vlr->flag & R_SMOOTH)) {
|
||||
float thresh= vlr->ob->smoothresh;
|
||||
if(inp>thresh)
|
||||
@ -1233,7 +1265,7 @@ static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int
|
||||
else {
|
||||
|
||||
if(lar->type==LA_AREA)
|
||||
inp= area_lamp_energy(shi->co, vn, lar);
|
||||
inp= area_lamp_energy_multisample(lar, shi->co, vn);
|
||||
|
||||
/* diffuse shaders (oren nayer gets inp from area light) */
|
||||
if(ma->diff_shader==MA_DIFF_ORENNAYAR) is= OrenNayar_Diff(inp, vn, lv, view, ma->roughness);
|
||||
|
@ -2369,7 +2369,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
ob= ob->parent;
|
||||
if(ob && (ob->flag & OB_POSEMODE)) {
|
||||
bArmature *arm= ob->data;
|
||||
if( ELEM(arm->drawtype, ARM_B_BONE, ARM_ENVELOPE)) {
|
||||
if( arm->drawtype==ARM_ENVELOPE) {
|
||||
initTransform(TFM_BONESIZE, CTX_NONE);
|
||||
Transform();
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user