diff options
author | Ton Roosendaal <ton@blender.org> | 2004-06-30 22:54:09 +0400 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2004-06-30 22:54:09 +0400 |
commit | a8ef804146751f8b5ec0f83b411f4ab7d041ed84 (patch) | |
tree | e85a6e52b41f7774cf472171ee11783324eec991 | |
parent | c9b4585618ea72f61c4671d4734c9e48b6ce6745 (diff) |
NEW: Ramp shades for diffuse and specular
http://www.blender3d.org/cms/Ramp_Shaders.348.0.html
Material color and specular now can be defined by a Colorband. The actual
color then is defined during shading based on:
- shade value (like dotproduct)
- energy value (dot product plus light)
- normal
- result of all shading (useful for adding stuff in the end)
Special request from [A]ndy! :)
-rw-r--r-- | source/blender/blenkernel/BKE_texture.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/displist.c | 114 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/image.c | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/material.c | 11 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/texture.c | 93 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 19 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 5 | ||||
-rw-r--r-- | source/blender/include/butspace.h | 1 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_material_types.h | 22 | ||||
-rw-r--r-- | source/blender/render/extern/include/render.h | 184 | ||||
-rw-r--r-- | source/blender/render/intern/source/renderHelp.c | 1 | ||||
-rw-r--r-- | source/blender/render/intern/source/rendercore.c | 305 | ||||
-rw-r--r-- | source/blender/render/intern/source/texture.c | 80 | ||||
-rw-r--r-- | source/blender/src/buttons_object.c | 10 | ||||
-rw-r--r-- | source/blender/src/buttons_shading.c | 367 | ||||
-rw-r--r-- | source/blender/src/previewrender.c | 93 |
16 files changed, 883 insertions, 428 deletions
diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h index 547ac593d15..dc1856a4803 100644 --- a/source/blender/blenkernel/BKE_texture.h +++ b/source/blender/blenkernel/BKE_texture.h @@ -51,7 +51,7 @@ void open_plugin_tex(struct PluginTex *pit); struct PluginTex *add_plugin_tex(char *str); void free_plugin_tex(struct PluginTex *pit); struct ColorBand *add_colorband(void); -int do_colorband(struct ColorBand *coba); +int do_colorband(struct ColorBand *coba, float in, float out[4]); void default_tex(struct Tex *tex); struct Tex *add_texture(char *name); void default_mtex(struct MTex *mtex); diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 84167694741..fcb8749fe3b 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -475,8 +475,9 @@ static void fastshade(float *co, float *nor, float *orco, Material *ma, char *co { ShadeInput shi; FastLamp *fl; - float i, t, inp, soft, inpr, inpg, inpb, isr=0, isg=0, isb=0, lv[3], view[3], lampdist, ld; - float inpr1, inpg1, inpb1, isr1=0, isg1=0, isb1=0; + float i, t, inp, is, soft, lv[3], lampdist, ld; + float diff1[3], diff2[3]; + float isr1=0, isg1=0, isb1=0, isr=0, isg=0, isb=0; int a, back; if(ma==0) return; @@ -485,6 +486,7 @@ static void fastshade(float *co, float *nor, float *orco, Material *ma, char *co shi.vlr= NULL; // have to do this! ma= shi.matren; shi.osatex= 0; // also prevents reading vlr + VECCOPY(shi.vn, nor); if(ma->mode & MA_VERTEXCOLP) { if(vertcol) { @@ -496,7 +498,6 @@ static void fastshade(float *co, float *nor, float *orco, Material *ma, char *co if(ma->texco) { VECCOPY(shi.lo, orco); - VECCOPY(shi.vn, nor); if(ma->texco & TEXCO_GLOB) { VECCOPY(shi.gl, shi.lo); @@ -552,19 +553,21 @@ static void fastshade(float *co, float *nor, float *orco, Material *ma, char *co } if( vertcol && (ma->mode & (MA_VERTEXCOL+MA_VERTEXCOLP))== MA_VERTEXCOL ) { - inpr= inpr1= ma->emit+vertcol[3]/255.0; - inpg= inpg1= ma->emit+vertcol[2]/255.0; - inpb= inpb1= ma->emit+vertcol[1]/255.0; + diff1[0]= diff2[0]= ma->r*(ma->emit+vertcol[3]/255.0); + diff1[1]= diff2[1]= ma->g*(ma->emit+vertcol[2]/255.0); + diff1[2]= diff2[2]= ma->b*(ma->emit+vertcol[1]/255.0); } else { - inpr= inpg= inpb= inpr1= inpg1= inpb1= ma->emit; + diff1[0]= diff2[0]= ma->r*ma->emit; + diff1[1]= diff2[1]= ma->g*ma->emit; + diff1[2]= diff2[2]= ma->b*ma->emit; } - view[0]= 0.0; - view[1]= 0.0; - view[2]= 1.0; + shi.view[0]= 0.0; + shi.view[1]= 0.0; + shi.view[2]= 1.0; - Normalise(view); + Normalise(shi.view); for (fl= fastlamplist; fl; fl= fl->next) { /* if(fl->mode & LA_LAYER) if((fl->lay & ma->lay)==0) continue; */ @@ -623,76 +626,103 @@ static void fastshade(float *co, float *nor, float *orco, Material *ma, char *co } } - if(fl->mode & LA_NO_DIFF) inp= 0.0; + if(fl->mode & LA_NO_DIFF) is= 0.0; else { - inp= nor[0]*lv[0]+ nor[1]*lv[1]+ nor[2]*lv[2]; + is= nor[0]*lv[0]+ nor[1]*lv[1]+ nor[2]*lv[2]; - if(ma->diff_shader==MA_DIFF_ORENNAYAR) inp= OrenNayar_Diff(nor, lv, view, ma->roughness); - else if(ma->diff_shader==MA_DIFF_TOON) inp= Toon_Diff(nor, lv, view, ma->param[0], ma->param[1]); + if(ma->diff_shader==MA_DIFF_ORENNAYAR) is= OrenNayar_Diff(nor, lv, shi.view, ma->roughness); + else if(ma->diff_shader==MA_DIFF_TOON) is= Toon_Diff(nor, lv, shi.view, ma->param[0], ma->param[1]); } back= 0; - if(inp<0.0) { + if(is<0.0) { back= 1; - inp= -inp; + is= -is; } - inp*= lampdist*ma->ref; + inp= is*lampdist*ma->ref; if(back==0) { - inpr+= inp*fl->r; - inpg+= inp*fl->g; - inpb+= inp*fl->b; + add_to_diffuse(diff1, &shi, is, inp*fl->r, inp*fl->g, inp*fl->b); + //diff1[0]+= inp*fl->r; + //diff1[1]+= inp*fl->g; + //diff1[2]+= inp*fl->b; } else if(col2) { - inpr1+= inp*fl->r; - inpg1+= inp*fl->g; - inpb1+= inp*fl->b; + add_to_diffuse(diff2, &shi, is, inp*fl->r, inp*fl->g, inp*fl->b); + //diff2[0]+= inp*fl->r; + //diff2[1]+= inp*fl->g; + //diff2[2]+= inp*fl->b; } if(ma->spec && (fl->mode & LA_NO_SPEC)==0) { + float specfac; if(ma->spec_shader==MA_SPEC_PHONG) - t= Phong_Spec(nor, lv, view, ma->har); + specfac= Phong_Spec(nor, lv, shi.view, ma->har); else if(ma->spec_shader==MA_SPEC_COOKTORR) - t= CookTorr_Spec(nor, lv, view, ma->har); + specfac= CookTorr_Spec(nor, lv, shi.view, ma->har); else if(ma->spec_shader==MA_SPEC_BLINN) - t= Blinn_Spec(nor, lv, view, ma->refrac, (float)ma->har); + specfac= Blinn_Spec(nor, lv, shi.view, ma->refrac, (float)ma->har); else - t= Toon_Spec(nor, lv, view, ma->param[2], ma->param[3]); + specfac= Toon_Spec(nor, lv, shi.view, ma->param[2], ma->param[3]); - if(t>0) { - t*= ma->spec*lampdist; + if(specfac>0) { + t= specfac*ma->spec*lampdist; if(back==0) { - isr+= t*(fl->r * ma->specr); - isg+= t*(fl->g * ma->specg); - isb+= t*(fl->b * ma->specb); + if(ma->mode & MA_RAMP_SPEC) { + float spec[3]; + do_specular_ramp(&shi, specfac, t, spec); + isr+= t*(fl->r * spec[0]); + isg+= t*(fl->g * spec[1]); + isb+= t*(fl->b * spec[2]); + } + else { + isr+= t*(fl->r * ma->specr); + isg+= t*(fl->g * ma->specg); + isb+= t*(fl->b * ma->specb); + } } else if(col2) { - isr1+= t*(fl->r * ma->specr); - isg1+= t*(fl->g * ma->specg); - isb1+= t*(fl->b * ma->specb); + if(ma->mode & MA_RAMP_SPEC) { + float spec[3]; + do_specular_ramp(&shi, specfac, t, spec); + isr1+= t*(fl->r * spec[0]); + isg1+= t*(fl->g * spec[1]); + isb1+= t*(fl->b * spec[2]); + } + else { + isr1+= t*(fl->r * ma->specr); + isg1+= t*(fl->g * ma->specg); + isb1+= t*(fl->b * ma->specb); + } } } } } - a= 256*(inpr*ma->r + ma->ambr +isr); + if(ma->mode & MA_RAMP_COL) ramp_diffuse_result(diff1, &shi); + if(ma->mode & MA_RAMP_SPEC) ramp_spec_result(&isr, &isg, &isb, &shi); + + a= 256*(diff1[0] + ma->ambr +isr); if(a>255) col1[3]= 255; else col1[3]= a; - a= 256*(inpg*ma->g + ma->ambg +isg); + a= 256*(diff1[1] + ma->ambg +isg); if(a>255) col1[2]= 255; else col1[2]= a; - a= 256*(inpb*ma->b + ma->ambb +isb); + a= 256*(diff1[2] + ma->ambb +isb); if(a>255) col1[1]= 255; else col1[1]= a; if(col2) { - a= 256*(inpr1*ma->r + ma->ambr +isr1); + if(ma->mode & MA_RAMP_COL) ramp_diffuse_result(diff2, &shi); + if(ma->mode & MA_RAMP_SPEC) ramp_spec_result(&isr1, &isg1, &isb1, &shi); + + a= 256*(diff2[0] + ma->ambr +isr1); if(a>255) col2[3]= 255; else col2[3]= a; - a= 256*(inpr1*ma->g + ma->ambg +isg1); + a= 256*(diff2[1] + ma->ambg +isg1); if(a>255) col2[2]= 255; else col2[2]= a; - a= 256*(inpr1*ma->b + ma->ambb +isb1); + a= 256*(diff2[2] + ma->ambb +isb1); if(a>255) col2[1]= 255; else col2[1]= a; } diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index d3f0d3b72af..f903641f347 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -729,8 +729,6 @@ int imagewrap(Tex *tex, float *texvec) } } - if(tex->flag & TEX_COLORBAND) do_colorband(tex->coba); - if(tex->nor) return 3; else return 1; } @@ -1557,8 +1555,6 @@ int imagewraposa(Tex *tex, float *texvec, float *dxt, float *dyt) return 0; } - if(tex->flag & TEX_COLORBAND) do_colorband(tex->coba); - if(tex->nor) return 3; else return 1; } diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 5d52e4750a1..a8219d560cf 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -71,13 +71,16 @@ void free_material(Material *ma) BPY_free_scriptlink(&ma->scriptlink); if(ma->ren) MEM_freeN(ma->ren); - ma->ren= 0; + ma->ren= NULL; for(a=0; a<8; a++) { mtex= ma->mtex[a]; if(mtex && mtex->tex) mtex->tex->id.us--; if(mtex) MEM_freeN(mtex); } + + if(ma->ramp_col) MEM_freeN(ma->ramp_col); + if(ma->ramp_spec) MEM_freeN(ma->ramp_spec); } void init_material(Material *ma) @@ -113,6 +116,10 @@ void init_material(Material *ma) ma->fresnel_tra_i= 1.25; ma->fresnel_mir_i= 1.25; + ma->rampfac_col= 1.0; + ma->rampfac_spec= 1.0; + ma->pr_lamp= 3; // two lamps, is bits + ma->mode= MA_TRACEBLE+MA_SHADOW+MA_RADIO; } @@ -145,6 +152,8 @@ Material *copy_material(Material *ma) } BPY_copy_scriptlink(&ma->scriptlink); + if(ma->ramp_col) man->ramp_col= MEM_dupallocN(ma->ramp_col); + if(ma->ramp_spec) man->ramp_spec= MEM_dupallocN(ma->ramp_spec); return man; } diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 44e16684f15..2507ca5c2b8 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -238,10 +238,9 @@ ColorBand *add_colorband() /* ------------------------------------------------------------------------- */ -int do_colorband(ColorBand *coba) +int do_colorband(ColorBand *coba, float in, float out[4]) { /* These vars form the texture channel, in render/intern/texture.c */ - extern float Tin, Tr, Tg, Tb, Ta; extern int Talpha; CBData *cbd1, *cbd2, *cbd0, *cbd3; float fac, mfac, t[4]; @@ -251,61 +250,55 @@ int do_colorband(ColorBand *coba) Talpha= 1; cbd1= coba->data; - - if(Tin <= cbd1->pos) { /* ultimate left */ - Tr= cbd1->r; - Tg= cbd1->g; - Tb= cbd1->b; - Ta= cbd1->a; + if(coba->tot==1) { + out[0]= cbd1->r; + out[1]= cbd1->g; + out[2]= cbd1->b; + out[3]= cbd1->a; } else { - /* we're looking for first pos > Tin */ - - for(a=0; a<coba->tot; a++, cbd1++) if(cbd1->pos >= Tin) break; + if(in < cbd1->pos) in= cbd1->pos; + + /* we're looking for first pos > in */ + for(a=0; a<coba->tot; a++, cbd1++) if(cbd1->pos > in) break; + + if(a==coba->tot) cbd1--; + if(in > cbd1->pos) in= cbd1->pos; + + cbd2= cbd1-1; + fac= (in-cbd1->pos)/(cbd2->pos-cbd1->pos); + + if(coba->ipotype==2) { + /* ipo from right to left: 3 2 1 0 */ - if(a==coba->tot) { /* ultimate right */ - cbd1--; - Tr= cbd1->r; - Tg= cbd1->g; - Tb= cbd1->b; - Ta= cbd1->a; + if(a>=coba->tot-1) cbd0= cbd1; + else cbd0= cbd1+1; + if(a<2) cbd3= cbd2; + else cbd3= cbd2-1; + + set_four_ipo(fac, t, KEY_BSPLINE); + + out[0]= t[3]*cbd3->r +t[2]*cbd2->r +t[1]*cbd1->r +t[0]*cbd0->r; + out[1]= t[3]*cbd3->g +t[2]*cbd2->g +t[1]*cbd1->g +t[0]*cbd0->g; + out[2]= t[3]*cbd3->b +t[2]*cbd2->b +t[1]*cbd1->b +t[0]*cbd0->b; + out[3]= t[3]*cbd3->a +t[2]*cbd2->a +t[1]*cbd1->a +t[0]*cbd0->a; + CLAMP(out[0], 0.0, 1.0); + CLAMP(out[1], 0.0, 1.0); + CLAMP(out[2], 0.0, 1.0); + CLAMP(out[3], 0.0, 1.0); } else { - cbd2= cbd1-1; - fac= (Tin-cbd1->pos)/(cbd2->pos-cbd1->pos); - - if(coba->ipotype==2) { - /* ipo from right to left: 3 2 1 0 */ - - if(a>=coba->tot-1) cbd0= cbd1; - else cbd0= cbd1+1; - if(a<2) cbd3= cbd2; - else cbd3= cbd2-1; - - set_four_ipo(fac, t, KEY_BSPLINE); - - Tr= t[3]*cbd3->r +t[2]*cbd2->r +t[1]*cbd1->r +t[0]*cbd0->r; - Tg= t[3]*cbd3->g +t[2]*cbd2->g +t[1]*cbd1->g +t[0]*cbd0->g; - Tb= t[3]*cbd3->b +t[2]*cbd2->b +t[1]*cbd1->b +t[0]*cbd0->b; - Ta= t[3]*cbd3->a +t[2]*cbd2->a +t[1]*cbd1->a +t[0]*cbd0->a; - CLAMP(Tr, 0.0, 1.0); - CLAMP(Tg, 0.0, 1.0); - CLAMP(Tb, 0.0, 1.0); - CLAMP(Ta, 0.0, 1.0); + + if(coba->ipotype==1) { /* EASE */ + mfac= fac*fac; + fac= 3.0f*mfac-2.0f*mfac*fac; } - else { + mfac= 1.0f-fac; - if(coba->ipotype==1) { /* EASE */ - mfac= fac*fac; - fac= 3.0f*mfac-2.0f*mfac*fac; - } - mfac= 1.0f-fac; - - Tr= mfac*cbd1->r + fac*cbd2->r; - Tg= mfac*cbd1->g + fac*cbd2->g; - Tb= mfac*cbd1->b + fac*cbd2->b; - Ta= mfac*cbd1->a + fac*cbd2->a; - } + out[0]= mfac*cbd1->r + fac*cbd2->r; + out[1]= mfac*cbd1->g + fac*cbd2->g; + out[2]= mfac*cbd1->b + fac*cbd2->b; + out[3]= mfac*cbd1->a + fac*cbd2->a; } } return 1; /* OK */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 0723b8175fc..361ac3666a0 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -1920,7 +1920,11 @@ static void direct_link_material(FileData *fd, Material *ma) for(a=0; a<8; a++) { ma->mtex[a]= newdataadr(fd, ma->mtex[a]); } - ma->ren= 0; /* should not be needed, nevertheless... */ + + ma->ramp_col= newdataadr(fd, ma->ramp_col); + ma->ramp_spec= newdataadr(fd, ma->ramp_spec); + + ma->ren= NULL; /* should not be needed, nevertheless... */ } /* ************ READ MESH ***************** */ @@ -4229,8 +4233,17 @@ static void do_versions(Main *main) } } - - + if(main->versionfile <= 233) { + Material *ma= main->mat.first; + + while(ma) { + if(ma->rampfac_col==0.0) ma->rampfac_col= 1.0; + if(ma->rampfac_spec==0.0) ma->rampfac_spec= 1.0; + if(ma->pr_lamp==0) ma->pr_lamp= 3; + ma= ma->id.next; + } + } + /* don't forget to set version number in blender.c! */ } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 32249c1c46b..d1d66ae2e63 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -912,7 +912,10 @@ static void write_materials(WriteData *wd, ListBase *idbase) for(a=0; a<8; a++) { if(ma->mtex[a]) writestruct(wd, DATA, "MTex", 1, ma->mtex[a]); } - + + if(ma->ramp_col) writestruct(wd, DATA, "ColorBand", 1, ma->ramp_col); + if(ma->ramp_spec) writestruct(wd, DATA, "ColorBand", 1, ma->ramp_spec); + write_scriptlink(wd, &ma->scriptlink); } ma= ma->id.next; diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h index f79310317ab..0797699794e 100644 --- a/source/blender/include/butspace.h +++ b/source/blender/include/butspace.h @@ -164,6 +164,7 @@ void butspace_context_switch(SpaceButs *buts, struct Base *new); #define B_MATHALO 1213 #define B_MATZTRANSP 1214 #define B_MATRAYTRANSP 1215 +#define B_MATCOLORBAND 1216 /* *********************** */ #define B_TEXBUTS 1400 diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h index f3838fe6d06..1ae6599e23a 100644 --- a/source/blender/makesdna/DNA_material_types.h +++ b/source/blender/makesdna/DNA_material_types.h @@ -42,6 +42,7 @@ struct MTex; struct Ipo; struct Material; +struct ColorBand; /* WATCH IT: change type? also make changes in ipo.h */ @@ -78,6 +79,14 @@ typedef struct Material { float param[4]; /* size, smooth, size, smooth, for toonshader */ short texco, mapto; + /* ramp colors */ + struct ColorBand *ramp_col; + struct ColorBand *ramp_spec; + char rampin_col, rampin_spec; + char rampblend_col, rampblend_spec; + short ramp_show, pad3; + float rampfac_col, rampfac_spec; + struct MTex *mtex[8]; struct Ipo *ipo; struct Material *ren; @@ -129,6 +138,8 @@ typedef struct Material { #define MA_RAYTRANSP 0x20000 #define MA_RAYMIRROR 0x40000 #define MA_SHADOW_TRA 0x80000 +#define MA_RAMP_COL 0x100000 +#define MA_RAMP_SPEC 0x200000 /* diff_shader */ #define MA_DIFF_LAMBERT 0 @@ -145,6 +156,17 @@ typedef struct Material { #define MA_DRAW_DYNABUTS 1 #define MA_FH_NOR 2 +/* ramps */ +#define MA_RAMP_IN_SHADER 0 +#define MA_RAMP_IN_ENERGY 1 +#define MA_RAMP_IN_NOR 2 +#define MA_RAMP_IN_RESULT 3 + +#define MA_RAMP_BLEND 0 +#define MA_RAMP_ADD 1 +#define MA_RAMP_MULT 2 +#define MA_RAMP_SUB 3 + /* texco */ #define TEXCO_ORCO 1 #define TEXCO_REFL 2 diff --git a/source/blender/render/extern/include/render.h b/source/blender/render/extern/include/render.h index c27e35fd1cf..d3953204678 100644 --- a/source/blender/render/extern/include/render.h +++ b/source/blender/render/extern/include/render.h @@ -176,103 +176,105 @@ int multitex(struct Tex *tex, float *texvec, float *dxt, float *dyt, int osatex) /* ------------------------------------------------------------------------- */ /* envmap (4) */ /* ------------------------------------------------------------------------- */ - struct EnvMap; - struct Tex; +struct EnvMap; +struct Tex; + void RE_free_envmapdata(struct EnvMap *env); void RE_free_envmap(struct EnvMap *env); struct EnvMap *RE_add_envmap(void); /* these two maybe not external? yes, they are, for texture.c */ struct EnvMap *RE_copy_envmap(struct EnvMap *env); - /* --------------------------------------------------------------------- */ - /* rendercore (2) */ - /* --------------------------------------------------------------------- */ - float Phong_Spec(float *n, float *l, float *v, int hard); - float CookTorr_Spec(float *n, float *l, float *v, int hard); - float Blinn_Spec(float *n, float *l, float *v, float refrac, float spec_power); - float Toon_Spec( float *n, float *l, float *v, float size, float smooth); - float OrenNayar_Diff(float *n, float *l, float *v, float rough); - float Toon_Diff( float *n, float *l, float *v, float size, float smooth); - - /* --------------------------------------------------------------------- */ - /* renderdatabase (3) */ - /* --------------------------------------------------------------------- */ - struct VlakRen *RE_findOrAddVlak(int nr); - struct VertRen *RE_findOrAddVert(int nr); - struct HaloRen *RE_findOrAddHalo(int nr); - HaloRen *RE_inithalo(Material *ma, - float *vec, - float *vec1, - float *orco, - float hasize, - float vectsize); - - - /** - * callbacks (11): - * - * If the callbacks aren't set, rendering will still proceed as - * desired, but the concerning functionality will not be enabled. - * - * There need to be better uncoupling between the renderer and - * these functions still! - * */ - - void RE_set_test_break_callback(int (*f)(void)); - - void RE_set_timecursor_callback(void (*f)(int)); - - void RE_set_renderdisplay_callback(void (*f)(int, int, int, int, unsigned int *)); - void RE_set_initrenderdisplay_callback(void (*f)(void)); - void RE_set_clearrenderdisplay_callback(void (*f)(short)); - - void RE_set_printrenderinfo_callback(void (*f)(double,int)); - - void RE_set_getrenderdata_callback(void (*f)(void)); - void RE_set_freerenderdata_callback(void (*f)(void)); - - - /*from renderhelp, should disappear!!! */ - /** Recalculate all normals on renderdata. */ - void set_normalflags(void); - /** - * On loan from zbuf.h: - * Tests whether the first three coordinates should be clipped - * wrt. the fourth component. Bits 1 and 2 test on x, 3 and 4 test on - * y, 5 and 6 test on z: - * xyz > test => set first bit (01), - * xyz < -test => set second bit (10), - * xyz == test => reset both bits (00). - * Note: functionality is duplicated from an internal function - * Also called in: initrender.c, radfactors.c - * @param v [4 floats] a coordinate - * @return a vector of bitfields - */ - int RE_testclip(float *v); - - /* patch for the external if, to support the split for the ui */ - void RE_addalphaAddfac(char *doel, char *bron, char addfac); - void RE_sky_char(float *view, char *col); - void RE_sky(float *view, float *col); - void RE_renderflare(struct HaloRen *har); - /** - * Shade the pixel at xn, yn for halo har, and write the result to col. - * Also called in: previewrender.c - * @param har The halo to be rendered on this location - * @param col [unsigned int 3] The destination colour vector - * @param zz Some kind of distance - * @param dist Square of the distance of this coordinate to the halo's center - * @param x [f] Pixel x relative to center - * @param y [f] Pixel y relative to center - * @param flarec Flare counter? Always har->flarec... - */ - void RE_shadehalo(struct HaloRen *har, - char *col, - unsigned int zz, - float dist, - float x, - float y, - short flarec); +/* --------------------------------------------------------------------- */ +/* rendercore (2) */ +/* --------------------------------------------------------------------- */ +float Phong_Spec(float *n, float *l, float *v, int hard); +float CookTorr_Spec(float *n, float *l, float *v, int hard); +float Blinn_Spec(float *n, float *l, float *v, float refrac, float spec_power); +float Toon_Spec( float *n, float *l, float *v, float size, float smooth); +float OrenNayar_Diff(float *n, float *l, float *v, float rough); +float Toon_Diff( float *n, float *l, float *v, float size, float smooth); +void add_to_diffuse(float *diff, ShadeInput *shi, float is, float r, float g, float b); +void ramp_diffuse_result(float *diff, ShadeInput *shi); +void do_specular_ramp(ShadeInput *shi, float is, float t, float *spec); +void ramp_spec_result(float *specr, float *specg, float *specb, ShadeInput *shi); + + +/* --------------------------------------------------------------------- */ +/* renderdatabase (3) */ +/* --------------------------------------------------------------------- */ +struct VlakRen *RE_findOrAddVlak(int nr); +struct VertRen *RE_findOrAddVert(int nr); +struct HaloRen *RE_findOrAddHalo(int nr); +HaloRen *RE_inithalo(Material *ma, float *vec, float *vec1, float *orco, float hasize, + float vectsize); + + +/** + * callbacks (11): + * + * If the callbacks aren't set, rendering will still proceed as + * desired, but the concerning functionality will not be enabled. + * + * There need to be better uncoupling between the renderer and + * these functions still! + * */ + +void RE_set_test_break_callback(int (*f)(void)); + +void RE_set_timecursor_callback(void (*f)(int)); + +void RE_set_renderdisplay_callback(void (*f)(int, int, int, int, unsigned int *)); +void RE_set_initrenderdisplay_callback(void (*f)(void)); +void RE_set_clearrenderdisplay_callback(void (*f)(short)); + +void RE_set_printrenderinfo_callback(void (*f)(double,int)); + +void RE_set_getrenderdata_callback(void (*f)(void)); +void RE_set_freerenderdata_callback(void (*f)(void)); + + +/*from renderhelp, should disappear!!! */ +/** Recalculate all normals on renderdata. */ +void set_normalflags(void); +/** + * On loan from zbuf.h: + * Tests whether the first three coordinates should be clipped + * wrt. the fourth component. Bits 1 and 2 test on x, 3 and 4 test on + * y, 5 and 6 test on z: + * xyz > test => set first bit (01), + * xyz < -test => set second bit (10), + * xyz == test => reset both bits (00). + * Note: functionality is duplicated from an internal function + * Also called in: initrender.c, radfactors.c + * @param v [4 floats] a coordinate + * @return a vector of bitfields + */ +int RE_testclip(float *v); + +/* patch for the external if, to support the split for the ui */ +void RE_addalphaAddfac(char *doel, char *bron, char addfac); +void RE_sky_char(float *view, char *col); +void RE_sky(float *view, float *col); +void RE_renderflare(struct HaloRen *har); +/** + * Shade the pixel at xn, yn for halo har, and write the result to col. + * Also called in: previewrender.c + * @param har The halo to be rendered on this location + * @param col [unsigned int 3] The destination colour vector + * @param zz Some kind of distance + * @param dist Square of the distance of this coordinate to the halo's center + * @param x [f] Pixel x relative to center + * @param y [f] Pixel y relative to center + * @param flarec Flare counter? Always har->flarec... + */ +void RE_shadehalo(struct HaloRen *har, + char *col, + unsigned int zz, + float dist, + float x, + float y, + short flarec); /***/ diff --git a/source/blender/render/intern/source/renderHelp.c b/source/blender/render/intern/source/renderHelp.c index 60150655e8f..532c55da997 100644 --- a/source/blender/render/intern/source/renderHelp.c +++ b/source/blender/render/intern/source/renderHelp.c @@ -278,7 +278,6 @@ void set_normalflags(void) vec[2]= vlr->v1->co[2]; if( (vec[0]*vlr->n[0] +vec[1]*vlr->n[1] +vec[2]*vlr->n[2])<0.0 ) { - vlr->puno= vlr->puno ^ 15; vlr->n[0]= -vlr->n[0]; vlr->n[1]= -vlr->n[1]; vlr->n[2]= -vlr->n[2]; diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 600b30807a5..96c01879500 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -44,6 +44,7 @@ #include "DNA_object_types.h" #include "DNA_camera_types.h" #include "DNA_lamp_types.h" +#include "DNA_texture_types.h" #include "BKE_global.h" #include "BKE_texture.h" @@ -1644,6 +1645,212 @@ void shade_color(ShadeInput *shi, ShadeResult *shr) shr->alpha= ma->alpha; } +/* ramp for at end of shade */ +void ramp_diffuse_result(float *diff, ShadeInput *shi) +{ + Material *ma= shi->matren; + float col[4], fac=0; + + if(ma->ramp_col) { + if(ma->rampin_col==MA_RAMP_IN_RESULT) { + + fac= 0.3*diff[0] + 0.58*diff[1] + 0.12*diff[2]; + do_colorband(ma->ramp_col, fac, col); + + /* blending method */ + fac= col[3]*ma->rampfac_col; + switch(ma->rampblend_col) { + case MA_RAMP_BLEND: + diff[0]= (1.0-fac)*diff[0] + fac*col[0]; + diff[1]= (1.0-fac)*diff[1] + fac*col[1]; + diff[2]= (1.0-fac)*diff[2] + fac*col[2]; + break; + case MA_RAMP_ADD: + diff[0]+= fac*col[0]; + diff[1]+= fac*col[1]; + diff[2]+= fac*col[2]; + break; + case MA_RAMP_MULT: + diff[0]*= (1.0-fac + fac*col[0]); + diff[1]*= (1.0-fac + fac*col[1]); + diff[2]*= (1.0-fac + fac*col[2]); + break; + case MA_RAMP_SUB: + diff[0]-= fac*col[0]; + diff[1]-= fac*col[1]; + diff[2]-= fac*col[2]; + break; + } + } + } +} + +/* r,g,b denote energy, ramp is used with different values to make new material color */ +void add_to_diffuse(float *diff, ShadeInput *shi, float is, float r, float g, float b) +{ + Material *ma= shi->matren; + float col[4], fac=0; + + if(ma->ramp_col && (ma->mode & MA_RAMP_COL)) { + + /* MA_RAMP_IN_RESULT is exceptional */ + if(ma->rampin_col==MA_RAMP_IN_RESULT) { + // normal add + diff[0] += r * ma->r; + diff[1] += g * ma->g; + diff[2] += b * ma->b; + } + else { + /* input */ + switch(ma->rampin_col) { + case MA_RAMP_IN_ENERGY: + fac= 0.3*r + 0.58*g + 0.12*b; + break; + case MA_RAMP_IN_SHADER: + fac= is; + break; + case MA_RAMP_IN_NOR: + fac= shi->view[0]*shi->vn[0] + shi->view[1]*shi->vn[1] + shi->view[2]*shi->vn[2]; + break; + } + + do_colorband(ma->ramp_col, fac, col); + + /* blending method */ + fac= col[3]*ma->rampfac_col; + switch(ma->rampblend_col) { + case MA_RAMP_BLEND: + col[0]= (1.0-fac)*ma->r + fac*col[0]; + col[1]= (1.0-fac)*ma->g + fac*col[1]; + col[2]= (1.0-fac)*ma->b + fac*col[2]; + break; + case MA_RAMP_ADD: + col[0]= ma->r + fac*col[0]; + col[1]= ma->g + fac*col[1]; + col[2]= ma->b + fac*col[2]; + break; + case MA_RAMP_MULT: + col[0]= ma->r*(1.0-fac + fac*col[0]); + col[1]= ma->g*(1.0-fac + fac*col[1]); + col[2]= ma->b*(1.0-fac + fac*col[2]); + break; + case MA_RAMP_SUB: + col[0]= ma->r - fac*col[0]; + col[1]= ma->g - fac*col[1]; + col[2]= ma->b - fac*col[2]; + break; + } + + /* output to */ + diff[0] += r * col[0]; + diff[1] += g * col[1]; + diff[2] += b * col[2]; + } + } + else { + diff[0] += r * ma->r; + diff[1] += g * ma->g; + diff[2] += b * ma->b; + } +} + +void ramp_spec_result(float *specr, float *specg, float *specb, ShadeInput *shi) +{ + Material *ma= shi->matren; + float col[4]; + float fac; + + if(ma->ramp_spec && (ma->rampin_spec==MA_RAMP_IN_RESULT)) { + fac= 0.3*(*specr) + 0.58*(*specg) + 0.12*(*specb); + do_colorband(ma->ramp_spec, fac, col); + + /* blending method */ + fac= col[3]*ma->rampfac_spec; + switch(ma->rampblend_spec) { + case MA_RAMP_BLEND: + *specr= (1.0-fac)*(*specr) + fac*col[0]; + *specg= (1.0-fac)*(*specg) + fac*col[1]; + *specb= (1.0-fac)*(*specb) + fac*col[2]; + break; + case MA_RAMP_ADD: + *specr += fac*col[0]; + *specg += fac*col[1]; + *specb += fac*col[2]; + break; + case MA_RAMP_MULT: + *specr *= (1.0-fac + fac*col[0]); + *specg *= (1.0-fac + fac*col[1]); + *specb *= (1.0-fac + fac*col[2]); + break; + case MA_RAMP_SUB: + *specr -= fac*col[0]; + *specg -= fac*col[1]; + *specb -= fac*col[2]; + break; + } + + } +} + +/* is = dot product shade, t = spec energy */ +void do_specular_ramp(ShadeInput *shi, float is, float t, float *spec) +{ + Material *ma= shi->matren; + float col[4]; + float fac=0.0; + + /* MA_RAMP_IN_RESULT is exception */ + if(ma->ramp_spec && (ma->rampin_spec!=MA_RAMP_IN_RESULT)) { + + /* input */ + switch(ma->rampin_spec) { + case MA_RAMP_IN_ENERGY: + fac= t; + break; + case MA_RAMP_IN_SHADER: + fac= is; + break; + case MA_RAMP_IN_NOR: + fac= shi->view[0]*shi->vn[0] + shi->view[1]*shi->vn[1] + shi->view[2]*shi->vn[2]; + break; + } + + do_colorband(ma->ramp_spec, fac, col); + + /* blending method */ + fac= col[3]*ma->rampfac_spec; + switch(ma->rampblend_spec) { + case MA_RAMP_BLEND: + spec[0]= (1.0-fac)*ma->specr + fac*col[0]; + spec[1]= (1.0-fac)*ma->specg + fac*col[1]; + spec[2]= (1.0-fac)*ma->specb + fac*col[2]; + break; + case MA_RAMP_ADD: + spec[0]= ma->specr + fac*col[0]; + spec[1]= ma->specg + fac*col[1]; + spec[2]= ma->specb + fac*col[2]; + break; + case MA_RAMP_MULT: + spec[0]= ma->specr*fac*col[0]; + spec[1]= ma->specg*fac*col[1]; + spec[2]= ma->specb*fac*col[2]; + break; + case MA_RAMP_SUB: + spec[0]= ma->specr - fac*col[0]; + spec[1]= ma->specg - fac*col[1]; + spec[2]= ma->specb - fac*col[2]; + break; + } + } + else { + spec[0]= ma->specr; + spec[1]= ma->specg; + spec[2]= ma->specb; + } +} + + + static void ambient_occlusion(World *wrld, ShadeInput *shi, ShadeResult *shr) { float f, shadfac[4]; @@ -1656,9 +1863,10 @@ static void ambient_occlusion(World *wrld, ShadeInput *shi, ShadeResult *shr) else if (wrld->aomix==WO_AOSUB) shadfac[3] = shadfac[3]-1.0; f= wrld->aoenergy*shadfac[3]*shi->matren->amb; - shr->diff[0] += f; - shr->diff[1] += f; - shr->diff[2] += f; + add_to_diffuse(shr->diff, shi, f, f, f, f); + //shr->diff[0] += f; + //shr->diff[1] += f; + //shr->diff[2] += f; } else { if (wrld->aomix==WO_AOADDSUB) { @@ -1672,19 +1880,19 @@ static void ambient_occlusion(World *wrld, ShadeInput *shi, ShadeResult *shr) shadfac[2] = shadfac[2]-1.0; } f= wrld->aoenergy*shi->matren->amb; - shr->diff[0] += f*shadfac[0]; - shr->diff[1] += f*shadfac[1]; - shr->diff[2] += f*shadfac[2]; + add_to_diffuse(shr->diff, shi, f, f*shadfac[0], f*shadfac[1], f*shadfac[2]); + //shr->diff[0] += f*shadfac[0]; + //shr->diff[1] += f*shadfac[1]; + //shr->diff[2] += f*shadfac[2]; } } } - void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) { LampRen *lar; Material *ma; - float i, inp, inpr, t, lv[3], lampdist, ld = 0; + float i, inp, inpr, is, t, lv[3], lampdist, ld = 0; float lvrot[3], *vn, *view, shadfac[4], soft; // shadfac = rgba int a; @@ -1780,12 +1988,18 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) } if( (ma->mode & (MA_VERTEXCOL+MA_VERTEXCOLP))== MA_VERTEXCOL ) { - shr->diff[0]= ma->emit+shi->vcol[0]; - shr->diff[1]= ma->emit+shi->vcol[1]; - shr->diff[2]= ma->emit+shi->vcol[2]; + // add_to_diffuse(shr->diff, shi, 1.0, ma->emit+shi->vcol[0], ma->emit+shi->vcol[1], ma->emit+shi->vcol[2]); + shr->diff[0]= ma->r*(ma->emit+shi->vcol[0]); + shr->diff[1]= ma->g*(ma->emit+shi->vcol[1]); + shr->diff[2]= ma->b*(ma->emit+shi->vcol[2]); } - else shr->diff[0]= shr->diff[1]= shr->diff[2]= ma->emit; - + else { + // add_to_diffuse(shr->diff, shi, 1.0, ma->emit, ma->emit, ma->emit); + shr->diff[0]= ma->r*ma->emit; + shr->diff[1]= ma->g*ma->emit; + shr->diff[2]= ma->b*ma->emit; + } + ambient_occlusion(&R.wrld, shi, shr); for(a=0; a<R.totlamp; a++) { @@ -1893,15 +2107,16 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) } - /* dot product and reflectivity*/ + /* dot product and reflectivity */ + /* inp = dotproduct, is = shader result, i = lamp energy (with shadow) */ inp= vn[0]*lv[0] + vn[1]*lv[1] + vn[2]*lv[2]; if(lar->mode & LA_NO_DIFF) { - i= 0.0; // skip shaders + is= 0.0; // skip shaders } else if(lar->type==LA_HEMI) { - i= 0.5*inp + 0.5; + is= 0.5*inp + 0.5; } else { @@ -1913,11 +2128,12 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) } /* diffuse shaders (oren nayer gets inp from area light) */ - if(ma->diff_shader==MA_DIFF_ORENNAYAR) i= OrenNayar_Diff_i(inp, vn, lv, view, ma->roughness); - else if(ma->diff_shader==MA_DIFF_TOON) i= Toon_Diff(vn, lv, view, ma->param[0], ma->param[1]); - else i= inp; // Lambert + if(ma->diff_shader==MA_DIFF_ORENNAYAR) is= OrenNayar_Diff_i(inp, vn, lv, view, ma->roughness); + else if(ma->diff_shader==MA_DIFF_TOON) is= Toon_Diff(vn, lv, view, ma->param[0], ma->param[1]); + else is= inp; // Lambert } + i= is; if(i>0.0) { i*= lampdist*ma->ref; } @@ -1943,9 +2159,9 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) if(lar->mode & LA_ONLYSHADOW) { shadfac[3]= i*lar->energy*(1.0-shadfac[3]); - shr->diff[0] -= shadfac[3]; - shr->diff[1] -= shadfac[3]; - shr->diff[2] -= shadfac[3]; + shr->diff[0] -= shadfac[3]*ma->r; + shr->diff[1] -= shadfac[3]*ma->g; + shr->diff[2] -= shadfac[3]*ma->b; continue; } @@ -1998,9 +2214,18 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) t= shadfac[3]*ma->spec*lampdist*specfac; - shr->spec[0]+= t*(lar->r * ma->specr); - shr->spec[1]+= t*(lar->g * ma->specg); - shr->spec[2]+= t*(lar->b * ma->specb); + if(ma->mode & MA_RAMP_SPEC) { + float spec[3]; + do_specular_ramp(shi, specfac, t, spec); + shr->spec[0]+= t*(lar->r * spec[0]); + shr->spec[1]+= t*(lar->g * spec[1]); + shr->spec[2]+= t*(lar->b * spec[2]); + } + else { + shr->spec[0]+= t*(lar->r * ma->specr); + shr->spec[1]+= t*(lar->g * ma->specg); + shr->spec[2]+= t*(lar->b * ma->specb); + } } } } @@ -2008,14 +2233,16 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) /* in case 'no diffuse' we still do most calculus, spec can be in shadow */ if(i>0.0 && !(lar->mode & LA_NO_DIFF)) { if(ma->mode & MA_SHADOW_TRA) { - shr->diff[0]+= i*shadfac[0]*lar->r; - shr->diff[1]+= i*shadfac[1]*lar->g; - shr->diff[2]+= i*shadfac[2]*lar->b; + add_to_diffuse(shr->diff, shi, is, i*shadfac[0]*lar->r, i*shadfac[1]*lar->g, i*shadfac[2]*lar->b); + //shr->diff[0]+= i*shadfac[0]*lar->r; + //shr->diff[1]+= i*shadfac[1]*lar->g; + //shr->diff[2]+= i*shadfac[2]*lar->b; } else { - shr->diff[0]+= i*lar->r; - shr->diff[1]+= i*lar->g; - shr->diff[2]+= i*lar->b; + add_to_diffuse(shr->diff, shi, is, i*lar->r, i*lar->g, i*lar->b); + //shr->diff[0]+= i*lar->r; + //shr->diff[1]+= i*lar->g; + //shr->diff[2]+= i*lar->b; } } } @@ -2039,22 +2266,24 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) if(shr->spec[1]<0.0) shr->spec[1]= 0.0; if(shr->spec[2]<0.0) shr->spec[2]= 0.0; - - shr->diff[0]+= ma->amb*shi->rad[0]; - shr->diff[0]*= ma->r; + shr->diff[0]+= ma->r*ma->amb*shi->rad[0]; + //shr->diff[0]*= ma->r; shr->diff[0]+= ma->ambr; if(shr->diff[0]<0.0) shr->diff[0]= 0.0; - shr->diff[1]+= ma->amb*shi->rad[1]; - shr->diff[1]*= ma->g; + shr->diff[1]+= ma->g*ma->amb*shi->rad[1]; + //shr->diff[1]*= ma->g; shr->diff[1]+= ma->ambg; if(shr->diff[1]<0.0) shr->diff[1]= 0.0; - shr->diff[2]+= ma->amb*shi->rad[2]; - shr->diff[2]*= ma->b; + shr->diff[2]+= ma->b*ma->amb*shi->rad[2]; + //shr->diff[2]*= ma->b; shr->diff[2]+= ma->ambb; if(shr->diff[2]<0.0) shr->diff[2]= 0.0; + if(ma->mode & MA_RAMP_COL) ramp_diffuse_result(shr->diff, shi); + if(ma->mode & MA_RAMP_SPEC) ramp_spec_result(shr->spec, shr->spec+1, shr->spec+2, shi); + /* refcol is for envmap only */ if(shi->refcol[0]!=0.0) { shr->diff[0]= ma->mirr*shi->refcol[1] + (1.0 - ma->mirr*shi->refcol[0])*shr->diff[0]; diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c index b287c14733f..d2233db8129 100644 --- a/source/blender/render/intern/source/texture.c +++ b/source/blender/render/intern/source/texture.c @@ -233,7 +233,6 @@ static int blend(Tex *tex, float *texvec) } BRICON; - if(tex->flag & TEX_COLORBAND) return do_colorband(tex->coba); return 0; } @@ -272,8 +271,6 @@ static int clouds(Tex *tex, float *texvec) BRICON; - if (tex->flag & TEX_COLORBAND) return (rv + do_colorband(tex->coba)); - return rv; } @@ -313,7 +310,6 @@ static int wood(Tex *tex, float *texvec) } BRICON; - if (tex->flag & TEX_COLORBAND) return (rv + do_colorband(tex->coba)); return rv; } @@ -349,7 +345,6 @@ static int marble(Tex *tex, float *texvec) } BRICON; - if (tex->flag & TEX_COLORBAND) return (rv + do_colorband(tex->coba)); return rv; } @@ -485,8 +480,6 @@ static float mg_mFractalOrfBmTex(Tex *tex, float *texvec) BRICON; - if (tex->flag & TEX_COLORBAND) return (rv + do_colorband(tex->coba)); - return rv; } @@ -515,8 +508,6 @@ static float mg_ridgedOrHybridMFTex(Tex *tex, float *texvec) BRICON; - if (tex->flag & TEX_COLORBAND) return (rv + do_colorband(tex->coba)); - return rv; } @@ -540,8 +531,6 @@ static float mg_HTerrainTex(Tex *tex, float *texvec) BRICON; - if (tex->flag & TEX_COLORBAND) return (rv + do_colorband(tex->coba)); - return rv; } @@ -563,7 +552,6 @@ static float mg_distNoiseTex(Tex *tex, float *texvec) BRICON; - if (tex->flag & TEX_COLORBAND) return (rv + do_colorband(tex->coba)); return rv; @@ -639,8 +627,6 @@ static float voronoiTex(Tex *tex, float *texvec) BRICON; - if (tex->flag & TEX_COLORBAND) return (rv + do_colorband(tex->coba)); - return rv; } @@ -666,8 +652,6 @@ static int texnoise(Tex *tex) Tin= ((float)val)/div;; BRICON; - if(tex->flag & TEX_COLORBAND) return do_colorband(tex->coba); - return 0; } @@ -706,7 +690,6 @@ static int plugintex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex } BRICON; - if(tex->flag & TEX_COLORBAND) rgbnor |= do_colorband(tex->coba); } return rgbnor; @@ -1036,34 +1019,45 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, float *dxt, float int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex) { - + int retval=0; /* return value, int:0, col:1, nor:2, everything:3 */ + switch(tex->type) { case 0: Tin= 0.0; return 0; case TEX_CLOUDS: - return clouds(tex, texvec); + retval= clouds(tex, texvec); + break; case TEX_WOOD: - return wood(tex, texvec); + retval= wood(tex, texvec); + break; case TEX_MARBLE: - return marble(tex, texvec); + retval= marble(tex, texvec); + break; case TEX_MAGIC: - return magic(tex, texvec); + retval= magic(tex, texvec); + break; case TEX_BLEND: - return blend(tex, texvec); + retval= blend(tex, texvec); + break; case TEX_STUCCI: Tin= 0.0; - return stucci(tex, texvec); + retval= stucci(tex, texvec); + break; case TEX_NOISE: - return texnoise(tex); + retval= texnoise(tex); + break; case TEX_IMAGE: - if(osatex) return imagewraposa(tex, texvec, dxt, dyt); - else return imagewrap(tex, texvec); + if(osatex) retval= imagewraposa(tex, texvec, dxt, dyt); + else retval= imagewrap(tex, texvec); + break; case TEX_PLUGIN: - return plugintex(tex, texvec, dxt, dyt, osatex); + retval= plugintex(tex, texvec, dxt, dyt, osatex); + break; case TEX_ENVMAP: - return envmaptex(tex, texvec, dxt, dyt, osatex); + retval= envmaptex(tex, texvec, dxt, dyt, osatex); + break; case TEX_MUSGRAVE: /* newnoise: musgrave types */ @@ -1073,12 +1067,15 @@ int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex) switch(tex->stype) { case TEX_MFRACTAL: case TEX_FBM: - return mg_mFractalOrfBmTex(tex, texvec); + retval= mg_mFractalOrfBmTex(tex, texvec); + break; case TEX_RIDGEDMF: case TEX_HYBRIDMF: - return mg_ridgedOrHybridMFTex(tex, texvec); + retval= mg_ridgedOrHybridMFTex(tex, texvec); + break; case TEX_HTERRAIN: - return mg_HTerrainTex(tex, texvec); + retval= mg_HTerrainTex(tex, texvec); + break; } break; /* newnoise: voronoi type */ @@ -1086,14 +1083,27 @@ int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex) /* ton: added this, for Blender convention reason. scaling texvec here is so-so... */ VecMulf(texvec, 1.0/tex->noisesize); - return voronoiTex(tex, texvec); + retval= voronoiTex(tex, texvec); + break; case TEX_DISTNOISE: /* ton: added this, for Blender convention reason. scaling texvec here is so-so... */ VecMulf(texvec, 1.0/tex->noisesize); - return mg_distNoiseTex(tex, texvec); + retval= mg_distNoiseTex(tex, texvec); + break; } - return 0; + + if (tex->flag & TEX_COLORBAND) { + float col[4]; + if (do_colorband(tex->coba, Tin, col)) { + retval |= 1; + Tr= col[0]; + Tg= col[1]; + Tb= col[2]; + Ta= col[3]; + } + } + return retval; } /* ------------------------------------------------------------------------- */ diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 9b5242075c0..e9c3e265ecd 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -1262,15 +1262,15 @@ static void editing_panel_deflectors(Object *ob) if(ob->pd) { uiBlockBeginAlign(block); uiDefButS(block, TOG|BIT|0, B_DIFF, "Force field", 10,160,150,20, &ob->pd->forcefield, 0, 0, 0, 0, "Object center attracts or repels particles"); - uiDefButF(block, NUM, B_DIFF, "Strength", 10,140,150,20, &ob->pd->f_strength, -100, 100, 0, 0, "Strength of force field"); - uiDefButF(block, NUM, B_DIFF, "Fall-off", 10,120,150,20, &ob->pd->f_power, 0, 10, 0, 0, "Falloff power (real gravitational fallof = 2)"); + uiDefButF(block, NUM, B_DIFF, "Strength", 10,140,150,20, &ob->pd->f_strength, -100, 100, 100, 0, "Strength of force field"); + uiDefButF(block, NUM, B_DIFF, "Fall-off", 10,120,150,20, &ob->pd->f_power, 0, 10, 100, 0, "Falloff power (real gravitational fallof = 2)"); /* only meshes collide now */ if(ob->type==OB_MESH) { uiBlockBeginAlign(block); uiDefButS(block, TOG|BIT|0, B_DIFF, "Deflection",10,80,150,20, &ob->pd->deflect, 0, 0, 0, 0, "Deflects particles based on collision"); - uiDefButF(block, NUM, B_DIFF, "Surface damping", 10,60,150,20, &ob->pd->pdef_damp, 0, 1, 0, 0, "Amount of damping during particle collision"); - uiDefButF(block, NUM, B_DIFF, "Random damping", 10,40,150,20, &ob->pd->pdef_rdamp, 0, 1, 0, 0, "Random variation of damping"); - uiDefButF(block, NUM, B_DIFF, "Permeability", 10,30,150,20, &ob->pd->pdef_perm, 0, 1, 0, 0, "Chance that the particle will pass through the mesh"); + uiDefButF(block, NUM, B_DIFF, "Surface damping", 10,60,150,20, &ob->pd->pdef_damp, 0.0, 1.0, 10, 0, "Amount of damping during particle collision"); + uiDefButF(block, NUM, B_DIFF, "Random damping", 10,40,150,20, &ob->pd->pdef_rdamp, 0.0, 1.0, 10, 0, "Random variation of damping"); + uiDefButF(block, NUM, B_DIFF, "Permeability", 10,30,150,20, &ob->pd->pdef_perm, 0.0, 1.0, 10, 0, "Chance that the particle will pass through the mesh"); } } } diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c index 0af5857d1fe..5d36112a635 100644 --- a/source/blender/src/buttons_shading.c +++ b/source/blender/src/buttons_shading.c @@ -191,12 +191,26 @@ void save_env(char *name) void drawcolorband(ColorBand *coba, float x1, float y1, float sizex, float sizey) { CBData *cbd; - float v3[2], v1[2], v2[2]; + float dx, v3[2], v1[2], v2[2]; int a; - if(coba==0) return; + if(coba==NULL) return; + + /* first background, to show tranparency */ + dx= sizex/12.0; + v1[0]= x1; + for(a=0; a<12; a++) { + if(a & 1) glColor3f(0.3, 0.3, 0.3); else glColor3f(0.8, 0.8, 0.8); + glRectf(v1[0], y1, v1[0]+dx, y1+0.5*sizey); + if(a & 1) glColor3f(0.8, 0.8, 0.8); else glColor3f(0.3, 0.3, 0.3); + glRectf(v1[0], y1+0.5*sizey, v1[0]+dx, y1+sizey); + v1[0]+= dx; + } glShadeModel(GL_SMOOTH); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + cbd= coba->data; v1[0]= v2[0]= x1; @@ -205,14 +219,14 @@ void drawcolorband(ColorBand *coba, float x1, float y1, float sizex, float sizey glBegin(GL_QUAD_STRIP); - glColor3fv( &cbd->r ); + glColor4fv( &cbd->r ); glVertex2fv(v1); glVertex2fv(v2); for(a=0; a<coba->tot; a++, cbd++) { v1[0]=v2[0]= x1+ cbd->pos*sizex; - glColor3fv( &cbd->r ); + glColor4fv( &cbd->r ); glVertex2fv(v1); glVertex2fv(v2); } @@ -221,7 +235,7 @@ void drawcolorband(ColorBand *coba, float x1, float y1, float sizex, float sizey glEnd(); glShadeModel(GL_FLAT); - + glDisable(GL_BLEND); /* outline */ v1[0]= x1; v1[1]= y1; @@ -266,10 +280,14 @@ void drawcolorband(ColorBand *coba, float x1, float y1, float sizex, float sizey glVertex2fv(v3); if(a==coba->cur) { - glVertex2f(v2[0]-1, v2[1]); - glVertex2f(v3[0]-1, v3[1]); - glVertex2f(v2[0]+1, v2[1]); - glVertex2f(v3[0]+1, v3[1]); + if(cbd->pos>0.01) { + glVertex2f(v2[0]-1, v2[1]); + glVertex2f(v3[0]-1, v3[1]); + } + if(cbd->pos<0.99) { + glVertex2f(v2[0]+1, v2[1]); + glVertex2f(v3[0]+1, v3[1]); + } } } glEnd(); @@ -278,19 +296,125 @@ void drawcolorband(ColorBand *coba, float x1, float y1, float sizex, float sizey glFlush(); } +static void drawcolorband_cb(void) +{ + ID *id, *idfrom; + + buttons_active_id(&id, &idfrom); + if( GS(id->name)==ID_TE) { + Tex *tex= (Tex *)id; + drawcolorband(tex->coba, 12,145,300,30); + } + else if( GS(id->name)==ID_MA) { + Material *ma= (Material *)id; + if(ma->ramp_show==0) + drawcolorband(ma->ramp_col, 12,110,300,30); + else + drawcolorband(ma->ramp_spec, 12,110,300,30); + } +} +static void do_colorbandbuts(ColorBand *coba, unsigned short event) +{ + uiBlock *block; + CBData *cbd; + float dx; + int a; + short mvalo[2], mval[2]; + + if(coba==NULL) return; + + switch(event) { + case B_ADDCOLORBAND: + + if(coba->tot < MAXCOLORBAND-1) coba->tot++; + coba->cur= coba->tot-1; + + do_colorbandbuts(coba, B_CALCCBAND); + + break; + + case B_DELCOLORBAND: + if(coba->tot<2) return; + + for(a=coba->cur; a<coba->tot; a++) { + coba->data[a]= coba->data[a+1]; + } + if(coba->cur) coba->cur--; + coba->tot--; + + allqueue(REDRAWBUTSSHADING, 0); + BIF_all_preview_changed(); + break; + + case B_CALCCBAND: + case B_CALCCBAND2: + if(coba->tot<2) return; + + for(a=0; a<coba->tot; a++) coba->data[a].cur= a; + qsort(coba->data, coba->tot, sizeof(CBData), vergcband); + for(a=0; a<coba->tot; a++) { + if(coba->data[a].cur==coba->cur) { + if(coba->cur!=a) addqueue(curarea->win, REDRAW, 0); /* button cur */ + coba->cur= a; + break; + } + } + if(event==B_CALCCBAND2) return; + + allqueue(REDRAWBUTSSHADING, 0); + BIF_all_preview_changed(); + + break; + + case B_DOCOLORBAND: + + /* weak; find panel where colorband is */ + block= uiFindOpenPanelBlockName(&curarea->uiblocks, "Colors"); + if(block==NULL) block= uiFindOpenPanelBlockName(&curarea->uiblocks, "Ramps"); + + if(block) { + cbd= coba->data + coba->cur; + uiGetMouse(mywinget(), mvalo); + + while(get_mbut() & L_MOUSE) { + uiGetMouse(mywinget(), mval); + if(mval[0]!=mvalo[0]) { + dx= mval[0]-mvalo[0]; + dx/= 345.0; + cbd->pos+= dx; + CLAMP(cbd->pos, 0.0, 1.0); + + glDrawBuffer(GL_FRONT); + uiPanelPush(block); + drawcolorband_cb(); + uiPanelPop(block); + glDrawBuffer(GL_BACK); + + do_colorbandbuts(coba, B_CALCCBAND2); + cbd= coba->data + coba->cur; /* because qsort */ + + mvalo[0]= mval[0]; + } + BIF_wait_for_statechange(); + } + allqueue(REDRAWBUTSSHADING, 0); + BIF_all_preview_changed(); + } + break; + } +} + void do_texbuts(unsigned short event) { Tex *tex; + Material *ma; ImBuf *ibuf; ScrArea *sa; - ID *id; - CBData *cbd; - uiBlock *block; - float dx; - int a, nr; - short mvalo[2], mval[2]; + ID *id; + int nr; + char *name, str[80]; tex= G.buts->lockpoin; @@ -490,79 +614,22 @@ void do_texbuts(unsigned short event) break; case B_ADDCOLORBAND: - if(tex==0 || tex->coba==0) return; - - if(tex->coba->tot < MAXCOLORBAND-1) tex->coba->tot++; - tex->coba->cur= tex->coba->tot-1; - - do_texbuts(B_CALCCBAND); - - break; - case B_DELCOLORBAND: - if(tex==0 || tex->coba==0 || tex->coba->tot<2) return; - - for(a=tex->coba->cur; a<tex->coba->tot; a++) { - tex->coba->data[a]= tex->coba->data[a+1]; - } - if(tex->coba->cur) tex->coba->cur--; - tex->coba->tot--; - - allqueue(REDRAWBUTSSHADING, 0); - BIF_all_preview_changed(); - break; - case B_CALCCBAND: case B_CALCCBAND2: - if(tex==0 || tex->coba==0 || tex->coba->tot<2) return; - - for(a=0; a<tex->coba->tot; a++) tex->coba->data[a].cur= a; - qsort(tex->coba->data, tex->coba->tot, sizeof(CBData), vergcband); - for(a=0; a<tex->coba->tot; a++) { - if(tex->coba->data[a].cur==tex->coba->cur) { - if(tex->coba->cur!=a) addqueue(curarea->win, REDRAW, 0); /* button cur */ - tex->coba->cur= a; - break; - } - } - if(event==B_CALCCBAND2) return; - - allqueue(REDRAWBUTSSHADING, 0); - BIF_all_preview_changed(); - - break; - case B_DOCOLORBAND: - if(tex==0 || tex->coba==0) return; - - block= uiFindOpenPanelBlockName(&curarea->uiblocks, "Colors"); - if(block) { - cbd= tex->coba->data + tex->coba->cur; - uiGetMouse(mywinget(), mvalo); - - while(get_mbut() & L_MOUSE) { - uiGetMouse(mywinget(), mval); - if(mval[0]!=mvalo[0]) { - dx= mval[0]-mvalo[0]; - dx/= 345.0; - cbd->pos+= dx; - CLAMP(cbd->pos, 0.0, 1.0); - - glDrawBuffer(GL_FRONT); - uiPanelPush(block); - drawcolorband(tex->coba, 10,150,300,20); - uiPanelPop(block); - glDrawBuffer(GL_BACK); - - do_texbuts(B_CALCCBAND2); - cbd= tex->coba->data + tex->coba->cur; /* because qsort */ - - mvalo[0]= mval[0]; - } - BIF_wait_for_statechange(); + /* these events can be called from material subcontext too */ + id= G.buts->lockpoin; + if(id) { + if( GS(id->name)==ID_TE) { + tex= (Tex *)id; + do_colorbandbuts(tex->coba, event); + } + else { + ma= (Material *)id; + if(ma->ramp_show==0) do_colorbandbuts(ma->ramp_col, event); + else do_colorbandbuts(ma->ramp_spec, event); } - allqueue(REDRAWBUTSSHADING, 0); - BIF_all_preview_changed(); } break; @@ -1126,21 +1193,39 @@ static void texture_panel_image(Tex *tex) } -static void drawcolorband_cb(void) +static void draw_colorband_buts(uiBlock *block, ColorBand *coba, int offs, int redraw) { - ID *id, *idfrom; + CBData *cbd; + + if(coba==NULL) return; - buttons_active_id(&id, &idfrom); - if( GS(id->name)==ID_TE) { - Tex *tex= (Tex *)id; - drawcolorband(tex->coba, 10,150,300,20); - } + uiDefBut(block, BUT, B_ADDCOLORBAND, "Add", 90,180+offs,40,20, 0, 0, 0, 0, 0, "Adds a new colour position to the colorband"); + uiDefButS(block, NUM, B_REDR, "Cur:", 130,180+offs,90,20, &coba->cur, 0.0, (float)(coba->tot-1), 0, 0, "Displays the active colour from the colorband"); + uiDefBut(block, BUT, B_DELCOLORBAND, "Del", 220,180+offs,40,20, 0, 0, 0, 0, 0, "Deletes the active position"); + uiDefButS(block, ROW, redraw, "E", 260,180+offs,17,20, &coba->ipotype, 5.0, 1.0, 0, 0, "Sets interpolation type 'Ease' (quadratic) "); + uiDefButS(block, ROW, B_TEXREDR_PRV, "L", 277,180+offs,16,20, &coba->ipotype, 5.0, 0.0, 0, 0, "Sets interpolation type Linear"); + uiDefButS(block, ROW, B_TEXREDR_PRV, "S", 293,180+offs,17,20, &coba->ipotype, 5.0, 2.0, 0, 0, "Sets interpolation type B-Spline"); + + uiDefBut(block, LABEL, B_DOCOLORBAND, "", 10,150+offs,300,30, 0, 0, 0, 0, 0, "Colorband"); /* only for event! */ + + uiBlockSetDrawExtraFunc(block, drawcolorband_cb); + cbd= coba->data + coba->cur; + + uiBlockBeginAlign(block); + uiDefButF(block, NUM, B_CALCCBAND, "Pos", 10,125+offs,110,20, &cbd->pos, 0.0, 1.0, 10, 0, "Sets the position of the active colour"); + uiDefButF(block, COL, B_BANDCOL, "", 10,105+offs,110,20, &(cbd->r), 0, 0, 0, 0, ""); + uiDefButF(block, NUMSLI, B_TEXREDR_PRV, "A ", 10,85+offs,110,20, &cbd->a, 0.0, 1.0, 0, 0, "Sets the alpha value for this position"); + + uiBlockBeginAlign(block); + uiDefButF(block, NUMSLI, B_TEXREDR_PRV, "R ", 125,125+offs,185,20, &cbd->r, 0.0, 1.0, B_BANDCOL, 0, "Sets the red value for the active colour"); + uiDefButF(block, NUMSLI, B_TEXREDR_PRV, "G ", 125,105+offs,185,20, &cbd->g, 0.0, 1.0, B_BANDCOL, 0, "Sets the green value for the active colour"); + uiDefButF(block, NUMSLI, B_TEXREDR_PRV, "B ", 125,85+offs,185,20, &cbd->b, 0.0, 1.0, B_BANDCOL, 0, "Sets the blue value for the active colour"); + uiBlockEndAlign(block); } static void texture_panel_colors(Tex *tex) { uiBlock *block; - CBData *cbd; block= uiNewBlock(&curarea->uiblocks, "texture_panel_colors", UI_EMBOSS, UI_HELV, curarea->win); uiNewPanelTabbed("Texture", "Texture"); @@ -1149,28 +1234,10 @@ static void texture_panel_colors(Tex *tex) /* COLORBAND */ uiBlockBeginAlign(block); - uiDefButS(block, TOG|BIT|0, B_COLORBAND, "Colorband",10,180,100,20, &tex->flag, 0, 0, 0, 0, "Toggles colorband operations"); + uiDefButS(block, TOG|BIT|0, B_COLORBAND, "Colorband",10,180,80,20, &tex->flag, 0, 0, 0, 0, "Toggles colorband operations"); if(tex->flag & TEX_COLORBAND) { - uiDefBut(block, BUT, B_ADDCOLORBAND, "Add", 110,180,50,20, 0, 0, 0, 0, 0, "Adds a new colour position to the colorband"); - uiDefButS(block, NUM, B_REDR, "Cur:", 160,180,100,20, &tex->coba->cur, 0.0, (float)(tex->coba->tot-1), 0, 0, "Displays the active colour from the colorband"); - uiDefBut(block, BUT, B_DELCOLORBAND, "Del", 260,180,50,20, 0, 0, 0, 0, 0, "Deletes the active position"); - uiDefBut(block, LABEL, B_DOCOLORBAND, "", 10,150,300,20, 0, 0, 0, 0, 0, "Colorband"); /* only for event! */ - - uiBlockSetDrawExtraFunc(block, drawcolorband_cb); - cbd= tex->coba->data + tex->coba->cur; - - uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_CALCCBAND, "Pos", 10,120,80,20, &cbd->pos, 0.0, 1.0, 10, 0, "Sets the position of the active colour"); - uiDefButS(block, ROW, B_TEXREDR_PRV, "E", 90,120,20,20, &tex->coba->ipotype, 5.0, 1.0, 0, 0, "More complicated Interpolation"); - uiDefButS(block, ROW, B_TEXREDR_PRV, "L", 110,120,20,20, &tex->coba->ipotype, 5.0, 0.0, 0, 0, "Sets interpolation type to Linear"); - uiDefButS(block, ROW, B_TEXREDR_PRV, "S", 130,120,20,20, &tex->coba->ipotype, 5.0, 2.0, 0, 0, "Sets interpolation type to Spline"); - uiDefButF(block, COL, B_BANDCOL, "", 150,120,30,20, &(cbd->r), 0, 0, 0, 0, ""); - uiDefButF(block, NUMSLI, B_TEXREDR_PRV, "A ", 180,120,130,20, &cbd->a, 0.0, 1.0, 0, 0, "Sets the alpha value for this position"); - uiBlockBeginAlign(block); - uiDefButF(block, NUMSLI, B_TEXREDR_PRV, "R ", 10,100,100,20, &cbd->r, 0.0, 1.0, B_BANDCOL, 0, "Sets the red value for the active colour"); - uiDefButF(block, NUMSLI, B_TEXREDR_PRV, "G ", 110,100,100,20, &cbd->g, 0.0, 1.0, B_BANDCOL, 0, "Sets the green value for the active colour"); - uiDefButF(block, NUMSLI, B_TEXREDR_PRV, "B ", 210,100,100,20, &cbd->b, 0.0, 1.0, B_BANDCOL, 0, "Sets the blue value for the active colour"); + draw_colorband_buts(block, tex->coba, 0, B_TEXREDR_PRV); } /* RGB-BRICON */ @@ -2260,6 +2327,20 @@ void do_matbuts(unsigned short event) BIF_preview_changed(G.buts); } break; + case B_MATCOLORBAND: + ma= G.buts->lockpoin; + if(ma) { + if(ma->mode & MA_RAMP_COL) + if(ma->ramp_col==NULL) ma->ramp_col= add_colorband(); + if(ma->mode & MA_RAMP_SPEC) + if(ma->ramp_spec==NULL) ma->ramp_spec= add_colorband(); + + allqueue(REDRAWBUTSSHADING, 0); + BIF_all_preview_changed(); + } + break; + + break; } } @@ -2611,6 +2692,53 @@ static void material_panel_shading(Material *ma) } +static void material_panel_ramps(Material *ma) +{ + uiBlock *block; + ColorBand *coba; + float *facp; + short bitval; + char *inputc, *methodc; + + block= uiNewBlock(&curarea->uiblocks, "material_panel_ramps", UI_EMBOSS, UI_HELV, curarea->win); + uiNewPanelTabbed("Material", "Material"); + if(uiNewPanel(curarea, block, "Ramps", "Material", 640, 0, 318, 204)==0) return; + + uiBlockBeginAlign(block); + uiBlockSetCol(block, TH_BUT_SETTING1); + uiDefButS(block, ROW, B_REDR, "Show Col Ramp",10,180,150,20, &ma->ramp_show, 0, 0, 0, 0, "Show ramp buttons for material diffuse color"); + uiDefButS(block, ROW, B_REDR, "Show Spec Ramp",160,180,150,20, &ma->ramp_show, 0, 1, 0, 0, "Show ramp buttons for material specular color"); + uiBlockSetCol(block, TH_AUTO); + + /* COLORBAND */ + if(ma->ramp_show==0) bitval= 20; else bitval= 21; + uiBlockBeginAlign(block); + uiDefButI(block, TOG|BIT|bitval, B_MATCOLORBAND, "Colorband",10,145,80,20, &ma->mode, 0, 0, 0, 0, "Toggles colorband ramp operations"); + + if(ma->mode & (1<<bitval)) { + if(ma->ramp_show==0) { + coba= ma->ramp_col; + inputc= &ma->rampin_col; + methodc= &ma->rampblend_col; + facp= &ma->rampfac_col; + } + else { + coba= ma->ramp_spec; + inputc= &ma->rampin_spec; + methodc= &ma->rampblend_spec; + facp= &ma->rampfac_spec; + } + draw_colorband_buts(block, coba, -35, B_MATPRV); // aligns with previous button + + uiDefBut(block, LABEL, 0, "Input",10,30,90,20, NULL, 0, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "Method",100,30,90,20, NULL, 0, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "Factor",190,30,120,20, NULL, 0, 0, 0, 0, ""); + uiBlockBeginAlign(block); + uiDefButC(block, MENU, B_MATPRV, "Shader %x0|Energy %x1|Normal %x2|Result %x3",10,10,90,20, inputc, 0, 0, 0, 0, "Input for Ramp"); + uiDefButC(block, MENU, B_MATPRV, "Mix %x0|Add %x1|Mult %x2|Sub %x3",110,10,90,20, methodc, 0, 0, 0, 0, "Blending method for Ramp (uses alpha in Colorband)"); + uiDefButF(block, NUMSLI, B_MATPRV, "", 190,10,120,20, facp, 0.0, 1.0, 100, 0, "Blending factor (also uses alpha in Colorband)"); + } +} static void material_panel_material(Object *ob, Material *ma) { @@ -2707,7 +2835,7 @@ static void material_panel_material(Object *ob, Material *ma) uiDefButC(block, ROW, REDRAWBUTSSHADING, "Ring", 83,57,40,20, &(ma->rgbsel), 2.0, 2.0, 0, 0, "Sets the colour of the rings with the RGB sliders"); } else { - uiDefButC(block, ROW, REDRAWBUTSSHADING, "Col", 83,97,40,20, &(ma->rgbsel), 2.0, 0.0, 0, 0, "Sets the basic colour of the material"); + uiDefButC(block, ROW, REDRAWBUTSSHADING, "Col", 83,97,40,20, &(ma->rgbsel), 2.0, 0.0, 0, 0, "Sets the diffuse colour of the material"); uiDefButC(block, ROW, REDRAWBUTSSHADING, "Spe", 83,77,40,20, &(ma->rgbsel), 2.0, 1.0, 0, 0, "Sets the specular colour of the material"); uiDefButC(block, ROW, REDRAWBUTSSHADING, "Mir", 83,57,40,20, &(ma->rgbsel), 2.0, 2.0, 0, 0, "Sets the mirror colour of the material"); } @@ -2756,11 +2884,17 @@ static void material_panel_preview(Material *ma) // label to force a boundbox for buttons not to be centered uiDefBut(block, LABEL, 0, " ", 20,20,10,10, 0, 0, 0, 0, 0, ""); uiBlockSetCol(block, TH_BUT_NEUTRAL); + uiBlockBeginAlign(block); uiDefIconButC(block, ROW, B_MATPRV, ICON_MATPLANE, 210,180,25,22, &(ma->pr_type), 10, 0, 0, 0, ""); - uiDefIconButC(block, ROW, B_MATPRV, ICON_MATSPHERE, 210,150,25,22, &(ma->pr_type), 10, 1, 0, 0, ""); - uiDefIconButC(block, ROW, B_MATPRV, ICON_MATCUBE, 210,120,25,22, &(ma->pr_type), 10, 2, 0, 0, ""); - uiDefIconButS(block, ICONTOG|BIT|0, B_MATPRV, ICON_TRANSP_HLT, 210,80,25,22, &(ma->pr_back), 0, 0, 0, 0, ""); - uiDefIconBut(block, BUT, B_MATPRV, ICON_EYE, 210,10, 25,22, 0, 0, 0, 0, 0, ""); + uiDefIconButC(block, ROW, B_MATPRV, ICON_MATSPHERE, 210,158,25,22, &(ma->pr_type), 10, 1, 0, 0, ""); + uiDefIconButC(block, ROW, B_MATPRV, ICON_MATCUBE, 210,136,25,22, &(ma->pr_type), 10, 2, 0, 0, ""); + uiBlockEndAlign(block); + + uiDefIconButS(block, ICONTOG|BIT|0, B_MATPRV, ICON_TRANSP_HLT, 210,100,25,22, &(ma->pr_back), 0, 0, 0, 0, ""); + + uiBlockBeginAlign(block); + uiDefIconButS(block, TOG|BIT|1, B_MATPRV, ICON_LAMP, 210,40,25,20, &(ma->pr_lamp), 0, 0, 0, 0, ""); + uiDefIconButS(block, TOG|BIT|0, B_MATPRV, ICON_LAMP, 210,20,25,20, &(ma->pr_lamp), 0, 0, 0, 0, ""); } } @@ -2781,6 +2915,7 @@ void material_panels() material_panel_material(ob, ma); if(ma) { + material_panel_ramps(ma); material_panel_shading(ma); material_panel_tramir(ma); material_panel_texture(ma); diff --git a/source/blender/src/previewrender.c b/source/blender/src/previewrender.c index cb94d0b327a..29bd5bedadb 100644 --- a/source/blender/src/previewrender.c +++ b/source/blender/src/previewrender.c @@ -37,6 +37,7 @@ #include <stdlib.h> #include <math.h> +#include <string.h> #ifdef HAVE_CONFIG_H #include <config.h> @@ -717,9 +718,9 @@ static void shade_preview_pixel(ShadeInput *shi, float *vec, int x, int y,char * { extern float fresnel_fac(float *view, float *vn, float ior, float fac); 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; - float view[3], lv[3], *la, alpha; + float v1,inp, is, inprspec=0, isr=0.0, isb=0.0, isg=0.0; + float diff[3]={0.0, 0.0, 0.0}; + float lv[3], *la, alpha; float eul[3], tmat[3][3], imat[3][3]; int temp, a; char tracol; @@ -727,10 +728,10 @@ static void shade_preview_pixel(ShadeInput *shi, float *vec, int x, int y,char * mat= shi->matren; v1= 1.0/PR_RECTX; - view[0]= v1*x; - view[1]= v1*y; - view[2]= 1.0; - Normalise(view); + shi->view[0]= v1*x; + shi->view[1]= v1*y; + shi->view[2]= 1.0; + Normalise(shi->view); shi->refcol[0]= shi->refcol[1]= shi->refcol[2]= shi->refcol[3]= 0.0; @@ -776,13 +777,11 @@ static void shade_preview_pixel(ShadeInput *shi, float *vec, int x, int y,char * shi->orn[2]= shi->vn[2]; } if(mat->texco & TEXCO_REFL) { - /* for bump texture */ - VECCOPY(shi->view, view); - inp= -2.0*(shi->vn[0]*view[0]+shi->vn[1]*view[1]+shi->vn[2]*view[2]); - shi->ref[0]= (view[0]+inp*shi->vn[0]); - shi->ref[1]= (view[1]+inp*shi->vn[1]); - shi->ref[2]= (view[2]+inp*shi->vn[2]); + inp= -2.0*(shi->vn[0]*shi->view[0]+shi->vn[1]*shi->view[1]+shi->vn[2]*shi->view[2]); + shi->ref[0]= (shi->view[0]+inp*shi->vn[0]); + shi->ref[1]= (shi->view[1]+inp*shi->vn[1]); + shi->ref[2]= (shi->view[2]+inp*shi->vn[2]); } /* Clear displase vec for preview */ @@ -821,7 +820,7 @@ static void shade_preview_pixel(ShadeInput *shi, float *vec, int x, int y,char * if(mat->mode & (MA_ZTRA|MA_RAYTRANSP)) if(mat->fresnel_tra!=0.0) - alpha*= fresnel_fac(view, shi->vn, mat->fresnel_tra_i, mat->fresnel_tra); + alpha*= fresnel_fac(shi->view, shi->vn, mat->fresnel_tra_i, mat->fresnel_tra); if(mat->mode & MA_SHLESS) { temp= 255.0*(mat->r); @@ -837,6 +836,8 @@ static void shade_preview_pixel(ShadeInput *shi, float *vec, int x, int y,char * for(a=0; a<2; a++) { + if((mat->pr_lamp & (1<<a))==0) continue; + if(a==0) la= pr1_lamp; else la= pr2_lamp; @@ -845,45 +846,54 @@ static void shade_preview_pixel(ShadeInput *shi, float *vec, int x, int y,char * lv[2]= vec[2]-la[2]; Normalise(lv); - inp= shi->vn[0]*lv[0]+shi->vn[1]*lv[1]+shi->vn[2]*lv[2]; - if(inp<0.0) inp= 0.0; + is= shi->vn[0]*lv[0]+shi->vn[1]*lv[1]+shi->vn[2]*lv[2]; + if(is<0.0) is= 0.0; if(mat->spec) { - if(inp>0.0) { + if(is>0.0) { /* specular shaders */ float specfac; if(mat->spec_shader==MA_SPEC_PHONG) - specfac= Phong_Spec(shi->vn, lv, view, mat->har); + specfac= Phong_Spec(shi->vn, lv, shi->view, mat->har); else if(mat->spec_shader==MA_SPEC_COOKTORR) - specfac= CookTorr_Spec(shi->vn, lv, view, mat->har); + specfac= CookTorr_Spec(shi->vn, lv, shi->view, mat->har); else if(mat->spec_shader==MA_SPEC_BLINN) - specfac= Blinn_Spec(shi->vn, lv, view, mat->refrac, (float)mat->har); + specfac= Blinn_Spec(shi->vn, lv, shi->view, mat->refrac, (float)mat->har); else - specfac= Toon_Spec(shi->vn, lv, view, mat->param[2], mat->param[3]); + specfac= Toon_Spec(shi->vn, lv, shi->view, mat->param[2], mat->param[3]); inprspec= specfac*mat->spec; - isr+= inprspec*mat->specr; - isg+= inprspec*mat->specg; - isb+= inprspec*mat->specb; - + if(mat->mode & MA_RAMP_SPEC) { + float spec[3]; + do_specular_ramp(shi, specfac, inprspec, spec); + isr+= inprspec*spec[0]; + isg+= inprspec*spec[1]; + isb+= inprspec*spec[2]; + } + else { + isr+= inprspec*mat->specr; + isg+= inprspec*mat->specg; + isb+= inprspec*mat->specb; + } } } /* diffuse shaders */ - if(mat->diff_shader==MA_DIFF_ORENNAYAR) inp= OrenNayar_Diff(shi->vn, lv, view, mat->roughness); - else if(mat->diff_shader==MA_DIFF_TOON) inp= Toon_Diff(shi->vn, lv, view, mat->param[0], mat->param[1]); + if(mat->diff_shader==MA_DIFF_ORENNAYAR) is= OrenNayar_Diff(shi->vn, lv, shi->view, mat->roughness); + else if(mat->diff_shader==MA_DIFF_TOON) is= Toon_Diff(shi->vn, lv, shi->view, mat->param[0], mat->param[1]); // else Lambert - - inp= (mat->ref*inp + mat->emit); + + inp= (mat->ref*is + mat->emit); if(a==0) la= pr1_col; else la= pr2_col; - ir+= inp*la[0]; - ig+= inp*la[1]; - ib+= inp*la[2]; + add_to_diffuse(diff, shi, is, inp*la[0], inp*la[1], inp*la[2]); + //ir+= inp*la[0]; + //ig+= inp*la[1]; + //ib+= inp*la[2]; } /* drawing checkerboard and sky */ @@ -899,7 +909,7 @@ static void shade_preview_pixel(ShadeInput *shi, float *vec, int x, int y,char * /* scale */ div= (0.85*shi->ref[1]); - shi->refcol[0]= mat->ray_mirror*fresnel_fac(view, shi->vn, mat->fresnel_mir_i, mat->fresnel_mir); + shi->refcol[0]= mat->ray_mirror*fresnel_fac(shi->view, shi->vn, mat->fresnel_mir_i, mat->fresnel_mir); /* not real 'alpha', but mirror overriding transparency */ if(mat->mode & MA_RAYTRANSP) { float fac= sqrt(shi->refcol[0]); @@ -923,26 +933,29 @@ static void shade_preview_pixel(ShadeInput *shi, float *vec, int x, int y,char * shi->refcol[3]= shi->refcol[0]*0.8*div; } } - + + if(mat->mode & MA_RAMP_COL) ramp_diffuse_result(diff, shi); + if(mat->mode & MA_RAMP_SPEC) ramp_spec_result(&isr, &isg, &isb, shi); + if(shi->refcol[0]==0.0) { - a= 255.0*( mat->r*ir +mat->ambr +isr); + a= 255.0*(diff[0] +mat->ambr +isr); if(a>255) a=255; else if(a<0) a= 0; rect[0]= a; - a= 255.0*(mat->g*ig +mat->ambg +isg); + a= 255.0*(diff[1] +mat->ambg +isg); if(a>255) a=255; else if(a<0) a= 0; rect[1]= a; - a= 255*(mat->b*ib +mat->ambb +isb); + a= 255*(diff[2] +mat->ambb +isb); if(a>255) a=255; else if(a<0) a= 0; rect[2]= a; } else { - a= 255.0*( mat->mirr*shi->refcol[1] + (1.0 - mat->mirr*shi->refcol[0])*(mat->r*ir +mat->ambr) +isr); + a= 255.0*( mat->mirr*shi->refcol[1] + (1.0 - mat->mirr*shi->refcol[0])*(diff[0] +mat->ambr) +isr); if(a>255) a=255; else if(a<0) a= 0; rect[0]= a; - a= 255.0*( mat->mirg*shi->refcol[2] + (1.0 - mat->mirg*shi->refcol[0])*(mat->g*ig +mat->ambg) +isg); + a= 255.0*( mat->mirg*shi->refcol[2] + (1.0 - mat->mirg*shi->refcol[0])*(diff[1] +mat->ambg) +isg); if(a>255) a=255; else if(a<0) a= 0; rect[1]= a; - a= 255.0*( mat->mirb*shi->refcol[3] + (1.0 - mat->mirb*shi->refcol[0])*(mat->b*ib +mat->ambb) +isb); + a= 255.0*( mat->mirb*shi->refcol[3] + (1.0 - mat->mirb*shi->refcol[0])*(diff[2] +mat->ambb) +isb); if(a>255) a=255; else if(a<0) a= 0; rect[2]= a; } |