Cubemap shadow (#558)

* Cubemap shadow WIP
* Fade out Point Light Shadow
* Fixed SpotLight Direction and Angle

Added Fadeout at the edges of Spot Light Cone

* Using Light.Out for Spot Light Projection Matrix
* Added Experimental Blob Shadows
* Fixed Crash with too many blob shadows.

Now using the 16 nearest spheres

* Remove long unused UNIT_SHADOW
* Fix merge
* Check cast shadows flag for dynamic shadows generation
* Make shadow spheres count customizable, add "shadows: all" setting
* Fix headers
* Fix copypaste error
* Fix shader compiling
* Format code, make subfunction for blobs rendering

Co-authored-by: Raildex <n@a>
Co-authored-by: Lwmte <3331699+Lwmte@users.noreply.github.com>
This commit is contained in:
Raildex 2022-06-29 16:54:48 +02:00 committed by GitHub
parent c0582c9a9c
commit 84f93608bb
34 changed files with 811 additions and 400 deletions

View file

@ -9,6 +9,16 @@ local strings = {
"",
""
},
all = {
"All",
"",
"",
"",
"",
"",
"",
""
},
apply = {
"Apply",
"",
@ -669,6 +679,16 @@ local strings = {
"",
""
},
none = {
"None",
"",
"",
"",
"",
"",
"",
""
},
ok = {
"OK",
"",
@ -739,6 +759,16 @@ local strings = {
"",
""
},
player = {
"Player",
"",
"",
"",
"",
"",
"",
""
},
render_options = {
"Render Options",
"",

View file

@ -22,7 +22,7 @@ int GetSpheres(ItemInfo* item, SPHERE* ptr, int worldSpace, Matrix local)
BoundingSphere spheres[MAX_SPHERES];
short itemNumber = (item - g_Level.Items.data());
int num = g_Renderer.getSpheres(itemNumber, spheres, worldSpace, local);
int num = g_Renderer.GetSpheres(itemNumber, spheres, worldSpace, local);
for (int i = 0; i < MAX_SPHERES; i++)
{

View file

@ -489,10 +489,13 @@ void GuiController::DoDebouncedInput()
if (TrInput & IN_LEFT)
{
if (rptLeft >= 8)
goLeft = 1;
else
rptLeft++;
if (invMode == InventoryMode::InGame)
{
if (rptLeft >= 8)
goLeft = 1;
else
rptLeft++;
}
if (!dbLeft)
goLeft = 1;
@ -507,10 +510,13 @@ void GuiController::DoDebouncedInput()
if (TrInput & IN_RIGHT)
{
if (rptRight >= 8)
goRight = 1;
else
rptRight++;
if (invMode == InventoryMode::InGame)
{
if (rptRight >= 8)
goRight = 1;
else
rptRight++;
}
if (!dbRight)
goRight = 1;
@ -785,7 +791,8 @@ void GuiController::HandleDisplaySettingsInput(bool pause)
case 2:
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
CurrentSettings.conf.EnableShadows = !CurrentSettings.conf.EnableShadows;
CurrentSettings.conf.ShadowMode--;
if (CurrentSettings.conf.ShadowMode < SHADOW_NONE) CurrentSettings.conf.ShadowMode = SHADOW_ALL;
break;
case 3:
@ -817,7 +824,8 @@ void GuiController::HandleDisplaySettingsInput(bool pause)
case 2:
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
CurrentSettings.conf.EnableShadows = !CurrentSettings.conf.EnableShadows;
CurrentSettings.conf.ShadowMode++;
if (CurrentSettings.conf.ShadowMode > SHADOW_ALL) CurrentSettings.conf.ShadowMode = SHADOW_NONE;
break;
case 3:

View file

@ -410,7 +410,7 @@ void StartTraps()
auto* object = &Objects[ID_DARTS];
if (object->loaded)
{
object->shadowSize = UNIT_SHADOW / 2;
object->castsShadow = true;
//object->drawRoutine = DrawDart;
object->collision = ObjectCollision;
object->control = DartControl;

View file

@ -29,7 +29,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseWolf;
obj->control = WolfControl;
obj->collision = CreatureCollision;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 6;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 375;
@ -49,7 +49,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCreature;
obj->control = BearControl;
obj->collision = CreatureCollision;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 20;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 500;
@ -70,7 +70,7 @@ static void StartEntity(ObjectInfo* obj)
obj->collision = CreatureCollision;
obj->HitPoints = 22;
obj->hitEffect = HIT_BLOOD;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->pivotLength = 250;
obj->radius = 340;
obj->intelligent = true;
@ -87,7 +87,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseBigRat;
obj->control = BigRatControl;
obj->collision = CreatureCollision;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 5;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 200;
@ -109,7 +109,7 @@ static void StartEntity(ObjectInfo* obj)
obj->collision = CreatureCollision;
obj->hitEffect = HIT_BLOOD;
obj->control = NatlaControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 400;
obj->radius = 204;
obj->intelligent = true;
@ -126,7 +126,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCreature;
obj->collision = CreatureCollision;
obj->control = GiantMutantControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 500;
obj->hitEffect = HIT_BLOOD;
obj->radius = 341;
@ -148,7 +148,7 @@ static void StartEntity(ObjectInfo* obj)
obj->collision = CreatureCollision;
obj->control = DoppelgangerControl;
//obj->drawRoutine = DrawEvilLara;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 1000;
obj->hitEffect = HIT_BLOOD;
obj->radius = 102;
@ -164,7 +164,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCreature;
obj->control = CentaurControl;
obj->collision = CreatureCollision;
obj->shadowSize = UNIT_SHADOW / 3;
obj->castsShadow = true;
obj->HitPoints = 120;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 400;

View file

@ -42,7 +42,7 @@ static void StartEntity(ObjectInfo* obj)
{
obj->control = SharkControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 30;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 200;
@ -63,7 +63,7 @@ static void StartEntity(ObjectInfo* obj)
{
obj->control = BarracudaControl;
obj->collision = CreatureCollision;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 12;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 200;
@ -85,7 +85,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseEagle;
obj->control = EagleControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 20;
obj->hitEffect = HIT_BLOOD;
obj->radius = 204;
@ -104,7 +104,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseEagle;
obj->control = EagleControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 15;
obj->hitEffect = HIT_BLOOD;
obj->radius = 204;
@ -124,7 +124,7 @@ static void StartEntity(ObjectInfo* obj)
obj->collision = CreatureCollision;
obj->HitPoints = 5;
obj->hitEffect = HIT_BLOOD;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->pivotLength = 50;
obj->radius = 204;
obj->intelligent = true;
@ -142,7 +142,7 @@ static void StartEntity(ObjectInfo* obj)
obj->control = YetiControl;
obj->HitPoints = 30;
obj->hitEffect = HIT_BLOOD;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->radius = 128;
obj->pivotLength = 100;
obj->intelligent = true;
@ -161,7 +161,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCreature;
obj->collision = CreatureCollision;
obj->control = SilencerControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 25;
obj->hitEffect = HIT_BLOOD;
obj->biteOffset = 0;
@ -192,7 +192,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCreature;
obj->collision = CreatureCollision;
obj->control = SilencerControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 25;
obj->hitEffect = HIT_BLOOD;
obj->biteOffset = 0;
@ -223,7 +223,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCreature;
obj->collision = CreatureCollision;
obj->control = SilencerControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 25;
obj->hitEffect = HIT_BLOOD;
obj->biteOffset = 0;
@ -245,7 +245,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseWorkerShotgun;
obj->collision = CreatureCollision;
obj->control = WorkerShotgunControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 25;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -266,7 +266,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseWorkerMachineGun;
obj->collision = CreatureCollision;
obj->control = WorkerMachineGunControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 20;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -287,7 +287,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCreature;
obj->collision = CreatureCollision;
obj->control = SmallSpiderControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 5;
obj->hitEffect = HIT_SMOKE;
obj->pivotLength = 0;
@ -305,7 +305,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCreature;
obj->collision = CreatureCollision;
obj->control = BigSpiderControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 40;
obj->hitEffect = HIT_SMOKE;
obj->pivotLength = 0;
@ -323,7 +323,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCreature;
obj->collision = CreatureCollision;
obj->control = WorkerDualGunControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 150;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 0;
@ -343,7 +343,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCreature;
obj->collision = CreatureCollision;
obj->control = BirdMonsterControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 200;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 0;
@ -362,7 +362,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseWorkerFlamethrower;
obj->collision = CreatureCollision;
obj->control = WorkerFlamethrower;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 20;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 0;
@ -382,7 +382,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCreature;
obj->collision = CreatureCollision;
obj->control = KnifeThrowerControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 60;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -407,7 +407,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCreature;
obj->collision = CreatureCollision;
obj->control = MercenaryUziControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 45;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 0;
@ -427,7 +427,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCreature;
obj->collision = CreatureCollision;
obj->control = MercenaryAutoPistolControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 50;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 0;
@ -457,7 +457,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCreature;
obj->collision = CreatureCollision;
obj->control = MercenaryAutoPistolControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 50;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 0;
@ -477,7 +477,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCreature;
obj->collision = CreatureCollision;
obj->control = MonkControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 50;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 0;
@ -496,7 +496,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCreature;
obj->collision = CreatureCollision;
obj->control = MonkControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 50;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 0;
@ -516,7 +516,7 @@ static void StartEntity(ObjectInfo* obj)
obj->collision = CreatureCollision;
obj->control = SwordGuardianControl;
//obj->drawRoutine = DrawStatue;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 80;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 0;
@ -539,7 +539,7 @@ static void StartEntity(ObjectInfo* obj)
obj->collision = CreatureCollision;
obj->control = SpearGuardianControl;
//obj->drawRoutine = DrawStatue;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 100;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 0;
@ -603,7 +603,7 @@ static void StartEntity(ObjectInfo* obj)
{
obj->collision = SkidooManCollision;
//obj->drawRoutine = DrawSkidoo; // TODO: recreate renderer for skidoo
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 100;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 0;
@ -669,6 +669,7 @@ static void StartVehicles(ObjectInfo* obj)
obj->saveFlags = true;
obj->savePosition = true;
obj->hitEffect = HIT_RICOCHET;
obj->castsShadow = true;
}
obj = &Objects[ID_SNOWMOBILE];
@ -681,6 +682,7 @@ static void StartVehicles(ObjectInfo* obj)
obj->saveFlags = true;
obj->savePosition = true;
obj->hitEffect = HIT_RICOCHET;
obj->castsShadow = true;
}
}

View file

@ -44,7 +44,7 @@ static void StartEntity(ObjectInfo* obj)
obj->collision = CreatureCollision;
obj->control = TonyControl;
obj->drawRoutine = S_DrawTonyBoss;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 100;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -64,7 +64,7 @@ static void StartEntity(ObjectInfo* obj)
{
obj->control = TigerControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 24;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 200;
@ -83,7 +83,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCobra;
obj->control = CobraControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 8;
obj->hitEffect = HIT_BLOOD;
obj->radius = 102;
@ -103,7 +103,7 @@ static void StartEntity(ObjectInfo* obj)
{
obj->control = RaptorControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 100;
obj->hitEffect = HIT_BLOOD;
obj->radius = 341;
@ -125,7 +125,7 @@ static void StartEntity(ObjectInfo* obj)
{
obj->control = TribemanAxeControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 28;
obj->hitEffect = HIT_BLOOD;
obj->radius = 102;
@ -145,7 +145,7 @@ static void StartEntity(ObjectInfo* obj)
{
obj->control = TribemanDartsControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 28;
obj->hitEffect = HIT_BLOOD;
obj->radius = 102;
@ -167,7 +167,7 @@ static void StartEntity(ObjectInfo* obj)
obj->collision = CreatureCollision;
obj->HitPoints = 800;
obj->hitEffect = HIT_BLOOD;
obj->shadowSize = 64;
obj->castsShadow = true;
obj->pivotLength = 1800;
obj->radius = 512;
obj->intelligent = true;
@ -185,7 +185,7 @@ static void StartEntity(ObjectInfo* obj)
{
obj->control = ScubaControl;
obj->collision = CreatureCollision;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 20;
obj->hitEffect = HIT_BLOOD;
obj->radius = 340;
@ -215,7 +215,7 @@ static void StartEntity(ObjectInfo* obj)
{
obj->control = FlameThrowerControl;
obj->collision = CreatureCollision;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 36;
obj->hitEffect = HIT_BLOOD;
obj->radius = 102;
@ -237,7 +237,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseMonkey;
obj->control = MonkeyControl;
obj->collision = CreatureCollision;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 8;
obj->hitEffect = HIT_BLOOD;
obj->radius = 102;
@ -258,7 +258,7 @@ static void StartEntity(ObjectInfo* obj)
{
obj->control = MPGunControl;
obj->collision = CreatureCollision;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 28;
obj->hitEffect = HIT_BLOOD;
obj->radius = 102;
@ -281,7 +281,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseMPStick;
obj->control = MPStickControl;
obj->collision = CreatureCollision;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 28;
obj->hitEffect = HIT_BLOOD;
obj->radius = 102;
@ -305,7 +305,7 @@ static void StartEntity(ObjectInfo* obj)
obj->collision = CreatureCollision;
obj->control = ShivaControl;
//obj->drawRoutine = DrawStatue;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 100;
obj->hitEffect = HIT_SMOKE;
obj->pivotLength = 0;
@ -326,7 +326,7 @@ static void StartEntity(ObjectInfo* obj)
obj->collision = CreatureCollision;
obj->control = LondonBossControl;
obj->drawRoutine = S_DrawLondonBoss;
obj->shadowSize = 0;
obj->castsShadow = true;
obj->pivotLength = 50;
obj->HitPoints = 300;
obj->hitEffect = HIT_BLOOD;
@ -347,7 +347,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCivvy;
obj->control = CivvyControl;
obj->collision = CreatureCollision;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 15;
obj->hitEffect = HIT_BLOOD;
obj->radius = 102;
@ -393,6 +393,7 @@ static void StartVehicles(ObjectInfo* obj)
obj->savePosition = true;
obj->saveAnim = true;
obj->saveFlags = true;
obj->castsShadow = true;
}
obj = &Objects[ID_RUBBER_BOAT];
@ -406,6 +407,8 @@ static void StartVehicles(ObjectInfo* obj)
obj->savePosition = true;
obj->saveFlags = true;
obj->saveAnim = true;
obj->castsShadow = true;
}
obj = &Objects[ID_KAYAK];
@ -418,6 +421,8 @@ static void StartVehicles(ObjectInfo* obj)
obj->saveAnim = true;
obj->saveFlags = true;
obj->savePosition = true;
obj->castsShadow = true;
}
obj = &Objects[ID_MINECART];
@ -429,6 +434,8 @@ static void StartVehicles(ObjectInfo* obj)
obj->saveAnim = true;
obj->saveFlags = true;
obj->savePosition = true;
obj->castsShadow = true;
}
obj = &Objects[ID_BIGGUN];
@ -454,6 +461,8 @@ static void StartVehicles(ObjectInfo* obj)
obj->saveAnim = true;
obj->saveFlags = true;
obj->savePosition = true;
obj->castsShadow = true;
}
}

View file

@ -86,7 +86,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseSmallScorpion;
obj->control = SmallScorpionControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 8;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 20;
@ -105,7 +105,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseScorpion;
obj->control = ScorpionControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 80;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -124,7 +124,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseHammerhead;
obj->control = HammerheadControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 8;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 20;
@ -144,7 +144,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseWildBoar;
obj->control = WildBoarControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 40;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -168,7 +168,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseTr4Dog;
obj->collision = CreatureCollision;
obj->control = Tr4DogControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 18;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -188,7 +188,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseBat;
obj->control = BatControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 5;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 10;
@ -207,7 +207,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseAhmet;
obj->control = AhmetControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 80;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 300;
@ -229,7 +229,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseBaddy;
obj->control = BaddyControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 25;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -255,7 +255,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseBaddy;
obj->control = BaddyControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 25;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -281,7 +281,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseSas;
obj->control = SasControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 40;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -305,7 +305,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseMummy;
obj->control = MummyControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 15;
obj->hitEffect = HIT_SMOKE;
obj->radius = 170;
@ -330,7 +330,7 @@ static void StartEntity(ObjectInfo* obj)
obj->collision = CreatureCollision;
obj->HitPoints = 15;
obj->hitEffect = HIT_SMOKE;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->pivotLength = 50;
obj->radius = 128;
obj->explodableMeshbits = 0xA00;
@ -349,7 +349,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseKnightTemplar;
obj->control = KnightTemplarControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 15;
obj->hitEffect = HIT_SMOKE;
obj->pivotLength = 50;
@ -371,7 +371,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseBigBeetle;
obj->control = BigBeetleControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 30;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -391,7 +391,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseSetha;
obj->control = SethaControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 500;
obj->hitEffect = HIT_NONE;
obj->pivotLength = 50;
@ -411,7 +411,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseDemigod;
obj->control = DemigodControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 200;
obj->hitEffect = HIT_RICOCHET;
obj->pivotLength = 50;
@ -434,7 +434,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseDemigod;
obj->control = DemigodControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 200;
obj->hitEffect = HIT_RICOCHET;
obj->pivotLength = 50;
@ -455,7 +455,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseDemigod;
obj->control = DemigodControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 200;
obj->hitEffect = HIT_RICOCHET;
obj->pivotLength = 50;
@ -489,7 +489,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseTroops;
obj->control = TroopsControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 40;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -510,7 +510,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseSentryGun;
obj->control = SentryGunControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->undead = true;
obj->HitPoints = 30;
obj->hitEffect = HIT_RICOCHET;
@ -535,7 +535,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseHarpy;
obj->control = HarpyControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 60;
obj->hitEffect = HIT_SMOKE;
obj->pivotLength = 50;
@ -553,7 +553,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseGuide;
obj->control = GuideControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = NOT_TARGETABLE;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 0;
@ -574,7 +574,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCrocodile;
obj->control = CrocodileControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 36;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 300;
@ -598,7 +598,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseSphinx;
obj->control = SphinxControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 1000;
obj->hitEffect = HIT_RICOCHET;
obj->pivotLength = 500;
@ -626,7 +626,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseHorseman;
obj->control = HorsemanControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 25;
obj->hitEffect = HIT_RICOCHET;
obj->pivotLength = 500;
@ -646,7 +646,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseBaboon;
obj->control = BaboonControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 30;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 200;
@ -665,7 +665,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseBaboon;
obj->control = BaboonControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 30;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 200;
@ -687,7 +687,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseBaboon;
obj->control = BaboonControl;
obj->collision = CreatureCollision;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 30;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 200;
@ -709,7 +709,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = TEN::Entities::TR4::InitialiseCrocgod;
obj->control = TEN::Entities::TR4::CrocgodControl;
obj->collision = CreatureCollision;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = NOT_TARGETABLE;
obj->hitEffect = HIT_SMOKE;
obj->pivotLength = 50;
@ -815,7 +815,7 @@ static void StartEntity(ObjectInfo* obj)
obj->intelligent = true;
obj->saveHitpoints = true;
obj->pivotLength = 500;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->radius = 512;
obj->HitPoints = 40;
obj->zoneType = ZONE_BASIC;
@ -833,7 +833,7 @@ static void StartEntity(ObjectInfo* obj)
obj->control = VonCroyControl;
obj->collision = CreatureCollision;
obj->pivotLength = 0;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 15;
obj->explodableMeshbits = 0x200000;
obj->intelligent = true;
@ -1162,7 +1162,7 @@ static void StartTrap(ObjectInfo* obj)
obj->control = LaraDoubleControl;
obj->collision = CreatureCollision;
obj->hitEffect = HIT_SMOKE;
obj->shadowSize = 128;
obj->castsShadow = true;
obj->HitPoints = 1000;
obj->pivotLength = 50;
obj->radius = 128;
@ -1194,6 +1194,8 @@ static void StartVehicles(ObjectInfo* obj)
obj->savePosition = true;
obj->saveAnim = true;
obj->saveFlags = true;
obj->castsShadow = true;
}
obj = &Objects[ID_MOTORBIKE];
@ -1206,6 +1208,8 @@ static void StartVehicles(ObjectInfo* obj)
obj->savePosition = true;
obj->saveAnim = true;
obj->saveFlags = true;
obj->castsShadow = true;
}
}

View file

@ -73,7 +73,7 @@ static void StartEntity(ObjectInfo *obj)
if (obj->loaded)
{
obj->initialise = InitialiseLaraLoad;
obj->shadowSize = 160;
obj->castsShadow = true;
obj->HitPoints = 1000;
obj->drawRoutine = nullptr;
obj->saveAnim = true;
@ -89,7 +89,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseGuard;
obj->control = GuardControl;
obj->collision = CreatureCollision;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 40;
obj->hitEffect = HIT_BLOOD;
obj->radius = 102;
@ -113,7 +113,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseGuard;
obj->collision = CreatureCollision;
obj->control = GuardControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 24;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -141,7 +141,7 @@ static void StartEntity(ObjectInfo *obj)
obj->collision = CreatureCollision;
obj->control = GuardControl;
obj->pivotLength = 50;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 24;
obj->hitEffect = HIT_BLOOD;
obj->radius = 102;
@ -171,7 +171,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseGuard;
obj->collision = CreatureCollision;
obj->control = GuardControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 24;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -201,7 +201,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseGuard;
obj->collision = CreatureCollision;
obj->control = GuardControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 24;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -231,7 +231,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseGuard;
obj->control = GuardControl;
obj->collision = CreatureCollision;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 24;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -261,7 +261,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseGuard;
obj->control = GuardControl;
obj->collision = CreatureCollision;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 24;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -293,7 +293,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseGuard;
obj->control = GuardControl;
obj->collision = CreatureCollision;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 24;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -317,7 +317,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseSubmarine;
obj->collision = CreatureCollision;
obj->control = SubmarineControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 100;
obj->hitEffect = HIT_RICOCHET;
obj->pivotLength = 200;
@ -340,7 +340,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseChef;
obj->control = ControlChef;
obj->collision = CreatureCollision;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 35;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -365,7 +365,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseLion;
obj->collision = CreatureCollision;
obj->control = LionControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 40;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -386,7 +386,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseDoberman;
obj->collision = CreatureCollision;
obj->control = DobermanControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 18;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -406,7 +406,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseTr5Dog;
obj->collision = CreatureCollision;
obj->control = Tr5DogControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 24;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -426,7 +426,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseReaper;
obj->collision = CreatureCollision;
obj->control = ReaperControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 10;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -447,7 +447,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseMafia2;
obj->collision = CreatureCollision;
obj->control = Mafia2Control;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 26;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -474,7 +474,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseLarson;
obj->collision = CreatureCollision;
obj->control = LarsonControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 60;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -498,7 +498,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseLarson;
obj->collision = CreatureCollision;
obj->control = LarsonControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 60;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -522,7 +522,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseCyborg;
obj->collision = CreatureCollision;
obj->control = CyborgControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 50;
obj->hitEffect = HIT_RICOCHET;
obj->pivotLength = 50;
@ -549,7 +549,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseSniper;
obj->collision = CreatureCollision;
obj->control = SniperControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 35;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -573,7 +573,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseGuardLaser;
obj->collision = CreatureCollision;
//obj->control = GuardControlLaser;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 24;
obj->hitEffect = HIT_RICOCHET;
obj->pivotLength = 50;
@ -598,7 +598,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseHydra;
obj->collision = CreatureCollision;
obj->control = HydraControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 30;
obj->hitEffect = HIT_RICOCHET;
obj->pivotLength = 50;
@ -624,7 +624,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseImp;
obj->collision = CreatureCollision;
obj->control = ImpControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 12;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 20;
@ -650,7 +650,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseLightingGuide;
//obj->control = ControlLightingGuide;
obj->drawRoutine = NULL;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->radius = 256;
obj->HitPoints = 16;
obj->pivotLength = 20;
@ -673,7 +673,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseBrownBeast;
obj->collision = CreatureCollision;
obj->control = ControlBrowsBeast;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 100;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 20;
@ -697,7 +697,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseLagoonWitch;
obj->collision = CreatureCollision;
obj->control = LagoonWitchControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 100;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 20;
@ -723,7 +723,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseInvisibleGhost;
obj->collision = CreatureCollision;
obj->control = InvisibleGhostControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 100;
obj->hitEffect = HIT_SMOKE;
obj->pivotLength = 20;
@ -774,7 +774,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseGladiator;
obj->control = ControlGladiator;
obj->collision = CreatureCollision;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 20;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -800,7 +800,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseRomanStatue;
obj->collision = CreatureCollision;
obj->control = RomanStatueControl;
obj->shadowSize = UNIT_SHADOW / 2;
obj->castsShadow = true;
obj->HitPoints = 300;
obj->hitEffect = HIT_SMOKE;
obj->pivotLength = 50;
@ -1116,6 +1116,7 @@ static void StartTrap(ObjectInfo *obj)
obj->hitEffect = HIT_RICOCHET;
obj->savePosition = true;
obj->saveFlags = true;
obj->castShadows = true;
}
obj = &Objects[ID_CLASSIC_ROLLING_BALL];

View file

@ -1,10 +1,16 @@
#pragma once
#include "ShaderLight.h"
struct alignas(16) Sphere
{
Vector3 position;
float radius;
};
struct alignas(16) CShadowLightBuffer
{
ShaderLight Light;
Matrix LightViewProjection;
Matrix LightViewProjections[6];
int CastShadows;
float Padding[15];
int NumSpheres;
int padding[2];
Sphere Spheres[16];
};

View file

@ -22,17 +22,17 @@ namespace TEN::Renderer
//+Y (down)
Vector3(0,1,0),
//+Z (forward)
Vector3(0,0,-1),
//-Z (backward)
Vector3(0,0,1),
//-Z (backward)
Vector3(0,0,-1),
};
static constexpr Vector3 upVectors[6] =
{
Vector3(0,-1,0),
Vector3(0,-1,0),
Vector3(0,0,1),
Vector3(0,0,-1),
Vector3(0,0,1),
Vector3(0,-1,0),
Vector3(0,-1,0),
};

View file

@ -34,6 +34,7 @@
#include "RenderTargetCubeArray/RenderTargetCubeArray.h"
#include "Specific/fast_vector.h"
#include "Renderer/TextureBase.h"
#include "Renderer/Texture2DArray/Texture2DArray.h"
#include "Renderer/ConstantBuffers/PostProcessBuffer.h"
#include "Renderer/Structures/RendererBone.h"
#include "Renderer/Structures/RendererVideoAdapter.h"
@ -262,10 +263,11 @@ namespace TEN::Renderer
RenderTarget2D m_dumpScreenRenderTarget;
RenderTarget2D m_renderTarget;
RenderTarget2D m_currentRenderTarget;
RenderTarget2D m_shadowMap;
RenderTarget2D m_depthMap;
RenderTargetCube m_reflectionCubemap;
Texture2DArray m_shadowMap;
// Shaders
ComPtr<ID3D11VertexShader> m_vsRooms;
ComPtr<ID3D11VertexShader> m_vsRooms_Anim;
@ -343,7 +345,6 @@ namespace TEN::Renderer
Texture2D m_binocularsTexture;
Texture2D m_LasersightTexture;
Texture2D m_whiteTexture;
RenderTargetCubeArray m_shadowMaps;
Texture2D loadingBarBorder;
Texture2D loadingBarInner;
Texture2D loadingScreenTexture;
@ -389,7 +390,6 @@ namespace TEN::Renderer
std::vector<RendererLine3D> m_lines3DToDraw;
std::vector<RendererLine2D> m_lines2DToDraw;
int m_nextSprite;
std::vector<std::optional<RendererObject>> m_moveableObjects;
std::vector<std::optional<RendererObject>> m_staticObjects;
std::vector<RendererSprite> m_sprites;
@ -403,8 +403,6 @@ namespace TEN::Renderer
std::vector<RendererAnimatedTextureSet> m_animatedTextureSets;
int m_numAnimatedTextureSets;
int m_currentCausticsFrame;
RendererUnderwaterDustParticle m_underwaterDustParticles[NUM_UNDERWATER_DUST_PARTICLES];
bool m_firstUnderwaterDustParticles = true;
std::vector<RendererMesh*> m_meshes;
std::vector<TexturePair> m_roomTextures;
std::vector<TexturePair> m_animatedTextures;
@ -444,6 +442,8 @@ namespace TEN::Renderer
bool m_firstWeather;
RendererWeatherParticle m_rain[NUM_RAIN_DROPS];
RendererWeatherParticle m_snow[NUM_SNOW_PARTICLES];
bool m_firstUnderwaterDustParticles = true;
RendererUnderwaterDustParticle m_underwaterDustParticles[NUM_UNDERWATER_DUST_PARTICLES];
// Old fade-in/out
RENDERER_FADE_STATUS m_fadeStatus = NO_FADE;
@ -507,7 +507,8 @@ namespace TEN::Renderer
void DrawBaddyGunflashes(RenderView& view);
void DrawStatics(RenderView& view, bool transparent);
void RenderShadowMap(RenderView& view);
void DrawWraithExtra(RendererItem* item, RenderView& view);
void ClearShadowMap(RenderView& view);
void RenderBlobShadows(RenderView& renderView);
void DrawDarts(RendererItem* item, RenderView& view);
void DrawLara(bool shadowMap, RenderView& view, bool transparent);
void DrawFires(RenderView& view);
@ -534,13 +535,6 @@ namespace TEN::Renderer
bool DrawGunFlashes(RenderView& view);
void DrawGunShells(RenderView& view);
void DrawLocusts(RenderView& view);
void RenderInventoryScene(ID3D11RenderTargetView* target, ID3D11DepthStencilView* depthTarget,
ID3D11ShaderResourceView* background);
void RenderTitleMenu(Menu menu);
void RenderPauseMenu(Menu menu);
void RenderLoadSaveMenu();
void RenderOptionsMenu(Menu menu, int initialY);
void RenderNewInventory();
void DrawStatistics();
void DrawExamines();
void DrawDiary();
@ -560,16 +554,26 @@ namespace TEN::Renderer
void DrawSparkParticles(RenderView& view);
void DrawDripParticles(RenderView& view);
void DrawExplosionParticles(RenderView& view);
void RenderToCubemap(const RenderTargetCube& dest, const Vector3& pos, int roomNumber);
void DrawLaraHolsters(bool transparent);
void DrawMoveableMesh(RendererItem* itemToDraw, RendererMesh* mesh, RendererRoom* room, int boneIndex, bool transparent);
void DrawSimpleParticles(RenderView& view);
void DrawFootprints(RenderView& view);
void DrawLoadingBar(float percent);
void RenderInventoryScene(ID3D11RenderTargetView* target, ID3D11DepthStencilView* depthTarget,
ID3D11ShaderResourceView* background);
void RenderTitleMenu(Menu menu);
void RenderPauseMenu(Menu menu);
void RenderLoadSaveMenu();
void RenderOptionsMenu(Menu menu, int initialY);
void RenderNewInventory();
void RenderToCubemap(const RenderTargetCube& dest, const Vector3& pos, int roomNumber);
void SetBlendMode(BLEND_MODES blendMode, bool force = false);
void SetDepthState(DEPTH_STATES depthState, bool force = false);
void SetCullMode(CULL_MODES cullMode, bool force = false);
void SetAlphaTest(ALPHA_TEST_MODES mode, float threshold, bool force = false);
void SetScissor(RendererRectangle rectangle);
void ResetScissor();
void ResetDebugVariables();
float CalculateFrameRate();
void AddSpriteBillboard(RendererSprite* sprite, Vector3 pos, Vector4 color, float rotation, float scale,
Vector2 size, BLEND_MODES blendMode, RenderView& view);
@ -579,15 +583,13 @@ namespace TEN::Renderer
void AddSpriteBillboardConstrainedLookAt(RendererSprite* sprite, Vector3 pos, Vector4 color, float rotation,
float scale, Vector2 size, BLEND_MODES blendMode, Vector3 lookAtAxis,
RenderView& view);
void addSprite3D(RendererSprite* sprite, Vector3 vtx1, Vector3 vtx2, Vector3 vtx3, Vector3 vtx4, Vector4 color,
void AddSprite3D(RendererSprite* sprite, Vector3 vtx1, Vector3 vtx2, Vector3 vtx3, Vector3 vtx4, Vector4 color,
float rotation, float scale, Vector2 size, BLEND_MODES blendMode, RenderView& view);
short GetRoomNumberForSpriteTest(Vector3 position);
void DoFadingAndCinematicBars(ID3D11RenderTargetView* target, ID3D11DepthStencilView* depthTarget,
RenderView& view);
RendererMesh* GetMesh(int meshIndex);
Texture2D CreateDefaultNormalTexture();
void DrawFootprints(RenderView& view);
void DrawLoadingBar(float percent);
inline void DrawIndexedTriangles(int count, int baseIndex, int baseVertex)
{
@ -677,7 +679,7 @@ namespace TEN::Renderer
void UpdateItemAnimations(int itemNumber, bool force);
void GetLaraAbsBonePosition(Vector3* pos, int joint);
void GetItemAbsBonePosition(int itemNumber, Vector3* pos, int joint);
int getSpheres(short itemNumber, BoundingSphere* ptr, char worldSpace, Matrix local);
int GetSpheres(short itemNumber, BoundingSphere* ptr, char worldSpace, Matrix local);
void GetBoneMatrix(short itemNumber, int joint, Matrix* outMatrix);
void DrawObjectOn2DPosition(short x, short y, short objectNum, short rotX, short rotY, short rotZ,
float scale1);

View file

@ -276,6 +276,7 @@ namespace TEN::Renderer
light->LocalIntensity = 0;
light->Distance = 0;
light->Direction = Vector3(oldLight->dx, oldLight->dy, oldLight->dz);
light->CastShadows = oldLight->castShadows;
light->Type = LIGHT_TYPES::LIGHT_TYPE_SUN;
}
else if (oldLight->type == LIGHT_TYPE_POINT)
@ -287,6 +288,7 @@ namespace TEN::Renderer
light->Distance = 0;
light->In = oldLight->in;
light->Out = oldLight->out;
light->CastShadows = oldLight->castShadows;
light->Type = LIGHT_TYPE_POINT;
}
else if (oldLight->type == LIGHT_TYPE_SHADOW)
@ -312,6 +314,7 @@ namespace TEN::Renderer
light->In = oldLight->in;
light->Out = oldLight->out;
light->Range = oldLight->length;
light->CastShadows = oldLight->castShadows;
light->Type = LIGHT_TYPE_SPOT;
}

View file

@ -3,6 +3,25 @@
namespace TEN::Renderer
{
void Renderer11::ResetDebugVariables()
{
m_timeUpdate = 0;
m_timeDraw = 0;
m_timeFrame = 0;
m_numDrawCalls = 0;
m_numRoomsDrawCalls = 0;
m_numMoveablesDrawCalls = 0;
m_numStaticsDrawCalls = 0;
m_numSpritesDrawCalls = 0;
m_numTransparentDrawCalls = 0;
m_numRoomsTransparentDrawCalls = 0;
m_numMoveablesTransparentDrawCalls = 0;
m_numStaticsTransparentDrawCalls = 0;
m_numSpritesTransparentDrawCalls = 0;
m_biggestRoomIndexBuffer = 0;
m_numPolygons = 0;
}
bool Renderer11::PrintDebugMessage(int x, int y, int alpha, byte r, byte g, byte b, LPCSTR Message)
{
return true;

View file

@ -42,101 +42,179 @@ namespace TEN::Renderer
using namespace TEN::Renderer;
using namespace std::chrono;
void Renderer11::RenderBlobShadows(RenderView& renderView)
{
const std::array<LARA_MESHES, 4> sphereMeshes = { LM_HIPS, LM_TORSO, LM_LFOOT, LM_RFOOT };
const std::array<float, 4> sphereScaleFactors = { 6.0f, 3.2f, 2.8f, 2.8f };
std::vector<Sphere> nearestSpheres;
// Collect Shadow Spheres
nearestSpheres.reserve(g_Configuration.ShadowMaxBlobs);
for (auto i = 0; i < sphereMeshes.size(); i++)
{
auto& newSphere = nearestSpheres.emplace_back();
MESH& m = g_Level.Meshes[Lara.MeshPtrs[sphereMeshes[i]]];
Vector3Int pos = { (int)m.sphere.Center.x, (int)m.sphere.Center.y, (int)m.sphere.Center.z };
if (sphereMeshes[i] == LM_LFOOT || sphereMeshes[i] == LM_RFOOT)
{
// Push feet spheres a little bit down
pos.y += 8;
}
GetLaraJointPosition(&pos, sphereMeshes[i]);
newSphere.position = Vector3(pos.x, pos.y, pos.z);
newSphere.radius = m.sphere.Radius * sphereScaleFactors[i];
}
for (auto& r : renderView.roomsToDraw)
{
for (auto& i : r->ItemsToDraw)
{
auto& nativeItem = g_Level.Items[i->ItemNumber];
//Skip everything thats not "alive" or is not a vehicle
if (!Objects[nativeItem.ObjectNumber].castsShadow)
continue;
auto bb = GetBoundsAccurate(&nativeItem);
Vector3 center = ((Vector3(bb->X1, bb->Y1, bb->Z1) + Vector3(bb->X2, bb->Y2, bb->Z2)) / 2) +
Vector3(nativeItem.Pose.Position.x, nativeItem.Pose.Position.y, nativeItem.Pose.Position.z);
center.y = nativeItem.Pose.Position.y;
float maxExtent = std::max(bb->X2 - bb->X1, bb->Z2 - bb->Z1);
auto& newSphere = nearestSpheres.emplace_back();
newSphere.position = center;
newSphere.radius = maxExtent;
}
}
if (nearestSpheres.size() > g_Configuration.ShadowMaxBlobs)
{
std::sort(nearestSpheres.begin(), nearestSpheres.end(), [](const Sphere& a, const Sphere& b)
{
auto& laraPos = LaraItem->Pose.Position;
auto laraPosition = Vector3(laraPos.x, laraPos.y, laraPos.z);
return Vector3::Distance(laraPosition, a.position) < Vector3::Distance(laraPosition, b.position);
});
std::copy(nearestSpheres.begin(), nearestSpheres.begin() + g_Configuration.ShadowMaxBlobs, m_stShadowMap.Spheres);
m_stShadowMap.NumSpheres = g_Configuration.ShadowMaxBlobs;
}
else
{
std::copy(nearestSpheres.begin(), nearestSpheres.end(), m_stShadowMap.Spheres);
m_stShadowMap.NumSpheres = nearestSpheres.size();
}
}
void Renderer11::ClearShadowMap(RenderView& renderView)
{
for (int step = 0; step < m_shadowMap.RenderTargetView.size(); step++)
{
m_context->ClearRenderTargetView(m_shadowMap.RenderTargetView[step].Get(), Colors::White);
m_context->ClearDepthStencilView(m_shadowMap.DepthStencilView[step].Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL,
1.0f, 0);
}
}
void Renderer11::RenderShadowMap(RenderView& renderView)
{
if (g_Configuration.ShadowMode == SHADOW_NONE)
return;
if (shadowLight == nullptr)
return;
if (shadowLight->Type != LIGHT_TYPE_POINT && shadowLight->Type != LIGHT_TYPE_SPOT)
return;
// Reset GPU state
SetBlendMode(BLENDMODE_OPAQUE);
SetCullMode(CULL_MODE_CCW);
// Bind and clear render target
m_context->ClearRenderTargetView(m_shadowMap.RenderTargetView.Get(), Colors::White);
m_context->ClearDepthStencilView(m_shadowMap.DepthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL,
1.0f, 0);
m_context->OMSetRenderTargets(1, m_shadowMap.RenderTargetView.GetAddressOf(),
m_shadowMap.DepthStencilView.Get());
m_context->RSSetViewports(1, &m_shadowMapViewport);
ResetScissor();
//DrawLara(false, true);
Vector3 lightPos = Vector3(shadowLight->Position.x, shadowLight->Position.y, shadowLight->Position.z);
Vector3 itemPos = Vector3(LaraItem->Pose.Position.x, LaraItem->Pose.Position.y, LaraItem->Pose.Position.z);
if (lightPos == itemPos)
return;
UINT stride = sizeof(RendererVertex);
UINT offset = 0;
// Set shaders
m_context->VSSetShader(m_vsShadowMap.Get(), nullptr, 0);
m_context->PSSetShader(m_psShadowMap.Get(), nullptr, 0);
m_context->IASetVertexBuffers(0, 1, m_moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
m_context->IASetInputLayout(m_inputLayout.Get());
m_context->IASetIndexBuffer(m_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
// Set texture
BindTexture(TEXTURE_COLOR_MAP, &std::get<0>(m_moveablesTextures[0]),
SAMPLER_ANISOTROPIC_CLAMP);
BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_moveablesTextures[0]), SAMPLER_NONE);
// Set camera matrices
Matrix view = Matrix::CreateLookAt(lightPos,
itemPos,
Vector3(0.0f, -1.0f, 0.0f));
Matrix projection = Matrix::CreatePerspectiveFieldOfView(90.0f * RADIAN, 1.0f, 64.0f,
(shadowLight->Type == LIGHT_TYPE_POINT
? shadowLight->Out
: shadowLight->Range) * 1.2f);
CCameraMatrixBuffer shadowProjection;
shadowProjection.ViewProjection = view * projection;
m_cbCameraMatrices.updateData(shadowProjection, m_context.Get());
m_context->VSSetConstantBuffers(0, 1, m_cbCameraMatrices.get());
m_stShadowMap.LightViewProjection = (view * projection);
SetAlphaTest(ALPHA_TEST_GREATER_THAN, ALPHA_TEST_THRESHOLD);
RendererObject& laraObj = *m_moveableObjects[ID_LARA];
RendererObject& laraSkin = *m_moveableObjects[ID_LARA_SKIN];
RendererRoom& room = m_rooms[LaraItem->RoomNumber];
m_stItem.World = m_LaraWorldMatrix;
m_stItem.Position = Vector4(LaraItem->Pose.Position.x, LaraItem->Pose.Position.y, LaraItem->Pose.Position.z, 1.0f);
m_stItem.AmbientLight = room.AmbientLight;
memcpy(m_stItem.BonesMatrices, laraObj.AnimationTransforms.data(), sizeof(Matrix) * 32);
m_cbItem.updateData(m_stItem, m_context.Get());
m_context->VSSetConstantBuffers(1, 1, m_cbItem.get());
m_context->PSSetConstantBuffers(1, 1, m_cbItem.get());
for (int k = 0; k < laraSkin.ObjectMeshes.size(); k++)
int steps = shadowLight->Type == LIGHT_TYPE_POINT ? 6 : 1;
for (int step = 0; step < steps; step++)
{
RendererMesh* mesh = GetMesh(Lara.MeshPtrs[k]);
// Bind render target
m_context->OMSetRenderTargets(1, m_shadowMap.RenderTargetView[step].GetAddressOf(),
m_shadowMap.DepthStencilView[step].Get());
for (auto& bucket : mesh->buckets)
m_context->RSSetViewports(1, &m_shadowMapViewport);
ResetScissor();
//DrawLara(false, true);
Vector3 lightPos = Vector3(shadowLight->Position.x, shadowLight->Position.y, shadowLight->Position.z);
Vector3 itemPos = Vector3(LaraItem->Pose.Position.x, LaraItem->Pose.Position.y, LaraItem->Pose.Position.z);
if (lightPos == itemPos)
return;
UINT stride = sizeof(RendererVertex);
UINT offset = 0;
// Set shaders
m_context->VSSetShader(m_vsShadowMap.Get(), nullptr, 0);
m_context->PSSetShader(m_psShadowMap.Get(), nullptr, 0);
m_context->IASetVertexBuffers(0, 1, m_moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
m_context->IASetInputLayout(m_inputLayout.Get());
m_context->IASetIndexBuffer(m_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
// Set texture
BindTexture(TEXTURE_COLOR_MAP, &std::get<0>(m_moveablesTextures[0]),
SAMPLER_ANISOTROPIC_CLAMP);
BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_moveablesTextures[0]), SAMPLER_NONE);
// Set camera matrices
Matrix view;
Matrix projection;
if (shadowLight->Type == LIGHT_TYPE_POINT)
{
if (bucket.NumVertices == 0 && bucket.BlendMode != 0)
continue;
view = Matrix::CreateLookAt(lightPos, lightPos +
RenderTargetCube::forwardVectors[step]*10240,
RenderTargetCube::upVectors[step]);
// Draw vertices
DrawIndexedTriangles(bucket.NumIndices, bucket.StartIndex, 0);
projection = Matrix::CreatePerspectiveFieldOfView(90.0f, 1.0f, 16.0f,
shadowLight->Out);
m_numMoveablesDrawCalls++;
}
}
if (m_moveableObjects[ID_LARA_SKIN_JOINTS].has_value())
{
RendererObject& laraSkinJoints = *m_moveableObjects[ID_LARA_SKIN_JOINTS];
for (int k = 0; k < laraSkinJoints.ObjectMeshes.size(); k++)
else if(shadowLight->Type == LIGHT_TYPE_SPOT)
{
RendererMesh* mesh = laraSkinJoints.ObjectMeshes[k];
view = Matrix::CreateLookAt(lightPos,
lightPos - shadowLight->Direction*10240,
Vector3(0.0f, -1.0f, 0.0f));
projection = Matrix::CreatePerspectiveFieldOfView(shadowLight->Out, 1.0f, 16.0f,shadowLight->Range);
}
CCameraMatrixBuffer shadowProjection;
shadowProjection.ViewProjection = view * projection;
m_cbCameraMatrices.updateData(shadowProjection, m_context.Get());
m_context->VSSetConstantBuffers(0, 1, m_cbCameraMatrices.get());
m_stShadowMap.LightViewProjections[step] = (view * projection);
SetAlphaTest(ALPHA_TEST_GREATER_THAN, ALPHA_TEST_THRESHOLD);
RendererObject& laraObj = *m_moveableObjects[ID_LARA];
RendererObject& laraSkin = *m_moveableObjects[ID_LARA_SKIN];
RendererRoom& room = m_rooms[LaraItem->RoomNumber];
m_stItem.World = m_LaraWorldMatrix;
m_stItem.Position = Vector4(LaraItem->Pose.Position.x, LaraItem->Pose.Position.y, LaraItem->Pose.Position.z, 1.0f);
m_stItem.AmbientLight = room.AmbientLight;
memcpy(m_stItem.BonesMatrices, laraObj.AnimationTransforms.data(), sizeof(Matrix) * 32);
m_cbItem.updateData(m_stItem, m_context.Get());
m_context->VSSetConstantBuffers(1, 1, m_cbItem.get());
m_context->PSSetConstantBuffers(1, 1, m_cbItem.get());
for (int k = 0; k < laraSkin.ObjectMeshes.size(); k++)
{
RendererMesh* mesh = GetMesh(Lara.MeshPtrs[k]);
for (auto& bucket : mesh->buckets)
{
@ -149,58 +227,80 @@ namespace TEN::Renderer
m_numMoveablesDrawCalls++;
}
}
}
for (int k = 0; k < laraSkin.ObjectMeshes.size(); k++)
{
RendererMesh* mesh = laraSkin.ObjectMeshes[k];
for (auto& bucket : mesh->buckets)
if (m_moveableObjects[ID_LARA_SKIN_JOINTS].has_value())
{
if (bucket.NumVertices == 0 && bucket.BlendMode != 0)
continue;
RendererObject& laraSkinJoints = *m_moveableObjects[ID_LARA_SKIN_JOINTS];
// Draw vertices
DrawIndexedTriangles(bucket.NumIndices, bucket.StartIndex, 0);
for (int k = 0; k < laraSkinJoints.ObjectMeshes.size(); k++)
{
RendererMesh* mesh = laraSkinJoints.ObjectMeshes[k];
m_numMoveablesDrawCalls++;
for (auto& bucket : mesh->buckets)
{
if (bucket.NumVertices == 0 && bucket.BlendMode != 0)
continue;
// Draw vertices
DrawIndexedTriangles(bucket.NumIndices, bucket.StartIndex, 0);
m_numMoveablesDrawCalls++;
}
}
}
}
// Draw items
RendererObject& hairsObj = *m_moveableObjects[ID_LARA_HAIR];
// First matrix is Lara's head matrix, then all 6 hairs matrices. Bones are adjusted at load time for accounting this.
m_stItem.World = Matrix::Identity;
Matrix matrices[7];
matrices[0] = laraObj.AnimationTransforms[LM_HEAD] * m_LaraWorldMatrix;
for (int i = 0; i < hairsObj.BindPoseTransforms.size(); i++)
{
HAIR_STRUCT* hairs = &Hairs[0][i];
Matrix world = Matrix::CreateFromYawPitchRoll(TO_RAD(hairs->pos.Orientation.y), TO_RAD(hairs->pos.Orientation.x), 0) *
Matrix::CreateTranslation(hairs->pos.Position.x, hairs->pos.Position.y, hairs->pos.Position.z);
matrices[i + 1] = world;
}
memcpy(m_stItem.BonesMatrices, matrices, sizeof(Matrix) * 7);
m_cbItem.updateData(m_stItem, m_context.Get());
m_context->VSSetConstantBuffers(1, 1, m_cbItem.get());
m_context->PSSetConstantBuffers(1, 1, m_cbItem.get());
for (int k = 0; k < hairsObj.ObjectMeshes.size(); k++)
{
RendererMesh* mesh = hairsObj.ObjectMeshes[k];
for (auto& bucket : mesh->buckets)
for (int k = 0; k < laraSkin.ObjectMeshes.size(); k++)
{
if (bucket.NumVertices == 0 && bucket.BlendMode != 0)
continue;
RendererMesh* mesh = laraSkin.ObjectMeshes[k];
// Draw vertices
DrawIndexedTriangles(bucket.NumIndices, bucket.StartIndex, 0);
for (auto& bucket : mesh->buckets)
{
if (bucket.NumVertices == 0 && bucket.BlendMode != 0)
continue;
m_numMoveablesDrawCalls++;
// Draw vertices
DrawIndexedTriangles(bucket.NumIndices, bucket.StartIndex, 0);
m_numMoveablesDrawCalls++;
}
}
// Draw items
RendererObject& hairsObj = *m_moveableObjects[ID_LARA_HAIR];
// First matrix is Lara's head matrix, then all 6 hairs matrices. Bones are adjusted at load time for accounting this.
m_stItem.World = Matrix::Identity;
Matrix matrices[7];
matrices[0] = laraObj.AnimationTransforms[LM_HEAD] * m_LaraWorldMatrix;
for (int i = 0; i < hairsObj.BindPoseTransforms.size(); i++)
{
HAIR_STRUCT* hairs = &Hairs[0][i];
Matrix world = Matrix::CreateFromYawPitchRoll(TO_RAD(hairs->pos.Orientation.y), TO_RAD(hairs->pos.Orientation.x), 0) *
Matrix::CreateTranslation(hairs->pos.Position.x, hairs->pos.Position.y, hairs->pos.Position.z);
matrices[i + 1] = world;
}
memcpy(m_stItem.BonesMatrices, matrices, sizeof(Matrix) * 7);
m_cbItem.updateData(m_stItem, m_context.Get());
m_context->VSSetConstantBuffers(1, 1, m_cbItem.get());
m_context->PSSetConstantBuffers(1, 1, m_cbItem.get());
for (int k = 0; k < hairsObj.ObjectMeshes.size(); k++)
{
RendererMesh* mesh = hairsObj.ObjectMeshes[k];
for (auto& bucket : mesh->buckets)
{
if (bucket.NumVertices == 0 && bucket.BlendMode != 0)
continue;
// Draw vertices
DrawIndexedTriangles(bucket.NumIndices, bucket.StartIndex, 0);
m_numMoveablesDrawCalls++;
}
}
}
}
@ -1306,22 +1406,7 @@ namespace TEN::Renderer
void Renderer11::RenderScene(ID3D11RenderTargetView* target, ID3D11DepthStencilView* depthTarget, RenderView& view)
{
m_timeUpdate = 0;
m_timeDraw = 0;
m_timeFrame = 0;
m_numDrawCalls = 0;
m_numRoomsDrawCalls = 0;
m_numMoveablesDrawCalls = 0;
m_numStaticsDrawCalls = 0;
m_numSpritesDrawCalls = 0;
m_numTransparentDrawCalls = 0;
m_nextSprite = 0;
m_numRoomsTransparentDrawCalls = 0;
m_numMoveablesTransparentDrawCalls = 0;
m_numStaticsTransparentDrawCalls = 0;
m_numSpritesTransparentDrawCalls = 0;
m_biggestRoomIndexBuffer = 0;
m_numPolygons = 0;
ResetDebugVariables();
using ns = std::chrono::nanoseconds;
using get_time = std::chrono::steady_clock;
@ -1339,10 +1424,12 @@ namespace TEN::Renderer
m_stAlphaTest.AlphaTest = -1;
m_stAlphaTest.AlphaThreshold = -1;
m_stShadowMap.NumSpheres = 0;
// Prepare the shadow map
if (g_Configuration.EnableShadows)
RenderShadowMap(view);
ClearShadowMap(view);
RenderShadowMap(view);
RenderBlobShadows(view);
// Setup Lara item
m_items[Lara.ItemNumber].ItemNumber = Lara.ItemNumber;
@ -1556,12 +1643,6 @@ namespace TEN::Renderer
// We'll draw waterfalls later
continue;
}
else if (objectNumber >= ID_WRAITH1 && objectNumber <= ID_WRAITH3)
{
// Wraiths have some additional special effects
DrawAnimatingItem(itemToDraw, view, transparent);
DrawWraithExtra(itemToDraw, view);
}
else if (objectNumber == ID_DARTS)
{
//TODO: for now legacy way, in the future mesh
@ -1705,46 +1786,6 @@ namespace TEN::Renderer
AddLine3D(start, end, Vector4(30 / 255.0f, 30 / 255.0f, 30 / 255.0f, 0.5f));
}
void Renderer11::DrawWraithExtra(RendererItem* item, RenderView& view)
{
ItemInfo* nativeItem = &g_Level.Items[item->ItemNumber];
WraithInfo* info = (WraithInfo*)nativeItem->Data;
for (int j = 0; j <= 4; j++)
{
Matrix rotation;
switch (j)
{
case 0:
rotation = Matrix::CreateRotationY(TO_RAD(-1092));
break;
case 1:
rotation = Matrix::CreateRotationY(TO_RAD(1092));
break;
case 2:
rotation = Matrix::CreateRotationZ(TO_RAD(-1092));
break;
case 3:
rotation = Matrix::CreateRotationZ(TO_RAD(1092));
break;
default:
rotation = Matrix::Identity;
break;
}
Matrix world = rotation * item->World;
for (int i = 0; i < 7; i++)
{
Vector3 p1 = Vector3(info[i].Position.x, info[i].Position.y, info[i].Position.z);
Vector3 p2 = Vector3(info[i + 1].Position.x, info[i + 1].Position.y, info[i + 1].Position.z);
AddLine3D(p1, p2, Vector4(info[i].r / 255.0f, info[i].g / 255.0f, info[i].b / 255.0f, 1.0f));
}
}
}
void Renderer11::DrawStatics(RenderView& view, bool transparent)
{
// Bind vertex and index buffer
@ -1894,16 +1935,17 @@ namespace TEN::Renderer
{
m_stShadowMap.CastShadows = false;
}
m_cbShadowMap.updateData(m_stShadowMap, m_context.Get());
BindConstantBufferVS(CB_SHADOW_LIGHT, m_cbShadowMap.get());
BindConstantBufferPS(CB_SHADOW_LIGHT, m_cbShadowMap.get());
numRoomsTransparentPolygons = 0;
for (int i = view.roomsToDraw.size() - 1; i >= 0; i--)
{
int index = i;
RendererRoom* room = view.roomsToDraw[index];
m_cbShadowMap.updateData(m_stShadowMap, m_context.Get());
BindConstantBufferPS(CB_SHADOW_LIGHT, m_cbShadowMap.get());
BindConstantBufferVS(CB_SHADOW_LIGHT, m_cbShadowMap.get());
ROOM_INFO* nativeRoom = &g_Level.Rooms[room->RoomNumber];
Vector3 cameraPosition = Vector3(Camera.pos.x, Camera.pos.y, Camera.pos.z);

View file

@ -347,7 +347,7 @@ namespace TEN::Renderer
x2Outer += splash.x;
z2Outer = outerRadius * cos(alpha * j * PI / 180);
z2Outer += splash.z;
addSprite3D(&m_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + splash.spriteSequenceStart + (int)splash.animationPhase],
AddSprite3D(&m_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + splash.spriteSequenceStart + (int)splash.animationPhase],
Vector3(xOuter, yOuter, zOuter),
Vector3(x2Outer, yOuter, z2Outer),
Vector3(x2Inner, yInner, z2Inner),
@ -511,7 +511,7 @@ namespace TEN::Renderer
p2 = Vector3::Transform(p2, rotationMatrix);
p3 = Vector3::Transform(p3, rotationMatrix);
addSprite3D(&m_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_SPLASH],
AddSprite3D(&m_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_SPLASH],
pos + p1,
pos + p2,
pos + p3,
@ -797,7 +797,7 @@ namespace TEN::Renderer
auto spriteIndex = Objects[ID_MISC_SPRITES].meshIndex + 1 + (int)footprint.RightFoot;
if (footprint.Active && g_Level.Sprites.size() > spriteIndex)
addSprite3D(&m_sprites[spriteIndex],
AddSprite3D(&m_sprites[spriteIndex],
footprint.Position[0], footprint.Position[1], footprint.Position[2], footprint.Position[3],
Vector4(footprint.Opacity), 0, 1, { 1,1 }, BLENDMODE_SUBTRACTIVE, view);
}

View file

@ -98,6 +98,9 @@ namespace TEN::Renderer
auto screenResolution = g_Configuration.SupportedScreenResolutions[g_Gui.GetCurrentSettings().selectedScreenResolution];
sprintf(stringBuffer, "%d x %d", screenResolution.x, screenResolution.y);
auto* shadowMode = g_Gui.GetCurrentSettings().conf.ShadowMode ?
(g_Gui.GetCurrentSettings().conf.ShadowMode == SHADOW_LARA ? STRING_SHADOWS_PLAYER : STRING_SHADOWS_ALL) : STRING_SHADOWS_NONE;
switch (menu)
{
case Menu::Options:
@ -138,7 +141,7 @@ namespace TEN::Renderer
// Enable dynamic shadows
DrawString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_SHADOWS), PRINTSTRING_COLOR_ORANGE, SF(title_option == 2));
DrawString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().conf.EnableShadows), PRINTSTRING_COLOR_WHITE, SF(title_option == 2));
DrawString(MenuRightSideEntry, y, g_GameFlow->GetString(shadowMode), PRINTSTRING_COLOR_WHITE, SF(title_option == 2));
GetNextLinePosition(&y);
// Enable caustics
@ -885,6 +888,9 @@ namespace TEN::Renderer
PrintDebugMessage("Biggest room's index buffer: %d", m_biggestRoomIndexBuffer);
PrintDebugMessage("Total rooms transparent polygons: %d", numRoomsTransparentPolygons);
PrintDebugMessage("Rooms: %d", view.roomsToDraw.size());
m_spriteBatch->Begin();
m_spriteBatch->Draw(m_shadowMap.ShaderResourceView.Get(), Vector2(512, 0), Colors::White);
m_spriteBatch->End();
break;
case RENDERER_DEBUG_PAGE::DIMENSION_STATS:

View file

@ -61,6 +61,13 @@ enum CULL_MODES
CULL_MODE_UNSET = -1
};
enum SHADOW_MODES
{
SHADOW_NONE,
SHADOW_LARA,
SHADOW_ALL
};
enum DEPTH_STATES
{
DEPTH_STATE_WRITE_ZBUFFER = 0,

View file

@ -427,7 +427,7 @@ namespace TEN::Renderer
int numLights = room.Lights.size();
shadowLight = NULL;
shadowLight = nullptr;
RendererLight* brightestLight = NULL;
float brightest = 0.0f;
@ -455,7 +455,7 @@ namespace TEN::Renderer
continue;
// If Lara, try to collect shadow casting light
if (effect->Effect->objectNumber == ID_LARA)
if (light->CastShadows && effect->Effect->objectNumber == ID_LARA)
{
float attenuation = 1.0f - distance / light->Out;
float intensity = std::max(0.0f, attenuation * (light->Color.x + light->Color.y + light->Color.z) / 3.0f);
@ -612,9 +612,10 @@ namespace TEN::Renderer
float intensity = std::max(0.0f, attenuation * (light->Color.x + light->Color.y + light->Color.z) / 3.0f);
light->LocalIntensity = intensity;
light->Distance = distance;
// If Lara, try to collect shadow casting light
if (nativeItem->ObjectNumber == ID_LARA && light->Type == LIGHT_TYPE_POINT)
if (light->CastShadows && nativeItem->ObjectNumber == ID_LARA && light->Type == LIGHT_TYPE_POINT)
{
if (intensity >= brightest)
{
@ -622,8 +623,6 @@ namespace TEN::Renderer
brightestLight = light;
}
}
light->Distance = distance;
}
else if (light->Type == LIGHT_TYPE_SPOT)
{
@ -645,7 +644,7 @@ namespace TEN::Renderer
light->LocalIntensity = intensity;
// If Lara, try to collect shadow casting light
if (nativeItem->ObjectNumber == ID_LARA)
if (light->CastShadows && nativeItem->ObjectNumber == ID_LARA)
{
if (intensity >= brightest)
{

View file

@ -456,7 +456,7 @@ namespace TEN::Renderer
*pos = Vector3::Transform(*pos, world);
}
int Renderer11::getSpheres(short itemNumber, BoundingSphere *spheres, char worldSpace, Matrix local)
int Renderer11::GetSpheres(short itemNumber, BoundingSphere *spheres, char worldSpace, Matrix local)
{
RendererItem* itemToDraw = &m_items[itemNumber];
ItemInfo* nativeItem = &g_Level.Items[itemNumber];

View file

@ -38,7 +38,6 @@ void TEN::Renderer::Renderer11::Initialise(int w, int h, bool windowed, HWND han
auto logoName = L"Textures/Logo.png";
SetTextureOrDefault(m_logo, logoName);
m_shadowMaps = RenderTargetCubeArray(m_device.Get(), g_Configuration.ShadowMapSize, MAX_DYNAMIC_SHADOWS, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_D16_UNORM);
// Load shaders
ComPtr<ID3D10Blob> blob;
std::string shadowSizeString = std::to_string(g_Configuration.ShadowMapSize);
@ -64,7 +63,7 @@ void TEN::Renderer::Renderer11::Initialise(int w, int h, bool windowed, HWND han
Utils::throwIfFailed(m_device->CreateInputLayout(inputLayout, 11, blob->GetBufferPointer(), blob->GetBufferSize(), &m_inputLayout));
m_vsRooms_Anim = Utils::compileVertexShader(m_device.Get(), L"Shaders\\DX11_Rooms.fx", "VS", "vs_4_0", &roomDefinesAnimated[0], blob);
m_psRooms = Utils::compilePixelShader(m_device.Get(), L"Shaders\\DX11_Rooms.fx", "PS", "ps_4_0", &roomDefines[0], blob);
m_psRooms = Utils::compilePixelShader(m_device.Get(), L"Shaders\\DX11_Rooms.fx", "PS", "ps_4_1", &roomDefines[0], blob);
m_vsItems = Utils::compileVertexShader(m_device.Get(), L"Shaders\\DX11_Items.fx", "VS", "vs_4_0", nullptr, blob);
m_psItems = Utils::compilePixelShader(m_device.Get(), L"Shaders\\DX11_Items.fx", "PS", "ps_4_0", nullptr, blob);
m_vsStatics = Utils::compileVertexShader(m_device.Get(), L"Shaders\\DX11_Statics.fx", "VS", "vs_4_0", nullptr, blob);
@ -90,7 +89,7 @@ void TEN::Renderer::Renderer11::Initialise(int w, int h, bool windowed, HWND han
m_vsFinalPass = Utils::compileVertexShader(m_device.Get(), L"Shaders\\DX11_FinalPass.fx", "VS", "vs_4_0", nullptr, blob);
m_psFinalPass = Utils::compilePixelShader(m_device.Get(), L"Shaders\\DX11_FinalPass.fx", "PS", "ps_4_0", nullptr, blob);
m_shadowMap = RenderTarget2D(m_device.Get(), g_Configuration.ShadowMapSize, g_Configuration.ShadowMapSize, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_D16_UNORM);
m_shadowMap = Texture2DArray(m_device.Get(), g_Configuration.ShadowMapSize, 6, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_D16_UNORM);
m_depthMap = RenderTarget2D(m_device.Get(), w, h, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_D16_UNORM);
// Initialise constant buffers

View file

@ -303,8 +303,10 @@ void TEN::Renderer::Renderer11::DrawLara(bool shadowMap, RenderView& view, bool
for (int k = 0; k < laraSkin.ObjectMeshes.size(); k++)
{
RendererMesh *mesh = GetMesh(Lara.MeshPtrs[k]);
DrawMoveableMesh(item, mesh, room, k, transparent);
}
DrawLaraHolsters(transparent);

View file

@ -90,7 +90,7 @@ namespace TEN::Renderer
}
void Renderer11::addSprite3D(RendererSprite* sprite, Vector3 vtx1, Vector3 vtx2, Vector3 vtx3, Vector3 vtx4, Vector4 color, float rotation, float scale, Vector2 size, BLEND_MODES blendMode, RenderView& view)
void Renderer11::AddSprite3D(RendererSprite* sprite, Vector3 vtx1, Vector3 vtx2, Vector3 vtx3, Vector3 vtx4, Vector4 color, float rotation, float scale, Vector2 size, BLEND_MODES blendMode, RenderView& view)
{
if (scale <= 0.0f)
scale = 1.0f;

View file

@ -16,5 +16,6 @@ namespace TEN::Renderer
float Out;
float Range;
bool AffectNeighbourRooms;
bool CastShadows;
};
}

View file

@ -0,0 +1,79 @@
#include "framework.h"
#include "Texture2DArray.h"
#include "Utils.h"
using TEN::Renderer::Utils::throwIfFailed;
TEN::Renderer::Texture2DArray::Texture2DArray(ID3D11Device* device, int resolution,int count, DXGI_FORMAT colorFormat, DXGI_FORMAT depthFormat) : resolution(resolution)
{
DepthStencilView.resize(count);
RenderTargetView.resize(count);
D3D11_TEXTURE2D_DESC desc = {};
desc.Width = resolution;
desc.Height = resolution;
desc.MipLevels = 1;
desc.ArraySize = count;
desc.Format = colorFormat;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0x0;
HRESULT res = device->CreateTexture2D(&desc, NULL, Texture.GetAddressOf());
throwIfFailed(res);
D3D11_RENDER_TARGET_VIEW_DESC viewDesc = {};
viewDesc.Format = desc.Format;
viewDesc.Texture2DArray.ArraySize = 1;
viewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
for (int i = 0; i < 6; i++)
{
viewDesc.Texture2DArray.FirstArraySlice = D3D11CalcSubresource(0, i, 1);
res = device->CreateRenderTargetView(Texture.Get(), &viewDesc, RenderTargetView[i].GetAddressOf());
throwIfFailed(res);
}
// Setup the description of the shader resource view.
D3D11_SHADER_RESOURCE_VIEW_DESC shaderDesc = {};
shaderDesc.Format = desc.Format;
shaderDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
shaderDesc.Texture2DArray.MostDetailedMip = 0;
shaderDesc.Texture2DArray.MipLevels = 1;
shaderDesc.Texture2DArray.ArraySize = count;
shaderDesc.Texture2DArray.FirstArraySlice = 0;
res = device->CreateShaderResourceView(Texture.Get(), &shaderDesc, ShaderResourceView.GetAddressOf());
throwIfFailed(res);
D3D11_TEXTURE2D_DESC depthTexDesc = {};
depthTexDesc.Width = resolution;
depthTexDesc.Height = resolution;
depthTexDesc.MipLevels = 1;
depthTexDesc.ArraySize = count;
depthTexDesc.SampleDesc.Count = 1;
depthTexDesc.SampleDesc.Quality = 0;
depthTexDesc.Format = depthFormat;
depthTexDesc.Usage = D3D11_USAGE_DEFAULT;
depthTexDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
depthTexDesc.CPUAccessFlags = 0;
depthTexDesc.MiscFlags = 0x0;
res = device->CreateTexture2D(&depthTexDesc, NULL, DepthStencilTexture.GetAddressOf());
throwIfFailed(res);
D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc = {};
dsvDesc.Format = depthTexDesc.Format;
dsvDesc.Flags = 0;
dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
dsvDesc.Texture2DArray.ArraySize = 1;
for (int i = 0; i < count; i++)
{
dsvDesc.Texture2DArray.FirstArraySlice = D3D11CalcSubresource(0, i, 1);
res = device->CreateDepthStencilView(DepthStencilTexture.Get(), &dsvDesc, DepthStencilView[i].GetAddressOf());
throwIfFailed(res);
}
}

View file

@ -0,0 +1,25 @@
#pragma once
#include <wrl/client.h>
#include <d3d11.h>
#include "Renderer/TextureBase.h"
#include <vector>
namespace TEN::Renderer
{
using Microsoft::WRL::ComPtr;
class Texture2DArray : public TextureBase
{
public:
std::vector<ComPtr<ID3D11RenderTargetView>> RenderTargetView;
ComPtr<ID3D11Texture2D> Texture;
std::vector<ComPtr<ID3D11DepthStencilView>> DepthStencilView;
ComPtr<ID3D11Texture2D> DepthStencilTexture;
int resolution;
D3D11_VIEWPORT viewport;
Texture2DArray() : resolution(0), viewport({}) {};
Texture2DArray(ID3D11Device* device, int resolution,int count, DXGI_FORMAT format, DXGI_FORMAT depthFormat = DXGI_FORMAT_D32_FLOAT);
};
}

Binary file not shown.

View file

@ -63,6 +63,9 @@
#define STRING_SFX_VOLUME "sfx_volume"
#define STRING_SCREEN_RESOLUTION "screen_resolution"
#define STRING_SHADOWS "shadows"
#define STRING_SHADOWS_PLAYER "player"
#define STRING_SHADOWS_ALL "all"
#define STRING_SHADOWS_NONE "none"
#define STRING_CAUSTICS "caustics"
#define STRING_VOLUMETRIC_FOG "volumetric_fog"
#define STRING_APPLY "apply"

View file

@ -3,6 +3,8 @@
#include "./Math.hlsli"
#include "./ShaderLight.hlsli"
#include "./AlphaTestBuffer.hlsli"
#define SHADOW_INTENSITY (0.55f)
#define INV_SHADOW_INTENSITY (1.0f-SHADOW_INTENSITY)
cbuffer LightsBuffer : register(b2)
{
@ -11,17 +13,26 @@ cbuffer LightsBuffer : register(b2)
float3 Padding;
};
struct Sphere
{
float3 position;
float radius;
};
cbuffer MiscBuffer : register(b3)
{
int Caustics;
};
cbuffer ShadowLightBuffer : register(b4)
{
ShaderLight Light;
float4x4 LightViewProjection;
float4x4 LightViewProjections[6];
int CastShadows;
float3 Padding2;
int NumSpheres;
int2 padding;
Sphere Spheres[16];
};
cbuffer RoomBuffer : register(b5)
@ -51,7 +62,6 @@ struct PixelShaderInput
float3 Normal: NORMAL;
float2 UV: TEXCOORD0;
float4 Color: COLOR;
float4 LightPosition: POSITION1;
float3x3 TBN : TBN;
float Fog : FOG;
float4 PositionCopy : TEXCOORD1;
@ -64,17 +74,9 @@ Texture2D NormalTexture : register(t1);
Texture2D CausticsTexture : register(t2);
Texture2D ShadowMap : register(t3);
Texture2DArray ShadowMap : register(t3);
SamplerComparisonState ShadowMapSampler : register(s3);
float hash(float3 n)
{
float x = n.x;
float y = n.y;
float z = n.z;
return float((frac(sin(x)) * 7385.6093) + (frac(cos(y)) * 1934.9663) - (frac(sin(z)) * 8349.2791));
}
struct PixelShaderOutput
{
float4 Color: SV_Target0;
@ -147,7 +149,6 @@ PixelShaderInput VS(VertexShaderInput input)
output.WorldPosition = input.Position.xyz;
output.LightPosition = mul(float4(input.Position, 1.0f), LightViewProjection);
float3x3 TBN = float3x3(input.Tangent, input.Bitangent, input.Normal);
output.TBN = TBN;
@ -164,7 +165,160 @@ PixelShaderInput VS(VertexShaderInput input)
float2 texOffset(int u, int v) {
return float2(u * 1.0f / SHADOW_MAP_SIZE, v * 1.0f / SHADOW_MAP_SIZE);
}
//https://gist.github.com/JuanDiegoMontoya/d8788148dcb9780848ce8bf50f89b7bb
int GetCubeFaceIndex(float3 dir)
{
float x = abs(dir.x);
float y = abs(dir.y);
float z = abs(dir.z);
if (x > y && x > z)
return 0 + (dir.x > 0 ? 0 : 1);
else if (y > z)
return 2 + (dir.y > 0 ? 0 : 1);
return 4 + (dir.z > 0 ? 0 : 1);
}
float2 GetCubeUVFromDir(int faceIndex, float3 dir)
{
float2 uv;
switch (faceIndex)
{
case 0:
uv = float2(-dir.z, dir.y);
break; // +X
case 1:
uv = float2(dir.z, dir.y);
break; // -X
case 2:
uv = float2(dir.x, dir.z);
break; // +Y
case 3:
uv = float2(dir.x, -dir.z);
break; // -Y
case 4:
uv = float2(dir.x, dir.y);
break; // +Z
default:
uv = float2(-dir.x, dir.y);
break; // -Z
}
return uv * .5 + .5;
}
void doPointLightShadow(float3 worldPos, inout float3 lighting)
{
float shadowFactor = 1.0f;
for (int i = 0; i < 6; i++)
{
float3 dir = normalize(worldPos - Light.Position);
int face = GetCubeFaceIndex(dir);
//debug coloring
/*
switch (face)
{
case 0:
lighting += float3(0.2, 0, 0);
break;
case 1:
lighting += float3(0.1, 0, 0);
break;
case 2:
lighting += float3(0, 0.2, 0);
break;
case 3:
lighting += float3(0, 0.1, 0);
break;
case 4:
lighting += float3(0, 0, 0.2);
break;
default:
lighting += float3(0, 0, 0.1);
break;
}
*/
float2 uv = GetCubeUVFromDir(face, dir);
float4 lightClipSpace = mul(float4(worldPos, 1.0f), LightViewProjections[i]);
lightClipSpace.xyz /= lightClipSpace.w;
if (lightClipSpace.x >= -1.0f && lightClipSpace.x <= 1.0f &&
lightClipSpace.y >= -1.0f && lightClipSpace.y <= 1.0f &&
lightClipSpace.z >= 0.0f && lightClipSpace.z <= 1.0f)
{
lightClipSpace.x = lightClipSpace.x / 2 + 0.5;
lightClipSpace.y = lightClipSpace.y / -2 + 0.5;
float sum = 0;
float x, y;
//perform PCF filtering on a 4 x 4 texel neighborhood
// what about borders of cubemap?
for (y = -1.5; y <= 1.5; y += 1.0)
{
for (x = -1.5; x <= 1.5; x += 1.0)
{
sum += ShadowMap.SampleCmpLevelZero(ShadowMapSampler, float3(lightClipSpace.xy + texOffset(x, y), i), lightClipSpace.z);
}
}
shadowFactor = sum / 16.0;
}
}
float distanceFactor = saturate(((distance(worldPos, Light.Position) ) / (Light.Out)));
lighting *= saturate((shadowFactor + SHADOW_INTENSITY) + (pow(distanceFactor, 4) * INV_SHADOW_INTENSITY));
}
void doBlobShadows(float3 worldPos, inout float3 lighting)
{
float shadowFactor = 1.0f;
for (int i = 0; i < NumSpheres; i++)
{
Sphere s = Spheres[i];
float dist = distance(worldPos, s.position);
if (dist > s.radius)
continue;
float radiusFactor = dist / s.radius;
float factor = 1 - (saturate(radiusFactor));
shadowFactor -= factor*shadowFactor;
}
shadowFactor = saturate(shadowFactor);
lighting *= saturate((shadowFactor+SHADOW_INTENSITY));
}
void doSpotLightShadow(float3 worldPos,inout float3 lighting)
{
float4 lightClipSpace = mul(float4(worldPos, 1.0f), LightViewProjections[0]);
lightClipSpace.xyz /= lightClipSpace.w;
float shadowFactor = 1.0f;
if (lightClipSpace.x >= -1.0f && lightClipSpace.x <= 1.0f &&
lightClipSpace.y >= -1.0f && lightClipSpace.y <= 1.0f &&
lightClipSpace.z >= 0.0f && lightClipSpace.z <= 1.0f)
{
lightClipSpace.x = lightClipSpace.x / 2 + 0.5;
lightClipSpace.y = lightClipSpace.y / -2 + 0.5;
float sum = 0;
float x, y;
//perform PCF filtering on a 4 x 4 texel neighborhood
for (y = -1.5; y <= 1.5; y += 1.0)
{
for (x = -1.5; x <= 1.5; x += 1.0)
{
sum += ShadowMap.SampleCmpLevelZero(ShadowMapSampler, float3(lightClipSpace.xy + texOffset(x, y),0), lightClipSpace.z);
}
}
shadowFactor = sum / 16.0;
}
float distanceFactor = saturate(((distance(worldPos, Light.Position)) / (Light.Out)));
//Fade out at the borders of the sampled texture
float angleFactor = min(max(sin(lightClipSpace.x * PI)*1.2, 0), 1);
lighting *= saturate((shadowFactor + SHADOW_INTENSITY) + (pow(distanceFactor, 4) * (1 - angleFactor) * INV_SHADOW_INTENSITY));
}
PixelShaderOutput PS(PixelShaderInput input) : SV_TARGET
{
PixelShaderOutput output;
@ -182,30 +336,19 @@ PixelShaderOutput PS(PixelShaderInput input) : SV_TARGET
if (CastShadows)
{
// Transform clip space coords to texture space coords (-1:1 to 0:1)
input.LightPosition.xyz /= input.LightPosition.w;
if (Light.Type == LT_POINT)
{
doPointLightShadow(input.WorldPosition,lighting);
if (input.LightPosition.x >= -1.0f && input.LightPosition.x <= 1.0f &&
input.LightPosition.y >= -1.0f && input.LightPosition.y <= 1.0f &&
input.LightPosition.z >= 0.0f && input.LightPosition.z <= 1.0f)
{
input.LightPosition.x = input.LightPosition.x / 2 + 0.5;
input.LightPosition.y = input.LightPosition.y / -2 + 0.5;
}
else if (Light.Type == LT_SPOT)
{
doSpotLightShadow(input.WorldPosition,lighting);
//PCF sampling for shadow map
float sum = 0;
float x, y;
//perform PCF filtering on a 4 x 4 texel neighborhood
for (y = -1.5; y <= 1.5; y += 1.0) {
for (x = -1.5; x <= 1.5; x += 1.0) {
sum += ShadowMap.SampleCmpLevelZero(ShadowMapSampler, input.LightPosition.xy + texOffset(x, y), input.LightPosition.z);
}
}
float shadowFactor = sum / 16.0;
lighting *= (saturate(shadowFactor + 0.75));
}
}
}
doBlobShadows(input.WorldPosition, lighting);
if (doLights)
{

View file

@ -92,7 +92,7 @@ BOOL CALLBACK DialogProc(HWND handle, UINT msg, WPARAM wParam, LPARAM lParam)
g_Configuration.EnableVolumetricFog = true;
SendDlgItemMessage(handle, IDC_VOLUMETRIC_FOG, BM_SETCHECK, 1, 0);
g_Configuration.EnableShadows = true;
g_Configuration.ShadowMode = SHADOW_LARA;
SendDlgItemMessage(handle, IDC_SHADOWS, BM_SETCHECK, 1, 0);
g_Configuration.EnableCaustics = true;
@ -117,7 +117,7 @@ BOOL CALLBACK DialogProc(HWND handle, UINT msg, WPARAM wParam, LPARAM lParam)
case IDOK:
// Get values from dialog components
g_Configuration.Windowed = (SendDlgItemMessage(handle, IDC_WINDOWED, BM_GETCHECK, 0, 0));
g_Configuration.EnableShadows = (SendDlgItemMessage(handle, IDC_SHADOWS, BM_GETCHECK, 0, 0));
g_Configuration.ShadowMode = (int)(SendDlgItemMessage(handle, IDC_SHADOWS, BM_GETCHECK, 0, 0));
g_Configuration.EnableCaustics = (SendDlgItemMessage(handle, IDC_CAUSTICS, BM_GETCHECK, 0, 0));
g_Configuration.EnableVolumetricFog = (SendDlgItemMessage(handle, IDC_VOLUMETRIC_FOG, BM_GETCHECK, 0, 0));
g_Configuration.EnableSound = (SendDlgItemMessage(handle, IDC_ENABLE_SOUNDS, BM_GETCHECK, 0, 0));
@ -190,7 +190,18 @@ bool SaveConfiguration()
return false;
}
if (SetBoolRegKey(rootKey, REGKEY_SHADOWS, g_Configuration.EnableShadows) != ERROR_SUCCESS)
if (SetDWORDRegKey(rootKey, REGKEY_SHADOWS, g_Configuration.ShadowMode) != ERROR_SUCCESS)
{
RegCloseKey(rootKey);
return false;
}
if (SetDWORDRegKey(rootKey, REGKEY_SHADOW_MAP, g_Configuration.ShadowMapSize) != ERROR_SUCCESS) {
RegCloseKey(rootKey);
return false;
}
if (SetDWORDRegKey(rootKey, REGKEY_SHADOW_BLOBS, g_Configuration.ShadowMaxBlobs) != ERROR_SUCCESS)
{
RegCloseKey(rootKey);
return false;
@ -208,11 +219,6 @@ bool SaveConfiguration()
return false;
}
if (SetDWORDRegKey(rootKey, REGKEY_SHADOW_MAP, g_Configuration.ShadowMapSize) != ERROR_SUCCESS) {
RegCloseKey(rootKey);
return false;
}
if (SetBoolRegKey(rootKey, REGKEY_ENABLE_SOUND, g_Configuration.EnableSound) != ERROR_SUCCESS)
{
RegCloseKey(rootKey);
@ -294,7 +300,7 @@ void InitDefaultConfiguration()
g_Configuration.SoundDevice = 1;
g_Configuration.EnableReverb = true;
g_Configuration.EnableCaustics = true;
g_Configuration.EnableShadows = true;
g_Configuration.ShadowMode = SHADOW_LARA;
g_Configuration.EnableSound = true;
g_Configuration.EnableVolumetricFog = true;
g_Configuration.MusicVolume = 100;
@ -349,8 +355,8 @@ bool LoadConfiguration()
return false;
}
bool shadows = false;
if (GetBoolRegKey(rootKey, REGKEY_SHADOWS, &shadows, true) != ERROR_SUCCESS)
DWORD shadowMode = 1;
if (GetDWORDRegKey(rootKey, REGKEY_SHADOWS, &shadowMode, 1) != ERROR_SUCCESS)
{
RegCloseKey(rootKey);
return false;
@ -363,6 +369,13 @@ bool LoadConfiguration()
return false;
}
DWORD shadowBlobs = 16;
if (GetDWORDRegKey(rootKey, REGKEY_SHADOW_BLOBS, &shadowBlobs, 16) != ERROR_SUCCESS)
{
RegCloseKey(rootKey);
return false;
}
bool enableSound = true;
if (GetBoolRegKey(rootKey, REGKEY_ENABLE_SOUND, &enableSound, true) != ERROR_SUCCESS)
{
@ -439,7 +452,8 @@ bool LoadConfiguration()
g_Configuration.Width = screenWidth;
g_Configuration.Height = screenHeight;
g_Configuration.Windowed = windowed;
g_Configuration.EnableShadows = shadows;
g_Configuration.ShadowMode = shadowMode;
g_Configuration.ShadowMaxBlobs = shadowBlobs;
g_Configuration.EnableCaustics = caustics;
g_Configuration.EnableVolumetricFog = volumetricFog;
g_Configuration.ShadowMapSize = shadowMapSize;

View file

@ -10,6 +10,7 @@
#define REGKEY_WINDOWED "Windowed"
#define REGKEY_SHADOWS "Shadows"
#define REGKEY_SHADOW_MAP "ShadowMap"
#define REGKEY_SHADOW_BLOBS "ShadowBlobs"
#define REGKEY_CAUSTICS "Caustics"
#define REGKEY_VOLUMETRIC_FOG "VolumetricFog"
@ -36,10 +37,11 @@ struct GameConfiguration
int MusicVolume;
int SfxVolume;
bool EnableShadows;
bool EnableCaustics;
bool EnableVolumetricFog;
int ShadowMode;
int ShadowMapSize = 1024;
int ShadowMaxBlobs = 16;
bool AutoTarget;
bool EnableRumble;

View file

@ -402,7 +402,7 @@ void InitialiseObjects()
obj->drawRoutine = DrawAnimatingItem;
obj->pivotLength = 0;
obj->radius = DEFAULT_RADIUS;
obj->shadowSize = NO_SHADOW;
obj->castsShadow = false;
obj->HitPoints = NOT_TARGETABLE;
obj->hitEffect = HIT_NONE;
obj->explodableMeshbits = 0;

View file

@ -6,8 +6,6 @@ struct ItemInfo;
struct CollisionInfo;
enum ZoneType : char;
constexpr auto UNIT_SHADOW = 256;
constexpr auto NO_SHADOW = 0;
constexpr auto DEFAULT_RADIUS = 10;
constexpr auto ROT_X = 0x0004;
constexpr auto ROT_Y = 0x0008;
@ -49,7 +47,7 @@ struct ObjectInfo
short HitPoints;
short pivotLength;
short radius;
short shadowSize;
bool castsShadow;
short biteOffset;
bool loaded;
bool intelligent;

View file

@ -201,6 +201,7 @@ CALL gen.bat</Command>
<ClInclude Include="Renderer\Structures\RendererRoom.h" />
<ClInclude Include="Renderer\Structures\RendererStringToDraw.h" />
<ClInclude Include="Renderer\Structures\RendererVideoAdapter.h" />
<ClInclude Include="Renderer\Texture2DArray\Texture2DArray.h" />
<ClInclude Include="Scripting\Flow\ScriptInterfaceFlowHandler.h" />
<ClInclude Include="Scripting\Include\Flow\ScriptInterfaceFlowHandler.h" />
<ClInclude Include="Scripting\Include\Objects\ScriptInterfaceObjectsHandler.h" />
@ -628,6 +629,7 @@ CALL gen.bat</Command>
<ClCompile Include="Game\effects\lara_fx.cpp" />
<ClCompile Include="Objects\Generic\Traps\dart_emitter.cpp" />
<ClCompile Include="Renderer\Renderer11DrawMenu.cpp" />
<ClCompile Include="Renderer\Texture2DArray\Texture2DArray.cpp" />
<ClCompile Include="Scripting\Internal\LuaHandler.cpp" />
<ClCompile Include="Scripting\Internal\ScriptAssert.cpp" />
<ClCompile Include="Scripting\Internal\ScriptInterfaceState.cpp" />
@ -1059,6 +1061,11 @@ CALL gen.bat</Command>
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DeploymentContent>
<FileType>Document</FileType>
<EntryPointName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">PS</EntryPointName>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Pixel</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">4.1</ShaderModel>
<AllResourcesBound Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</AllResourcesBound>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">SHADOW_MAP_SIZE=512</PreprocessorDefinitions>
</None>
<None Include="Shaders\DX11_ShadowMap.fx">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>