Esempio n. 1
0
/* trilinear interpolation */
static void vol_get_precached_scattering(Render *re, ShadeInput *shi, float scatter_col[3], const float co[3])
{
	VolumePrecache *vp = shi->obi->volume_precache;
	float bbmin[3], bbmax[3], dim[3];
	float world_co[3], sample_co[3];
	
	if (!vp) return;
	
	/* find sample point in global space bounding box 0.0-1.0 */
	global_bounds_obi(re, shi->obi, bbmin, bbmax);
	sub_v3_v3v3(dim, bbmax, bbmin);
	mul_v3_m4v3(world_co, re->viewinv, co);

	/* sample_co in 0.0-1.0 */
	sample_co[0] = (world_co[0] - bbmin[0]) / dim[0];
	sample_co[1] = (world_co[1] - bbmin[1]) / dim[1];
	sample_co[2] = (world_co[2] - bbmin[2]) / dim[2];

	scatter_col[0] = BLI_voxel_sample_triquadratic(vp->data_r, vp->res, sample_co);
	scatter_col[1] = BLI_voxel_sample_triquadratic(vp->data_g, vp->res, sample_co);
	scatter_col[2] = BLI_voxel_sample_triquadratic(vp->data_b, vp->res, sample_co);
}
Esempio n. 2
0
int voxeldatatex(struct Tex *tex, const float texvec[3], struct TexResult *texres)
{	 
	VoxelData *vd = tex->vd;
	float co[3], offset[3] = {0.5, 0.5, 0.5}, a;
	int retval = (vd->data_type == TEX_VD_RGBA_PREMUL) ? TEX_RGB : TEX_INT;
	int depth = (vd->data_type == TEX_VD_RGBA_PREMUL) ? 4 : 1;
	int ch;

	if (vd->dataset == NULL) {
		texres->tin = 0.0f;
		return 0;
	}
	
	/* scale lookup from 0.0-1.0 (original location) to -1.0, 1.0, consistent with image texture tex coords */
	/* in implementation this works backwards, bringing sample locations from -1.0, 1.0
	 * to the range 0.0, 1.0, before looking up in the voxel structure. */
	copy_v3_v3(co, texvec);
	mul_v3_fl(co, 0.5f);
	add_v3_v3(co, offset);

	/* co is now in the range 0.0, 1.0 */
	switch (vd->extend) {
		case TEX_CLIP:
		{
			if ((co[0] < 0.f || co[0] > 1.f) || (co[1] < 0.f || co[1] > 1.f) || (co[2] < 0.f || co[2] > 1.f)) {
				texres->tin = 0.f;
				return retval;
			}
			break;
		}
		case TEX_REPEAT:
		{
			co[0] = co[0] - floorf(co[0]);
			co[1] = co[1] - floorf(co[1]);
			co[2] = co[2] - floorf(co[2]);
			break;
		}
		case TEX_EXTEND:
		{
			CLAMP(co[0], 0.f, 1.f);
			CLAMP(co[1], 0.f, 1.f);
			CLAMP(co[2], 0.f, 1.f);
			break;
		}
	}

	for (ch = 0; ch < depth; ch++) {
		float *dataset = vd->dataset + ch*vd->resol[0]*vd->resol[1]*vd->resol[2];
		float *result = &texres->tin;

		if (vd->data_type == TEX_VD_RGBA_PREMUL) {
			switch (ch) {
				case 0:
					result = &texres->tr;
					break;
				case 1:
					result = &texres->tg;
					break;
				case 2:
					result = &texres->tb;
					break;
			}
		}

		switch (vd->interp_type) {
			case TEX_VD_NEARESTNEIGHBOR:
				*result = BLI_voxel_sample_nearest(dataset, vd->resol, co);
				break;  
			case TEX_VD_LINEAR:
				*result = BLI_voxel_sample_trilinear(dataset, vd->resol, co);
				break;
			case TEX_VD_QUADRATIC:
				*result = BLI_voxel_sample_triquadratic(dataset, vd->resol, co);
				break;
			case TEX_VD_TRICUBIC_CATROM:
			case TEX_VD_TRICUBIC_BSPLINE:
				*result = BLI_voxel_sample_tricubic(dataset, vd->resol, co, (vd->interp_type == TEX_VD_TRICUBIC_BSPLINE));
				break;
		}
	}

	a = texres->tin;
	texres->tin *= vd->int_multiplier;
	BRICONT;
	
	if (vd->data_type == TEX_VD_RGBA_PREMUL) {
		/* unmultiply */
		if (a>0.001f) {
			texres->tr /= a;
			texres->tg /= a;
			texres->tb /= a;
		}
		texres->talpha = 1;
	}
	else {
		texres->tr = texres->tin;
		texres->tg = texres->tin;
		texres->tb = texres->tin;
	}

	texres->ta = texres->tin;
	BRICONTRGB;
	
	return retval;
}