Misc Render Features
==================== - "From Dupli" option for orco and uv texture coordinates. For dupliverts, duplifaces and dupli particles, this uses the orco and uv at the point on the parent surface. Can for example be used for texturing feathers and leafs. Note that uv only works for duplifaces and particles emitted from faces, these are not defined at vertices. - "Width Fade" option for strand render, to fade out along the width of the strand. Committing this so it can be tested, might be changed or removed even, if it doesn't give nice results.
This commit is contained in:
@@ -1496,11 +1496,10 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
|
||||
float loc[3],loc1[3],loc0[3],vel[3],mat[4][4],nmat[3][3],co[3],nor[3],time;
|
||||
float *orco=0,*surfnor=0,*uvco=0, strandlen=0.0f, curlen=0.0f;
|
||||
float hasize, pa_size, pa_time, r_tilt, cfra=bsystem_time(ob,(float)CFRA,0.0);
|
||||
float adapt_angle=0.0, adapt_pix=0.0, random;
|
||||
float simplify[2];
|
||||
float adapt_angle=0.0, adapt_pix=0.0, random, simplify[2];
|
||||
int i, a, k, max_k=0, totpart, totuv=0, override_uv=-1, dosimplify = 0;
|
||||
int path_possible=0, keys_possible=0, baked_keys=0, totchild=psys->totchild;
|
||||
int seed, path_nbr=0, path=0, orco1=0, adapt=0, uv[3]={0,0,0};
|
||||
int seed, path_nbr=0, path=0, orco1=0, adapt=0, uv[3]={0,0,0}, num;
|
||||
char **uv_name=0;
|
||||
|
||||
/* 1. check that everything is ok & updated */
|
||||
@@ -1644,6 +1643,13 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
|
||||
strandbuf->overrideuv= override_uv;
|
||||
strandbuf->minwidth= ma->strand_min;
|
||||
|
||||
if(ma->strand_widthfade == 0.0f)
|
||||
strandbuf->widthfade= 0.0f;
|
||||
else if(ma->strand_widthfade >= 1.0f)
|
||||
strandbuf->widthfade= 2.0f - ma->strand_widthfade;
|
||||
else
|
||||
strandbuf->widthfade= 1.0f/MAX2(ma->strand_widthfade, 1e-5f);
|
||||
|
||||
if(part->flag & PART_HAIR_BSPLINE)
|
||||
strandbuf->flag |= R_STRAND_BSPLINE;
|
||||
if(ma->mode & MA_STR_B_UNITS)
|
||||
@@ -1700,13 +1706,25 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
|
||||
|
||||
if(uvco && ELEM(part->from,PART_FROM_FACE,PART_FROM_VOLUME)){
|
||||
layer=psmd->dm->faceData.layers + CustomData_get_layer_index(&psmd->dm->faceData,CD_MFACE);
|
||||
for(i=0; i<totuv; i++){
|
||||
MFace *mface=psmd->dm->getFaceData(psmd->dm,pa->num,CD_MFACE);
|
||||
|
||||
mtface=(MTFace*)CustomData_get_layer_n(&psmd->dm->faceData,CD_MTFACE,i);
|
||||
mtface+=pa->num;
|
||||
|
||||
psys_interpolate_uvs(mtface,mface->v4,pa->fuv,uvco+2*i);
|
||||
num= pa->num_dmcache;
|
||||
|
||||
if(num == DMCACHE_NOTFOUND)
|
||||
if(pa->num < psmd->dm->getNumFaces(psmd->dm))
|
||||
num= pa->num;
|
||||
|
||||
for(i=0; i<totuv; i++){
|
||||
if(num != DMCACHE_NOTFOUND) {
|
||||
MFace *mface=psmd->dm->getFaceData(psmd->dm,num,CD_MFACE);
|
||||
mtface=(MTFace*)CustomData_get_layer_n(&psmd->dm->faceData,CD_MTFACE,i);
|
||||
mtface+=num;
|
||||
|
||||
psys_interpolate_uvs(mtface,mface->v4,pa->fuv,uvco+2*i);
|
||||
}
|
||||
else {
|
||||
uvco[2*i]= 0.0f;
|
||||
uvco[2*i + 1]= 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4076,6 +4094,7 @@ static void database_init_objects(Render *re, unsigned int lay, int nolamps, int
|
||||
{
|
||||
Base *base;
|
||||
Object *ob;
|
||||
ObjectInstanceRen *obi;
|
||||
Scene *sce;
|
||||
float mat[4][4], obmat[4][4];
|
||||
|
||||
@@ -4136,11 +4155,18 @@ static void database_init_objects(Render *re, unsigned int lay, int nolamps, int
|
||||
Mat4Invert(imat, obmat);
|
||||
MTC_Mat4MulSerie(mat, re->viewmat, dob->mat, imat, re->viewinv, 0, 0, 0, 0);
|
||||
|
||||
RE_addRenderInstance(re, NULL, obd, ob, dob->index, 0, mat);
|
||||
obi= RE_addRenderInstance(re, NULL, obd, ob, dob->index, 0, mat);
|
||||
VECCOPY(obi->dupliorco, dob->orco);
|
||||
obi->dupliuv[0]= dob->uv[0];
|
||||
obi->dupliuv[1]= dob->uv[1];
|
||||
|
||||
psysindex= 1;
|
||||
for(psys=obd->particlesystem.first; psys; psys=psys->next)
|
||||
for(psys=obd->particlesystem.first; psys; psys=psys->next) {
|
||||
RE_addRenderInstance(re, NULL, obd, ob, dob->index, psysindex++, mat);
|
||||
VECCOPY(obi->dupliorco, dob->orco);
|
||||
obi->dupliuv[0]= dob->uv[0];
|
||||
obi->dupliuv[1]= dob->uv[1];
|
||||
}
|
||||
|
||||
obd->flag |= OB_DONE;
|
||||
obd->transflag |= OB_RENDER_DUPLI;
|
||||
|
||||
@@ -93,10 +93,10 @@ static void ibuf_get_color(float *col, struct ImBuf *ibuf, int x, int y)
|
||||
else {
|
||||
char *rect = (char *)( ibuf->rect+ ofs);
|
||||
|
||||
col[0] = ((float)rect[0])/255.0f;
|
||||
col[1] = ((float)rect[1])/255.0f;
|
||||
col[2] = ((float)rect[2])/255.0f;
|
||||
col[3] = ((float)rect[3])/255.0f;
|
||||
col[0] = ((float)rect[0])*(1.0f/255.0f);
|
||||
col[1] = ((float)rect[1])*(1.0f/255.0f);
|
||||
col[2] = ((float)rect[2])*(1.0f/255.0f);
|
||||
col[3] = ((float)rect[3])*(1.0f/255.0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1261,7 +1261,7 @@ void project_renderdata(Render *re, void (*projectfunc)(float *, float mat[][4],
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void RE_addRenderInstance(Render *re, ObjectRen *obr, Object *ob, Object *par, int index, int psysindex, float mat[][4])
|
||||
ObjectInstanceRen *RE_addRenderInstance(Render *re, ObjectRen *obr, Object *ob, Object *par, int index, int psysindex, float mat[][4])
|
||||
{
|
||||
ObjectInstanceRen *obi;
|
||||
float mat3[3][3];
|
||||
@@ -1281,6 +1281,8 @@ void RE_addRenderInstance(Render *re, ObjectRen *obr, Object *ob, Object *par, i
|
||||
}
|
||||
|
||||
BLI_addtail(&re->instancetable, obi);
|
||||
|
||||
return obi;
|
||||
}
|
||||
|
||||
void RE_makeRenderInstances(Render *re)
|
||||
|
||||
@@ -919,6 +919,8 @@ void shade_input_set_shade_texco(ShadeInput *shi)
|
||||
shi->dylo[2]= dl*o3[2]-shi->dy_u*o1[2]-shi->dy_v*o2[2];
|
||||
}
|
||||
}
|
||||
|
||||
VECCOPY(shi->duplilo, obi->dupliorco);
|
||||
}
|
||||
|
||||
if(texco & TEXCO_GLOB) {
|
||||
@@ -1033,6 +1035,10 @@ void shade_input_set_shade_texco(ShadeInput *shi)
|
||||
}
|
||||
}
|
||||
|
||||
shi->dupliuv[0]= -1.0f + 2.0f*obi->dupliuv[0];
|
||||
shi->dupliuv[1]= -1.0f + 2.0f*obi->dupliuv[1];
|
||||
shi->dupliuv[2]= 0.0f;
|
||||
|
||||
if(shi->totuv == 0) {
|
||||
ShadeInputUV *suv= &shi->uv[0];
|
||||
|
||||
|
||||
@@ -436,7 +436,7 @@ typedef struct StrandPart {
|
||||
GHash *hash;
|
||||
StrandPoint point1, point2;
|
||||
ShadeSample ssamp1, ssamp2, ssamp;
|
||||
float t[3];
|
||||
float t[3], s[3];
|
||||
} StrandPart;
|
||||
|
||||
typedef struct StrandSortSegment {
|
||||
@@ -520,6 +520,23 @@ static void add_strand_obindex(RenderLayer *rl, int offset, ObjectRen *obr)
|
||||
}
|
||||
}
|
||||
|
||||
static void strand_apply_shaderesult_alpha(ShadeResult *shr, float alpha)
|
||||
{
|
||||
if(alpha < 1.0f) {
|
||||
shr->combined[0] *= alpha;
|
||||
shr->combined[1] *= alpha;
|
||||
shr->combined[2] *= alpha;
|
||||
shr->combined[3] *= alpha;
|
||||
|
||||
shr->col[0] *= alpha;
|
||||
shr->col[1] *= alpha;
|
||||
shr->col[2] *= alpha;
|
||||
shr->col[3] *= alpha;
|
||||
|
||||
shr->alpha *= alpha;
|
||||
}
|
||||
}
|
||||
|
||||
static void do_strand_point_project(float winmat[][4], ZSpan *zspan, float *co, float *hoco, float *zco)
|
||||
{
|
||||
projectvert(co, winmat, hoco);
|
||||
@@ -537,7 +554,6 @@ static void strand_project_point(float winmat[][4], float winx, float winy, Stra
|
||||
spoint->y= spoint->hoco[1]*div*winy*0.5f;
|
||||
}
|
||||
|
||||
#include "BLI_rand.h"
|
||||
static void strand_shade_point(Render *re, ShadeSample *ssamp, StrandSegment *sseg, StrandPoint *spoint);
|
||||
|
||||
static void strand_shade_get(StrandPart *spart, int lookup, ShadeSample *ssamp, StrandPoint *spoint, StrandVert *svert, StrandSegment *sseg)
|
||||
@@ -576,22 +592,6 @@ static void strand_shade_segment(StrandPart *spart)
|
||||
strand_shade_get(spart, !last, &spart->ssamp2, &sseg->point2, sseg->v[2], sseg);
|
||||
sseg->shaded= 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
float c[3];
|
||||
|
||||
c[0]= BLI_frand();
|
||||
c[1]= BLI_frand();
|
||||
c[2]= BLI_frand();
|
||||
|
||||
spart->ssamp1.shr[0].combined[0] *= c[0];
|
||||
spart->ssamp1.shr[0].combined[1] *= c[1];
|
||||
spart->ssamp1.shr[0].combined[2] *= c[2];
|
||||
|
||||
spart->ssamp2.shr[0].combined[0] *= c[0];
|
||||
spart->ssamp2.shr[0].combined[1] *= c[1];
|
||||
spart->ssamp2.shr[0].combined[2] *= c[2];
|
||||
#endif
|
||||
}
|
||||
|
||||
static void do_strand_blend(void *handle, int x, int y, float u, float v, float z)
|
||||
@@ -599,7 +599,7 @@ static void do_strand_blend(void *handle, int x, int y, float u, float v, float
|
||||
StrandPart *spart= (StrandPart*)handle;
|
||||
StrandBuffer *buffer= spart->segment->buffer;
|
||||
ShadeResult *shr;
|
||||
float /**pass,*/ t;
|
||||
float /**pass,*/ t, s;
|
||||
int offset, zverg;
|
||||
|
||||
/* check again solid z-buffer */
|
||||
@@ -625,6 +625,14 @@ static void do_strand_blend(void *handle, int x, int y, float u, float v, float
|
||||
interpolate_shade_result(spart->ssamp1.shr, spart->ssamp2.shr, t,
|
||||
spart->ssamp.shr, spart->addpassflag);
|
||||
|
||||
/* alpha along width */
|
||||
if(buffer->widthfade != 0.0f) {
|
||||
s = fabs(u*spart->s[0] + v*spart->s[1] + (1.0f-u-v)*spart->s[2]);
|
||||
s = 1.0f - pow(s, buffer->widthfade);
|
||||
|
||||
strand_apply_shaderesult_alpha(spart->ssamp.shr, s);
|
||||
}
|
||||
|
||||
/* add in shaderesult array for part */
|
||||
spart->ssamp.shi[0].mask= (1<<spart->sample);
|
||||
addtosamp_shr(shr, &spart->ssamp, spart->addpassflag);
|
||||
@@ -696,19 +704,7 @@ static void strand_shade_point(Render *re, ShadeSample *ssamp, StrandSegment *ss
|
||||
shade_input_do_shade(shi, shr);
|
||||
|
||||
/* apply simplification */
|
||||
if(spoint->alpha < 1.0f) {
|
||||
shr->combined[0] *= spoint->alpha;
|
||||
shr->combined[1] *= spoint->alpha;
|
||||
shr->combined[2] *= spoint->alpha;
|
||||
shr->combined[3] *= spoint->alpha;
|
||||
|
||||
shr->col[0] *= spoint->alpha;
|
||||
shr->col[1] *= spoint->alpha;
|
||||
shr->col[2] *= spoint->alpha;
|
||||
shr->col[3] *= spoint->alpha;
|
||||
|
||||
shr->alpha *= spoint->alpha;
|
||||
}
|
||||
strand_apply_shaderesult_alpha(shr, spoint->alpha);
|
||||
|
||||
/* include lamphalos for strand, since halo layer was added already */
|
||||
if(re->flag & R_LAMPHALO)
|
||||
@@ -747,12 +743,18 @@ static void do_scanconvert_strand(Render *re, StrandPart *spart, ZSpan *zspan, f
|
||||
spart->sample= sample;
|
||||
|
||||
spart->t[0]= t-dt;
|
||||
spart->s[0]= -1.0f;
|
||||
spart->t[1]= t-dt;
|
||||
spart->s[1]= 1.0f;
|
||||
spart->t[2]= t;
|
||||
spart->s[2]= 1.0f;
|
||||
zspan_scanconvert_strand(zspan, spart, jco1, jco2, jco3, do_strand_blend);
|
||||
spart->t[0]= t-dt;
|
||||
spart->s[0]= -1.0f;
|
||||
spart->t[1]= t;
|
||||
spart->s[1]= 1.0f;
|
||||
spart->t[2]= t;
|
||||
spart->s[2]= -1.0f;
|
||||
zspan_scanconvert_strand(zspan, spart, jco1, jco3, jco4, do_strand_blend);
|
||||
}
|
||||
|
||||
|
||||
@@ -1427,7 +1427,14 @@ void do_material_tex(ShadeInput *shi)
|
||||
|
||||
/* which coords */
|
||||
if(mtex->texco==TEXCO_ORCO) {
|
||||
co= shi->lo; dx= shi->dxlo; dy= shi->dylo;
|
||||
if(mtex->texflag & MTEX_DUPLI_MAPTO) {
|
||||
co= shi->duplilo; dx= dxt; dy= dyt;
|
||||
dxt[0]= dxt[1]= dxt[2]= 0.0f;
|
||||
dyt[0]= dyt[1]= dyt[2]= 0.0f;
|
||||
}
|
||||
else {
|
||||
co= shi->lo; dx= shi->dxlo; dy= shi->dylo;
|
||||
}
|
||||
}
|
||||
else if(mtex->texco==TEXCO_STICKY) {
|
||||
co= shi->sticky; dx= shi->dxsticky; dy= shi->dysticky;
|
||||
@@ -1466,21 +1473,28 @@ void do_material_tex(ShadeInput *shi)
|
||||
co= shi->gl; dx= shi->dxco; dy= shi->dyco;
|
||||
}
|
||||
else if(mtex->texco==TEXCO_UV) {
|
||||
ShadeInputUV *suv= &shi->uv[shi->actuv];
|
||||
int i;
|
||||
if(mtex->texflag & MTEX_DUPLI_MAPTO) {
|
||||
co= shi->dupliuv; dx= dxt; dy= dyt;
|
||||
dxt[0]= dxt[1]= dxt[2]= 0.0f;
|
||||
dyt[0]= dyt[1]= dyt[2]= 0.0f;
|
||||
}
|
||||
else {
|
||||
ShadeInputUV *suv= &shi->uv[shi->actuv];
|
||||
int i;
|
||||
|
||||
if(mtex->uvname[0] != 0) {
|
||||
for(i = 0; i < shi->totuv; i++) {
|
||||
if(strcmp(shi->uv[i].name, mtex->uvname)==0) {
|
||||
suv= &shi->uv[i];
|
||||
break;
|
||||
if(mtex->uvname[0] != 0) {
|
||||
for(i = 0; i < shi->totuv; i++) {
|
||||
if(strcmp(shi->uv[i].name, mtex->uvname)==0) {
|
||||
suv= &shi->uv[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
co= suv->uv;
|
||||
dx= suv->dxuv;
|
||||
dy= suv->dyuv;
|
||||
co= suv->uv;
|
||||
dx= suv->dxuv;
|
||||
dy= suv->dyuv;
|
||||
}
|
||||
}
|
||||
else if(mtex->texco==TEXCO_WINDOW) {
|
||||
co= shi->winco; dx= shi->dxwin; dy= shi->dywin;
|
||||
|
||||
Reference in New Issue
Block a user