Finished hair strand render project (well, for release), also with a good

doc;

http://www.blender3d.org/cms/Hair_Strand_Rendering.722.0.html

- added width control for strands
- made tangent (anisotropic) render an option
  (so you can render strands more solid, like metal/wood)

Also:
- ALT+A anim playback with static particles made cursor flashing
This commit is contained in:
Ton Roosendaal 2005-11-12 16:22:10 +00:00
parent 0c4172ffb5
commit 9bf198bbca
8 changed files with 90 additions and 17 deletions

@ -376,7 +376,7 @@ static void precalc_effectors(Object *ob, PartEff *paf, Particle *pa, ListBase *
if(ec->ob->type==OB_CURVE) {
float vec[4], dir[3];
ec->oldspeed[0]= ec->oldspeed[1]= ec->oldspeed[2];
ec->oldspeed[0]= ec->oldspeed[1]= ec->oldspeed[2]= 0.0f;
/* scale corrects speed vector to curve size */
if(paf->totkey>1) ec->scale= (paf->totkey-1)/pa->lifetime;
@ -584,6 +584,19 @@ void pdDoEffectors(ListBase *lb, float *opco, float *force, float *speed, float
where_on_path(ob, f_force*loc_time*ec->time_scale, guidevec, guidedir);
else
where_on_path(ob, loc_time*ec->time_scale, guidevec, guidedir);
/* rotate */
if(0) {
float q[4], x1;
Normalise(guidedir);
q[0]= (float)cos(0.5*guidevec[3]);
x1= (float)sin(0.5*guidevec[3]);
q[1]= -x1*guidedir[0];
q[2]= -x1*guidedir[1];
q[3]= -x1*guidedir[2];
}
VECSUB(guidedir, guidevec, ec->oldloc);
VECCOPY(ec->oldloc, guidevec);
@ -1878,6 +1891,6 @@ void build_particle_system(Object *ob)
disable_speed_curve(0);
waitcursor(0);
if(waitcursor_set) waitcursor(0);
}

@ -100,8 +100,10 @@ void init_material(Material *ma)
ma->param[1]= 0.1;
ma->param[2]= 0.5;
ma->param[3]= 0.1;
ma->rms=0.1;
ma->darkness=1.0;
ma->rms= 0.1;
ma->darkness= 1.0;
ma->strand_sta= ma->strand_end= 1.0f;
ma->ang= 1.0;
ma->ray_depth= 2;
@ -115,7 +117,7 @@ void init_material(Material *ma)
ma->rampfac_spec= 1.0;
ma->pr_lamp= 3; // two lamps, is bits
ma->mode= MA_TRACEBLE+MA_SHADOW+MA_RADIO;
ma->mode= MA_TRACEBLE|MA_SHADOW|MA_RADIO|MA_TANGENT_STR;
}
Material *add_material(char *name)

@ -5012,6 +5012,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
Object *ob;
Scene *sce= main->scene.first;
Camera *cam= main->camera.first;
Material *ma= main->mat.first;
/* deformflag is local in modifier now */
for(ob=main->object.first; ob; ob= ob->id.next) {
@ -5052,6 +5053,12 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
sce= sce->id.next;
}
for(; ma; ma= ma->id.next) {
if(ma->strand_sta==0.0f) {
ma->strand_sta= ma->strand_end= 1.0f;
ma->mode |= MA_TANGENT_STR;
}
}
}
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */

@ -146,6 +146,8 @@ void borderselect_icu_key(struct IpoCurve *icu, float xmin, float xmax,
void select_ipo_key(struct Ipo *ipo, float selx, int sel);
void select_icu_key(struct IpoCurve *icu, float selx, int selectmode);
void setexprap_ipoloop(struct Ipo *ipo, int code);
/* callbacks */
int select_bezier_add(struct BezTriple *bezt);
int select_bezier_subtract(struct BezTriple *bezt);

@ -64,7 +64,7 @@ typedef struct Material {
float translucency;
float fresnel_mir, fresnel_mir_i;
float fresnel_tra, fresnel_tra_i;
float filter, pad0; /* filter added, for raytrace transparency */
float filter; /* filter added, for raytrace transparency */
short ray_depth, ray_depth_tra;
short har;
char seed1, seed2;
@ -73,6 +73,7 @@ typedef struct Material {
int mode2; /* even more material settings :) */
short flarec, starc, linec, ringc;
float hasize, flaresize, subsize, flareboost;
float strand_sta, strand_end, strand_ease;
/* for buttons and render*/
char rgbsel, texact, pr_type, pad;
@ -153,6 +154,7 @@ typedef struct Material {
#define MA_RAMP_SPEC 0x200000
#define MA_RAYBIAS 0x400000
#define MA_FULL_OSA 0x800000
#define MA_TANGENT_STR 0x1000000
/* diff_shader */
#define MA_DIFF_LAMBERT 0

@ -414,7 +414,7 @@ typedef struct Scene {
#define R_FACE_SPLIT 32
/* Tells render to divide face other way. */
#define R_DIVIDE_24 64
/* vertex normals are tangent vector, for hair shader */
/* vertex normals are tangent or view-corrected vector, for hair strands */
#define R_TANGENT 128
/* vertren->texofs (texcoordinate offset relative to vertren->orco */

@ -940,6 +940,7 @@ static void static_particle_strand(Object *ob, Material *ma, float *orco, float
static VertRen *v1= NULL, *v2= NULL;
VlakRen *vlr;
float nor[3], cross[3], w, dx, dy;
int flag;
VecSubf(nor, vec, vec1);
Normalise(nor); // nor needed as tangent
@ -951,9 +952,25 @@ static void static_particle_strand(Object *ob, Material *ma, float *orco, float
dx= R.rectx*cross[0]*R.winmat[0][0]/w;
dy= R.recty*cross[1]*R.winmat[1][1]/w;
w= sqrt(dx*dx + dy*dy);
if(w!=0.0f)
VecMulf(cross, 1.0/w);
if(w!=0.0f) {
float fac;
if(ma->strand_ease!=0.0f) {
if(ma->strand_ease<0.0f)
fac= pow(ctime, 1.0+ma->strand_ease);
else
fac= pow(ctime, 1.0/(1.0f-ma->strand_ease));
}
else fac= ctime;
VecMulf(cross, ((1.0f-fac)*ma->strand_sta + (fac)*ma->strand_end)/w);
}
if(ma->mode & MA_TANGENT_STR)
flag= ME_SMOOTH|R_NOPUNOFLIP|R_TANGENT;
else
flag= ME_SMOOTH;
/* a bit weak... ctime should be 0.0 for first vertex always */
if(ctime == 0.0f) {
v1= RE_findOrAddVert(R.totvert++);
v2= RE_findOrAddVert(R.totvert++);
@ -973,7 +990,7 @@ static void static_particle_strand(Object *ob, Material *ma, float *orco, float
else {
vlr= RE_findOrAddVlak(R.totvlak++);
vlr->flag= ME_SMOOTH|R_NOPUNOFLIP|R_TANGENT;
vlr->flag= flag;
vlr->ob= vlr_set_ob(ob);
vlr->v1= v1;
vlr->v2= v2;
@ -1015,7 +1032,7 @@ static void render_static_particle_system(Object *ob, PartEff *paf)
float xn, yn, zn, imat[3][3], mat[4][4], hasize;
float mtime, ptime, ctime, vec[3], vec1[3], view[3], nor[3];
float *orco= NULL;
int a, mat_nr=1, seed;
int a, mat_nr=1, seed, totvlako, totverto;
pa= paf->keys;
if(pa==NULL || (paf->flag & PAF_ANIMATED) || paf->disp!=100) {
@ -1024,7 +1041,10 @@ static void render_static_particle_system(Object *ob, PartEff *paf)
if(pa==NULL) return;
}
ma= give_render_material(ob, 1);
totvlako= R.totvlak;
totverto= R.totvert;
ma= give_render_material(ob, paf->omat);
if(ma->mode & MA_HALO)
R.flag |= R_HALO;
@ -1157,6 +1177,9 @@ static void render_static_particle_system(Object *ob, PartEff *paf)
MEM_freeN(paf->keys);
paf->keys= NULL;
}
if((ma->mode & MA_TANGENT_STR)==0)
calc_vertexnormals(totverto, totvlako);
}

@ -3123,6 +3123,29 @@ static void material_panel_ramps(Material *ma)
}
}
/* NOTE: this is a block-menu, needs 0 events, otherwise the menu closes */
static uiBlock *strand_menu(void *mat_v)
{
Material *ma= mat_v;
uiBlock *block;
block= uiNewBlock(&curarea->uiblocks, "strand menu", UI_EMBOSS, UI_HELV, curarea->win);
/* use this for a fake extra empy space around the buttons */
uiDefBut(block, LABEL, 0, "", 0, 0, 250, 100, NULL, 0, 0, 0, 0, "");
uiBlockBeginAlign(block);
uiDefButBitI(block, TOG, MA_TANGENT_STR, 0, "Use Tangent Shading", 10,70,230,20, &(ma->mode), 0, 0, 0, 0, "Uses direction of strands as normal for tangent-shading");
uiDefButF(block, NUMSLI, 0, "Start ", 10, 50, 230,20, &ma->strand_sta, 0.25, 20.0, 2, 0, "Start size of strands in pixels");
uiDefButF(block, NUMSLI, 0, "End ", 10, 30, 230,20, &ma->strand_end, 0.25, 10.0, 2, 0, "End size of strands in pixels");
uiDefButF(block, NUMSLI, 0, "Shape ", 10, 10, 230,20, &ma->strand_ease, -0.9, 0.9, 2, 0, "Shape of strands, positive value makes it rounder, negative makes it spiky");
uiBlockSetDirection(block, UI_TOP);
return block;
}
static void material_panel_material(Object *ob, Material *ma)
{
uiBlock *block;
@ -3194,12 +3217,13 @@ static void material_panel_material(Object *ob, Material *ma)
if(!(ma->mode & MA_HALO)) {
uiBlockBeginAlign(block);
uiBlockSetCol(block, TH_BUT_SETTING1);
uiDefButBitI(block, TOG, MA_VERTEXCOL, B_REDR, "VCol Light", 8,146,73,20, &(ma->mode), 0, 0, 0, 0, "Adds vertex colours as extra light");
uiDefButBitI(block, TOG, MA_VERTEXCOLP, B_REDR, "VCol Paint", 82,146,73,20, &(ma->mode), 0, 0, 0, 0, "Replaces material's colours with vertex colours");
uiDefButBitI(block, TOG, MA_FACETEXTURE, B_REDR, "TexFace", 156,146,73,20, &(ma->mode), 0, 0, 0, 0, "Sets UV-Editor assigned texture as color and texture info for faces");
uiDefButBitI(block, TOG, MA_VERTEXCOL, B_REDR, "VCol Light", 8,146,74,20, &(ma->mode), 0, 0, 0, 0, "Adds vertex colours as extra light");
uiDefButBitI(block, TOG, MA_VERTEXCOLP, B_REDR, "VCol Paint", 82,146,74,20, &(ma->mode), 0, 0, 0, 0, "Replaces material's colours with vertex colours");
uiDefButBitI(block, TOG, MA_FACETEXTURE, B_REDR, "TexFace", 156,146,74,20, &(ma->mode), 0, 0, 0, 0, "Sets UV-Editor assigned texture as color and texture info for faces");
uiDefButBitI(block, TOG, MA_SHLESS, B_MATPRV, "Shadeless", 230,146,73,20, &(ma->mode), 0, 0, 0, 0, "Makes material insensitive to light or shadow");
uiDefButBitI(block, TOG, MA_FULL_OSA, 0, "Full Osa", 8,127,147,19, &(ma->mode), 0.0, 10.0, 0, 0, "Forces to render all OSA samples, for shading and texture antialiasing");
uiDefButBitI(block, TOG, MA_WIRE, 0, "Wire", 156,127,73,19, &(ma->mode), 0, 0, 0, 0, "Renders only the edges of faces as a wireframe");
uiDefButBitI(block, TOG, MA_FULL_OSA, 0, "Full Osa", 8,127,74,19, &(ma->mode), 0.0, 10.0, 0, 0, "Forces to render all OSA samples, for shading and texture antialiasing");
uiDefBlockBut(block, strand_menu, ma, "Strands", 82,127,74, 20, "Display strand settings for static particles");
uiDefButBitI(block, TOG, MA_WIRE, 0, "Wire", 156,127,74,19, &(ma->mode), 0, 0, 0, 0, "Renders only the edges of faces as a wireframe");
uiDefButBitI(block, TOG, MA_ZINV, 0, "ZInvert", 230,127,73,19, &(ma->mode), 0, 0, 0, 0, "Renders material's faces with inverted Z Buffer");
}