Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTon Roosendaal <ton@blender.org>2003-12-16 17:12:01 +0300
committerTon Roosendaal <ton@blender.org>2003-12-16 17:12:01 +0300
commit97d4dbc9c317e6d5cd171a9e76ce4aeca2bdf93c (patch)
tree3136f667159fdaa3d0c804f9a0f16c7d27f2d1a7 /source/blender
parent356cf7953482891afe3dd289b1584b355de23b17 (diff)
Another commit for raytracing, now with glass refraction & fresnel!
Changelog: - enable refraction with button "Ray Transp" in Material buttons. - set "Angular Index" value for amount of refraction. - use the "Alpha" value to define transparency. - remember to set a higher "Depth" too... glass can bounce quite some more than expected. - for correct refraction, 3D models MUST have normals pointing in the right direction (consistently pointing outside). - refraction 'sees' the thickness of glass based on what you model. So make for realistic glass both sides of a surface. - I needed to do some rewriting for correct mirroring/refraction, especially to prevent specularity being blended away. Solved this with localizing shading results in the rendercore.c. Now specularity correctly is added, and reduces the 'mirror' value. - Localizing more parts of the render code is being planned. The old render heavily relies on struct Render and struct Osa to store globals. For scanline render no problem, but recursive raytracing dislikes that. - done test with gamma-corrected summation of colors during tracing, is commented out still. But this will give more balanced reflections. Now dark reflections that are reflected in a bright surface seem incorrect. - Introduced 'Fresnel' effect for Mirror and Transparency. This influences the amount of mirror/transparency based at viewing angle. Next to a new Fresnel slider, also a 'falloff' button has been added to define the way it spreads. - Fresnel also works for Ztransp rendering - created new Panel for Raytrace options I have to evaluate still where it all should be logically located. - material preview shows fake reflection and fake refraction as well.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_osa_types.h1
-rw-r--r--source/blender/blenkernel/intern/material.c20
-rw-r--r--source/blender/blenloader/intern/readfile.c14
-rw-r--r--source/blender/include/butspace.h4
-rw-r--r--source/blender/makesdna/DNA_material_types.h6
-rw-r--r--source/blender/render/intern/include/rendercore.h11
-rw-r--r--source/blender/render/intern/source/ray.c419
-rw-r--r--source/blender/render/intern/source/renderHelp.c4
-rw-r--r--source/blender/render/intern/source/rendercore.c203
-rw-r--r--source/blender/renderconverter/intern/convertBlenderScene.c6
-rw-r--r--source/blender/src/buttons_shading.c81
-rw-r--r--source/blender/src/previewrender.c117
12 files changed, 624 insertions, 262 deletions
diff --git a/source/blender/blenkernel/BKE_osa_types.h b/source/blender/blenkernel/BKE_osa_types.h
index 32f91dd3ff7..28d4147c11b 100644
--- a/source/blender/blenkernel/BKE_osa_types.h
+++ b/source/blender/blenkernel/BKE_osa_types.h
@@ -44,6 +44,7 @@ typedef struct RE_Osa
float dxlv[3], dylv[3];
float dxwin[3], dywin[3];
float dxsticky[3], dysticky[3];
+ float dxrefract[3], dyrefract[3];
} Osa;
/* extern Osa O; */
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 28d47d4d90e..16ed3f00355 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -86,6 +86,7 @@ void init_material(Material *ma)
ma->r= ma->g= ma->b= ma->ref= 0.8;
ma->specr= ma->specg= ma->specb= 1.0;
ma->mirr= ma->mirg= ma->mirb= 1.0;
+ ma->spectra= 1.0;
ma->amb= 0.5;
ma->alpha= 1.0;
ma->spec= ma->hasize= 0.5;
@@ -104,6 +105,11 @@ void init_material(Material *ma)
ma->param[2]= 0.5;
ma->param[3]= 0.1;
+ ma->ang= 1.0;
+ ma->ray_depth= 2;
+ ma->ray_depth_tra= 2;
+ ma->falloff_mir= 1.0;
+ ma->falloff_tra= 1.0;
ma->mode= MA_TRACEBLE+MA_SHADOW+MA_RADIO;
}
@@ -577,14 +583,14 @@ void init_render_material(Material *ma)
}
if(needuv) ma->texco |= NEED_UV;
- if(R.r.mode & R_RAYTRACE) {
- if(ma->ray_mirror!=0.0) {
- ma->texco |= NEED_UV|TEXCO_REFL;
- if(R.osa) ma->texco |= TEXCO_OSA;
- }
+ if(ma->mode & MA_RAYMIRROR) {
+ ma->texco |= NEED_UV|TEXCO_REFL;
+ if(R.osa) ma->texco |= TEXCO_OSA;
+ }
+ if(ma->mode & MA_RAYTRANSP) {
+ ma->texco |= NEED_UV;
+ if(R.osa) ma->texco |= TEXCO_OSA;
}
-
-
ma->ambr= ma->amb*R.wrld.ambr;
ma->ambg= ma->amb*R.wrld.ambg;
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index f57961e8482..a94c8e79dd6 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -3929,7 +3929,19 @@ static void do_versions(Main *main)
}
}
}
-
+ if(main->versionfile <= 231) {
+ Material *ma= main->mat.first;
+ while(ma) {
+ if(ma->ang==0.0) {
+ ma->ang= 1.0;
+ ma->ray_depth= 2;
+ ma->ray_depth_tra= 2;
+ ma->falloff_mir= 1.0;
+ ma->falloff_tra= 1.0;
+ }
+ ma= ma->id.next;
+ }
+ }
/* don't forget to set version number in blender.c! */
}
diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h
index f8f52fd6ea9..cb2b60826dd 100644
--- a/source/blender/include/butspace.h
+++ b/source/blender/include/butspace.h
@@ -135,6 +135,8 @@ void test_idbutton_cb(void *namev, void *arg2_unused);
#define B_COLLAMP 1102
#define B_TEXCLEARLAMP 1103
#define B_SBUFF 1104
+#define B_SHADBUF 1105
+#define B_SHADRAY 1106
/* *********************** */
#define B_MATBUTS 1300
@@ -152,6 +154,8 @@ void test_idbutton_cb(void *namev, void *arg2_unused);
#define B_MTEXCOPY 1211
#define B_MATLAY 1212
#define B_MATHALO 1213
+#define B_MATZTRANSP 1214
+#define B_MATRAYTRANSP 1215
/* *********************** */
#define B_TEXBUTS 1400
diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h
index 505dd319046..9162499ed48 100644
--- a/source/blender/makesdna/DNA_material_types.h
+++ b/source/blender/makesdna/DNA_material_types.h
@@ -57,7 +57,9 @@ typedef struct Material {
float amb, emit, ang, spectra, ray_mirror;
float alpha, ref, spec, zoffs, add;
float kfac; /* for transparent solids */
- short ray_depth, pad1;
+ float fresnel_mir, falloff_mir;
+ float fresnel_tra, falloff_tra;
+ short ray_depth, ray_depth_tra;
short har;
char seed1, seed2;
@@ -124,6 +126,8 @@ typedef struct Material {
#define MA_HALO_SHADE 0x4000
#define MA_HALO_FLARE 0x8000
#define MA_RADIO 0x10000
+#define MA_RAYTRANSP 0x20000
+#define MA_RAYMIRROR 0x40000
/* diff_shader */
#define MA_DIFF_LAMBERT 0
diff --git a/source/blender/render/intern/include/rendercore.h b/source/blender/render/intern/include/rendercore.h
index 0be15d90776..3e915b34b7c 100644
--- a/source/blender/render/intern/include/rendercore.h
+++ b/source/blender/render/intern/include/rendercore.h
@@ -38,10 +38,21 @@
struct HaloRen;
+typedef struct ShadeResult
+{
+ float diff[3];
+ float spec[3];
+ float alpha;
+
+} ShadeResult;
+
+
float mistfactor(float *co); /* dist en hoogte, return alpha */
void renderspothalo(unsigned short *col);
void render_lighting_halo(struct HaloRen *har, float *colf);
unsigned int calchalo_z(struct HaloRen *har, unsigned int zz);
+void shade_lamp_loop(int mask, ShadeResult *shr);
+float fresnel_fac(float *view, float *vn, float fresnel, float falloff);
float spec(float inp, int hard);
diff --git a/source/blender/render/intern/source/ray.c b/source/blender/render/intern/source/ray.c
index 40e13899852..5120c81d9e5 100644
--- a/source/blender/render/intern/source/ray.c
+++ b/source/blender/render/intern/source/ray.c
@@ -46,6 +46,7 @@
#include "render.h"
#include "render_intern.h"
+#include "rendercore.h"
#include "jitter.h"
#define OCRES 64
@@ -1143,9 +1144,8 @@ static int d3dda(Isect *is)
/* for now; mostly a duplicate of shadepixel() itself... could be unified once */
/* R.view has been set */
-static void shade_ray(Isect *is, int mask)
+static void shade_ray(Isect *is, int mask, ShadeResult *shr)
{
- extern void shade_lamp_loop(int );
VertRen *v1, *v2, *v3;
float n1[3], n2[3], n3[3];
float *o1, *o2, *o3;
@@ -1166,15 +1166,17 @@ static void shade_ray(Isect *is, int mask)
/* face normal, check for flip */
R.vno= R.vlr->n;
- l= R.vlr->n[0]*R.view[0]+R.vlr->n[1]*R.view[1]+R.vlr->n[2]*R.view[2];
- if(l<0.0) {
- flip= 1;
- R.vlr->n[0]= -R.vlr->n[0];
- R.vlr->n[1]= -R.vlr->n[1];
- R.vlr->n[2]= -R.vlr->n[2];
- R.vlr->puno= ~(R.vlr->puno);
+ if((R.mat->mode & MA_RAYTRANSP)==0) {
+ l= R.vlr->n[0]*R.view[0]+R.vlr->n[1]*R.view[1]+R.vlr->n[2]*R.view[2];
+ if(l<0.0) {
+ flip= 1;
+ R.vlr->n[0]= -R.vlr->n[0];
+ R.vlr->n[1]= -R.vlr->n[1];
+ R.vlr->n[2]= -R.vlr->n[2];
+ R.vlr->puno= ~(R.vlr->puno);
+ }
}
-
+
if(R.vlr->v4) {
if(is->isect==2) {
v1= R.vlr->v3;
@@ -1338,7 +1340,7 @@ static void shade_ray(Isect *is, int mask)
VECCOPY(R.vn, R.vlr->n);
}
- shade_lamp_loop(mask);
+ shade_lamp_loop(mask, shr);
if(flip) {
R.vlr->n[0]= -R.vlr->n[0];
@@ -1348,20 +1350,121 @@ static void shade_ray(Isect *is, int mask)
}
}
+static void refraction(float *refract, float *n, float *view, float index)
+{
+ float dot, fac;
+
+ VECCOPY(refract, view);
+ if(index==0.0) return;
+
+ dot= view[0]*n[0] + view[1]*n[1] + view[2]*n[2];
+
+ if(dot>0.0) {
+ fac= 1.0 - (1.0 - dot*dot)*index*index;
+ if(fac<= 0.0) return;
+ fac= -dot*index + sqrt(fac);
+ }
+ else {
+ index = 1.0/index;
+ fac= 1.0 - (1.0 - dot*dot)*index*index;
+ if(fac<= 0.0) return;
+ fac= -dot*index - sqrt(fac);
+ }
+
+ refract[0]= index*view[0] + fac*n[0];
+ refract[1]= index*view[1] + fac*n[1];
+ refract[2]= index*view[2] + fac*n[2];
+}
+
+static void calc_dx_dy_refract(float *ref, float *n, float *view, float index)
+{
+ float dref[3], dview[3], dnor[3];
+
+ refraction(ref, n, view, index);
+
+ dview[0]= view[0]+ O.dxview;
+ dview[1]= view[1];
+ dview[2]= view[2];
+
+ if(R.vlr->flag & R_SMOOTH) {
+ VecAddf(dnor, n, O.dxno);
+ refraction(dref, dnor, dview, index);
+ }
+ else {
+ refraction(dref, n, dview, index);
+ }
+ VecSubf(O.dxrefract, ref, dref);
+
+ dview[0]= view[0];
+ dview[1]= view[1]+ O.dyview;
+
+ if(R.vlr->flag & R_SMOOTH) {
+ VecAddf(dnor, n, O.dyno);
+ refraction(dref, dnor, dview, index);
+ }
+ else {
+ refraction(dref, n, dview, index);
+ }
+ VecSubf(O.dyrefract, ref, dref);
+
+}
+
+
+/* orn = original face normal */
+static void reflection(float *ref, float *n, float *view, float *orn)
+{
+ float f1;
+
+ f1= -2.0*(n[0]*view[0]+ n[1]*view[1]+ n[2]*view[2]);
+
+ if(orn==NULL) {
+ // heuristic, should test this! is to prevent normal going to the back
+ if(f1> -0.2) f1= -0.2;
+ }
+
+ ref[0]= (view[0]+f1*n[0]);
+ ref[1]= (view[1]+f1*n[1]);
+ ref[2]= (view[2]+f1*n[2]);
+
+ if(orn) {
+ /* test phong normals, then we should prevent vector going to the back */
+ f1= ref[0]*orn[0]+ ref[1]*orn[1]+ ref[2]*orn[2];
+ if(f1>0.0) {
+ f1+= .01;
+ ref[0]-= f1*orn[0];
+ ref[1]-= f1*orn[1];
+ ref[2]-= f1*orn[2];
+ }
+ }
+}
+
+static void color_combine(float *result, float fac1, float fac2, float *col1, float *col2)
+{
+ float col1t[3], col2t[3];
+
+ col1t[0]= sqrt(col1[0]);
+ col1t[1]= sqrt(col1[1]);
+ col1t[2]= sqrt(col1[2]);
+ col2t[0]= sqrt(col2[0]);
+ col2t[1]= sqrt(col2[1]);
+ col2t[2]= sqrt(col2[2]);
+
+ result[0]= (fac1*col1t[0] + fac2*col2t[0]);
+ result[0]*= result[0];
+ result[1]= (fac1*col1t[1] + fac2*col2t[1]);
+ result[1]*= result[1];
+ result[2]= (fac1*col1t[2] + fac2*col2t[2]);
+ result[2]*= result[2];
+}
+
/* the main recursive tracer itself */
-static void traceray(float f, short depth, float *start, float *vec, float *col, int mask)
+static void traceray(short depth, float *start, float *vec, float *col, int mask)
{
- extern unsigned short shortcol[4]; // only for old render, which stores ushort
+ ShadeResult shr;
Isect isec;
- float f1, fr, fg, fb;
+ float f, f1, fr, fg, fb;
float ref[3];
- if(depth<0) return;
-
- fr= R.mat->mirr;
- fg= R.mat->mirg;
- fb= R.mat->mirb;
-
VECCOPY(isec.start, start);
isec.end[0]= start[0]+g_oc.ocsize*vec[0];
isec.end[1]= start[1]+g_oc.ocsize*vec[1];
@@ -1374,26 +1477,65 @@ static void traceray(float f, short depth, float *start, float *vec, float *col,
VECCOPY(R.view, vec);
Normalise(R.view);
- shade_ray(&isec, mask); // returns shortcol
+ shade_ray(&isec, mask, &shr);
- f1= 1.0-f;
+ if(depth>0) {
- col[0]= f*fr*(shortcol[0]/65535.0)+ f1*col[0];
- col[1]= f*fg*(shortcol[1]/65535.0)+ f1*col[1];
- col[2]= f*fb*(shortcol[2]/65535.0)+ f1*col[2];
+ if(R.mat->mode & MA_RAYMIRROR) {
+ f= R.mat->ray_mirror;
+ if(f!=0.0) f*= fresnel_fac(R.view, R.vn, R.mat->fresnel_mir, R.mat->falloff_mir);
+ }
+ else f= 0.0;
+
+ /* have to do it here, make local vars... */
+ fr= R.mat->mirr;
+ fg= R.mat->mirg;
+ fb= R.mat->mirb;
- /* is already new material: */
- if(R.mat->ray_mirror>0.0) {
- f1= -2*(R.vn[0]*R.view[0]+R.vn[1]*R.view[1]+R.vn[2]*R.view[2]);
- if(f1> -0.2) f1= -0.2;
+ if(R.mat->mode & MA_RAYTRANSP && shr.alpha!=1.0) {
+ float f, f1, refract[3], tracol[3];
+
+ refraction(refract, R.vn, R.view, R.mat->ang);
+ traceray(depth-1, R.co, refract, tracol, mask);
+
+ f= shr.alpha; f1= 1.0-f;
+ shr.diff[0]= f*shr.diff[0] + f1*tracol[0];
+ shr.diff[1]= f*shr.diff[1] + f1*tracol[1];
+ shr.diff[2]= f*shr.diff[2] + f1*tracol[2];
+ shr.alpha= 1.0;
+ }
+
+ if(f!=0.0) {
- ref[0]= (R.view[0]+f1*R.vn[0]);
- ref[1]= (R.view[1]+f1*R.vn[1]);
- ref[2]= (R.view[2]+f1*R.vn[2]);
+ reflection(ref, R.vn, R.view, NULL);
+ traceray(depth-1, R.co, ref, col, mask);
+
+ f1= 1.0-f;
- f*= R.mat->ray_mirror;
- traceray(f, depth-1, R.co, ref, col, mask);
+ /* combine */
+ //color_combine(col, f*fr*(1.0-shr.spec[0]), f1, col, shr.diff);
+ //col[0]+= shr.spec[0];
+ //col[1]+= shr.spec[1];
+ //col[2]+= shr.spec[2];
+
+ col[0]= f*fr*(1.0-shr.spec[0])*col[0] + f1*shr.diff[0] + shr.spec[0];
+
+ col[1]= f*fg*(1.0-shr.spec[1])*col[1] + f1*shr.diff[1] + shr.spec[1];
+
+ col[2]= f*fb*(1.0-shr.spec[2])*col[2] + f1*shr.diff[2] + shr.spec[2];
+ }
+ else {
+ col[0]= shr.diff[0] + shr.spec[0];
+ col[1]= shr.diff[1] + shr.spec[1];
+ col[2]= shr.diff[2] + shr.spec[2];
+ }
+ }
+ else {
+ col[0]= shr.diff[0] + shr.spec[0];
+ col[1]= shr.diff[1] + shr.spec[1];
+ col[2]= shr.diff[2] + shr.spec[2];
}
+
}
else { /* sky */
char skycol[4];
@@ -1402,13 +1544,10 @@ static void traceray(float f, short depth, float *start, float *vec, float *col,
Normalise(R.view);
RE_sky(skycol);
-
- f1= 1.0-f;
- f/= 255.0;
- col[0]= f*fr*skycol[0]+ f1*col[0];
- col[1]= f*fg*skycol[1]+ f1*col[1];
- col[2]= f*fb*skycol[2]+ f1*col[2];
+ col[0]= skycol[0]/255.0;
+ col[1]= skycol[1]/255.0;
+ col[2]= skycol[2]/255.0;
}
}
@@ -1497,94 +1636,174 @@ static void *jitter_cube(int resol)
}
-/* ***************** extern calls ************** */
+/* ***************** main calls ************** */
/* extern call from render loop */
-void ray_mirror(int mask)
+void ray_trace(int mask, ShadeResult *shr)
{
- float i, vec[3];
+ VlakRen *vlr;
+ float i, f, f1, fr, fg, fb, vec[3], mircol[3], tracol[3];
+ int do_tra, do_mir;
+
+ do_tra= ((R.mat->mode & MA_RAYTRANSP) && shr->alpha!=1.0);
+ do_mir= ((R.mat->mode & MA_RAYMIRROR) && R.mat->ray_mirror!=0.0);
+ vlr= R.vlr;
if(R.r.mode & R_OSA) {
- VlakRen *vlr;
- float accum[3], rco[3], rvno[3], col[3], ref[3], dxref[3], dyref[3];
- float div= 0.0;
+ float accum[3], rco[3], ref[3], dxref[3], dyref[3];
+ float accur[3], refract[3], divr=0.0, div= 0.0;
int j;
+ if(do_tra) calc_dx_dy_refract(refract, R.vn, R.view, R.mat->ang);
+
accum[0]= accum[1]= accum[2]= 0.0;
+ accur[0]= accur[1]= accur[2]= 0.0;
/* store variables which change during tracing */
VECCOPY(rco, R.co);
- VECCOPY(rvno, R.vno);
VECCOPY(ref, R.ref);
VECCOPY(dxref, O.dxref);
VECCOPY(dyref, O.dyref);
- vlr= R.vlr;
-
+
for(j=0; j<R.osa; j++) {
if(mask & 1<<j) {
- vec[0]= ref[0] + (jit[j][0]-0.5)*dxref[0] + (jit[j][1]-0.5)*dyref[0] ;
- vec[1]= ref[1] + (jit[j][0]-0.5)*dxref[1] + (jit[j][1]-0.5)*dyref[1] ;
- vec[2]= ref[2] + (jit[j][0]-0.5)*dxref[2] + (jit[j][1]-0.5)*dyref[2] ;
- /* prevent normal go to backside */
- i= vec[0]*rvno[0]+ vec[1]*rvno[1]+ vec[2]*rvno[2];
- if(i>0.0) {
- i+= .01;
- vec[0]-= i*rvno[0];
- vec[1]-= i*rvno[1];
- vec[2]-= i*rvno[2];
+ if(do_tra) {
+ vec[0]= refract[0] + (jit[j][0]-0.5)*O.dxrefract[0] + (jit[j][1]-0.5)*O.dyrefract[0] ;
+ vec[1]= refract[1] + (jit[j][0]-0.5)*O.dxrefract[1] + (jit[j][1]-0.5)*O.dyrefract[1] ;
+ vec[2]= refract[2] + (jit[j][0]-0.5)*O.dxrefract[2] + (jit[j][1]-0.5)*O.dyrefract[2] ;
+
+ R.co[0]+= (jit[j][0]-0.5)*O.dxco[0] + (jit[j][1]-0.5)*O.dyco[0] ;
+ R.co[1]+= (jit[j][0]-0.5)*O.dxco[1] + (jit[j][1]-0.5)*O.dyco[1] ;
+ R.co[2]+= (jit[j][0]-0.5)*O.dxco[2] + (jit[j][1]-0.5)*O.dyco[2] ;
+
+ traceray(R.mat->ray_depth_tra, R.co, vec, tracol, mask);
+
+ VecAddf(accur, accur, tracol);
+ divr+= 1.0;
+
+ /* restore */
+ VECCOPY(R.co, rco);
+ R.vlr= vlr;
+ R.mat= vlr->mat;
+ R.matren= R.mat->ren;
}
-
- R.co[0]+= (jit[j][0]-0.5)*O.dxco[0] + (jit[j][1]-0.5)*O.dyco[0] ;
- R.co[1]+= (jit[j][0]-0.5)*O.dxco[1] + (jit[j][1]-0.5)*O.dyco[1] ;
- R.co[2]+= (jit[j][0]-0.5)*O.dxco[2] + (jit[j][1]-0.5)*O.dyco[2] ;
-
- /* we use a new mask here, only shadow uses it */
- /* result in accum, this is copied to R.refcol for shade_lamp_loop */
- traceray(1.0, R.mat->ray_depth, R.co, vec, col, 1<<j);
-
- VecAddf(accum, accum, col);
- div+= 1.0;
- /* restore */
- VECCOPY(R.co, rco);
- R.vlr= vlr;
- R.mat= vlr->mat;
- R.matren= R.mat->ren;
+ if(do_mir) {
+ vec[0]= ref[0] + 2.0*(jit[j][0]-0.5)*dxref[0] + 2.0*(jit[j][1]-0.5)*dyref[0] ;
+ vec[1]= ref[1] + 2.0*(jit[j][0]-0.5)*dxref[1] + 2.0*(jit[j][1]-0.5)*dyref[1] ;
+ vec[2]= ref[2] + 2.0*(jit[j][0]-0.5)*dxref[2] + 2.0*(jit[j][1]-0.5)*dyref[2] ;
+
+ /* prevent normal go to backside */
+ i= vec[0]*R.vlr->n[0]+ vec[1]*R.vlr->n[1]+ vec[2]*R.vlr->n[2];
+ if(i>0.0) {
+ i+= .01;
+ vec[0]-= i*R.vlr->n[0];
+ vec[1]-= i*R.vlr->n[1];
+ vec[2]-= i*R.vlr->n[2];
+ }
+
+ R.co[0]+= (jit[j][0]-0.5)*O.dxco[0] + (jit[j][1]-0.5)*O.dyco[0] ;
+ R.co[1]+= (jit[j][0]-0.5)*O.dxco[1] + (jit[j][1]-0.5)*O.dyco[1] ;
+ R.co[2]+= (jit[j][0]-0.5)*O.dxco[2] + (jit[j][1]-0.5)*O.dyco[2] ;
+
+ /* we use a new mask here, only shadow uses it */
+ /* result in accum, this is copied to shade_lamp_loop */
+ traceray(R.mat->ray_depth, R.co, vec, mircol, 1<<j);
+
+ VecAddf(accum, accum, mircol);
+ div+= 1.0;
+
+ /* restore */
+ VECCOPY(R.co, rco);
+ R.vlr= vlr;
+ R.mat= vlr->mat;
+ R.matren= R.mat->ren;
+ }
}
}
- R.refcol[0]= R.mat->ray_mirror;
- R.refcol[1]= R.mat->ray_mirror*accum[0]/div;
- R.refcol[2]= R.mat->ray_mirror*accum[1]/div;
- R.refcol[3]= R.mat->ray_mirror*accum[2]/div;
+
+ if(divr!=0.0) {
+ f= shr->alpha; f1= 1.0-f; f1/= divr;
+ shr->diff[0]= f*shr->diff[0] + f1*accur[0];
+ shr->diff[1]= f*shr->diff[1] + f1*accur[1];
+ shr->diff[2]= f*shr->diff[2] + f1*accur[2];
+ shr->alpha= 1.0;
+ }
+
+ if(div!=0.0) {
+ i= R.mat->ray_mirror;
+ fr= R.mat->mirr;
+ fg= R.mat->mirg;
+ fb= R.mat->mirb;
+
+ /* result */
+ f= i*fr*(1.0-shr->spec[0]); f1= 1.0-i; f/= div;
+ shr->diff[0]= f*accum[0] + f1*shr->diff[0];
+
+ f= i*fg*(1.0-shr->spec[1]); f1= 1.0-i; f/= div;
+ shr->diff[1]= f*accum[1] + f1*shr->diff[1];
+
+ f= i*fb*(1.0-shr->spec[2]); f1= 1.0-i; f/= div;
+ shr->diff[2]= f*accum[2] + f1*shr->diff[2];
+ }
}
else {
- i= -2.0*(R.vn[0]*R.view[0]+R.vn[1]*R.view[1]+R.vn[2]*R.view[2]);
- vec[0]= (R.view[0]+i*R.vn[0]);
- vec[1]= (R.view[1]+i*R.vn[1]);
- vec[2]= (R.view[2]+i*R.vn[2]);
-
- /* test phong normals, then we should prevent vector going to the back */
- if(R.vlr->flag & R_SMOOTH) {
- i= vec[0]*R.vno[0]+ vec[1]*R.vno[1]+ vec[2]*R.vno[2];
- if(i>0.0) {
- i+= .01;
- vec[0]-= i*R.vno[0];
- vec[1]-= i*R.vno[1];
- vec[2]-= i*R.vno[2];
- }
+ if(do_tra) {
+ float rvn[3], view[3], rco[3], ref[3], refract[3];
+
+ /* store variables which change during tracing */
+ VECCOPY(view, R.view);
+ VECCOPY(rco, R.co);
+ VECCOPY(rvn, R.vn);
+ VECCOPY(ref, R.ref);
+
+ refraction(refract, R.vn, R.view, R.mat->ang);
+ traceray(R.mat->ray_depth_tra, R.co, refract, tracol, mask);
+
+ f= shr->alpha; f1= 1.0-f;
+ shr->diff[0]= f*shr->diff[0] + f1*tracol[0];
+ shr->diff[1]= f*shr->diff[1] + f1*tracol[1];
+ shr->diff[2]= f*shr->diff[2] + f1*tracol[2];
+ shr->alpha= 1.0;
+
+ /* store variables which change during tracing */
+ VECCOPY(R.view, view);
+ VECCOPY(R.co, rco);
+ VECCOPY(R.ref, ref);
+ VECCOPY(R.vn, rvn);
+ R.vlr= vlr;
+ R.mat= vlr->mat;
+ R.matren= R.mat->ren;
}
- /* result in r.refcol, this is added in shade_lamp_loop */
- i= R.mat->ray_mirror;
- traceray(1.0, R.mat->ray_depth, R.co, vec, R.refcol+1, mask);
- R.refcol[0]= i;
- R.refcol[1]*= i;
- R.refcol[2]*= i;
- R.refcol[3]*= i;
+ if(do_mir) {
+ i= R.mat->ray_mirror*fresnel_fac(R.view, R.vn, R.mat->fresnel_mir, R.mat->falloff_mir);
+ if(i!=0.0) {
+ fr= R.mat->mirr;
+ fg= R.mat->mirg;
+ fb= R.mat->mirb;
+
+ if(R.vlr->flag & R_SMOOTH)
+ reflection(vec, R.vn, R.view, R.vlr->n);
+ else
+ reflection(vec, R.vn, R.view, NULL);
+
+ traceray(R.mat->ray_depth, R.co, vec, mircol, mask);
+
+ f= i*fr*(1.0-shr->spec[0]); f1= 1.0-i;
+ shr->diff[0]= f*mircol[0] + f1*shr->diff[0];
+
+ f= i*fg*(1.0-shr->spec[1]); f1= 1.0-i;
+ shr->diff[1]= f*mircol[1] + f1*shr->diff[1];
+
+ f= i*fb*(1.0-shr->spec[2]); f1= 1.0-i;
+ shr->diff[2]= f*mircol[2] + f1*shr->diff[2];
+ }
+ }
}
}
diff --git a/source/blender/render/intern/source/renderHelp.c b/source/blender/render/intern/source/renderHelp.c
index 6566e982f1d..d1ee202748d 100644
--- a/source/blender/render/intern/source/renderHelp.c
+++ b/source/blender/render/intern/source/renderHelp.c
@@ -265,8 +265,8 @@ void set_normalflags(void)
for(a1=0; a1<R.totvlak; a1++) {
if((a1 & 255)==0) vlr= R.blovl[a1>>8];
else vlr++;
-
- if(vlr->flag & R_NOPUNOFLIP) {
+
+ if((vlr->flag & R_NOPUNOFLIP)) {
/* we flip render normal here, is not that neat, but otherwise render() needs rewrite... */
vlr->n[0]= -vlr->n[0];
vlr->n[1]= -vlr->n[1];
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index c86a8299538..d1bc18fb544 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -1552,12 +1552,22 @@ void RE_calc_R_ref()
}
+float fresnel_fac(float *view, float *vn, float fresnel, float falloff)
+{
+ float fac= fabs(view[0]*vn[0] + view[1]*vn[1] + view[2]*vn[2]);
+
+ if(falloff>0.0) fac= pow(fac, falloff); else fac= 1.0;
+ if(fac>1.0) fac= 1.0;
+
+ return (1.0 - fresnel*fac);
+}
+
/* mask is used to define the amount of rays/samples */
-void shade_lamp_loop(int mask)
+void shade_lamp_loop(int mask, ShadeResult *shr)
{
LampRen *lar;
Material *ma;
- float i, inp, inpr, t, lv[3], lampdist, ld = 0, ir, ig, ib, isr=0,isg=0,isb=0;
+ float i, inp, inpr, t, lv[3], lampdist, ld = 0;
float lvrot[3], *vn, *view, shadfac, soft;
int a;
@@ -1565,8 +1575,12 @@ void shade_lamp_loop(int mask)
view= R.view;
ma= R.matren;
+ memset(shr, 0, sizeof(ShadeResult));
+
/* separate loop */
if(ma->mode & MA_ONLYSHADOW) {
+ float ir;
+
shadfac= ir= 0.0;
for(a=0; a<R.totlamp; a++) {
lar= R.la[a];
@@ -1603,9 +1617,7 @@ void shade_lamp_loop(int mask)
}
}
if(ir>0.0) shadfac/= ir;
- ma->alpha= (R.mat->alpha)*(1.0-shadfac);
-
- shortcol[0]=shortcol[1]=shortcol[2]= 0;
+ shr->alpha= (R.mat->alpha)*(1.0-shadfac);
return;
}
@@ -1615,6 +1627,8 @@ void shade_lamp_loop(int mask)
ma->g= R.vcol[1];
ma->b= R.vcol[2];
}
+
+ ma->alpha= R.mat->alpha; // copy to render material, for fresnel and spectra
if(ma->texco) {
if(ma->mode & (MA_VERTEXCOLP|MA_FACETEXTURE)) {
@@ -1626,38 +1640,18 @@ void shade_lamp_loop(int mask)
}
if(ma->mode & MA_SHLESS) {
- ir= ma->r;
- ig= ma->g;
- ib= ma->b;
-
- if(usegamtab) {
- a= 65535*ir;
- if(a<0) a=0; else if(a>65535) a= 65535;
- shortcol[0]= igamtab2[a];
- a= 65535*ig;
- if(a<0) a=0; else if(a>65535) a= 65535;
- shortcol[1]= igamtab2[a];
- a= 65535*ib;
- if(a<0) a=0; else if(a>65535) a= 65535;
- shortcol[2]= igamtab2[a];
- }
- else {
- a= 65535*ir;
- if(a<0) shortcol[0]= 0; else if(a>65535) shortcol[0]= 65535; else shortcol[0]= a;
- a= 65535*ig;
- if(a<0) shortcol[1]= 0; else if(a>65535) shortcol[1]= 65535; else shortcol[1]= a;
- a= 65535*ib;
- if(a<0) shortcol[2]= 0; else if(a>65535) shortcol[2]= 65535; else shortcol[2]= a;
- }
+ shr->diff[0]= ma->r;
+ shr->diff[1]= ma->g;
+ shr->diff[2]= ma->b;
return;
}
if( (ma->mode & (MA_VERTEXCOL+MA_VERTEXCOLP))== MA_VERTEXCOL ) {
- ir= ma->emit+R.vcol[0];
- ig= ma->emit+R.vcol[1];
- ib= ma->emit+R.vcol[2];
+ shr->diff[0]= ma->emit+R.vcol[0];
+ shr->diff[1]= ma->emit+R.vcol[1];
+ shr->diff[2]= ma->emit+R.vcol[2];
}
- else ir= ig= ib= ma->emit;
+ else shr->diff[0]= shr->diff[1]= shr->diff[2]= ma->emit;
for(a=0; a<R.totlamp; a++) {
lar= R.la[a];
@@ -1749,9 +1743,9 @@ void shade_lamp_loop(int mask)
shadfac = 1.0 - testshadowbuf(lar->shb, inp);
if(shadfac>0.0) {
shadfac*= inp*soft*lar->energy;
- ir -= shadfac;
- ig -= shadfac;
- ib -= shadfac;
+ shr->diff[0] -= shadfac;
+ shr->diff[1] -= shadfac;
+ shr->diff[2] -= shadfac;
continue;
}
@@ -1839,9 +1833,9 @@ void shade_lamp_loop(int mask)
}
t= ma->spec*spec(t, ma->har);
- isr+= t*(lar->r * ma->specr);
- isg+= t*(lar->g * ma->specg);
- isb+= t*(lar->b * ma->specb);
+ shr->spec[0]+= t*(lar->r * ma->specr);
+ shr->spec[1]+= t*(lar->g * ma->specg);
+ shr->spec[2]+= t*(lar->b * ma->specb);
}
else {
/* specular shaders */
@@ -1858,93 +1852,55 @@ void shade_lamp_loop(int mask)
t= shadfac*ma->spec*lampdist*specfac;
- isr+= t*(lar->r * ma->specr);
- isg+= t*(lar->g * ma->specg);
- isb+= t*(lar->b * ma->specb);
+ shr->spec[0]+= t*(lar->r * ma->specr);
+ shr->spec[1]+= t*(lar->g * ma->specg);
+ shr->spec[2]+= t*(lar->b * ma->specb);
}
}
}
/* in case 'no diffuse' we still do most calculus, spec can be in shadow */
if(i>0.0 && !(lar->mode & LA_NO_DIFF)) {
- ir+= i*lar->r;
- ig+= i*lar->g;
- ib+= i*lar->b;
+ shr->diff[0]+= i*lar->r;
+ shr->diff[1]+= i*lar->g;
+ shr->diff[2]+= i*lar->b;
}
}
-
- /* sum shading here, to make all variables local (because of raytrace) */
- if(ir<0.0) ir= 0.0; else ir*= ma->r;
- ir+= ma->ambr +ma->amb*R.rad[0];
-
- if(ig<0.0) ig= 0.0; else ig*= ma->g;
- ig+= ma->ambg +ma->amb*R.rad[1];
-
- if(ib<0.0) ib= 0.0; else ib*= ma->b;
- ib+= ma->ambb +ma->amb*R.rad[2];
-
- if(isr<0.0) isr= 0.0;
- if(isg<0.0) isg= 0.0;
- if(isb<0.0) isb= 0.0;
- if(ma->mode & MA_ZTRA) { /* ztra shade */
+ if(ma->mode & (MA_ZTRA|MA_RAYTRANSP)) {
+ if(ma->fresnel_tra!=0.0)
+ ma->alpha*= fresnel_fac(R.view, R.vn, ma->fresnel_tra, ma->falloff_tra);
+
if(ma->spectra!=0.0) {
- t = MAX3(isr, isb, isg);
+ t = MAX3(shr->spec[0], shr->spec[1], shr->spec[2]);
t *= ma->spectra;
if(t>1.0) t= 1.0;
- if(ma->mapto & MAP_ALPHA) ma->alpha= (1.0-t)*ma->alpha+t;
- else ma->alpha= (1.0-t)*R.mat->alpha+t;
+ ma->alpha= (1.0-t)*ma->alpha+t;
}
}
- /* Result of ray_mirror() is written in R.refcol.
- Ugly is that shade_lamp_loop is called from within ray_mirror as well */
- if(R.r.mode & R_RAYTRACE) {
- if(ma->ray_mirror!=0.0) {
- static int only_once= 1;
- if(only_once) {
- float mirr= ma->mirr, mirg= ma->mirg, mirb= ma->mirb;
- extern void ray_mirror(int);
-
- only_once= 0;
- ray_mirror(mask);
- only_once= 1;
-
- /* this is because the material mir color can be textured */
- ma->mirr= mirr; ma->mirb= mirb; ma->mirg= mirg;
- }
- }
- }
+ shr->alpha= ma->alpha;
+
+ if(shr->spec[0]<0.0) shr->spec[0]= 0.0;
+ if(shr->spec[1]<0.0) shr->spec[1]= 0.0;
+ if(shr->spec[2]<0.0) shr->spec[2]= 0.0;
+
+ if(shr->diff[0]<0.0) shr->diff[0]= 0.0; else shr->diff[0]*= ma->r;
+ shr->diff[0]+= ma->ambr +ma->amb*R.rad[0];
- if(R.refcol[0]==0.0) {
- a= 65535.0*( ir + isr);
- if(a>65535) a=65535; else if(a<0) a= 0;
- shortcol[0]= a;
- a= 65535.0*(ig + isg);
- if(a>65535) a=65535; else if(a<0) a= 0;
- shortcol[1]= a;
- a= 65535*(ib + isb);
- if(a>65535) a=65535; else if(a<0) a= 0;
- shortcol[2]= a;
- }
- else {
- a= 65535.0*( ma->mirr*R.refcol[1] + (1.0 - ma->mirr*R.refcol[0])*ir +isr);
- if(a>65535) a=65535; else if(a<0) a= 0;
- shortcol[0]= a;
- a= 65535.0*( ma->mirg*R.refcol[2] + (1.0 - ma->mirg*R.refcol[0])*ig +isg);
- if(a>65535) a=65535; else if(a<0) a= 0;
- shortcol[1]= a;
- a= 65535.0*( ma->mirb*R.refcol[3] + (1.0 - ma->mirb*R.refcol[0])*ib +isb);
- if(a>65535) a=65535; else if(a<0) a= 0;
- shortcol[2]= a;
- }
-
- if(usegamtab) {
- shortcol[0]= igamtab2[ shortcol[0] ];
- shortcol[1]= igamtab2[ shortcol[1] ];
- shortcol[2]= igamtab2[ shortcol[2] ];
+ if(shr->diff[1]<0.0) shr->diff[1]= 0.0; else shr->diff[1]*= ma->g;
+ shr->diff[1]+= ma->ambg +ma->amb*R.rad[1];
+
+ if(shr->diff[2]<0.0) shr->diff[2]= 0.0; else shr->diff[2]*= ma->b;
+ shr->diff[2]+= ma->ambb +ma->amb*R.rad[2];
+
+ if(R.refcol[0]!=0.0) {
+ shr->diff[0]= ma->mirr*R.refcol[1] + (1.0 - ma->mirr*R.refcol[0])*shr->diff[0];
+ shr->diff[1]= ma->mirg*R.refcol[2] + (1.0 - ma->mirg*R.refcol[0])*shr->diff[1];
+ shr->diff[2]= ma->mirb*R.refcol[3] + (1.0 - ma->mirb*R.refcol[0])*shr->diff[2];
}
+
}
@@ -1955,6 +1911,7 @@ void shadepixel(float x, float y, int vlaknr, int mask)
static VertRen *v1, *v2, *v3;
static float t00, t01, t10, t11, dvlak, n1[3], n2[3], n3[3];
static float s00, s01, s10, s11;
+ ShadeResult shr;
float *o1, *o2, *o3;
float u, v, l, dl, hox, hoy, detsh, fac, deler, alpha;
char *cp1, *cp2, *cp3;
@@ -2350,7 +2307,33 @@ void shadepixel(float x, float y, int vlaknr, int mask)
R.winco[1]= (y+(R.ystart))/(float)R.afmy;
}
- shade_lamp_loop(mask);
+ shade_lamp_loop(mask, &shr);
+
+ if(R.r.mode & R_RAYTRACE) {
+ if(R.matren->ray_mirror!=0.0 || (R.mat->mode & MA_RAYTRANSP && shr.alpha!=1.0)) {
+ extern void ray_trace(int, ShadeResult *);
+
+ ray_trace(mask, &shr);
+ }
+ }
+
+ fac= shr.diff[0] + shr.spec[0];
+ if(fac<=0.0) shortcol[0]= 0; else if(fac>=1.0) shortcol[0]= 65535;
+ else shortcol[0]= 65535.0*fac;
+
+ fac= shr.diff[1] + shr.spec[1];
+ if(fac<=0.0) shortcol[1]= 0; else if(fac>=1.0) shortcol[1]= 65535;
+ else shortcol[1]= 65535.0*fac;
+
+ fac= shr.diff[2] + shr.spec[2];
+ if(fac<=0.0) shortcol[2]= 0; else if(fac>=1.0) shortcol[2]= 65535;
+ else shortcol[2]= 65535.0*fac;
+
+ if(usegamtab) {
+ shortcol[0]= igamtab2[ shortcol[0] ];
+ shortcol[1]= igamtab2[ shortcol[1] ];
+ shortcol[2]= igamtab2[ shortcol[2] ];
+ }
/* MIST */
if( (R.wrld.mode & WO_MIST) && (R.matren->mode & MA_NOMIST)==0 ){
@@ -2358,8 +2341,8 @@ void shadepixel(float x, float y, int vlaknr, int mask)
}
else alpha= 1.0;
- if(R.matren->alpha!=1.0 || alpha!=1.0) {
- fac= alpha*(R.matren->alpha);
+ if(shr.alpha!=1.0 || alpha!=1.0) {
+ fac= alpha*(shr.alpha);
/* gamma */
if(R.osa && usegamtab) fac*= fac;
diff --git a/source/blender/renderconverter/intern/convertBlenderScene.c b/source/blender/renderconverter/intern/convertBlenderScene.c
index 3f20e1166f6..310000b8624 100644
--- a/source/blender/renderconverter/intern/convertBlenderScene.c
+++ b/source/blender/renderconverter/intern/convertBlenderScene.c
@@ -1660,7 +1660,7 @@ static void init_render_mesh(Object *ob)
vlr->mat= ma;
vlr->puno= mface->puno;
vlr->flag= mface->flag;
- if(me->flag & ME_NOPUNOFLIP) {
+ if((me->flag & ME_NOPUNOFLIP) || (ma->mode & MA_RAYTRANSP)) {
vlr->flag |= R_NOPUNOFLIP;
vlr->puno= 15;
}
@@ -2132,7 +2132,7 @@ static void init_render_surf(Object *ob)
vlr->mat= matar[ dl->col];
vlr->ec= ME_V1V2+ME_V2V3;
vlr->flag= dl->rt;
- if(cu->flag & CU_NOPUNOFLIP) {
+ if( (cu->flag & CU_NOPUNOFLIP) || (vlr->mat->mode & MA_RAYTRANSP)) {
vlr->flag |= R_NOPUNOFLIP;
vlr->puno= 15;
}
@@ -2272,7 +2272,7 @@ static void init_render_surf(Object *ob)
vlr->mat= matar[ dl->col];
vlr->ec= ME_V1V2+ME_V2V3;
vlr->flag= dl->rt;
- if(cu->flag & CU_NOPUNOFLIP) {
+ if( (cu->flag & CU_NOPUNOFLIP) || (vlr->mat->mode & MA_RAYTRANSP)) {
vlr->flag |= R_NOPUNOFLIP;
vlr->puno= 15;
}
diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c
index ec5b2710a01..452c5b4ccab 100644
--- a/source/blender/src/buttons_shading.c
+++ b/source/blender/src/buttons_shading.c
@@ -1662,15 +1662,23 @@ void do_lampbuts(unsigned short event)
BIF_preview_changed(G.buts);
}
break;
- case B_SBUFF:
- {
- la= G.buts->lockpoin;
- la->bufsize = la->bufsize&=(~15);
- allqueue(REDRAWBUTSSHADING, 0);
- allqueue(REDRAWOOPS, 0);
- /*la->bufsize = la->bufsize % 64;*/
- }
+ case B_SBUFF:
+ la= G.buts->lockpoin;
+ la->bufsize = la->bufsize&=(~15);
+ allqueue(REDRAWBUTSSHADING, 0);
+ allqueue(REDRAWOOPS, 0);
break;
+ case B_SHADBUF:
+ la= G.buts->lockpoin;
+ la->mode &= ~LA_SHAD_RAY;
+ allqueue(REDRAWBUTSSHADING, 0);
+ allqueue(REDRAWVIEW3D, 0);
+ break;
+ case B_SHADRAY:
+ la= G.buts->lockpoin;
+ la->mode &= ~LA_SHAD;
+ allqueue(REDRAWBUTSSHADING, 0);
+ break;
}
if(event) freefastshade();
@@ -1816,8 +1824,8 @@ static void lamp_panel_spot(Object *ob, Lamp *la)
uiBlockSetCol(block, TH_BUT_SETTING1);
uiBlockBeginAlign(block);
- uiDefButS(block, TOG|BIT|13, B_REDR,"Ray Shadow", 10,180,80,19,&la->mode, 0, 0, 0, 0, "Use ray tracing for shadow");
- uiDefButS(block, TOG|BIT|0, REDRAWVIEW3D, "Buf.Shadow",10,160,80,19,&la->mode, 0, 0, 0, 0, "Lets spotlight produce shadows using shadow buffer");
+ uiDefButS(block, TOG|BIT|13, B_SHADRAY,"Ray Shadow", 10,180,80,19,&la->mode, 0, 0, 0, 0, "Use ray tracing for shadow");
+ uiDefButS(block, TOG|BIT|0, B_SHADBUF, "Buf.Shadow",10,160,80,19,&la->mode, 0, 0, 0, 0, "Lets spotlight produce shadows using shadow buffer");
uiBlockEndAlign(block);
uiDefButS(block, TOG|BIT|5, 0,"OnlyShadow", 10,120,80,19,&la->mode, 0, 0, 0, 0, "Causes spotlight to cast shadows only without illuminating objects");
@@ -2005,6 +2013,23 @@ void do_matbuts(unsigned short event)
ma->lay= 1;
scrarea_queue_winredraw(curarea);
}
+ break;
+ case B_MATZTRANSP:
+ ma= G.buts->lockpoin;
+ if(ma) {
+ ma->mode &= ~MA_RAYTRANSP;
+ allqueue(REDRAWBUTSSHADING, 0);
+ BIF_preview_changed(G.buts);
+ }
+ break;
+ case B_MATRAYTRANSP:
+ ma= G.buts->lockpoin;
+ if(ma) {
+ ma->mode &= ~MA_ZTRA;
+ allqueue(REDRAWBUTSSHADING, 0);
+ BIF_preview_changed(G.buts);
+ }
+ break;
}
}
@@ -2216,6 +2241,33 @@ static void material_panel_texture(Material *ma)
uiBlockSetCol(block, TH_AUTO);
}
+static void material_panel_raytrace(Material *ma)
+{
+ uiBlock *block;
+
+ block= uiNewBlock(&curarea->uiblocks, "material_panel_raytrace", UI_EMBOSS, UI_HELV, curarea->win);
+ uiNewPanelTabbed("Shaders", "Material");
+ if(uiNewPanel(curarea, block, "Raytrace", "Material", 640, 0, 318, 204)==0) return;
+
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUMSLI, B_MATPRV, "RayMir ", 10,160,200,19, &(ma->ray_mirror), 0.0, 1.0, 0, 2, "Sets the amount mirror reflection for raytrace");
+ uiDefButS(block, NUM, B_MATPRV, "Depth:", 210,160,100,19, &(ma->ray_depth), 0.0, 6.0, 0, 0, "Amount of inter-reflections calculated maximal ");
+ uiDefButF(block, NUMSLI, B_MATPRV, "Fresnel ", 10,140,200,19, &(ma->fresnel_mir), 0.0, 1.0, 0, 2, "Sets Fresnel falloff for mirror reflection");
+ uiDefButF(block, NUM, B_MATPRV, "Falloff ", 210,140,100,19, &(ma->falloff_mir), 0.0, 5.0, 0, 2, "Sets the falloff strength of Fresnel");
+
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUMSLI, B_MATPRV, "Ang Index ",10,80,200,19, &(ma->ang), 0.0, 1.0, 0, 2, "Sets the angular index of refraction for raytrace");
+ uiDefButS(block, NUM, B_MATPRV, "Depth:", 210,80,100,19, &(ma->ray_depth_tra), 0.0, 6.0, 0, 0, "Amount of refractions calculated maximal ");
+ uiDefButF(block, NUMSLI, B_MATPRV, "Fresnel ", 10,60,200,19, &(ma->fresnel_tra), 0.0, 1.0, 0, 2, "Sets Fresnel falloff for transparency");
+ uiDefButF(block, NUM, B_MATPRV, "Falloff ", 210,60,100,19, &(ma->falloff_tra), 0.0, 5.0, 0, 2, "Sets the falloff strength of Fresnel");
+ uiBlockEndAlign(block);
+
+ uiBlockSetCol(block, TH_BUT_SETTING1);
+ uiDefButI(block, TOG|BIT|18, B_MATPRV, "Ray Mirror", 160,185,150,19, &(ma->mode), 0, 0, 0, 0, "Enables raytracing for mirror reflection rendering");
+ uiDefButI(block, TOG|BIT|17, B_MATRAYTRANSP,"Ray Transp",160,105,150,19, &(ma->mode), 0, 0, 0, 0, "Enables raytracing for transparency rendering");
+
+}
+
static void material_panel_shading(Material *ma)
{
uiBlock *block;
@@ -2287,13 +2339,9 @@ static void material_panel_shading(Material *ma)
uiDefButF(block, NUMSLI, B_MATPRV, "Size:", 90, 100,150,19, &(ma->param[2]), 0.0, 1.53, 0, 0, "Sets the size of specular toon area");
uiDefButF(block, NUMSLI, B_MATPRV, "Smooth:",90, 80,150,19, &(ma->param[3]), 0.0, 1.0, 0, 0, "Sets the smoothness of specular toon area");
}
-
+ uiBlockEndAlign(block);
/* default shading variables */
- uiBlockBeginAlign(block);
- uiDefButF(block, NUMSLI, 0, "RayMir ", 9,55,154,19, &(ma->ray_mirror), 0.0, 1.0, 0, 0, "Sets the amount mirror reflection for raytrace");
- uiDefButS(block, NUM, 0, "Depth:", 163,55,80,19, &(ma->ray_depth), 0.0, 6.0, 0, 0, "Amount of inter-reflections calculated maximal ");
- uiBlockEndAlign(block);
uiDefButF(block, NUMSLI, B_MATPRV, "Amb ", 9,30,117,19, &(ma->amb), 0.0, 1.0, 0, 0, "Sets the amount of global ambient color the material receives");
uiDefButF(block, NUMSLI, B_MATPRV, "Emit ", 133,30,110,19, &(ma->emit), 0.0, 1.0, 0, 0, "Sets the amount of light the material emits");
uiDefButF(block, NUMSLI, B_MATPRV, "Add ", 9,10,117,19, &(ma->add), 0.0, 1.0, 0, 0, "Sets a glow factor for transparant materials");
@@ -2305,7 +2353,7 @@ static void material_panel_shading(Material *ma)
uiDefButI(block, TOG|BIT|1, 0, "Shadow", 245,142,65,18, &(ma->mode), 0, 0, 0, 0, "Makes material receive shadows from spotlights");
uiDefButI(block, TOG|BIT|16, 0, "Radio", 245,123,65,18, &(ma->mode), 0, 0, 0, 0, "Enables material for radiosty rendering");
uiDefButI(block, TOG|BIT|3, 0, "Wire", 245,104,65,18, &(ma->mode), 0, 0, 0, 0, "Renders only the edges of faces as a wireframe");
- uiDefButI(block, TOG|BIT|6, 0, "ZTransp", 245,85, 65,18, &(ma->mode), 0, 0, 0, 0, "Enables Z-Buffering of transparent faces");
+ uiDefButI(block, TOG|BIT|6, B_MATZTRANSP,"ZTransp", 245,85, 65,18, &(ma->mode), 0, 0, 0, 0, "Enables Z-Buffering of transparent faces");
uiDefButI(block, TOG|BIT|9, 0, "Env", 245,66, 65,18, &(ma->mode), 0, 0, 0, 0, "Causes faces to disappear: allows world to show through");
uiDefButI(block, TOG|BIT|10, 0, "OnlyShadow", 245,47, 65,18, &(ma->mode), 0, 0, 0, 0, "Renders shadows falling on material only");
uiDefButI(block, TOG|BIT|14, 0, "No Mist", 245,28, 65,18, &(ma->mode), 0, 0, 0, 0, "Sets the material to ignore mist values");
@@ -2482,6 +2530,7 @@ void material_panels()
if(ma) {
material_panel_shading(ma);
+ material_panel_raytrace(ma);
material_panel_texture(ma);
mtex= ma->mtex[ ma->texact ];
diff --git a/source/blender/src/previewrender.c b/source/blender/src/previewrender.c
index 5b4bff52cb2..0b302a40602 100644
--- a/source/blender/src/previewrender.c
+++ b/source/blender/src/previewrender.c
@@ -86,8 +86,8 @@
#include "RE_renderconverter.h"
-#define PR_RECTX 121
-#define PR_RECTY 121
+#define PR_RECTX 141
+#define PR_RECTY 141
#define PR_XMIN 10
#define PR_YMIN 5
#define PR_XMAX 200
@@ -219,6 +219,14 @@ static int ray_previewrender(int x,
static unsigned int previewback(int type, int x, int y)
{
+
+ /* checkerboard, for later
+ x+= PR_RECTX/2;
+ y+= PR_RECTX/2;
+ if( ((x/24) + (y/24)) & 1) return 0x40404040;
+ else return 0xa0a0a0a0;
+ */
+
if(type & MA_DARK) {
if(abs(x)>abs(y)) return 0;
else return 0x40404040;
@@ -667,8 +675,40 @@ static float pr2_lamp[3]= {-8.8, -5.6, -1.5};
static float pr1_col[3]= {0.8, 0.8, 0.8};
static float pr2_col[3]= {0.5, 0.6, 0.7};
+static void refraction_prv(int *x, int *y, float *n, float index)
+{
+ float dot, fac, view[3], len;
+
+
+ if(index==0.0) return;
+
+ view[0]= index*(float)*x;
+ view[1]= ((float)*y)/index;
+ view[2]= 20.0;
+ len= Normalise(view);
+
+ dot= view[0]*n[0] + view[1]*n[1] + view[2]*n[2];
+
+ if(dot>0.0) {
+ fac= 1.0 - (1.0 - dot*dot)*index*index;
+ if(fac<= 0.0) return;
+ fac= -dot*index + sqrt(fac);
+ }
+ else {
+ index = 1.0/index;
+ fac= 1.0 - (1.0 - dot*dot)*index*index;
+ if(fac<= 0.0) return;
+ fac= -dot*index - sqrt(fac);
+ }
+
+ *x= (int)(len*(index*view[0] + fac*n[0]));
+ *y= (int)(len*(index*view[1] + fac*n[1]));
+}
+
+
static void shade_preview_pixel(float *vec, int x, int y,char *rect, int smooth)
{
+ extern float fresnel_fac(float *view, float *vn, float fresnel, float falloff);
Material *mat;
float v1,inp, inprspec=0, isr=0.0, isb=0.0, isg=0.0;
float ir=0.0, ib=0.0, ig=0.0;
@@ -678,13 +718,6 @@ static void shade_preview_pixel(float *vec, int x, int y,char *rect, int smooth)
char tracol;
mat= R.matren;
- /* pr1_lamp[0]= mat->mtex[0]->ofs[0]; */
- /* pr1_lamp[1]= mat->mtex[0]->ofs[1]; */
- /* pr1_lamp[2]= mat->mtex[0]->ofs[2]; */
-
- /* pr2_lamp[0]= mat->mtex[0]->size[0]; */
- /* pr2_lamp[1]= mat->mtex[0]->size[1]; */
- /* pr2_lamp[2]= mat->mtex[0]->size[2]; */
v1= 1.0/PR_RECTX;
view[0]= v1*x;
@@ -738,7 +771,8 @@ static void shade_preview_pixel(float *vec, int x, int y,char *rect, int smooth)
inp= -2.0*(R.vn[0]*view[0]+R.vn[1]*view[1]+R.vn[2]*view[2]);
R.ref[0]= (view[0]+inp*R.vn[0]);
- R.ref[1]= -(view[1]+inp*R.vn[1]);
+ R.ref[1]= (view[1]+inp*R.vn[1]);
+ if(smooth) R.ref[1]= -R.ref[1];
R.ref[2]= (view[2]+inp*R.vn[2]);
}
@@ -815,6 +849,38 @@ static void shade_preview_pixel(float *vec, int x, int y,char *rect, int smooth)
ig+= inp*la[1];
ib+= inp*la[2];
}
+
+ /* drawing checkerboard and sky */
+ if(mat->mode & MA_RAYMIRROR) {
+ float col, div, y, z;
+ int fac;
+
+ /* rotate a bit in x */
+ y= R.ref[1]; z= R.ref[2];
+ R.ref[1]= 0.98*y - 0.17*z;
+ R.ref[2]= 0.17*y + 0.98*z;
+
+ /* scale */
+ div= (0.85*R.ref[1]);
+
+ R.refcol[0]= mat->ray_mirror*fresnel_fac(view, R.vn, mat->fresnel_mir, mat->falloff_mir);;
+
+ if(div<0.0) {
+ /* minus 0.5 prevents too many small tiles in distance */
+ fac= (int)(R.ref[0]/(div-0.1) ) + (int)(R.ref[2]/(div-0.1) );
+ if(fac & 1) col= 0.8;
+ else col= 0.3;
+
+ R.refcol[1]= R.refcol[0]*col;
+ R.refcol[2]= R.refcol[1];
+ R.refcol[3]= R.refcol[2];
+ }
+ else {
+ R.refcol[1]= 0.0;
+ R.refcol[2]= R.refcol[0]*0.3*div;
+ R.refcol[3]= R.refcol[0]*0.8*div;
+ }
+ }
if(R.refcol[0]==0.0) {
a= 255.0*( mat->r*ir +mat->ambr +isr);
@@ -840,18 +906,25 @@ static void shade_preview_pixel(float *vec, int x, int y,char *rect, int smooth)
}
}
- if(mat->alpha!=1.0) {
-
- alpha= mat->alpha;
-
- /* ztra shade */
- if(mat->spectra!=0.0) {
- inp= mat->spectra*inprspec;
- if(inp>1.0) inp= 1.0;
-
- alpha= (1.0-inp)*alpha+ inp;
+ alpha= mat->alpha;
+
+ if(mat->mode & (MA_ZTRA|MA_RAYTRANSP))
+ if(mat->fresnel_tra!=0.0)
+ alpha*= fresnel_fac(view, R.vn, mat->fresnel_tra, mat->falloff_tra);
+
+ /* ztra shade */
+ if(mat->spectra!=0.0) {
+ inp = MAX3(isr, isg, isb);
+ inp *= mat->spectra;
+ if(inp>1.0) inp= 1.0;
+ alpha= (1.0-inp)*alpha+inp;
+ }
+
+ if(alpha!=1.0) {
+ if(mat->mode & MA_RAYTRANSP) {
+ refraction_prv(&x, &y, R.vn, mat->ang);
}
-
+
tracol= previewback(mat->pr_back, x, y) & 255;
tracol= (1.0-alpha)*tracol;
@@ -859,7 +932,6 @@ static void shade_preview_pixel(float *vec, int x, int y,char *rect, int smooth)
rect[0]= tracol+ (rect[0]*alpha) ;
rect[1]= tracol+ (rect[1]*alpha) ;
rect[2]= tracol+ (rect[2]*alpha) ;
-
}
}
@@ -924,6 +996,7 @@ void BIF_previewrender(SpaceButs *sbuts)
MTC_Mat4One(R.viewinv);
R.osatex= 0;
+
if(mat) {
/* rendervars */
init_render_world();