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); }
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; }
void KBBox::TransformByMatrix(const KMatrix4d& mat) { KBBox newBBox; for (int i = 0; i < 3; ++i) { for (int j = 0; j < 2; ++j) { KVec3d v = ToVec3d((*this)[j]); v[i] = (*this)[j == 1 ? 0 : 1][i]; KVec3d out_v; Vec3TransformCoord(out_v, v, mat); newBBox.ContainVert(ToVec3f(out_v)); } } (*this) = newBBox; }
bool EyeRayGen::GetImageCoordidates(const KVec3& pos, KVec2& out_image_pos) const { KVec3d vdir = ToVec3d(pos) - mEyePos; vdir.normalize(); double sx = vdir * mHorizonVec; double sy = vdir * mViewUp; double sz = vdir * mViewDir; double cx = sqrt(1.0f - fabs(sx)*fabs(sx)); double cy = sqrt(1.0f - fabs(sy)*fabs(sy)); if (sz < 0) return false; out_image_pos[0] = float(sx / (mTanFovX * sz)); out_image_pos[1] = float(sy / (mTanFovY * sz)); return true; }
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; }