- changed calculus for area light to use double precision. Using float

already gave noise with area size of 0.1.
  Limited buttons to minimum value of 0.01 for area light. For people
  who want smaller they can scale it down in 3d, effectively reducing
  the energy then as well.
This commit is contained in:
Ton Roosendaal
2004-01-04 13:27:18 +00:00
parent bf541a5f63
commit 03fe244b58
4 changed files with 67 additions and 40 deletions

View File

@@ -34,8 +34,17 @@
#ifndef RENDERCORE_H
#define RENDERCORE_H
#include "render_types.h"
/* vector defines */
#define VECADD(dest, v1, v2) dest[0]= v1[0]+v2[0];dest[1]= v1[1]+v2[1];dest[2]= v1[2]+v2[2]
#define VECSUB(dest, v1, v2) dest[0]= v1[0]-v2[0];dest[1]= v1[1]-v2[1];dest[2]= v1[2]-v2[2]
#define CROSS(dest, a, b) dest[0]= a[1] * b[2] - a[2] * b[1]; dest[1]= a[2] * b[0] - a[0] * b[2]; dest[2]= a[0] * b[1] - a[1] * b[0]
#define VECMUL(dest, f) dest[0]*= f; dest[1]*= f; dest[2]*= f
struct HaloRen;
struct ShadeInput;

View File

@@ -58,10 +58,6 @@
#define DEPTH_SHADOW_TRA 10
/* vector defines */
#define VECADD(dest, v1, v2) dest[0]= v1[0]+v2[0];dest[1]= v1[1]+v2[1];dest[2]= v1[2]+v2[2]
#define VECSUB(dest, v1, v2) dest[0]= v1[0]-v2[0];dest[1]= v1[1]-v2[1];dest[2]= v1[2]-v2[2]
/* ********** structs *************** */

View File

@@ -1227,33 +1227,54 @@ void halovert()
/* ---------------- shaders ----------------------- */
/* Stoke's form factor */
static double Normalise_d(double *n)
{
double d;
d= n[0]*n[0]+n[1]*n[1]+n[2]*n[2];
if(d>0.00000000000000001) {
d= sqrt(d);
n[0]/=d;
n[1]/=d;
n[2]/=d;
} else {
n[0]=n[1]=n[2]= 0.0;
d= 0.0;
}
return d;
}
/* Stoke's form factor. Need doubles here for extreme small area sizes */
static float area_lamp_energy(float *co, float *vn, LampRen *lar)
{
float tvec[3], fac;
float vec[4][3]; /* vectors of rendered co to vertices lamp */
float cross[4][3]; /* cross products of this */
float rad[4]; /* angles between vecs */
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 */
VecSubf(vec[0], co, lar->area[0]);
VecSubf(vec[1], co, lar->area[1]);
VecSubf(vec[2], co, lar->area[2]);
VecSubf(vec[3], co, lar->area[3]);
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]);
Normalise(vec[0]);
Normalise(vec[1]);
Normalise(vec[2]);
Normalise(vec[3]);
Normalise_d(vec[0]);
Normalise_d(vec[1]);
Normalise_d(vec[2]);
Normalise_d(vec[3]);
/* cross product */
Crossf(cross[0], vec[0], vec[1]);
Crossf(cross[1], vec[1], vec[2]);
Crossf(cross[2], vec[2], vec[3]);
Crossf(cross[3], vec[3], vec[0]);
Normalise(cross[0]);
Normalise(cross[1]);
Normalise(cross[2]);
Normalise(cross[3]);
CROSS(cross[0], vec[0], vec[1]);
CROSS(cross[1], vec[1], vec[2]);
CROSS(cross[2], vec[2], vec[3]);
CROSS(cross[3], vec[3], vec[0]);
Normalise_d(cross[0]);
Normalise_d(cross[1]);
Normalise_d(cross[2]);
Normalise_d(cross[3]);
/* angles */
rad[0]= vec[0][0]*vec[1][0]+ vec[0][1]*vec[1][1]+ vec[0][2]*vec[1][2];
@@ -1267,16 +1288,15 @@ static float area_lamp_energy(float *co, float *vn, LampRen *lar)
rad[3]= acos(rad[3]);
/* Stoke formula */
VecMulf(cross[0], rad[0]);
VecMulf(cross[1], rad[1]);
VecMulf(cross[2], rad[2]);
VecMulf(cross[3], rad[3]);
VECMUL(cross[0], rad[0]);
VECMUL(cross[1], rad[1]);
VECMUL(cross[2], rad[2]);
VECMUL(cross[3], rad[3]);
VECCOPY(tvec, vn);
fac= tvec[0]*cross[0][0]+ tvec[1]*cross[0][1]+ tvec[2]*cross[0][2];
fac+= tvec[0]*cross[1][0]+ tvec[1]*cross[1][1]+ tvec[2]*cross[1][2];
fac+= tvec[0]*cross[2][0]+ tvec[1]*cross[2][1]+ tvec[2]*cross[2][2];
fac+= tvec[0]*cross[3][0]+ tvec[1]*cross[3][1]+ tvec[2]*cross[3][2];
fac= vn[0]*cross[0][0]+ vn[1]*cross[0][1]+ vn[2]*cross[0][2];
fac+= vn[0]*cross[1][0]+ vn[1]*cross[1][1]+ vn[2]*cross[1][2];
fac+= vn[0]*cross[2][0]+ vn[1]*cross[2][1]+ vn[2]*cross[2][2];
fac+= 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
@@ -2445,9 +2465,11 @@ temp_y= floor(y);
/* exposure correction */
if(R.wrld.exposure!=0.0 || R.wrld.range!=1.0) {
col[0]= R.wrld.linfac*(1.0-exp( col[0]*R.wrld.logfac) );
col[1]= R.wrld.linfac*(1.0-exp( col[1]*R.wrld.logfac) );
col[2]= R.wrld.linfac*(1.0-exp( col[2]*R.wrld.logfac) );
if((shi.matren->mode & MA_SHLESS)==0) {
col[0]= R.wrld.linfac*(1.0-exp( col[0]*R.wrld.logfac) );
col[1]= R.wrld.linfac*(1.0-exp( col[1]*R.wrld.logfac) );
col[2]= R.wrld.linfac*(1.0-exp( col[2]*R.wrld.logfac) );
}
}
/* MIST */

View File

@@ -1913,11 +1913,11 @@ static void lamp_panel_lamp(Object *ob, Lamp *la)
//uiDefButS(block, MENU, B_LAMPREDRAW, "Shape %t|Square %x0|Rect %x1|Cube %x2|Box %x3",
uiDefButS(block, MENU, B_LAMPREDRAW, "Shape %t|Square %x0|Rect %x1",
10, 150, 100, 19, &la->area_shape, 0,0,0,0, "Sets area light shape");
uiDefButF(block, NUM,B_LAMPREDRAW,"Size ", 10,130,100,19, &la->area_size, 0.001, 100.0, 10, 0, "Area light size, doesn't affect energy amount");
uiDefButF(block, NUM,B_LAMPREDRAW,"Size ", 10,130,100,19, &la->area_size, 0.01, 100.0, 10, 0, "Area light size, doesn't affect energy amount");
if ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_BOX)
uiDefButF(block, NUM,B_LAMPREDRAW,"SizeY ", 10,110,100,19, &la->area_sizey, 0.001, 100.0, 10, 0, "Area light size Y, doesn't affect energy amount");
uiDefButF(block, NUM,B_LAMPREDRAW,"SizeY ", 10,110,100,19, &la->area_sizey, 0.01, 100.0, 10, 0, "Area light size Y, doesn't affect energy amount");
if(la->area_shape==LA_AREA_BOX)
uiDefButF(block, NUM,B_LAMPREDRAW,"SizeZ ", 10,90,100,19, &la->area_sizez, 0.001, 100.0, 10, 0, "Area light size Z, doesn't affect energy amount");
uiDefButF(block, NUM,B_LAMPREDRAW,"SizeZ ", 10,90,100,19, &la->area_sizez, 0.01, 100.0, 10, 0, "Area light size Z, doesn't affect energy amount");
}
else if ELEM(la->type, LA_LOCAL, LA_SPOT) {
uiBlockSetCol(block, TH_BUT_SETTING1);