light shadow cameras initialization made automatic

This commit is contained in:
turanszkij
2016-08-07 00:42:23 +02:00
parent 5893adbf74
commit fb66bc1c5a
5 changed files with 103 additions and 97 deletions
-1
View File
@@ -103,7 +103,6 @@ void wiEmittedParticle::CreateLight()
if (light == nullptr && material->blendFlag == BLENDMODE_ADDITIVE)
{
light = new Light();
light->SetUp();
light->color.x = material->baseColor.x;
light->color.y = material->baseColor.y;
light->color.z = material->baseColor.z;
+87 -69
View File
@@ -2367,7 +2367,6 @@ void Model::FinishLoading()
}
for (Light* x : lights)
{
x->SetUp();
transforms.push_back(x);
}
for (Decal* x : decals)
@@ -3823,53 +3822,21 @@ void Object::Serialize(wiArchive& archive)
#pragma region LIGHT
vector<wiRenderTarget> Light::shadowMaps_pointLight;
vector<wiRenderTarget> Light::shadowMaps_spotLight;
Light::Light():Transform() {
color = XMFLOAT4(0, 0, 0, 0);
enerDis = XMFLOAT4(0, 0, 0, 0);
type = LightType::POINT;
//shadowMap.resize(0);
shadow = false;
noHalo = false;
lensFlareRimTextures.resize(0);
lensFlareNames.resize(0);
shadowMap_index = -1;
shadowBias = 9.99995464e-005f;
}
Light::~Light() {
shadowCam.clear();
//shadowMap.clear();
shadowMaps_dirLight.clear();
lensFlareRimTextures.clear();
for (string x : lensFlareNames)
wiResourceManager::GetGlobal()->del(x);
lensFlareNames.clear();
}
void Light::SetUp()
{
if (!shadowCam.empty())
return;
if (type == Light::DIRECTIONAL) {
float lerp = 0.5f;
float lerp1 = 0.12f;
float lerp2 = 0.016f;
XMVECTOR a0, a, b0, b;
a0 = XMVector3Unproject(XMVectorSet(0, (float)wiRenderer::GetDevice()->GetScreenHeight(), 0, 1), 0, 0, (float)wiRenderer::GetDevice()->GetScreenWidth(), (float)wiRenderer::GetDevice()->GetScreenHeight(), 0.1f, 1.0f, wiRenderer::getCamera()->GetProjection(), wiRenderer::getCamera()->GetView(), XMMatrixIdentity());
a = XMVector3Unproject(XMVectorSet(0, (float)wiRenderer::GetDevice()->GetScreenHeight(), 1, 1), 0, 0, (float)wiRenderer::GetDevice()->GetScreenWidth(), (float)wiRenderer::GetDevice()->GetScreenHeight(), 0.1f, 1.0f, wiRenderer::getCamera()->GetProjection(), wiRenderer::getCamera()->GetView(), XMMatrixIdentity());
b0 = XMVector3Unproject(XMVectorSet((float)wiRenderer::GetDevice()->GetScreenWidth(), (float)wiRenderer::GetDevice()->GetScreenHeight(), 0, 1), 0, 0, (float)wiRenderer::GetDevice()->GetScreenWidth(), (float)wiRenderer::GetDevice()->GetScreenHeight(), 0.1f, 1.0f, wiRenderer::getCamera()->GetProjection(), wiRenderer::getCamera()->GetView(), XMMatrixIdentity());
b = XMVector3Unproject(XMVectorSet((float)wiRenderer::GetDevice()->GetScreenWidth(), (float)wiRenderer::GetDevice()->GetScreenHeight(), 1, 1), 0, 0, (float)wiRenderer::GetDevice()->GetScreenWidth(), (float)wiRenderer::GetDevice()->GetScreenHeight(), 0.1f, 1.0f, wiRenderer::getCamera()->GetProjection(), wiRenderer::getCamera()->GetView(), XMMatrixIdentity());
float size = XMVectorGetX(XMVector3Length(XMVectorSubtract(XMVectorLerp(b0, b, lerp), XMVectorLerp(a0, a, lerp))));
float size1 = XMVectorGetX(XMVector3Length(XMVectorSubtract(XMVectorLerp(b0, b, lerp1), XMVectorLerp(a0, a, lerp1))));
float size2 = XMVectorGetX(XMVector3Length(XMVectorSubtract(XMVectorLerp(b0, b, lerp2), XMVectorLerp(a0, a, lerp2))));
XMVECTOR rot = XMQuaternionIdentity();
shadowCam.push_back(SHCAM(size, rot, 0, wiRenderer::getCamera()->zFarP));
shadowCam.push_back(SHCAM(size1, rot, 0, wiRenderer::getCamera()->zFarP));
shadowCam.push_back(SHCAM(size2, rot, 0, wiRenderer::getCamera()->zFarP));
}
else if (type == Light::SPOT && shadow) {
shadowCam.push_back(SHCAM(XMFLOAT4(0, 0, 0, 1), wiRenderer::getCamera()->zNearP, enerDis.y, enerDis.z));
}
else if (type == Light::POINT && shadow) {
shadowCam.push_back(SHCAM(XMFLOAT4(0.5f, -0.5f, -0.5f, -0.5f), wiRenderer::getCamera()->zNearP, enerDis.y, XM_PI / 2.0f)); //+x
shadowCam.push_back(SHCAM(XMFLOAT4(0.5f, 0.5f, 0.5f, -0.5f), wiRenderer::getCamera()->zNearP, enerDis.y, XM_PI / 2.0f)); //-x
shadowCam.push_back(SHCAM(XMFLOAT4(1, 0, 0, -0), wiRenderer::getCamera()->zNearP, enerDis.y, XM_PI / 2.0f)); //+y
shadowCam.push_back(SHCAM(XMFLOAT4(0, 0, 0, -1), wiRenderer::getCamera()->zNearP, enerDis.y, XM_PI / 2.0f)); //-y
shadowCam.push_back(SHCAM(XMFLOAT4(0.707f, 0, 0, -0.707f), wiRenderer::getCamera()->zNearP, enerDis.y, XM_PI / 2.0f)); //+z
shadowCam.push_back(SHCAM(XMFLOAT4(0, 0.707f, 0.707f, 0), wiRenderer::getCamera()->zNearP, enerDis.y, XM_PI / 2.0f)); //-z
}
}
void Light::UpdateTransform()
{
@@ -3878,45 +3845,96 @@ void Light::UpdateTransform()
void Light::UpdateLight()
{
//Shadows
if (type == Light::DIRECTIONAL) {
if (type == Light::DIRECTIONAL)
{
if (shadow)
{
if (shadowCam_dirLight.empty())
{
float lerp = 0.5f;
float lerp1 = 0.12f;
float lerp2 = 0.016f;
XMVECTOR a0, a, b0, b;
a0 = XMVector3Unproject(XMVectorSet(0, (float)wiRenderer::GetDevice()->GetScreenHeight(), 0, 1), 0, 0, (float)wiRenderer::GetDevice()->GetScreenWidth(), (float)wiRenderer::GetDevice()->GetScreenHeight(), 0.1f, 1.0f, wiRenderer::getCamera()->GetProjection(), wiRenderer::getCamera()->GetView(), XMMatrixIdentity());
a = XMVector3Unproject(XMVectorSet(0, (float)wiRenderer::GetDevice()->GetScreenHeight(), 1, 1), 0, 0, (float)wiRenderer::GetDevice()->GetScreenWidth(), (float)wiRenderer::GetDevice()->GetScreenHeight(), 0.1f, 1.0f, wiRenderer::getCamera()->GetProjection(), wiRenderer::getCamera()->GetView(), XMMatrixIdentity());
b0 = XMVector3Unproject(XMVectorSet((float)wiRenderer::GetDevice()->GetScreenWidth(), (float)wiRenderer::GetDevice()->GetScreenHeight(), 0, 1), 0, 0, (float)wiRenderer::GetDevice()->GetScreenWidth(), (float)wiRenderer::GetDevice()->GetScreenHeight(), 0.1f, 1.0f, wiRenderer::getCamera()->GetProjection(), wiRenderer::getCamera()->GetView(), XMMatrixIdentity());
b = XMVector3Unproject(XMVectorSet((float)wiRenderer::GetDevice()->GetScreenWidth(), (float)wiRenderer::GetDevice()->GetScreenHeight(), 1, 1), 0, 0, (float)wiRenderer::GetDevice()->GetScreenWidth(), (float)wiRenderer::GetDevice()->GetScreenHeight(), 0.1f, 1.0f, wiRenderer::getCamera()->GetProjection(), wiRenderer::getCamera()->GetView(), XMMatrixIdentity());
float size = XMVectorGetX(XMVector3Length(XMVectorSubtract(XMVectorLerp(b0, b, lerp), XMVectorLerp(a0, a, lerp))));
float size1 = XMVectorGetX(XMVector3Length(XMVectorSubtract(XMVectorLerp(b0, b, lerp1), XMVectorLerp(a0, a, lerp1))));
float size2 = XMVectorGetX(XMVector3Length(XMVectorSubtract(XMVectorLerp(b0, b, lerp2), XMVectorLerp(a0, a, lerp2))));
XMVECTOR rot = XMQuaternionIdentity();
float lerp = 0.5f;//third slice distance from cam (percentage)
float lerp1 = 0.12f;//second slice distance from cam (percentage)
float lerp2 = 0.016f;//first slice distance from cam (percentage)
XMVECTOR c, d, e, e1, e2;
c = XMVector3Unproject(XMVectorSet((float)wiRenderer::GetDevice()->GetScreenWidth() * 0.5f, (float)wiRenderer::GetDevice()->GetScreenHeight() * 0.5f, 1, 1), 0, 0, (float)wiRenderer::GetDevice()->GetScreenWidth(), (float)wiRenderer::GetDevice()->GetScreenHeight(), 0.1f, 1.0f, wiRenderer::getCamera()->GetProjection(), wiRenderer::getCamera()->GetView(), XMMatrixIdentity());
d = XMVector3Unproject(XMVectorSet((float)wiRenderer::GetDevice()->GetScreenWidth() * 0.5f, (float)wiRenderer::GetDevice()->GetScreenHeight() * 0.5f, 0, 1), 0, 0, (float)wiRenderer::GetDevice()->GetScreenWidth(), (float)wiRenderer::GetDevice()->GetScreenHeight(), 0.1f, 1.0f, wiRenderer::getCamera()->GetProjection(), wiRenderer::getCamera()->GetView(), XMMatrixIdentity());
shadowCam_dirLight.push_back(SHCAM(size, rot, 0, wiRenderer::getCamera()->zFarP));
shadowCam_dirLight.push_back(SHCAM(size1, rot, 0, wiRenderer::getCamera()->zFarP));
shadowCam_dirLight.push_back(SHCAM(size2, rot, 0, wiRenderer::getCamera()->zFarP));
}
if (!shadowCam.empty()) {
float lerp = 0.5f;//third slice distance from cam (percentage)
float lerp1 = 0.12f;//second slice distance from cam (percentage)
float lerp2 = 0.016f;//first slice distance from cam (percentage)
XMVECTOR c, d, e, e1, e2;
c = XMVector3Unproject(XMVectorSet((float)wiRenderer::GetDevice()->GetScreenWidth() * 0.5f, (float)wiRenderer::GetDevice()->GetScreenHeight() * 0.5f, 1, 1), 0, 0, (float)wiRenderer::GetDevice()->GetScreenWidth(), (float)wiRenderer::GetDevice()->GetScreenHeight(), 0.1f, 1.0f, wiRenderer::getCamera()->GetProjection(), wiRenderer::getCamera()->GetView(), XMMatrixIdentity());
d = XMVector3Unproject(XMVectorSet((float)wiRenderer::GetDevice()->GetScreenWidth() * 0.5f, (float)wiRenderer::GetDevice()->GetScreenHeight() * 0.5f, 0, 1), 0, 0, (float)wiRenderer::GetDevice()->GetScreenWidth(), (float)wiRenderer::GetDevice()->GetScreenHeight(), 0.1f, 1.0f, wiRenderer::getCamera()->GetProjection(), wiRenderer::getCamera()->GetView(), XMMatrixIdentity());
float f = shadowCam[0].size / (float)wiRenderer::SHADOWMAPRES;
e = XMVectorFloor(XMVectorLerp(d, c, lerp) / f)*f;
f = shadowCam[1].size / (float)wiRenderer::SHADOWMAPRES;
e1 = XMVectorFloor(XMVectorLerp(d, c, lerp1) / f)*f;
f = shadowCam[2].size / (float)wiRenderer::SHADOWMAPRES;
e2 = XMVectorFloor(XMVectorLerp(d, c, lerp2) / f)*f;
if (!shadowCam_dirLight.empty()) {
XMMATRIX rrr = XMMatrixRotationQuaternion(XMLoadFloat4(&rotation));
shadowCam[0].Update(rrr*XMMatrixTranslationFromVector(e));
if (shadowCam.size()>1) {
shadowCam[1].Update(rrr*XMMatrixTranslationFromVector(e1));
if (shadowCam.size()>2)
shadowCam[2].Update(rrr*XMMatrixTranslationFromVector(e2));
float f = shadowCam_dirLight[0].size / (float)wiRenderer::SHADOWMAPRES;
e = XMVectorFloor(XMVectorLerp(d, c, lerp) / f)*f;
f = shadowCam_dirLight[1].size / (float)wiRenderer::SHADOWMAPRES;
e1 = XMVectorFloor(XMVectorLerp(d, c, lerp1) / f)*f;
f = shadowCam_dirLight[2].size / (float)wiRenderer::SHADOWMAPRES;
e2 = XMVectorFloor(XMVectorLerp(d, c, lerp2) / f)*f;
XMMATRIX rrr = XMMatrixRotationQuaternion(XMLoadFloat4(&rotation));
shadowCam_dirLight[0].Update(rrr*XMMatrixTranslationFromVector(e));
if (shadowCam_dirLight.size()>1) {
shadowCam_dirLight[1].Update(rrr*XMMatrixTranslationFromVector(e1));
if (shadowCam_dirLight.size()>2)
shadowCam_dirLight[2].Update(rrr*XMMatrixTranslationFromVector(e2));
}
}
}
bounds.createFromHalfWidth(wiRenderer::getCamera()->translation, XMFLOAT3(10000, 10000, 10000));
}
else if (type == Light::SPOT) {
if (!shadowCam.empty()) {
shadowCam[0].Update(XMLoadFloat4x4(&world));
if (shadow)
{
if (!shadowCam_spotLight.empty())
{
shadowCam_spotLight[0].Update(XMLoadFloat4x4(&world));
shadowCam_spotLight[0].Create_Perspective(XM_PIDIV2);
}
else
{
shadowCam_spotLight.push_back(SHCAM(XMFLOAT4(0, 0, 0, 1), 0.1f, 1000.0f, enerDis.z));
}
}
bounds.createFromHalfWidth(translation, XMFLOAT3(enerDis.y, enerDis.y, enerDis.y));
}
else if (type == Light::POINT) {
for (unsigned int i = 0; i<shadowCam.size(); ++i) {
shadowCam[i].Update(XMLoadFloat3(&translation));
if (shadow)
{
if (!shadowCam_pointLight.empty())
{
for (unsigned int i = 0; i < shadowCam_pointLight.size(); ++i) {
shadowCam_pointLight[i].Update(XMLoadFloat3(&translation));
shadowCam_pointLight[i].Create_Perspective(XM_PIDIV2);
}
}
else
{
shadowCam_pointLight.push_back(SHCAM(XMFLOAT4(0.5f, -0.5f, -0.5f, -0.5f), 0.1f, 1000.0f, XM_PIDIV2)); //+x
shadowCam_pointLight.push_back(SHCAM(XMFLOAT4(0.5f, 0.5f, 0.5f, -0.5f), 0.1f, 1000.0f, XM_PIDIV2)); //-x
shadowCam_pointLight.push_back(SHCAM(XMFLOAT4(1, 0, 0, -0), 0.1f, 1000.0f, XM_PIDIV2)); //+y
shadowCam_pointLight.push_back(SHCAM(XMFLOAT4(0, 0, 0, -1), 0.1f, 1000.0f, XM_PIDIV2)); //-y
shadowCam_pointLight.push_back(SHCAM(XMFLOAT4(0.707f, 0, 0, -0.707f), 0.1f, 1000.0f, XM_PIDIV2)); //+z
shadowCam_pointLight.push_back(SHCAM(XMFLOAT4(0, 0.707f, 0.707f, 0), 0.1f, 1000.0f, XM_PIDIV2)); //-z
}
}
bounds.createFromHalfWidth(translation, XMFLOAT3(enerDis.y, enerDis.y, enerDis.y));
+4 -15
View File
@@ -770,7 +770,9 @@ struct Light : public Cullable , public Transform
vector<wiRenderTarget> shadowMaps_dirLight;
int shadowMap_index;
vector<SHCAM> shadowCam;
vector<SHCAM> shadowCam_pointLight;
vector<SHCAM> shadowCam_dirLight;
vector<SHCAM> shadowCam_spotLight;
float shadowBias;
@@ -781,21 +783,8 @@ struct Light : public Cullable , public Transform
};
LightType type;
Light():Transform(){
color=XMFLOAT4(0,0,0,0);
enerDis=XMFLOAT4(0,0,0,0);
type=LightType::POINT;
//shadowMap.resize(0);
shadow = false;
shadowCam.resize(0);
noHalo=false;
lensFlareRimTextures.resize(0);
lensFlareNames.resize(0);
shadowMap_index = -1;
shadowBias = 0.00001f;
}
Light();
virtual ~Light();
void SetUp();
virtual void UpdateTransform();
void UpdateLight();
void Serialize(wiArchive& archive);
+11 -11
View File
@@ -2091,7 +2091,7 @@ void wiRenderer::DrawLights(Camera* camera, GRAPHICSTHREAD threadID)
lcb.col=XMFLOAT4(l->color.x*l->enerDis.x,l->color.y*l->enerDis.x,l->color.z*l->enerDis.x,1);
lcb.mBiasResSoftshadow=XMFLOAT4(l->shadowBias,(float)SHADOWMAPRES,(float)SOFTSHADOW,0);
for (unsigned int shmap = 0; shmap < l->shadowMaps_dirLight.size(); ++shmap){
lcb.mShM[shmap]=l->shadowCam[shmap].getVP();
lcb.mShM[shmap]=l->shadowCam_dirLight[shmap].getVP();
if(l->shadowMaps_dirLight[shmap].depth)
GetDevice()->BindResourcePS(l->shadowMaps_dirLight[shmap].depth->GetTexture(),TEXSLOT_SHADOW0+shmap,threadID);
}
@@ -2140,7 +2140,7 @@ void wiRenderer::DrawLights(Camera* camera, GRAPHICSTHREAD threadID)
if (l->shadow && l->shadowMap_index>=0)
{
lcb.mShM = l->shadowCam[0].getVP();
lcb.mShM = l->shadowCam_spotLight[0].getVP();
if(Light::shadowMaps_spotLight[l->shadowMap_index].depth)
GetDevice()->BindResourcePS(Light::shadowMaps_spotLight[l->shadowMap_index].depth->GetTexture(), TEXSLOT_SHADOW0, threadID);
}
@@ -2361,13 +2361,13 @@ void wiRenderer::DrawForShadowMap(GRAPHICSTHREAD threadID)
l->shadowMaps_dirLight[index].Activate(threadID);
const float siz = l->shadowCam[index].size * 0.5f;
const float f = l->shadowCam[index].farplane;
const float siz = l->shadowCam_dirLight[index].size * 0.5f;
const float f = l->shadowCam_dirLight[index].farplane;
AABB boundingbox;
boundingbox.createFromHalfWidth(XMFLOAT3(0, 0, 0), XMFLOAT3(siz, f, siz));
if (spTree)
wiSPTree::getVisible(spTree->root, boundingbox.get(
XMMatrixInverse(0, XMLoadFloat4x4(&l->shadowCam[index].View))
XMMatrixInverse(0, XMLoadFloat4x4(&l->shadowCam_dirLight[index].View))
), culledObjects);
#pragma region BLOAT
@@ -2391,7 +2391,7 @@ void wiRenderer::DrawForShadowMap(GRAPHICSTHREAD threadID)
//MAPPED_SUBRESOURCE mappedResource;
ShadowCB cb;
cb.mVP = l->shadowCam[index].getVP();
cb.mVP = l->shadowCam_dirLight[index].getVP();
GetDevice()->UpdateBuffer(constantBuffers[CBTYPE_SHADOW], &cb, threadID);
@@ -2461,8 +2461,8 @@ void wiRenderer::DrawForShadowMap(GRAPHICSTHREAD threadID)
Light::shadowMaps_spotLight[i].Set(threadID);
Frustum frustum;
XMFLOAT4X4 proj, view;
XMStoreFloat4x4(&proj, XMLoadFloat4x4(&l->shadowCam[0].Projection));
XMStoreFloat4x4(&view, XMLoadFloat4x4(&l->shadowCam[0].View));
XMStoreFloat4x4(&proj, XMLoadFloat4x4(&l->shadowCam_spotLight[0].Projection));
XMStoreFloat4x4(&view, XMLoadFloat4x4(&l->shadowCam_spotLight[0].View));
frustum.ConstructFrustum(wiRenderer::getCamera()->zFarP, proj, view);
if (spTree)
wiSPTree::getVisible(spTree->root, frustum, culledObjects);
@@ -2489,7 +2489,7 @@ void wiRenderer::DrawForShadowMap(GRAPHICSTHREAD threadID)
//MAPPED_SUBRESOURCE mappedResource;
ShadowCB cb;
cb.mVP = l->shadowCam[index].getVP();
cb.mVP = l->shadowCam_spotLight[index].getVP();
GetDevice()->UpdateBuffer(constantBuffers[CBTYPE_SHADOW], &cb, threadID);
@@ -2570,8 +2570,8 @@ void wiRenderer::DrawForShadowMap(GRAPHICSTHREAD threadID)
GetDevice()->UpdateBuffer(constantBuffers[CBTYPE_POINTLIGHT], &lcb, threadID);
CubeMapRenderCB cb;
for (unsigned int shcam = 0; shcam < l->shadowCam.size(); ++shcam)
cb.mViewProjection[shcam] = l->shadowCam[shcam].getVP();
for (unsigned int shcam = 0; shcam < l->shadowCam_pointLight.size(); ++shcam)
cb.mViewProjection[shcam] = l->shadowCam_pointLight[shcam].getVP();
GetDevice()->UpdateBuffer(constantBuffers[CBTYPE_CUBEMAPRENDER], &cb, threadID);
+1 -1
View File
@@ -7,7 +7,7 @@ namespace wiVersion
// minor features, major bug fixes
const int minor = 8;
// minor bug fixes, alterations, refactors
const int revision = 36;
const int revision = 38;
long GetVersion()