*Added output of BB/primitves test/hits
*"Added" SCE_PASS_RAYHITS to visually see each pixel primitive and BB tests (not-completed for UI) *Added runtime exchange of tree structure *Removed FLOAT_EPSILON from BLI_bvhkdop BB's
This commit is contained in:
@@ -26,6 +26,7 @@ class RENDER_PT_shading(RenderButtonsPanel):
|
||||
colsub = col.column()
|
||||
colsub.active = rd.render_raytracing
|
||||
colsub.itemR(rd, "raytrace_structure", text="Structure")
|
||||
colsub.itemR(rd, "raytrace_tree_type", text="Tree Type")
|
||||
colsub.itemR(rd, "octree_resolution", text="Octree")
|
||||
col.itemR(rd, "dither_intensity", text="Dither", slider=True)
|
||||
|
||||
|
||||
@@ -161,6 +161,8 @@ typedef struct SceneRenderLayer {
|
||||
#define SCE_PASS_RADIO 8192 /* Radio removed, can use for new GI? */
|
||||
#define SCE_PASS_MIST 16384
|
||||
|
||||
#define SCE_PASS_RAYHITS 32768
|
||||
|
||||
/* note, srl->passflag is treestore element 'nr' in outliner, short still... */
|
||||
|
||||
|
||||
@@ -233,7 +235,8 @@ typedef struct RenderData {
|
||||
/* render engine, octree resolution */
|
||||
short renderer, ocres;
|
||||
short raystructure;
|
||||
short pad4[3];
|
||||
short raytrace_tree_type;
|
||||
short pad4[2];
|
||||
|
||||
/**
|
||||
* What to do with the sky/background. Picks sky/premul/key
|
||||
@@ -675,6 +678,11 @@ typedef struct Scene {
|
||||
#define R_RAYSTRUCTURE_SINGLE_OCTREE 2
|
||||
#define R_RAYSTRUCTURE_SINGLE_BVH 3
|
||||
|
||||
/* raytrace tree type */
|
||||
#define R_RAYTRACE_TREE_BVH 0
|
||||
#define R_RAYTRACE_TREE_BLIBVH 1
|
||||
#define R_RAYTRACE_TREE_BIH 2
|
||||
|
||||
/* scemode (int now) */
|
||||
#define R_DOSEQ 0x0001
|
||||
#define R_BG_RENDER 0x0002
|
||||
|
||||
@@ -293,6 +293,12 @@ void rna_def_scene_render_data(BlenderRNA *brna)
|
||||
{R_RAYSTRUCTURE_SINGLE_BVH, "{R_RAYSTRUCTURE_SINGLE_BVH", 0, "Single BVH", "BVH of all primitives (no instance support)"},
|
||||
{R_RAYSTRUCTURE_SINGLE_OCTREE, "{R_RAYSTRUCTURE_SINGLE_OCTREE", 0, "Octree", "Octree of all primitives (no instance support)"},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
static EnumPropertyItem raytrace_tree_type_items[] = {
|
||||
{R_RAYTRACE_TREE_BVH, "{R_RAYTRACE_TREE_BVH", 0, "BVH", "rayobject_bvh.c"},
|
||||
{R_RAYTRACE_TREE_BLIBVH, "{R_RAYTRACE_TREE_BLIBVH", 0, "BLIbvh", "rayobject_blibvh.c"},
|
||||
{R_RAYTRACE_TREE_BIH, "{R_RAYSTRUCTURE_SINGLE_BVH", 0, "BIH", "rayobject_bih.c"},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
static EnumPropertyItem fixed_oversample_items[] = {
|
||||
{5, "OVERSAMPLE_5", 0, "5", ""},
|
||||
@@ -694,6 +700,12 @@ void rna_def_scene_render_data(BlenderRNA *brna)
|
||||
RNA_def_property_enum_items(prop, raytrace_structure_items);
|
||||
RNA_def_property_ui_text(prop, "Raytrace Acceleration Structure", "Type of raytrace accelerator structure.");
|
||||
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
|
||||
|
||||
prop= RNA_def_property(srna, "raytrace_tree_type", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "raytrace_tree_type");
|
||||
RNA_def_property_enum_items(prop, raytrace_tree_type_items);
|
||||
RNA_def_property_ui_text(prop, "Raytrace tree type", "Type of raytrace accelerator structure.");
|
||||
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
|
||||
|
||||
prop= RNA_def_property(srna, "antialiasing", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "mode", R_OSA);
|
||||
|
||||
@@ -31,12 +31,43 @@
|
||||
#ifndef RE_RAYTRACE_H
|
||||
#define RE_RAYTRACE_H
|
||||
|
||||
#define RE_RAY_COUNTER
|
||||
#define RE_RAYCOUNTER
|
||||
#ifdef RE_RAYCOUNTER
|
||||
|
||||
typedef struct RayCounter RayCounter;
|
||||
struct RayCounter
|
||||
{
|
||||
|
||||
struct
|
||||
{
|
||||
unsigned long long test, hit;
|
||||
|
||||
} faces, bb, raycast;
|
||||
|
||||
unsigned long long rayshadow_last_hit_optimization;
|
||||
};
|
||||
|
||||
/* #define RE_RC_INIT(isec, shi) (isec).count = re_rc_counter+(shi).thread */
|
||||
#define RE_RC_INIT(isec, shi) (isec).raycounter = &((shi).raycounter)
|
||||
void RE_RC_INFO (RayCounter *rc);
|
||||
void RE_RC_MERGE(RayCounter *rc, RayCounter *tmp);
|
||||
#define RE_RC_COUNT(var) (var)++
|
||||
|
||||
extern RayCounter re_rc_counter[];
|
||||
|
||||
#else
|
||||
|
||||
#define RE_RC_INIT(isec,shi)
|
||||
#define RE_RC_INFO(rc)
|
||||
#define RE_RC_MERGE(dest,src)
|
||||
#define RE_RC_COUNT(var)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Internals about raycasting structures can be found on intern/raytree.h */
|
||||
typedef struct RayObject RayObject;
|
||||
typedef struct Isect Isect;
|
||||
typedef struct RayCounter RayCounter;
|
||||
struct DerivedMesh;
|
||||
struct Mesh;
|
||||
|
||||
@@ -50,7 +81,6 @@ void RE_rayobject_free(RayObject *r);
|
||||
RayObject* RE_rayobject_octree_create(int ocres, int size);
|
||||
RayObject* RE_rayobject_instance_create(RayObject *target, float transform[][4], void *ob, void *target_ob);
|
||||
|
||||
#define RE_rayobject_tree_create RE_rayobject_bvh_create
|
||||
RayObject* RE_rayobject_blibvh_create(int size); /* BLI_kdopbvh.c */
|
||||
RayObject* RE_rayobject_bvh_create(int size); /* rayobject_bvh.c */
|
||||
RayObject* RE_rayobject_bih_create(int size); /* rayobject_bih.c */
|
||||
@@ -93,38 +123,11 @@ struct Isect
|
||||
|
||||
void *userdata;
|
||||
|
||||
#ifdef RE_RAY_COUNTER
|
||||
RayCounter *count;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#ifdef RE_RAYCOUNTER
|
||||
|
||||
struct RayCounter
|
||||
{
|
||||
|
||||
struct
|
||||
{
|
||||
unsigned long long test, hit;
|
||||
|
||||
} intersect_rayface, raycast;
|
||||
|
||||
unsigned long long rayshadow_last_hit_optimization;
|
||||
};
|
||||
|
||||
void RE_RC_INIT (RayCounter *rc);
|
||||
void RE_RC_MERGE(RayCounter *rc, RayCounter *tmp);
|
||||
#define RE_RC_COUNT(var) (var)++
|
||||
|
||||
#else
|
||||
|
||||
#define RE_RC_INIT(rc)
|
||||
#define RE_RC_MERGE(dest,src)
|
||||
#define RE_RC_COUNT(var)
|
||||
|
||||
RayCounter *raycounter;
|
||||
#endif
|
||||
|
||||
|
||||
};
|
||||
|
||||
/* ray types */
|
||||
#define RE_RAY_SHADOW 0
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#ifndef RE_SHADER_EXT_H
|
||||
#define RE_SHADER_EXT_H
|
||||
|
||||
#include "RE_raytrace.h" /* For RE_RAYCOUNTER */
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
/* this include is for shading and texture exports */
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
@@ -57,6 +58,7 @@ typedef struct ShadeResult
|
||||
float nor[3];
|
||||
float rad[3];
|
||||
float winspeed[4];
|
||||
float rayhits[4];
|
||||
} ShadeResult;
|
||||
|
||||
/* only here for quick copy */
|
||||
@@ -178,6 +180,10 @@ typedef struct ShadeInput
|
||||
struct Group *light_override;
|
||||
struct Material *mat_override;
|
||||
|
||||
#ifdef RE_RAYCOUNTER
|
||||
RayCounter raycounter;
|
||||
#endif
|
||||
|
||||
} ShadeInput;
|
||||
|
||||
|
||||
|
||||
@@ -347,6 +347,13 @@ static char *get_pass_name(int passtype, int channel)
|
||||
if(channel==-1) return "Mist";
|
||||
return "Mist.Z";
|
||||
}
|
||||
if(passtype == SCE_PASS_RAYHITS)
|
||||
{
|
||||
if(channel==-1) return "Rayhits";
|
||||
if(channel==0) return "Rayhits.R";
|
||||
if(channel==1) return "Rayhits.G";
|
||||
return "Rayhits.B";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
@@ -398,6 +405,8 @@ static int passtype_from_name(char *str)
|
||||
if(strcmp(str, "Mist")==0)
|
||||
return SCE_PASS_MIST;
|
||||
|
||||
if(strcmp(str, "RAYHITS")==0)
|
||||
return SCE_PASS_RAYHITS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -523,7 +532,7 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop, int
|
||||
rl->lay= srl->lay;
|
||||
rl->lay_zmask= srl->lay_zmask;
|
||||
rl->layflag= srl->layflag;
|
||||
rl->passflag= srl->passflag;
|
||||
rl->passflag= srl->passflag | SCE_PASS_RAYHITS;
|
||||
rl->pass_xor= srl->pass_xor;
|
||||
rl->light_override= srl->light_override;
|
||||
rl->mat_override= srl->mat_override;
|
||||
@@ -565,6 +574,8 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop, int
|
||||
render_layer_add_pass(rr, rl, 1, SCE_PASS_INDEXOB);
|
||||
if(srl->passflag & SCE_PASS_MIST)
|
||||
render_layer_add_pass(rr, rl, 1, SCE_PASS_MIST);
|
||||
if(rl->passflag & SCE_PASS_RAYHITS)
|
||||
render_layer_add_pass(rr, rl, 4, SCE_PASS_RAYHITS);
|
||||
|
||||
}
|
||||
/* sss, previewrender and envmap don't do layers, so we make a default one */
|
||||
|
||||
@@ -54,10 +54,14 @@ float RE_rayobject_bb_intersect(const Isect *isec, const float *_bb)
|
||||
float t1z = (bb[isec->bv_index[4]] - isec->start[2]) * isec->idot_axis[2];
|
||||
float t2z = (bb[isec->bv_index[5]] - isec->start[2]) * isec->idot_axis[2];
|
||||
|
||||
RE_RC_COUNT(isec->raycounter->bb.test);
|
||||
|
||||
if(t1x > t2y || t2x < t1y || t1x > t2z || t2x < t1z || t1y > t2z || t2y < t1z) return FLT_MAX;
|
||||
if(t2x < 0.0 || t2y < 0.0 || t2z < 0.0) return FLT_MAX;
|
||||
if(t1x > isec->labda || t1y > isec->labda || t1z > isec->labda) return FLT_MAX;
|
||||
|
||||
RE_RC_COUNT(isec->raycounter->bb.hit);
|
||||
|
||||
dist = t1x;
|
||||
if (t1y > dist) dist = t1y;
|
||||
if (t1z > dist) dist = t1z;
|
||||
@@ -157,7 +161,7 @@ static int intersect_rayface(RayFace *face, Isect *is)
|
||||
if(is->orig.ob == face->ob && is->orig.face == face->face)
|
||||
return 0;
|
||||
|
||||
RE_RC_COUNT(is->count->intersect_rayface.test);
|
||||
RE_RC_COUNT(is->raycounter->faces.test);
|
||||
|
||||
VECCOPY(co1, face->v1);
|
||||
VECCOPY(co2, face->v2);
|
||||
@@ -276,7 +280,7 @@ static int intersect_rayface(RayFace *face, Isect *is)
|
||||
}
|
||||
#endif
|
||||
|
||||
RE_RC_COUNT(is->count->intersect_rayface.hit);
|
||||
RE_RC_COUNT(is->raycounter->faces.hit);
|
||||
|
||||
is->isect= ok; // wich half of the quad
|
||||
is->labda= labda;
|
||||
@@ -294,7 +298,7 @@ static int intersect_rayface(RayFace *face, Isect *is)
|
||||
int RE_rayobject_raycast(RayObject *r, Isect *isec)
|
||||
{
|
||||
int i;
|
||||
RE_RC_COUNT(isec->count->raycast.test);
|
||||
RE_RC_COUNT(isec->raycounter->raycast.test);
|
||||
|
||||
/* Setup vars used on raycast */
|
||||
isec->labda *= Normalize(isec->vec);
|
||||
@@ -315,15 +319,15 @@ int RE_rayobject_raycast(RayObject *r, Isect *isec)
|
||||
/* Last hit heuristic */
|
||||
if(isec->mode==RE_RAY_SHADOW && isec->last_hit && RE_rayobject_intersect(isec->last_hit, isec))
|
||||
{
|
||||
RE_RC_COUNT(isec->count->raycast.hit);
|
||||
RE_RC_COUNT(isec->count->rayshadow_last_hit_optimization );
|
||||
RE_RC_COUNT(isec->raycounter->raycast.hit);
|
||||
RE_RC_COUNT(isec->raycounter->rayshadow_last_hit_optimization );
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef RE_RAYCOUNTER
|
||||
if(RE_rayobject_intersect(r, isec))
|
||||
{
|
||||
RE_RC_COUNT(isec->count->raycast.hit);
|
||||
RE_RC_COUNT(isec->raycounter->raycast.hit);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@@ -383,16 +387,40 @@ void RE_rayobject_merge_bb(RayObject *r, float *min, float *max)
|
||||
}
|
||||
|
||||
#ifdef RE_RAYCOUNTER
|
||||
void RE_merge_raycounter(RayCounter *dest, RayCounter *tmp)
|
||||
void RE_RC_INFO(RayCounter *info)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<3; i++) dest->casted[i] += tmp->casted[i];
|
||||
for(i=0; i<3; i++) dest->hit [i] += tmp->hit [i];
|
||||
|
||||
dest->test_primitives += tmp->test_primitives;
|
||||
dest->hit_primitives += tmp->hit_primitives;
|
||||
|
||||
dest->test_bb += tmp->test_bb;
|
||||
dest->hit_bb += tmp->hit_bb;
|
||||
printf("----------- Raycast counter --------\n");
|
||||
printf("Rays total: %llu\n", info->raycast.test );
|
||||
printf("Rays hit: %llu\n", info->raycast.hit );
|
||||
printf("\n");
|
||||
printf("BB tests: %llu\n", info->bb.test );
|
||||
printf("BB hits: %llu\n", info->bb.hit );
|
||||
printf("\n");
|
||||
printf("Primitives tests: %llu\n", info->faces.test );
|
||||
printf("Primitives hits: %llu\n", info->faces.hit );
|
||||
printf("\n");
|
||||
printf("Shadow Last hit reuse: %llu\n", info->rayshadow_last_hit_optimization);
|
||||
printf("\n");
|
||||
printf("Primitives tests per ray: %f\n", info->faces.test / ((float)info->raycast.test) );
|
||||
printf("Primitives hits per ray: %f\n", info->faces.hit / ((float)info->raycast.test) );
|
||||
printf("\n");
|
||||
printf("BB tests per ray: %f\n", info->bb.test / ((float)info->raycast.test) );
|
||||
printf("BB hits per ray: %f\n", info->bb.hit / ((float)info->raycast.test) );
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void RE_RC_MERGE(RayCounter *dest, RayCounter *tmp)
|
||||
{
|
||||
dest->faces.test += tmp->faces.test;
|
||||
dest->faces.hit += tmp->faces.hit;
|
||||
|
||||
dest->bb.test += tmp->bb.test;
|
||||
dest->bb.hit += tmp->bb.hit;
|
||||
|
||||
dest->raycast.test += tmp->raycast.test;
|
||||
dest->raycast.hit += tmp->raycast.hit;
|
||||
|
||||
dest->rayshadow_last_hit_optimization += tmp->rayshadow_last_hit_optimization;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -66,7 +66,7 @@ RayObject *RE_rayobject_blibvh_create(int size)
|
||||
assert( RayObject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */
|
||||
|
||||
obj->rayobj.api = &bvh_api;
|
||||
obj->bvh = BLI_bvhtree_new(size, FLT_EPSILON, 4, 6);
|
||||
obj->bvh = BLI_bvhtree_new(size, 0.0, 4, 6);
|
||||
|
||||
INIT_MINMAX(obj->bb[0], obj->bb[1]);
|
||||
return RayObject_unalignRayAPI((RayObject*) obj);
|
||||
|
||||
@@ -70,6 +70,22 @@
|
||||
extern struct Render R;
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
RayObject *RE_rayobject_tree_create(int type, int size)
|
||||
{
|
||||
if(type == R_RAYTRACE_TREE_BVH)
|
||||
return RE_rayobject_bvh_create(size);
|
||||
if(type == R_RAYTRACE_TREE_BIH)
|
||||
return RE_rayobject_bih_create(size);
|
||||
if(type == R_RAYTRACE_TREE_BLIBVH)
|
||||
return RE_rayobject_blibvh_create(size);
|
||||
|
||||
return RE_rayobject_bvh_create(size);
|
||||
}
|
||||
|
||||
#ifdef RE_RAYCOUNTER
|
||||
RayCounter re_rc_counter[BLENDER_MAX_THREADS] = {};
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static int vlr_check_intersect(Isect *is, int ob, RayFace *face)
|
||||
{
|
||||
@@ -123,6 +139,16 @@ void freeraytree(Render *re)
|
||||
obi->raytree = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef RE_RAYCOUNTER
|
||||
{
|
||||
RayCounter sum = {};
|
||||
int i;
|
||||
for(i=0; i<BLENDER_MAX_THREADS; i++)
|
||||
RE_RC_MERGE(&sum, re_rc_counter+i);
|
||||
RE_RC_INFO(&sum);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static int is_raytraceable_vlr(Render *re, VlakRen *vlr)
|
||||
@@ -180,7 +206,7 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi)
|
||||
if(re->r.raystructure == R_RAYSTRUCTURE_HIER_BVH_OCTREE)
|
||||
raytree = obr->raytree = RE_rayobject_octree_create( re->r.ocres, faces );
|
||||
else //if(re->r.raystructure == R_RAYSTRUCTURE_HIER_BVH_BVH)
|
||||
raytree = obr->raytree = RE_rayobject_tree_create( faces );
|
||||
raytree = obr->raytree = RE_rayobject_tree_create( re->r.raytrace_tree_type, faces );
|
||||
|
||||
face = obr->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "ObjectRen faces");
|
||||
obr->rayobi = obi;
|
||||
@@ -240,7 +266,7 @@ static void makeraytree_hier(Render *re)
|
||||
num_objects++;
|
||||
|
||||
//Create raytree
|
||||
re->raytree = RE_rayobject_tree_create( num_objects );
|
||||
re->raytree = RE_rayobject_tree_create( re->r.raytrace_tree_type, num_objects );
|
||||
|
||||
for(obi=re->instancetable.first; obi; obi=obi->next)
|
||||
if(is_raytraceable(re, obi))
|
||||
@@ -292,7 +318,7 @@ static void makeraytree_single(Render *re)
|
||||
if(re->r.raystructure == R_RAYSTRUCTURE_SINGLE_OCTREE)
|
||||
raytree = re->raytree = RE_rayobject_octree_create( re->r.ocres, faces );
|
||||
else //if(re->r.raystructure == R_RAYSTRUCTURE_SINGLE_BVH)
|
||||
raytree = re->raytree = RE_rayobject_tree_create( faces );
|
||||
raytree = re->raytree = RE_rayobject_tree_create( re->r.raytrace_tree_type, faces );
|
||||
|
||||
face = re->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "Render ray faces");
|
||||
|
||||
@@ -322,6 +348,17 @@ static void makeraytree_single(Render *re)
|
||||
|
||||
void makeraytree(Render *re)
|
||||
{
|
||||
#ifdef RE_RAYCOUNTER
|
||||
if(re->r.raystructure == R_RAYSTRUCTURE_SINGLE_OCTREE)
|
||||
printf("Building single octree\n");
|
||||
else if(re->r.raystructure == R_RAYSTRUCTURE_SINGLE_BVH)
|
||||
printf("Building single tree\n");
|
||||
else if(re->r.raystructure == R_RAYSTRUCTURE_HIER_BVH_OCTREE)
|
||||
printf("Building tree of octrees\n");
|
||||
else
|
||||
printf("Building tree of trees\n");
|
||||
#endif
|
||||
|
||||
if(ELEM(re->r.raystructure, R_RAYSTRUCTURE_SINGLE_BVH, R_RAYSTRUCTURE_SINGLE_OCTREE))
|
||||
BENCH(makeraytree_single(re), tree_build);
|
||||
else
|
||||
@@ -563,6 +600,7 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, flo
|
||||
|
||||
isec.orig.ob = obi;
|
||||
isec.orig.face = vlr;
|
||||
RE_RC_INIT(isec, shi);
|
||||
|
||||
if(RE_rayobject_raycast(R.raytree, &isec)) {
|
||||
float d= 1.0f;
|
||||
@@ -1306,7 +1344,6 @@ void ray_trace(ShadeInput *shi, ShadeResult *shr)
|
||||
|
||||
do_tra= ((shi->mat->mode & (MA_RAYTRANSP)) && shr->alpha!=1.0f);
|
||||
do_mir= ((shi->mat->mode & MA_RAYMIRROR) && shi->ray_mirror!=0.0f);
|
||||
|
||||
|
||||
/* raytrace mirror amd refract like to separate the spec color */
|
||||
if(shi->combinedflag & SCE_PASS_SPEC)
|
||||
@@ -1465,6 +1502,7 @@ int ray_trace_shadow_rad(ShadeInput *ship, ShadeResult *shr)
|
||||
isec.mode= RE_RAY_MIRROR;
|
||||
isec.orig.ob = ship->obi;
|
||||
isec.orig.face = ship->vlr;
|
||||
RE_RC_INIT(isec, shi);
|
||||
|
||||
for(a=0; a<8*8; a++) {
|
||||
|
||||
@@ -1669,6 +1707,7 @@ static void ray_ao_qmc(ShadeInput *shi, float *shadfac)
|
||||
float dxyview[3], skyadded=0, div;
|
||||
int aocolor;
|
||||
|
||||
RE_RC_INIT(isec, *shi);
|
||||
isec.orig.ob = shi->obi;
|
||||
isec.orig.face = shi->vlr;
|
||||
isec.skip = RE_SKIP_VLR_NEIGHBOUR;
|
||||
@@ -1802,6 +1841,7 @@ static void ray_ao_spheresamp(ShadeInput *shi, float *shadfac)
|
||||
float dxyview[3];
|
||||
int j= -1, tot, actual=0, skyadded=0, aocolor, resol= R.wrld.aosamp;
|
||||
|
||||
RE_RC_INIT(isec, *shi);
|
||||
isec.orig.ob = shi->obi;
|
||||
isec.orig.face = shi->vlr;
|
||||
isec.skip = RE_SKIP_VLR_NEIGHBOUR;
|
||||
@@ -2238,6 +2278,7 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac)
|
||||
int lampvec; /* indicates if lampco is a vector lamp */
|
||||
|
||||
/* setup isec */
|
||||
RE_RC_INIT(isec, *shi);
|
||||
if(shi->mat->mode & MA_SHADOW_TRA) isec.mode= RE_RAY_SHADOW_TRA;
|
||||
else isec.mode= RE_RAY_SHADOW;
|
||||
|
||||
@@ -2323,6 +2364,7 @@ static void ray_translucent(ShadeInput *shi, LampRen *lar, float *distfac, float
|
||||
assert(0);
|
||||
|
||||
/* setup isec */
|
||||
RE_RC_INIT(isec, *shi);
|
||||
isec.mode= RE_RAY_SHADOW_TRA;
|
||||
|
||||
if(lar->mode & LA_LAYER) isec.lay= lar->lay; else isec.lay= -1;
|
||||
|
||||
@@ -521,6 +521,12 @@ static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset,
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SCE_PASS_RAYHITS:
|
||||
/* */
|
||||
col= &shr->rayhits;
|
||||
pixsize= 4;
|
||||
break;
|
||||
}
|
||||
if(col) {
|
||||
fp= rpass->rect + pixsize*offset;
|
||||
@@ -597,6 +603,10 @@ static void add_passes(RenderLayer *rl, int offset, ShadeInput *shi, ShadeResult
|
||||
fp= rpass->rect + offset;
|
||||
*fp= shr->mist;
|
||||
break;
|
||||
case SCE_PASS_RAYHITS:
|
||||
col= shr->rayhits;
|
||||
pixsize= 4;
|
||||
break;
|
||||
}
|
||||
if(col) {
|
||||
fp= rpass->rect + pixsize*offset;
|
||||
|
||||
@@ -142,6 +142,7 @@ void shade_input_do_shade(ShadeInput *shi, ShadeResult *shr)
|
||||
float alpha;
|
||||
|
||||
/* ------ main shading loop -------- */
|
||||
memset(&shi->raycounter, 0, sizeof(shi->raycounter));
|
||||
|
||||
if(shi->mat->nodetree && shi->mat->use_nodes) {
|
||||
ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
|
||||
@@ -188,6 +189,16 @@ void shade_input_do_shade(ShadeInput *shi, ShadeResult *shr)
|
||||
|
||||
/* add z */
|
||||
shr->z= -shi->co[2];
|
||||
|
||||
/* RAYHITS */
|
||||
if(1 || shi->passflag & SCE_PASS_RAYHITS)
|
||||
{
|
||||
shr->rayhits[0] = (float)shi->raycounter.faces.test;
|
||||
shr->rayhits[1] = (float)shi->raycounter.bb.hit;
|
||||
shr->rayhits[2] = 0.0;
|
||||
shr->rayhits[3] = 1.0;
|
||||
RE_RC_MERGE(&re_rc_counter[shi->thread], &shi->raycounter);
|
||||
}
|
||||
}
|
||||
|
||||
/* **************************************************************************** */
|
||||
|
||||
Reference in New Issue
Block a user