Example #1
0
bool CalcRefractedRay(TracingInstance* pLocalData, const ShadingContext& shadingCtx, float refractRatio, KColor& refractColor)
{
	KRay transRay;
	// TODO: implement the refraction computation
	transRay.InitTranslucentRay(shadingCtx, NULL);
	return CalcuShadingByRay(pLocalData, transRay, refractColor, NULL);
}
Example #2
0
bool CalcSecondaryRay(TracingInstance* pLocalData, const KVec3& org, UINT32 excludingBBox, UINT32 excludingTri, const KVec3& ray_dir, KColor& out_clr)
{
	KRay secondaryRay;
	secondaryRay.Init(ToVec3d(org), ToVec3d(ray_dir), NULL);
	secondaryRay.mExcludeBBoxNode = excludingBBox;
	secondaryRay.mExcludeTriID = excludingTri;
	return CalcuShadingByRay(pLocalData, secondaryRay, out_clr, NULL);
}
void LocalTRSFrame::TransformRay(KRay& out_ray, const KRay& in_ray, const LocalTRSFrame::LclTRS& trs)
{
	KMatrix4 inv_trs = trs.trs.getInverse();
	KVec3d newOrig;
	Vec3TransformCoord(newOrig, in_ray.GetOrg(), inv_trs);
	KVec3d oldDst = in_ray.GetOrg() + in_ray.GetDir();
	KVec3d newDst;
	Vec3TransformCoord(newDst, oldDst, inv_trs);
	KVec3d newDir = newDst - newOrig;

	out_ray.Init(newOrig, newDir, NULL);
}
Example #4
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;
}
Example #5
0
void TracingInstance::CalcuShadingContext(const KRay& hitRay, const IntersectContext& hit_ctx, ShadingContext& out_shading_ctx) const
{
	const KSceneSet* pPlainScene = mpScene->GetSource();
	const KScene* pKDScene = pPlainScene->GetNodeKDScene(hit_ctx.bbox_node_idx);
	KAnimation::LocalTRSFrame::LclTRS nodeTRS;
	pPlainScene->GetNodeTransform(nodeTRS, hit_ctx.bbox_node_idx, mCameraContext.inMotionTime);
	const nvmath::Mat33f scene_rot = nodeTRS.trs.getRotation();
	const nvmath::Mat44f scene_trans = nodeTRS.trs.getMatrix();
	const KTriDesc* pTri = mpScene->GetAccelTriData(hit_ctx.bbox_node_idx, hit_ctx.tri_id);
	UINT32 mesh_idx = pTri->GetMeshIdx();
	UINT32 node_idx = pTri->GetNodeIdx();
	UINT32 tri_idx = pTri->mTriIdx;
	const KTriMesh* pMesh = pKDScene->GetMesh(mesh_idx);
	const KNode* pNode = pKDScene->GetNode(node_idx);
	const UINT32* pn_idx = pMesh->mFaces[tri_idx].pn_idx;
	
	out_shading_ctx.tracing_instance = this;
	out_shading_ctx.excluding_bbox = hit_ctx.bbox_node_idx;
	out_shading_ctx.excluding_tri = hit_ctx.tri_id;
	assert(out_shading_ctx.excluding_bbox < NOT_HIT_INDEX);
	assert(out_shading_ctx.excluding_tri < NOT_HIT_INDEX);
	
	KTriMesh::PN_Data pn_vert[3];
	pMesh->ComputePN_Data(pn_vert[0], pMesh->mFaces[tri_idx].pn_idx[0], mCameraContext.inMotionTime);
	pMesh->ComputePN_Data(pn_vert[1], pMesh->mFaces[tri_idx].pn_idx[1], mCameraContext.inMotionTime);
	pMesh->ComputePN_Data(pn_vert[2], pMesh->mFaces[tri_idx].pn_idx[2], mCameraContext.inMotionTime);

	if (!pMesh->mTexFaces.empty()) {
		KTriMesh::TT_Data tt_data;
		pMesh->InterpolateTT(tri_idx, hit_ctx, tt_data, mCameraContext.inMotionTime);
		out_shading_ctx.uv.uv = tt_data.texcoord;
		out_shading_ctx.tangent.tangent = tt_data.tangent;
		out_shading_ctx.tangent.binormal = tt_data.binormal;
		out_shading_ctx.hasUV = 1;
	}
	else
		out_shading_ctx.hasUV = 0;

	KVec3 temp_vec;
	// interpolate the normal
	temp_vec =	pn_vert[0].nor * hit_ctx.w +
				pn_vert[1].nor * hit_ctx.u +
				pn_vert[2].nor * hit_ctx.v;
	out_shading_ctx.normal = temp_vec * pNode->GetObjectRot();
	temp_vec = out_shading_ctx.normal * scene_rot;
	out_shading_ctx.normal = temp_vec;
	float rcp_len_nor = 1.0f / nvmath::length(temp_vec);
	out_shading_ctx.normal *= rcp_len_nor;

	// interpolate the position
	out_shading_ctx.position = pn_vert[0].pos * hit_ctx.w +
						 pn_vert[1].pos * hit_ctx.u +
						 pn_vert[2].pos * hit_ctx.v;
	Vec3TransformCoord(temp_vec, out_shading_ctx.position, pNode->GetObjectTM());
	Vec3TransformCoord(out_shading_ctx.position, temp_vec, scene_trans);
	
	const nvmath::Mat33f world_rot = nvmath::Mat33f(pNode->GetObjectRot()) * scene_rot;
	KVec3 edge[3];
	edge[0] = (pn_vert[1].pos - pn_vert[0].pos) * world_rot;
	edge[1] = (pn_vert[2].pos - pn_vert[1].pos) * world_rot;
	edge[2] = (pn_vert[0].pos - pn_vert[2].pos) * world_rot;
	float edge_len_sqr[3];
	edge_len_sqr[0] = nvmath::lengthSquared(edge[0]);
	edge_len_sqr[1] = nvmath::lengthSquared(edge[1]);
	edge_len_sqr[2] = nvmath::lengthSquared(edge[2]);
	float edge_len[3];
	edge_len[0] = sqrt(edge_len_sqr[0]);
	edge_len[1] = sqrt(edge_len_sqr[1]);
	edge_len[2] = sqrt(edge_len_sqr[2]);
	// Calculate the face normal and triangle size
	out_shading_ctx.face_size = edge_len[0] + edge_len[1] + edge_len[2];
	out_shading_ctx.face_size *= 0.05f;
	// Move the shading position along it normal for a epsilon distance.
	out_shading_ctx.position += (out_shading_ctx.normal * out_shading_ctx.face_size * 0.0001f);

	KVec3 face_nor;
	face_nor = edge[0] ^ edge[1];
	out_shading_ctx.face_normal = face_nor;
	out_shading_ctx.face_normal.normalize();

	KVec3d rayDir = hitRay.GetDir();
	rayDir.normalize(); // Normalize the ray direction because it's not normalized

	// Get the surface shader
	ISurfaceShader* pSurfShader = pNode->mpSurfShader;
	out_shading_ctx.surface_shader = pSurfShader;

	out_shading_ctx.out_vec = ToVec3f(-rayDir);
}
Example #6
0
bool CalcuShadingByRay(TracingInstance* pLocalData, const KRay& ray, KColor& out_clr, IntersectContext* out_ctx/* = NULL*/)
{
	const LightScheme* pLightScheme = LightScheme::GetInstance();
	const KAccelStruct_BVH* pScene = pLocalData->GetScenePtr();
	UINT32 rayBounceDepth = pLocalData->GetBoundDepth();
	// Check the maximum bounce depth
	if (rayBounceDepth >= MAX_REFLECTION_BOUNCE) {
		out_clr = pLocalData->GetBackGroundColor(ToVec3f(ray.GetDir()));
		return false;
	}
	pLocalData->IncBounceDepth();

	IntersectContext hit_ctx;
	if (out_ctx) {
		hit_ctx.bbox_node_idx = out_ctx->bbox_node_idx;
		hit_ctx.kd_leaf_idx = out_ctx->kd_leaf_idx;
	}

	bool res = false;

	bool isHit = false;
	KColor irradiance;
	
	if ((pLocalData->CastRay(ray, hit_ctx))) 
			isHit = true;
	
	out_clr.Clear();

	if (isHit) {
		// This ray hits something, shade the ray sample by surface shader of the hit object.
		//
		if (out_ctx)
			*out_ctx = hit_ctx;
		
		// Calculate the data in shading context
		ShadingContext shadingCtx;
		pLocalData->CalcuShadingContext(ray, hit_ctx, shadingCtx);
		if (shadingCtx.surface_shader) {

			if (shadingCtx.surface_shader->mNormalMap && shadingCtx.hasUV) {
				KVec4 samp_res;
				samp_res = shadingCtx.surface_shader->mNormalMap->SampleBilinear(shadingCtx.uv.uv);
				KVec3 normal = shadingCtx.tangent.tangent * (samp_res[0] *2.0f - 1.0f);
				normal += (shadingCtx.tangent.binormal * (samp_res[1] * 2.0f - 1.0f));
				normal += (shadingCtx.normal * (samp_res[2] * 2.0f - 1.0f));
				nvmath::normalize(normal);

				float irrad_scale = 1.0f;
				irrad_scale = normal * shadingCtx.normal;
				irradiance.Scale(irrad_scale);

				shadingCtx.normal = normal;
			}

		
			out_clr = irradiance;
			pLightScheme->Shade(pLocalData, shadingCtx, hit_ctx, out_clr);
			res = true;
		}
		else {
			// No surface shader? just output its normal
			out_clr.r = shadingCtx.normal[0] * 0.5f + 0.5f;
			out_clr.g = shadingCtx.normal[1] * 0.5f + 0.5f;
			out_clr.b = shadingCtx.normal[2] * 0.5f + 0.5f;
		}
	}
	else {
		// This ray hits nothing, so it should evaluate the environment shader to determine current color of the ray sample.
		//
		const KEnvShader* pEnvShader = KEnvShader::GetEnvShader();
		if (pEnvShader) {
			KVec3 n_ray_dir = ToVec3f(ray.GetDir());
			n_ray_dir.normalize();
			*pLocalData->mEvnContext.pos = ToVec3f(ray.GetOrg());
			*pLocalData->mEvnContext.dir = n_ray_dir;
			pEnvShader->Sample(pLocalData->mEvnContext, out_clr);
		}
	}

	pLocalData->DecBounceDepth();
	return res;
}
Example #7
0
bool CalcReflectedRay(TracingInstance* pLocalData, const ShadingContext& shadingCtx, KColor& reflectColor)
{
	KRay reflectRay;
	reflectRay.InitReflectionRay(shadingCtx, shadingCtx.out_vec, NULL);
	return CalcuShadingByRay(pLocalData, reflectRay, reflectColor, NULL);
}
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;
}