Пример #1
0
bool LightScheme::GetLightIter(TracingInstance* pLocalData, const KVec2& samplePos, UINT32 lightIdx, const ShadingContext* shadingCtx,  const IntersectContext* hit_ctx, LightIterator& out_iter) const
{
	const ILightObject* pLightObj = GetLightPtr(lightIdx);
		
	KVec3 lightPos_f;
	KVec3d lightPos;
	KColor litClr;
	if (pLightObj->EvaluateLighting(samplePos, shadingCtx->position, lightPos_f, out_iter)) {

		lightPos = ToVec3d(lightPos_f);
		bool isOccluded = false;
		KColor transmission(out_iter.intensity);
		{
			KVec3d adjustedPos = ToVec3d(shadingCtx->position);
			KVec3d lightDir = lightPos - adjustedPos;
			float l_n = ToVec3f(lightDir) * shadingCtx->normal;
			float l_fn = ToVec3f(lightDir) * shadingCtx->face_normal;

			if (l_n > 0 && l_fn < 0) 
				AdjustHitPos(pLocalData, *hit_ctx, *shadingCtx, adjustedPos);

			KVec3d temp_light_pos(lightPos);
			lightDir = adjustedPos - temp_light_pos;
					
			KRay ray;
			lightDir = temp_light_pos - adjustedPos;
			ray.Init(adjustedPos, lightDir, NULL);
			ray.mExcludeBBoxNode = hit_ctx->bbox_node_idx;
			ray.mExcludeTriID = hit_ctx->tri_id;

			KColor trans_coefficent;
			pLocalData->ComputeLightTransimission(ray, 1.0f, trans_coefficent);
			transmission.Modulate(trans_coefficent);

		}

		if (transmission.Luminance() > 0) {
			out_iter.intensity = transmission;
			return true;
		}
	}

	return false;
}
Пример #2
0
bool LightScheme::GetLightIter(TracingInstance* pLocalData, const KVec2& samplePos, UINT32 lightIdx, const ShadingContext* shadingCtx,  const IntersectContext* hit_ctx, LightIterator& out_iter) const
{
	const ILightObject* pLightObj = GetLightPtr(lightIdx);
		
	KVec3 lightPos_f;
	KVec3d lightPos;
	KColor litClr;
	if (pLightObj->EvaluateLighting(samplePos, shadingCtx->position, lightPos_f, out_iter)) {

		lightPos = ToVec3d(lightPos_f);
		bool isOccluded = false;
		KColor transmission(out_iter.intensity);
		{
			KVec3d adjustedPos = ToVec3d(shadingCtx->position);
			KVec3d lightDir = lightPos - adjustedPos;
			float l_n = ToVec3f(lightDir) * shadingCtx->normal;
			float l_fn = ToVec3f(lightDir) * shadingCtx->face_normal;
			if (l_n > 0) {

				if (l_fn < 0) 
					AdjustHitPos(pLocalData, *hit_ctx, *shadingCtx, adjustedPos);

				KVec3d temp_light_pos(lightPos);
				lightDir = adjustedPos - temp_light_pos;
					
				// Clamp the shadow ray if the light source is out of the scene's bounding box.
				// Doing so can improve the floating point precision.
				const KBBox& sceneBBox = pLocalData->GetScenePtr()->GetSceneBBox();
				bool needClampRay = !sceneBBox.IsInside(ToVec3f(temp_light_pos));
				if (needClampRay) {
					KRay ray;
					ray.Init(temp_light_pos, lightDir, NULL);
					double t0, t1;
					if (IntersectBBox(ray, sceneBBox, t0, t1)) {
						temp_light_pos = ray.GetOrg() + ray.GetDir() * t0;
					}

				}
					
				KRay ray;
				lightDir = adjustedPos - temp_light_pos;
				ray.Init(temp_light_pos, lightDir, NULL);
				ray.mExcludeBBoxNode = INVALID_INDEX;
				ray.mExcludeTriID = INVALID_INDEX;

				float lum = 1.0f;
				while (lum > 0) {
					IntersectContext test_ctx;
					test_ctx.ray_t = 1.0;
					isOccluded = pLocalData->CastRay(ray, test_ctx);
					if (isOccluded) {
						if (test_ctx.bbox_node_idx == hit_ctx->bbox_node_idx && test_ctx.tri_id == hit_ctx->tri_id)
							break;

						// Calculate how much light can pass through the hit surface
						KColor temp_trans;
						ShadingContext shading_context;
						pLocalData->CalcuShadingContext(ray, test_ctx, shading_context);
						TransContext& transCtx = pLocalData->GetCurrentTransCtxStorage();
						pLocalData->ConvertToTransContext(test_ctx, shading_context, transCtx);
						shading_context.surface_shader->ShaderTransmission(transCtx, temp_trans);
						transmission.Modulate(temp_trans);

						lum = transmission.Luminance();
						if (lum > 0.001f) {
							KVec3d go_dis = lightDir*test_ctx.ray_t;
							temp_light_pos += (go_dis * 1.00001);
							lightDir -= (go_dis * 0.9999);
							ray.Init(temp_light_pos, lightDir, NULL);
							ray.mExcludeBBoxNode = test_ctx.bbox_node_idx;
							ray.mExcludeTriID = test_ctx.tri_id; 

						}
						else {
							transmission.Clear();
							break;
						}
					}
					else 
						break;

				}
			}
			else
				transmission.Clear();

		}

		if (transmission.Luminance() > 0) {
			out_iter.intensity = transmission;
			return true;
		}
	}

	return false;
}