Пример #1
0
static void
trace_pixel(ri_vector_t *radiance, int x, int y)
{
	unsigned char     type;
	double            bsdf[3];
	ri_ray_t          ray;
	ri_intersection_state_t state;
	pathnode_t        node;
	ri_vector_t       Le;
 
	/* first check a ray hits scene object through pixel (x, y) */
	ri_vector_copy(&ray.org, cam_pos);
	sample_pixel(&ray.dir, x, y);

	ray.thread_num = 0;

	if (!ri_raytrace(ri_render_get(), &ray, &state)) {
		/* hits background */
		ri_texture_ibl_fetch(radiance, light->texture, ray.dir);
		return;
	}

	node.depth = 2;
	node.G[0] = 1.0; node.G[1] = 1.0; node.G[2] = 1.0;
	ri_mem_copy(&node.state, &state, sizeof(ri_intersection_state_t));
	ri_vector_copy(&node.indir, ray.dir);
	// assume that the camera is not located in the transparent object
	node.interior = 0;

	trace_path(&node);

	/* connect the path to the IBL light source */
	type = sample_reflection_type(node.state.geom->material);

	//if (node.interior) printf("???\n");

	sample_outdir(&ray.dir, &type,
		      node.interior,
		      node.state.geom->material,
		      node.indir, node.state.Ng);

	brdf(bsdf,
	     type, &node.state,
	     node.indir, ray.dir, node.state.Ng);
	node.G[0] *= bsdf[0];
	node.G[1] *= bsdf[1];
	node.G[2] *= bsdf[2];

	ri_vector_copy(&ray.org, node.state.P);

	light_sample(&Le, ray.org, ray.dir);

	radiance->f[0] = Le.f[0] * node.G[0];
	radiance->f[1] = Le.f[1] * node.G[1];
	radiance->f[2] = Le.f[2] * node.G[2];
}
Пример #2
0
void			do_lum(t_obj *obc, t_cod *cor, t_sph *obj_hit, double omeg)
{
  obc->bounce -= 80;
  if (obc->bri)
    {
      normalize(cor->n);
      normalize(cor->l_x);
      brdf(cor, obj_hit, obc, omeg);
    }
}
Пример #3
0
void alsIrradiateSample(
	VR::VRayContext &rc,
	DirectionalMessageData *dmd,
	const VR::Color &diffuse
)
{
	if (dmd->sss_depth >= SSS_MAX_SAMPLES)
		return;
	
	//void *orig_op;
	//AiStateGetMsgPtr("als_sss_op", &orig_op);
	//
	//int als_context = ALS_CONTEXT_NONE;
	//AiStateGetMsgInt("als_context", &als_context);

	//AtRay ray;
	//AtScrSample scrs;

	// There are a few contexts in which we can be called here:
	// 1) Intersecting same object with same shader
	// 2) Intersecting same object with different shader
	// 3) Intersecting different object with same shader
	// 4) Intersecting different object with different shader
	// 5) Called from an indirect ray from another shader while tracing for SSS
	// 2 and 4 could possibly be because we're running from a layer shader. if we try to evaluate in that context we will simply crash
	// 5 will cause fireflies so we need to detect this and return

	// just return if this is a different object.
	// More elaborate checks may be needed; see VRayFastSSS2 source, considerPointForSSS().
	if (rc.parent && rc.rayresult.sb != rc.parent->rayresult.sb)
	{
		return;
	}

	// if we're in a layered context and running a different shader from the one that's tracing for sss, just return to let the other shader handle it
	//if (als_context == ALS_CONTEXT_LAYER && (dmd->shader_orig != sg->shader))
	//{
	//    return;
	//}

	DiffusionSample& samp = dmd->samples[dmd->sss_depth];
	samp.S = (rc.rayresult.wpoint - dmd->Po);
	samp.r = VR::length(samp.S);
	samp.Rd.set(0.0f, 0.0f, 0.0f);

	// The original alSurface line below seems wrong, but looks like has no effect on Arnold;
	// we probably only want to subtract just the distance from the previous SSS hit to this one.
	// In the V-Ray version, I'm using the fact that the direction along the SSS ray is a unit
	// one, so I can just use the hit ray coefficient.
	// dmd->maxdist -= samp.r;
	dmd->maxdist -= float(rc.rayresult.wpointCoeff-rc.rayparams.mint);

	// if we're not using trace sets to explicitly define what objects we want to trace against, then assume we only want to trace against ourselves
	// or if we're not doing sss in this shader, just continue the ray
	/*
	if ((!trace_set_enabled && orig_op != sg->Op) || sssMix == 0.0f)
	{
		if (dmd->sss_depth < SSS_MAX_SAMPLES && dmd->maxdist > 0.0f)
		{
			AiMakeRay(&ray, AI_RAY_SUBSURFACE, &sg->P, &sg->Rd, dmd->maxdist, sg);
			AiTrace(&ray, &scrs);
		}
		return;
	}*/

	// AiStateSetMsgInt("als_raytype", ALS_RAY_UNDEFINED);
	
	// assert(sg->P != dmd->Po);
	// put normals the right way round
	VR::Vector Nref = rc.rayresult.normal;
	matchNormals(Nref, rc.rayresult.gnormal);
	matchNormals(Nref, rc.rayresult.origNormal);

	// void* brdf_data = AiOrenNayarMISCreateData(sg, 0.0f);
	// AiLightsPrepare(sg);
	VR::Color result_direct(0.0f, 0.0f, 0.0f);

	VR::Color Rnond(0.0f, 0.0f, 0.0f);
	bool directional = dmd->directional;

	// In V-Ray, always compute dipole diffuse reflectance; we use this as approximation
	// when V-Ray needs to know the diffuse surface color.
	for (int c = 0; c < dmd->numComponents; ++c)
	{
		Rnond += directionalDipole(rc.rayresult.wpoint, rc.rayresult.normal, dmd->Po, dmd->No, rc.rayresult.normal, dmd->No, dmd->sp[c]) * dmd->weights[c];
	}

	// Calculate the direct lighting.
	ALSIrradiateBRDF brdf(dmd, Rnond, samp, diffuse);
	result_direct=rc.vray->getSequenceData().directLightManager->eval(rc, brdf);

	/*
	while (AiLightsGetSample(sg))
	{
		// get the group assigned to this light from the hash table using the light's pointer
		int lightGroup = lightGroupMap[sg->Lp];
		float diffuse_strength = AiLightGetDiffuse(sg->Lp);

		// Does not using MIS here get us anything?
		// AtRGB L = AiEvaluateLightSample(sg, brdf_data, AiOrenNayarMISSample, AiOrenNayarMISBRDF, AiOrenNayarMISPDF);
		VR::Color L = sg->Li * VR::Max(VR::dotf(sg->Ld, sg->N), 0.0f) * (1.0f/VR::pi()) * sg->we * diffuse_strength;
		if (L.isBlack()) continue;
		if (directional)
		{
			VR::Color R(0.0f, 0.0f, 0.0f);
			for (int c=0; c < dmd->numComponents; ++c)
			{
				if (samp.r < dmd->sp[c].safe_radius)
					R += directionalDipole(sg->P, sg->N, dmd->Po, dmd->No, sg->N, dmd->No, dmd->sp[c]) * dmd->weights[c];
				else
					R += directionalDipole(sg->P, sg->N, dmd->Po, dmd->No, sg->Ld, dmd->wo, dmd->sp[c]) * dmd->weights[c]; 
			}
			L *= R;
			result_direct += L;
			vassert(VR::fastfinite(result_direct.sum()));
		}
		else
		{
			L *= Rnond;
			result_direct += L;
			vassert(VR::fastfinite(result_direct.sum()));
		}
	}*/

	// Calculate the indirect lighting if GI in V-Ray is enabled.
	VR::Color result_indirect(0.0f, 0.0f, 0.0f);

	if (rc.vray->getSequenceData().params.gi.indirectOn) {
		VR::Vector U, V;
		VR::computeTangentVectors(rc.rayresult.normal, U, V);

		VR::VRayContext &nrc=rc.newSpawnContext(0, VR::Color(1.0f, 1.0f, 1.0f), VR::RT_INDIRECT | VR::RT_ENVIRONMENT, rc.rayresult.gnormal);

		for (int i=0; i<1; i++)
		{
			float samples[2];
			samples[0]=nrc.getDMCValue();
			samples[1]=nrc.getDMCValue();

			float stheta = sqrtf(float(samples[0]));
			float phi = float(VR::pi()*2.0f * samples[1]);

			VR::Vector dir;
			dir.x = stheta * cosf(phi);
			dir.y = stheta * sinf(phi);
			float cs=sqrtf(VR::Max(0.0f, 1.0f - float(samples[0])));
			dir.z = cs;
		
			dir=dir.x*U+dir.y*V+dir.z*rc.rayresult.normal;

			nrc.setTracedDir(dir);
			nrc.rayparams.rayProbability=2.0f*cs;

			VR::Color giColor=nrc.traceCurrentRay();

			VR::Color f;
			if (directional)
			{
				VR::Color R(0.0f, 0.0f, 0.0f);
				for (int c = 0; c < dmd->numComponents; ++c)
				{
					R += directionalDipole(rc.rayresult.wpoint, rc.rayresult.normal, dmd->Po, dmd->No, dir, dmd->wo, dmd->sp[c]) * dmd->weights[c];
				}
				f = R;
				result_indirect += giColor * R;
				vassert(VR::fastfinite(result_indirect.sum()));
			}
			else
			{
				f = Rnond;
				result_indirect += giColor * Rnond;
				vassert(VR::fastfinite(result_indirect.sum()));
			}
		}
		nrc.releaseContext();
	}

	// TODO: this is guaranteed to be 1 in every case, right?
	// result_indirect *= AiSamplerGetSampleInvCount(sampit);
	samp.Rd = result_direct + result_indirect;

	vassert(VR::fastfinite(samp.Rd.sum()));

   
	samp.N = rc.rayresult.normal;
	samp.Ng = rc.rayresult.gnormal;
	samp.P = rc.rayresult.wpoint;

	dmd->sss_depth++;

	//AiStateSetMsgInt("als_raytype", ALS_RAY_SSS);
	//
	//if (dmd->sss_depth < SSS_MAX_SAMPLES && dmd->maxdist > 0.0f)
	//{
	//    
	//    AiMakeRay(&ray, AI_RAY_SUBSURFACE, &sg->P, &sg->Rd, dmd->maxdist, sg);
	//    AiTrace(&ray, &scrs);
	//}
}
Пример #4
0
static int
trace_path(pathnode_t *path)
{
	unsigned char     type;		/* type of reflection */
	int               hit;
	int               prev_interior;
	double            bsdf[3];
	ri_vector_t       outdir;
	ri_ray_t          ray;
	ri_intersection_state_t next_state;

	ri_material_t *material;

	if (path->depth >= MAX_PATH_VERTICES) {
		return 0;
	}

	material = path->state.geom->material;

	if (!russian_roulette(material)) {
		return 0;
	}

	type = sample_reflection_type(material);

	prev_interior = path->interior;

	if (path->interior && !floateq(material->ior, 1.0f)) {
		/* ray exits from a transparent object */
		path->interior = 0;
	}

	sample_outdir(&outdir, &type,
		      path->interior, material,
		      path->indir, path->state.Ng);

	if (type == 'T' && prev_interior) {
		/* ray enters into a transparent object */
		path->interior = 1;
	}


	/* find next surface point where ray hits */
	ri_vector_copy(&ray.org, path->state.P);
	ri_vector_copy(&ray.dir, outdir);

	ray.thread_num = 0;

	hit = ri_raytrace(ri_render_get(), &ray, &next_state);
	if (!hit) {
		return 0;	
	}

	brdf(bsdf,
	     type, &path->state,
	     path->indir, outdir, path->state.Ng);
	path->G[0] *= bsdf[0];
	path->G[1] *= bsdf[1];
	path->G[2] *= bsdf[2];

	path->depth++;

	ri_vector_copy(&path->indir, outdir);
	//ri_vector_neg(&path->indir);
	ri_mem_copy(&path->state, &next_state, sizeof(ri_intersection_state_t));
	
	return trace_path(path);

}