예제 #1
0
	void Shadow::_updateCamera()
	{
		Camera * worldCam = World::Instance()->MainCamera();

		mInverseWorldCameraVP = World::Instance()->MainCamera()->GetViewProjMatrix().Inverse();

		float nearClip = worldCam->GetNearClip();
		float farClip = mDist[K_NumShadowLayers - 1];

		Vec3 xAixs = worldCam->GetDirection();
		Vec3 yAixs = worldCam->GetUp();
		Vec3 zAixs = Environment::Instance()->GetEvParam()->LightDir;

		if (Math::Abs(zAixs.Dot(yAixs)) > 0.99f)
		{
			yAixs = zAixs.CrossN(xAixs);
			xAixs = yAixs.CrossN(zAixs);
		}
		else
		{
			xAixs = yAixs.CrossN(zAixs);
			yAixs = zAixs.CrossN(xAixs);
		}

		if (xAixs.Dot(worldCam->GetDirection()) < 0)
			xAixs = -xAixs;

		yAixs = zAixs.CrossN(xAixs);

		Mat4 matView;
		Quat qOrient = Quat::S_FromAxis(xAixs, yAixs, zAixs);

		matView.MakeViewLH(worldCam->GetPosition(), qOrient);

		Vec3 corner[8], t_corner[8];

		worldCam->GetWorldCorner(t_corner, nearClip, farClip);

		float dist = t_corner[4].Distance(t_corner[5]);

		for (int i = 0; i < 8; ++i)
		{
			corner[i] = t_corner[i] * matView;
		}

		Aabb aabb = Aabb::Invalid;

		for (int i = 0; i < 8; ++i)
		{
			aabb.minimum = aabb.minimum.Minimum(corner[i]);
			aabb.maximum = aabb.maximum.Maximum(corner[i]);
		}

		Vec3 center = aabb.GetCenter();
		float width = aabb.GetWidth();
		float height = aabb.GetHeight();
		float depth = aabb.GetDepth();

		center *= matView.Inverse();

		Vec3 lightPos = center - zAixs * mOffset;

		mLightCamera->SetPosition(lightPos);
		mLightCamera->SetOrientation(qOrient);
		mLightCamera->SetOrthoWidth(width);
		mLightCamera->SetOrthoHeight(height);
		mLightCamera->SetNearClip(nearClip);
		mLightCamera->SetFarClip(mOffset + depth);
		mLightCamera->SetProjectionType(PROJTYPE_ORTHO);
	}
예제 #2
0
	void Shadow::_calcuCascadedMatrix(int layer)
	{
		Camera * worldCam = World::Instance()->MainCamera();

		mInverseWorldCameraVP = World::Instance()->MainCamera()->GetViewProjMatrix().Inverse();

		float nearClip, farClip = mDist[layer];

		if (layer == 0)
			nearClip = worldCam->GetNearClip();
		else
			nearClip = mDist[layer - 1];

		Vec3 xAixs = worldCam->GetDirection();
		Vec3 yAixs = worldCam->GetUp();
		Vec3 zAixs = Environment::Instance()->GetEvParam()->LightDir;

		if (Math::Abs(zAixs.Dot(yAixs)) > 0.99f)
		{
			yAixs = zAixs.CrossN(xAixs);
			xAixs = yAixs.CrossN(zAixs);
		}
		else
		{
			xAixs = yAixs.CrossN(zAixs);
			yAixs = zAixs.CrossN(xAixs);
		}

		if (xAixs.Dot(worldCam->GetDirection()) < 0)
			xAixs = -xAixs;

		yAixs = zAixs.CrossN(xAixs);

		Mat4 matView, matProj;
		Quat qOrient = Quat::S_FromAxis(xAixs, yAixs, zAixs);

		matView.MakeViewLH(worldCam->GetPosition(), qOrient);

		Vec3 corner[8], t_corner[8];

		worldCam->GetWorldCorner(t_corner, nearClip, farClip);

		float dist = t_corner[4].Distance(t_corner[5]);

		for (int i = 0; i < 8; ++i)
		{
			corner[i] = t_corner[i] * matView;
		}

		Aabb aabb = Aabb::Invalid;

		for (int i = 0; i < 8; ++i)
		{
			aabb.minimum = aabb.minimum.Minimum(corner[i]);
			aabb.maximum = aabb.maximum.Maximum(corner[i]);
		}

		Vec3 center = aabb.GetCenter();
		float width = aabb.GetWidth();
		float height = aabb.GetHeight();
		float depth = aabb.GetDepth();

		center *= matView.Inverse();

		Vec3 lightPos = center - zAixs * mOffset;

		matView.MakeViewLH(lightPos, qOrient);
		matProj.MakeOrthoLH(width, height, nearClip, mOffset + depth);

		mCascadedMatrix[layer].mView = matView;
		mCascadedMatrix[layer].mProj = matProj;
		mCascadedMatrix[layer].mViewProj = matView * matProj;
	}