[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [29125] branches/render25/source/blender/ render/intern: Render Branch: lamp halo's can now be textured.
Brecht Van Lommel
brecht at blender.org
Tue Jun 1 15:28:13 CEST 2010
Revision: 29125
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=29125
Author: blendix
Date: 2010-06-01 15:28:13 +0200 (Tue, 01 Jun 2010)
Log Message:
-----------
Render Branch: lamp halo's can now be textured. Had to reorganize the
code to separate cone intersection, integration between intersections,
and shadow/texture lookup.
Modified Paths:
--------------
branches/render25/source/blender/render/intern/include/shadowbuf.h
branches/render25/source/blender/render/intern/source/lamp.c
branches/render25/source/blender/render/intern/source/shadowbuf.c
Modified: branches/render25/source/blender/render/intern/include/shadowbuf.h
===================================================================
--- branches/render25/source/blender/render/intern/include/shadowbuf.h 2010-06-01 13:06:13 UTC (rev 29124)
+++ branches/render25/source/blender/render/intern/include/shadowbuf.h 2010-06-01 13:28:13 UTC (rev 29125)
@@ -52,11 +52,13 @@
to hide bias issues at grazing angles */
float shadowbuf_test(struct Render *re, struct ShadBuf *shb,
- float *co, float *dxco, float *dyco, float inp, float mat_bias);
+ float co[3], float dxco[3], float dyco[3], float inp, float mat_bias);
-/* Determine shadow facetor between two points */
+/* Test shadow factor for a receiving point, coordinate must already
+ be projected in lamp space using shadowbuffer window matrix. */
-float shadow_halo(struct LampRen *lar, float *p1, float *p2);
+float shadowbuf_test_halo(struct ShadBuf *shb, float co[3]);
+void shadowbuf_project_halo(struct LampRen *lar, float co[3], float sco[3]);
/* Utility for Envmap */
Modified: branches/render25/source/blender/render/intern/source/lamp.c
===================================================================
--- branches/render25/source/blender/render/intern/source/lamp.c 2010-06-01 13:06:13 UTC (rev 29124)
+++ branches/render25/source/blender/render/intern/source/lamp.c 2010-06-01 13:28:13 UTC (rev 29125)
@@ -316,6 +316,28 @@
return 0;
}
+static void lamp_texture_color(Render *re, LampRen *lar, ShadeInput *shi, float vec[3], float dist, float latex[3])
+{
+ /* compute influence */
+ copy_v3_v3(latex, &lar->r);
+
+ if(lar->mode & LA_TEXTURE) {
+ if(lar->type==LA_SPOT && (lar->mode & LA_OSATEX)) {
+ shi->geometry.osatex= 1; /* signal for multitex() */
+
+ shi->texture.dxlv[0]= vec[0] - (shi->geometry.co[0]-lar->co[0]+shi->geometry.dxco[0])/dist;
+ shi->texture.dxlv[1]= vec[1] - (shi->geometry.co[1]-lar->co[1]+shi->geometry.dxco[1])/dist;
+ shi->texture.dxlv[2]= vec[2] - (shi->geometry.co[2]-lar->co[2]+shi->geometry.dxco[2])/dist;
+
+ shi->texture.dylv[0]= vec[0] - (shi->geometry.co[0]-lar->co[0]+shi->geometry.dyco[0])/dist;
+ shi->texture.dylv[1]= vec[1] - (shi->geometry.co[1]-lar->co[1]+shi->geometry.dyco[1])/dist;
+ shi->texture.dylv[2]= vec[2] - (shi->geometry.co[2]-lar->co[2]+shi->geometry.dyco[2])/dist;
+ }
+
+ do_lamp_tex(re, lar, vec, shi, latex, LA_TEXTURE);
+ }
+}
+
int lamp_sample(float lv[3], float lainf[3], float lashdw[3],
Render *re, LampRen *lar, ShadeInput *shi,
float co[3], float r[2])
@@ -328,25 +350,7 @@
return 0;
if(lainf) {
- /* compute influence */
- copy_v3_v3(lainf, &lar->r);
-
- if(lar->mode & LA_TEXTURE) {
- if(lar->type==LA_SPOT && (lar->mode & LA_OSATEX)) {
- shi->geometry.osatex= 1; /* signal for multitex() */
-
- shi->texture.dxlv[0]= vec[0] - (shi->geometry.co[0]-lar->co[0]+shi->geometry.dxco[0])/dist;
- shi->texture.dxlv[1]= vec[1] - (shi->geometry.co[1]-lar->co[1]+shi->geometry.dxco[1])/dist;
- shi->texture.dxlv[2]= vec[2] - (shi->geometry.co[2]-lar->co[2]+shi->geometry.dxco[2])/dist;
-
- shi->texture.dylv[0]= vec[0] - (shi->geometry.co[0]-lar->co[0]+shi->geometry.dyco[0])/dist;
- shi->texture.dylv[1]= vec[1] - (shi->geometry.co[1]-lar->co[1]+shi->geometry.dyco[1])/dist;
- shi->texture.dylv[2]= vec[2] - (shi->geometry.co[2]-lar->co[2]+shi->geometry.dyco[2])/dist;
- }
-
- do_lamp_tex(re, lar, vec, shi, lainf, LA_TEXTURE);
- }
-
+ lamp_texture_color(re, lar, shi, vec, dist, lainf);
mul_v3_fl(lainf, fac);
}
@@ -367,17 +371,71 @@
/***************************** spot halo ***********************************/
-static void spothalo(Render *re, struct LampRen *lar, ShadeInput *shi, float *intens)
+static void lamp_unproject_halo(LampRen *lar, float co[3])
{
- double a, b, c, disc, nray[3], npos[3];
- float t0, t1 = 0.0f, t2= 0.0f, t3, haint;
- float p1[3], p2[3], ladist, maxz = 0.0f, maxy = 0.0f;
+ co[2] /= lar->sh_zfac;
+
+ mul_m3_v3(lar->mat, co);
+ add_v3_v3(co, lar->co);
+}
+
+static void lamp_halo_integrate(Render *re, LampRen *lar, ShadeInput *shi, float p1[3], float p2[3], float result[3])
+{
+ struct ShadBuf *shb= lar->shb;
+ ShadeInput shi_local = *shi;
+ float vec[3], dist, totsample, fac;
+ float lp1[3], lp2[3], lp[3], t, sample[3], step;
+
+ if(!shb || !lar->shadhalostep) {
+ copy_v3_v3(result, &lar->r);
+ return;
+ }
+
+ shadowbuf_project_halo(lar, p1, lp1);
+ shadowbuf_project_halo(lar, p2, lp2);
+
+ lamp_unproject_halo(lar, p1);
+ lamp_unproject_halo(lar, p2);
+
+ step= lar->shadhalostep/(0.5f*lar->bufsize);
+ t= step;
+ zero_v3(result);
+ totsample= 0.0f;
+
+ while(t < 1.0f) {
+ /* compute location, vector to lamp and distance */
+ interp_v3_v3v3(shi_local.geometry.co, p1, p2, t);
+ sub_v3_v3v3(vec, shi_local.geometry.co, lar->co);
+ dist= normalize_v3(vec);
+
+ interp_v3_v3v3(lp, lp1, lp2, t);
+
+ /* intensity, blend, shadow, texture */
+ fac = lar->haint;
+ fac = lamp_spot_falloff(lar, vec, fac);
+ fac *= shadowbuf_test_halo(shb, lp);
+
+ lamp_texture_color(re, lar, &shi_local, vec, dist, sample);
+
+ /* accumulate */
+ madd_v3_v3fl(result, sample, fac);
+ totsample += 1.0f;
+
+ t += step;
+ }
+
+ if(totsample != 0.0f)
+ mul_v3_fl(result, 1.0f/totsample);
+}
+
+static int lamp_halo_intersect_cone(Render *re, LampRen *lar, ShadeInput *shi, float p1[3], float p2[3], float *dist)
+{
+ double disc, nray[3], npos[3], a, b, c;
+ float t0, t1 = 0.0f, t2= 0.0f, t3;
+ float ladist, maxz = 0.0f, maxy = 0.0f;
int snijp, doclip=1, use_yco=0;
int ok1=0, ok2=0;
-
- *intens= 0.0f;
- haint= lar->haint;
-
+
if(re->cam.type == CAM_ORTHO) {
/* camera pos (view vector) cannot be used... */
/* camera position (cox,coy,0) rotate around lamp */
@@ -397,16 +455,7 @@
/* rotate view */
VECCOPY(nray, shi->geometry.view);
mul_m3_v3_double(lar->imat, nray);
-
- if(re->db.wrld.mode & WO_MIST) {
- /* patchy... */
- haint *= environment_mist_factor(re, -lar->co[2], lar->co);
- if(haint==0.0f) {
- return;
- }
- }
-
/* rotate maxz */
if(shi->geometry.co[2]==0.0f) doclip= 0; /* for when halo at sky */
else {
@@ -437,7 +486,7 @@
/*
* Only one intersection point...
*/
- return;
+ return 0;
}
else {
disc = b*b - a*c;
@@ -453,6 +502,7 @@
snijp= 2;
}
}
+
if(snijp==2) {
/* sort */
if(t1>t2) {
@@ -468,7 +518,7 @@
if(p2[2]<=0.0f && t1!=t2) ok2= 1;
/* at least 1 point with negative z */
- if(ok1==0 && ok2==0) return;
+ if(ok1==0 && ok2==0) return 0;
/* intersction point with -ladist, the bottom of the cone */
if(use_yco==0) {
@@ -490,15 +540,15 @@
t2= t3;
}
}
- else if(ok1==0 || ok2==0) return;
+ else if(ok1==0 || ok2==0) return 0;
/* at least 1 visible interesction point */
- if(t1<0.0f && t2<0.0f) return;
+ if(t1<0.0f && t2<0.0f) return 0;
if(t1<0.0f) t1= 0.0f;
if(t2<0.0f) t2= 0.0f;
- if(t1==t2) return;
+ if(t1==t2) return 0;
/* sort again to be sure */
if(t1>t2) {
@@ -510,7 +560,7 @@
if(use_yco==0) t0= (maxz-npos[2])/nray[2];
else t0= (maxy-npos[1])/nray[1];
- if(t0<t1) return;
+ if(t0<t1) return 0;
if(t0<t2) t2= t0;
}
@@ -518,49 +568,67 @@
p1[0]= npos[0] + t1*nray[0];
p1[1]= npos[1] + t1*nray[1];
p1[2]= npos[2] + t1*nray[2];
+
p2[0]= npos[0] + t2*nray[0];
p2[1]= npos[1] + t2*nray[1];
p2[2]= npos[2] + t2*nray[2];
-
-
- /* now we have 2 points, make three lengths with it */
-
- a= sqrt(p1[0]*p1[0]+p1[1]*p1[1]+p1[2]*p1[2]);
- b= sqrt(p2[0]*p2[0]+p2[1]*p2[1]+p2[2]*p2[2]);
- c= len_v3v3(p1, p2);
-
- a/= ladist;
- a= sqrt(a);
- b/= ladist;
- b= sqrt(b);
- c/= ladist;
-
- *intens= c*( (1.0-a)+(1.0-b) );
- /* WATCH IT: do not clip a,b en c at 1.0, this gives nasty little overflows
- at the edges (especially with narrow halos) */
- if(*intens<=0.0f) return;
+ *dist= ladist;
- /* soft area */
- /* not needed because t0 has been used for p1/p2 as well */
- /* if(doclip && t0<t2) { */
- /* *intens *= (t0-t1)/(t2-t1); */
- /* } */
-
- *intens *= haint;
- *intens *= shadow_halo(lar, p1, p2);
+ return 1;
}
+
+ return 0;
}
+static void spothalo(Render *re, LampRen *lar, ShadeInput *shi, float result[3])
+{
+ float a, b, c, p1[3], p2[3], fac= 1.0f, ladist;
+
+ result[0]= result[1]= result[2]= 0.0f;
+
+ /* compute influence of mist, patchy .. */
+ if(re->db.wrld.mode & WO_MIST) {
+ fac= environment_mist_factor(re, -lar->co[2], lar->co);
+ if(fac == 0.0f)
+ return;
+ }
+
+ /* intersect with lamp cone */
+ if(!lamp_halo_intersect_cone(re, lar, shi, p1, p2, &ladist))
+ return;
+
+ /* now we have 2 points, make three lengths with it */
+ a= sqrtf(len_v3(p1)/ladist);
+ b= sqrtf(len_v3(p2)/ladist);
+ c= len_v3v3(p1, p2)/ladist;
+
+ fac *= c*((1.0-a) + (1.0-b));
+
+ /* WATCH IT: do not clip a,b en c at 1.0, this gives nasty little overflows
+ at the edges (especially with narrow halos) */
+ if(fac <= 0.0f)
+ return;
+
+ /* soft area */
+ /* not needed because t0 has been used for p1/p2 as well */
+ /* if(doclip && t0<t2) { */
+ /* result *= (t0-t1)/(t2-t1); */
+ /* } */
+
+ lamp_halo_integrate(re, lar, shi, p1, p2, result);
+ mul_v3_fl(result, fac);
+}
+
void lamp_spothalo_render(Render *re, ShadeInput *shi, float *col, float alpha)
{
ListBase *lights;
GroupObject *go;
LampRen *lar;
- float i;
+ float color[3];
if(alpha==0.0f) return;
-
+
lights= lamps_get(re, shi);
for(go=lights->first; go; go= go->next) {
lar= go->lampren;
@@ -573,13 +641,14 @@
continue;
if((lar->lay & shi->shading.lay)==0)
continue;
-
- spothalo(re, lar, shi, &i);
- if(i>0.0f) {
- col[3]+= i*alpha; // all premul
- col[0]+= i*lar->r*alpha;
- col[1]+= i*lar->g*alpha;
- col[2]+= i*lar->b*alpha;
+
+ spothalo(re, lar, shi, color);
+
+ if(!is_zero_v3(color)) {
+ col[0]+= color[0]*alpha;
+ col[1]+= color[1]*alpha;
+ col[2]+= color[2]*alpha;
+ col[3]+= rgb_to_grayscale(color)*alpha; // all premul
}
}
}
Modified: branches/render25/source/blender/render/intern/source/shadowbuf.c
===================================================================
--- branches/render25/source/blender/render/intern/source/shadowbuf.c 2010-06-01 13:06:13 UTC (rev 29124)
+++ branches/render25/source/blender/render/intern/source/shadowbuf.c 2010-06-01 13:28:13 UTC (rev 29125)
@@ -99,7 +99,7 @@
typedef struct ShadBuf {
/* regular shadowbuffer */
- short samp, shadhalostep, totbuf;
+ short samp, totbuf;
float persmat[4][4];
float viewmat[4][4];
float winmat[4][4];
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list