Merge remote-tracking branch 'origin/develop' into assetDir

This commit is contained in:
hispidence 2023-05-20 18:24:32 +01:00
commit 1346728ce0
26 changed files with 695 additions and 1338 deletions

View file

@ -14,6 +14,11 @@ Version 1.0.9
* Add TR1 cowboy.
* Add TR3 wall mounted blade.
* Add TR3 claw mutant.
* Add TR5 lasers
- Choose colour for the lasers via tint menu.
- Laser OCB means width of the laser in sectors.
- Negative OCB laser will trigger heavy trigger.
- Positive OCB kills Lara.
* Add removable puzzles from puzzle holes and puzzle dones.
- Employed by setting the trigger type as "Switch" for either puzzle hole or puzzle done.
- Can be mixed with puzzle done and puzzle holes of the same or different type.
@ -28,8 +33,8 @@ Version 1.0.9
* Add "Reset to defaults" entry to controls menu and automatically bind XBOX gamepad profile if connected.
Lua API changes:
* Add class Vec2
* Add function String::SetTranslated()
* Add Vec2 class.
* Add function String::SetTranslated()
* Add function Misc::IsStringDisplaying()
* Add the following for use in AddCallback and RemoveCallback:
- PRESTART, POSTSTART

View file

@ -512,7 +512,10 @@ void HandleWeapon(ItemInfo& laraItem)
{
if (player.Control.Weapon.GunType == LaraWeaponType::Flare)
{
if (!player.LeftArm.FrameNumber)
// NOTE: Original engines for some reason do this check, but it introduces a bug when player
// can't drop a flare underwater after it was dropped and picked up again once. -- Lwmte, 20/05/23
//if (!player.LeftArm.FrameNumber)
{
player.Control.HandStatus = HandStatus::WeaponUndraw;
}

View file

@ -47,6 +47,7 @@
#include "Objects/TR5/Emitter/tr5_bats_emitter.h"
#include "Objects/TR5/Emitter/tr5_rats_emitter.h"
#include "Objects/TR5/Emitter/tr5_spider_emitter.h"
#include "Objects/TR5/Trap/LaserBarrier.h"
#include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h"
#include "Scripting/Include/Objects/ScriptInterfaceObjectsHandler.h"
#include "Scripting/Include/ScriptInterfaceGame.h"
@ -79,6 +80,7 @@ using namespace TEN::Hud;
using namespace TEN::Input;
using namespace TEN::Math;
using namespace TEN::Renderer;
using namespace TEN::Traps::TR5;
int GameTimer = 0;
int GlobalCounter = 0;
@ -417,6 +419,7 @@ void CleanUp()
ClearFootprints();
ClearDrips();
ClearRipples();
ClearLaserBarrierEffects();
DisableSmokeParticles();
DisableSparkParticles();
DisableDebris();

View file

@ -51,7 +51,7 @@ namespace TEN::Entities::Creatures::TR1
COWBOY_ANIM_IDLE
};
void InitialiseCowboy(short itemNumber)
void InitializeCowboy(short itemNumber)
{
auto& item = g_Level.Items[itemNumber];

View file

@ -2,6 +2,6 @@
namespace TEN::Entities::Creatures::TR1
{
void InitialiseCowboy(short itemNumber);
void InitializeCowboy(short itemNumber);
void CowboyControl(short itemNumber);
}

View file

@ -170,7 +170,7 @@ static void StartEntity(ObjectInfo* obj)
obj = &Objects[ID_COWBOY];
if (obj->loaded)
{
obj->Initialize = InitialiseCowboy;
obj->Initialize = InitializeCowboy;
obj->control = CowboyControl;
obj->collision = CreatureCollision;
obj->shadowType = ShadowMode::All;

View file

@ -0,0 +1,188 @@
#include "framework.h"
#include "Objects/TR5/Trap/LaserBarrier.h"
#include "Game/collision/collide_room.h"
#include "Game/collision/floordata.h"
#include "Game/effects/effects.h"
#include "Game/effects/item_fx.h"
#include "Game/items.h"
#include "Game/Lara/lara.h"
#include "Specific/level.h"
using namespace TEN::Effects::Items;
namespace TEN::Traps::TR5
{
// NOTES:
// item.ItemFlags[0] = barrier height.
// TODO:
// - Randomize opacity pulses for each barrier.
// - Make SpawnLaserBarrierLight() spawn a line of light once engine allows it.
// - Make beam counts an attribute once attributes are implemented.
extern std::unordered_map<int, LaserBarrier> LaserBarriers = {};
void LaserBarrier::Initialize(const ItemInfo& item)
{
float barrierHeight = item.ItemFlags[0];
int beamCount = std::max((int)floor((barrierHeight / 2) / LaserBarrierBeam::HEIGHT), 1);
Color = item.Model.Color;
Color.w = 0.0f;
Beams.resize(beamCount);
IsLethal = (item.TriggerFlags > 0);
IsHeavyActivator = (item.TriggerFlags <= 0);
Update(item);
}
void LaserBarrier::Update(const ItemInfo& item)
{
// Calculate dimension values.
float barrierHalfWidth = (abs(item.TriggerFlags) * BLOCK(1)) / 2;
float barrierHeight = item.ItemFlags[0];
float beamStepHeight = barrierHeight / Beams.size();
// Determine beam vertex base.
auto basePos = item.Pose.Position.ToVector3();
auto rotMatrix = EulerAngles(0, item.Pose.Orientation.y + ANGLE(90.0f), 0).ToRotationMatrix();
auto baseVertices = std::array<Vector3, LaserBarrierBeam::VERTEX_COUNT>
{
basePos + Vector3::Transform(Vector3(barrierHalfWidth, -LaserBarrierBeam::HEIGHT / 2, 0.0f), rotMatrix),
basePos + Vector3::Transform(Vector3(-barrierHalfWidth, -LaserBarrierBeam::HEIGHT / 2, 0.0f), rotMatrix),
basePos + Vector3::Transform(Vector3(-barrierHalfWidth, LaserBarrierBeam::HEIGHT / 2, 0.0f), rotMatrix),
basePos + Vector3::Transform(Vector3(barrierHalfWidth, LaserBarrierBeam::HEIGHT / 2, 0.0f), rotMatrix)
};
// Set vertex positions.
auto beamOffset = Vector3(0.0f, -LaserBarrierBeam::HEIGHT, 0.0f);
for (auto& beam : Beams)
{
assertion(beam.VertexPoints.size() == baseVertices.size(), "Laser barrier beam vertex count out of sync.");
for (int i = 0; i < beam.VertexPoints.size(); i++)
beam.VertexPoints[i] = baseVertices[i] + beamOffset;
beamOffset.y -= beamStepHeight;
}
// Determine bounding box reference points.
auto point0 = Beams.back().VertexPoints[0];
auto point1 = Beams.back().VertexPoints[1];
auto point2 = Beams.front().VertexPoints[2];
auto point3 = Beams.front().VertexPoints[3];
// Update bounding box.
BoundingBox.Center = (point0 + point1 + point2 + point3) / 4;
BoundingBox.Extents = Vector3(
std::abs(point0.x - point1.x) / 2,
std::abs(point0.y - point2.y) / 2,
std::abs(point0.z - point2.z) / 2);
}
void InitializeLaserBarrier(short itemNumber)
{
auto& item = g_Level.Items[itemNumber];
// Initialize barrier height.
auto pointColl = GetCollision(&item);
float barrierHeight = item.Pose.Position.y - pointColl.Position.Ceiling;
item.ItemFlags[0] = barrierHeight;
// Initialize barrier effect.
auto barrier = LaserBarrier{};
barrier.Initialize(item);
LaserBarriers.insert({ itemNumber, barrier });
}
static void SpawnLaserBarrierLight(const ItemInfo& item, float intensity, float amplitude)
{
float intensityNorm = intensity - Random::GenerateFloat(0.0f, amplitude);
TriggerDynamicLight(
item.Pose.Position.x, item.Pose.Position.y, item.Pose.Position.z,
8,
intensityNorm * (item.Model.Color.x / 2),
intensityNorm * (item.Model.Color.y / 2),
intensityNorm * (item.Model.Color.z / 2));
}
void ControlLaserBarrier(short itemNumber)
{
constexpr auto LIGHT_INTENSITY = 150.0f;
constexpr auto LIGHT_AMPLITUDE = 31.0f;
if (!LaserBarriers.count(itemNumber))
return;
auto& item = g_Level.Items[itemNumber];
auto& barrier = LaserBarriers.at(itemNumber);
if (!TriggerActive(&item))
{
barrier.IsActive = false;
barrier.Color.w = 0.0f;
item.Model.Color.w = 0.0f;
return;
}
// Brightness fade-in and distortion.
if (item.Model.Color.w < 1.0f)
item.Model.Color.w += 0.02f;
if (barrier.Color.w < 1.0f)
barrier.Color.w += 0.02f;
// TODO: Weird.
if (item.Model.Color.w > 8.0f)
{
barrier.Color.w = 0.8f;
item.Model.Color.w = 0.8f;
}
barrier.IsActive = true;
barrier.Update(item);
if (item.Model.Color.w >= 0.8f)
SpawnLaserBarrierLight(item, LIGHT_INTENSITY, LIGHT_AMPLITUDE);
SoundEffect(SFX_TR5_DOOR_BEAM, &item.Pose);
}
void CollideLaserBarrier(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll)
{
constexpr auto LIGHT_INTENSITY = 255.0f;
constexpr auto LIGHT_AMPLITUDE = 100.0f;
if (!LaserBarriers.count(itemNumber))
return;
auto& item = g_Level.Items[itemNumber];
auto& barrier = LaserBarriers.at(itemNumber);
if (!barrier.IsActive)
return;
auto playerBox = GameBoundingBox(playerItem).ToBoundingOrientedBox(playerItem->Pose);
if (barrier.BoundingBox.Intersects(playerBox))
{
if (barrier.IsLethal &&
playerItem->HitPoints > 0 && playerItem->Effect.Type != EffectType::Smoke)
{
ItemRedLaserBurn(playerItem, 2.0f * FPS);
DoDamage(playerItem, MAXINT);
}
else if (barrier.IsHeavyActivator)
{
TestTriggers(&item, true, item.Flags & IFLAG_ACTIVATION_MASK);
}
barrier.Color.w = Random::GenerateFloat(0.6f, 1.0f);
SpawnLaserBarrierLight(item, LIGHT_INTENSITY, LIGHT_AMPLITUDE);
}
}
void ClearLaserBarrierEffects()
{
LaserBarriers.clear();
}
}

View file

@ -0,0 +1,40 @@
#pragma once
#include "Math/Math.h"
using namespace TEN::Math;
struct CollisionInfo;
struct ItemInfo;
namespace TEN::Traps::TR5
{
struct LaserBarrierBeam
{
static constexpr auto VERTEX_COUNT = 4;
static constexpr auto HEIGHT = BLOCK(0.4f);
std::array<Vector3, VERTEX_COUNT> VertexPoints = {};
};
struct LaserBarrier
{
Vector4 Color = Vector4::Zero;
BoundingOrientedBox BoundingBox = {};
std::vector<LaserBarrierBeam> Beams = {};
bool IsActive = false;
bool IsLethal = false;
bool IsHeavyActivator = false;
void Initialize(const ItemInfo& item);
void Update(const ItemInfo& item);
};
extern std::unordered_map<int, LaserBarrier> LaserBarriers;
void InitializeLaserBarrier(short itemNumber);
void ControlLaserBarrier(short itemNumber);
void CollideLaserBarrier(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll);
void ClearLaserBarrierEffects();
}

View file

@ -57,13 +57,14 @@
// Traps
#include "Objects/Effects/tr5_electricity.h"
#include "Objects/TR5/Trap/LaserBarrier.h"
#include "Objects/TR5/Object/tr5_rollingball.h"
#include "Objects/TR5/Trap/tr5_explosion.h"
#include "Objects/TR5/Trap/tr5_fallingceiling.h"
#include "Objects/TR5/Trap/tr5_romehammer.h"
#include "Objects/TR5/Trap/tr5_ventilator.h"
#include "Objects/TR5/Trap/tr5_wreckingball.h"
#include "Objects/TR5/Trap/tr5_zip_line.h"
#include "Objects/TR5/Trap/tr5_romehammer.h"
#include "Objects/TR5/Trap/tr5_fallingceiling.h"
#include "Objects/TR5/Trap/tr5_explosion.h"
#include "Objects/TR5/Trap/tr5_wreckingball.h"
// Switches
#include "Objects/TR5/Switch/tr5_crowdove_switch.h"
@ -73,6 +74,7 @@
using namespace TEN::Entities::Creatures::TR5;
using namespace TEN::Entities::Switches;
using namespace TEN::Traps::TR5;
static void StartEntity(ObjectInfo *obj)
{
@ -951,6 +953,16 @@ static void StartTrap(ObjectInfo *obj)
obj->drawRoutine = nullptr;
obj->usingDrawAnimatingItem = false;
}
obj = &Objects[ID_LASER_BARRIER];
if (obj->loaded)
{
obj->Initialize = InitializeLaserBarrier;
obj->control = ControlLaserBarrier;
obj->collision = CollideLaserBarrier;
obj->drawRoutine = nullptr;
obj->usingDrawAnimatingItem = false;
}
}
static void StartSwitch(ObjectInfo *obj)

View file

@ -767,7 +767,7 @@ enum GAME_OBJECT_ID : short
ID_LARA_START_POS,
ID_TELEPORTER,
ID_LIFT_TELEPORTER,
ID_LASERS,
ID_LASER_BARRIER,
ID_STEAM_LASERS,
ID_FLOOR_LASERS,
ID_KILL_ALL_TRIGGERS,

View file

@ -8,4 +8,5 @@ using DirectX::SimpleMath::Vector4;
struct alignas(16) CSpriteBuffer
{
float IsSoftParticle;
int RenderType;
};

View file

@ -518,6 +518,7 @@ namespace TEN::Renderer
void InitializeMenuBars(int y);
void DrawAllStrings();
void DrawLaserBarriers(RenderView& view);
void DrawHorizonAndSky(RenderView& renderView, ID3D11DepthStencilView* depthTarget);
void DrawRooms(RenderView& view, bool transparent);
void DrawRoomsSorted(RendererTransparentFaceInfo* info, bool resetPipeline, RenderView& view);
@ -602,24 +603,24 @@ namespace TEN::Renderer
float CalculateFrameRate();
void AddSpriteBillboard(RendererSprite* sprite, const Vector3& pos, const Vector4& color, float orient2D, float scale,
Vector2 size, BLEND_MODES blendMode, bool isSoftParticle, RenderView& view);
Vector2 size, BLEND_MODES blendMode, bool isSoftParticle, RenderView& view, SpriteRenderType renderType = SpriteRenderType::Default);
void AddSpriteBillboardConstrained(RendererSprite* sprite, const Vector3& pos, const Vector4& color, float orient2D,
float scale, Vector2 size, BLEND_MODES blendMode, const Vector3& constrainAxis,
bool isSoftParticle, RenderView& view);
float scale, Vector2 size, BLEND_MODES blendMode, const Vector3& constrainAxis,
bool isSoftParticle, RenderView& view, SpriteRenderType renderType = SpriteRenderType::Default);
void AddSpriteBillboardConstrainedLookAt(RendererSprite* sprite, const Vector3& pos, const Vector4& color, float orient2D,
float scale, Vector2 size, BLEND_MODES blendMode, const Vector3& lookAtAxis,
bool isSoftParticle, RenderView& view);
float scale, Vector2 size, BLEND_MODES blendMode, const Vector3& lookAtAxis,
bool isSoftParticle, RenderView& view, SpriteRenderType renderType = SpriteRenderType::Default);
void AddQuad(RendererSprite* sprite, const Vector3& vertex0, const Vector3& vertex1, const Vector3& vertex2, const Vector3& vertex3,
const Vector4 color, float orient2D, float scale, Vector2 size, BLEND_MODES blendMode, bool softParticles,
RenderView& view);
void AddQuad(RendererSprite* sprite, const Vector3& vertex0, const Vector3& vertex1, const Vector3& vertex2, const Vector3& vertex3,
const Vector4& color0, const Vector4& color1, const Vector4& color2, const Vector4& color3, float orient2D,
float scale, Vector2 size, BLEND_MODES blendMode, bool isSoftParticle, RenderView& view);
float scale, Vector2 size, BLEND_MODES blendMode, bool isSoftParticle, RenderView& view, SpriteRenderType renderType = SpriteRenderType::Default);
void AddColoredQuad(const Vector3& vertex0, const Vector3& vertex1, const Vector3& vertex2, const Vector3& vertex3,
const Vector4& color, BLEND_MODES blendMode, RenderView& view);
void AddColoredQuad(const Vector3& vertex0, const Vector3& vertex1, const Vector3& vertex2, const Vector3& vertex3,
const Vector4& color0, const Vector4& color1, const Vector4& color2, const Vector4& color3,
BLEND_MODES blendMode, RenderView& view);
BLEND_MODES blendMode, RenderView& view, SpriteRenderType renderType = SpriteRenderType::Default);
Matrix GetWorldMatrixForSprite(RendererSpriteToDraw* spr, RenderView& view);
RendererObject& GetRendererObject(GAME_OBJECT_ID id);

View file

@ -1513,6 +1513,7 @@ namespace TEN::Renderer
DrawHelicalLasers(view);
DrawRopes(view);
DrawStreamers(view);
DrawLaserBarriers(view);
// Here is where we actually output sprites
DrawSprites(view);

View file

@ -26,9 +26,10 @@
#include "Game/misc.h"
#include "Game/Setup.h"
#include "Math/Math.h"
#include "Objects/TR5/Trap/LaserBarrier.h"
#include "Objects/Utils/object_helper.h"
#include "Renderer/Quad/RenderQuad.h"
#include "Renderer/RendererSprites.h"
#include "Renderer/Quad/RenderQuad.h"
#include "Specific/level.h"
using namespace TEN::Effects::Blood;
@ -41,13 +42,14 @@ using namespace TEN::Effects::Ripple;
using namespace TEN::Effects::Streamer;
using namespace TEN::Entities::Creatures::TR5;
using namespace TEN::Math;
using namespace TEN::Traps::TR5;
extern BLOOD_STRUCT Blood[MAX_SPARKS_BLOOD];
extern FIRE_SPARKS FireSparks[MAX_SPARKS_FIRE];
extern SMOKE_SPARKS SmokeSparks[MAX_SPARKS_SMOKE];
extern SHOCKWAVE_STRUCT ShockWaves[MAX_SHOCKWAVE];
extern FIRE_LIST Fires[MAX_FIRE_LIST];
extern GUNFLASH_STRUCT Gunflashes[MAX_GUNFLASH]; // offset 0xA31D8
extern GUNFLASH_STRUCT Gunflashes[MAX_GUNFLASH];
extern Particle Particles[MAX_PARTICLES];
extern SPLASH_STRUCT Splashes[MAX_SPLASHES];
@ -60,9 +62,31 @@ namespace TEN::Renderer
RendererSprite* Sprite;
BLEND_MODES BlendMode;
std::vector<RendererSpriteToDraw> SpritesToDraw;
bool IsBillboard;
bool IsSoftParticle;
bool IsBillboard = false;
bool IsSoftParticle = false;
SpriteRenderType RenderType;
};
void Renderer11::DrawLaserBarriers(RenderView& view)
{
if (LaserBarriers.empty())
return;
for (const auto& [entityID, barrier] : LaserBarriers)
{
for (const auto& beam : barrier.Beams)
{
AddColoredQuad(
beam.VertexPoints[0], beam.VertexPoints[1],
beam.VertexPoints[2], beam.VertexPoints[3],
barrier.Color, barrier.Color,
barrier.Color, barrier.Color,
BLENDMODE_ADDITIVE, view, SpriteRenderType::LaserBarrier);
}
}
}
void Renderer11::DrawStreamers(RenderView& view)
{
@ -1117,6 +1141,7 @@ namespace TEN::Renderer
currentSpriteBucket.BlendMode = view.spritesToDraw[0].BlendMode;
currentSpriteBucket.IsBillboard = view.spritesToDraw[0].Type != RENDERER_SPRITE_TYPE::SPRITE_TYPE_3D;
currentSpriteBucket.IsSoftParticle = view.spritesToDraw[0].SoftParticle;
currentSpriteBucket.RenderType = view.spritesToDraw[0].renderType;
for (auto& rDrawSprite : view.spritesToDraw)
{
@ -1125,6 +1150,7 @@ namespace TEN::Renderer
if (rDrawSprite.Sprite != currentSpriteBucket.Sprite ||
rDrawSprite.BlendMode != currentSpriteBucket.BlendMode ||
rDrawSprite.SoftParticle != currentSpriteBucket.IsSoftParticle ||
rDrawSprite.renderType != currentSpriteBucket.RenderType ||
currentSpriteBucket.SpritesToDraw.size() == INSTANCED_SPRITES_BUCKET_SIZE ||
isBillboard != currentSpriteBucket.IsBillboard)
{
@ -1134,10 +1160,12 @@ namespace TEN::Renderer
currentSpriteBucket.BlendMode = rDrawSprite.BlendMode;
currentSpriteBucket.IsBillboard = isBillboard;
currentSpriteBucket.IsSoftParticle = rDrawSprite.SoftParticle;
currentSpriteBucket.RenderType = rDrawSprite.renderType;
currentSpriteBucket.SpritesToDraw.clear();
}
if (DoesBlendModeRequireSorting(rDrawSprite.BlendMode))
//HACK: prevent sprites like Explosionsmoke which have blendmode_subtractive from having laser effects
if (DoesBlendModeRequireSorting(rDrawSprite.BlendMode) && currentSpriteBucket.RenderType)
{
// If blend mode requires sorting, save sprite for later.
int distance = (rDrawSprite.pos - Vector3(Camera.pos.x, Camera.pos.y, Camera.pos.z)).Length();
@ -1212,9 +1240,13 @@ namespace TEN::Renderer
BindTexture(TEXTURE_COLOR_MAP, spriteBucket.Sprite->Texture, SAMPLER_LINEAR_CLAMP);
if (spriteBucket.BlendMode == BLEND_MODES::BLENDMODE_ALPHATEST)
{
SetAlphaTest(ALPHA_TEST_GREATER_THAN, ALPHA_TEST_THRESHOLD, true);
}
else
{
SetAlphaTest(ALPHA_TEST_NONE, 0);
}
m_cbInstancedSpriteBuffer.updateData(m_stInstancedSpriteBuffer, m_context.Get());
BindConstantBufferVS(CB_INSTANCED_SPRITES, m_cbInstancedSpriteBuffer.get());
@ -1245,6 +1277,8 @@ namespace TEN::Renderer
continue;
m_stSprite.IsSoftParticle = spriteBucket.IsSoftParticle ? 1 : 0;
m_stSprite.RenderType = spriteBucket.RenderType;
m_cbSprite.updateData(m_stSprite, m_context.Get());
BindConstantBufferVS(CB_SPRITE, m_cbSprite.get());
BindConstantBufferPS(CB_SPRITE, m_cbSprite.get());
@ -1253,9 +1287,13 @@ namespace TEN::Renderer
BindTexture(TEXTURE_COLOR_MAP, spriteBucket.Sprite->Texture, SAMPLER_LINEAR_CLAMP);
if (spriteBucket.BlendMode == BLEND_MODES::BLENDMODE_ALPHATEST)
{
SetAlphaTest(ALPHA_TEST_GREATER_THAN, ALPHA_TEST_THRESHOLD, true);
}
else
{
SetAlphaTest(ALPHA_TEST_NONE, 0);
}
m_primitiveBatch->Begin();
@ -1309,6 +1347,8 @@ namespace TEN::Renderer
if (resetPipeline)
{
m_stSprite.IsSoftParticle = info->sprite->SoftParticle ? 1 : 0;
m_stSprite.RenderType = SpriteRenderType::Default;
m_cbSprite.updateData(m_stSprite, m_context.Get());
BindConstantBufferVS(CB_SPRITE, m_cbSprite.get());
BindConstantBufferPS(CB_SPRITE, m_cbSprite.get());

View file

@ -5,7 +5,7 @@
namespace TEN::Renderer
{
void Renderer11::AddSpriteBillboard(RendererSprite* sprite, const Vector3& pos, const Vector4& color, float orient2D, float scale,
Vector2 size, BLEND_MODES blendMode, bool isSoftParticle, RenderView& view)
Vector2 size, BLEND_MODES blendMode, bool isSoftParticle, RenderView& view, SpriteRenderType renderType)
{
if (m_Locked)
return;
@ -32,13 +32,14 @@ namespace TEN::Renderer
spr.c3 = color;
spr.c4 = color;
spr.color = color;
spr.renderType = renderType;
view.spritesToDraw.push_back(spr);
}
void Renderer11::AddSpriteBillboardConstrained(RendererSprite* sprite, const Vector3& pos, const Vector4 &color, float orient2D,
float scale, Vector2 size, BLEND_MODES blendMode, const Vector3& constrainAxis,
bool softParticles, RenderView& view)
bool softParticles, RenderView& view, SpriteRenderType renderType)
{
if (m_Locked)
return;
@ -66,13 +67,14 @@ namespace TEN::Renderer
spr.c3 = color;
spr.c4 = color;
spr.color = color;
spr.renderType = renderType;
view.spritesToDraw.push_back(spr);
}
void Renderer11::AddSpriteBillboardConstrainedLookAt(RendererSprite* sprite, const Vector3& pos, const Vector4& color, float orient2D,
float scale, Vector2 size, BLEND_MODES blendMode, const Vector3& lookAtAxis,
bool isSoftParticle, RenderView& view)
bool isSoftParticle, RenderView& view, SpriteRenderType renderType)
{
if (m_Locked)
return;
@ -100,6 +102,7 @@ namespace TEN::Renderer
spr.c3 = color;
spr.c4 = color;
spr.color = color;
spr.renderType = renderType;
view.spritesToDraw.push_back(spr);
}
@ -108,12 +111,12 @@ namespace TEN::Renderer
const Vector4 color, float orient2D, float scale, Vector2 size, BLEND_MODES blendMode, bool softParticles,
RenderView& view)
{
AddQuad(sprite, vertex0, vertex1, vertex2, vertex3, color, color, color, color, orient2D, scale, size, blendMode, softParticles, view);
AddQuad(sprite, vertex0, vertex1, vertex2, vertex3, color, color, color, color, orient2D, scale, size, blendMode, softParticles, view, SpriteRenderType::Default);
}
void Renderer11::AddQuad(RendererSprite* sprite, const Vector3& vertex0, const Vector3& vertex1, const Vector3& vertex2, const Vector3& vertex3,
const Vector4& color0, const Vector4& color1, const Vector4& color2, const Vector4& color3, float orient2D,
float scale, Vector2 size, BLEND_MODES blendMode, bool isSoftParticle, RenderView& view)
float scale, Vector2 size, BLEND_MODES blendMode, bool isSoftParticle, RenderView& view, SpriteRenderType renderType)
{
if (m_Locked)
return;
@ -143,6 +146,7 @@ namespace TEN::Renderer
spr.BlendMode = blendMode;
spr.pos = (vertex0 + vertex1 + vertex2 + vertex3) / 4.0f;
spr.SoftParticle = isSoftParticle;
spr.renderType = renderType;
view.spritesToDraw.push_back(spr);
}
@ -150,12 +154,12 @@ namespace TEN::Renderer
void Renderer11::AddColoredQuad(const Vector3& vertex0, const Vector3& vertex1, const Vector3& vertex2, const Vector3& vertex3,
const Vector4& color, BLEND_MODES blendMode, RenderView& view)
{
AddColoredQuad(vertex0, vertex1, vertex2, vertex3, color, color, color, color, blendMode, view);
AddColoredQuad(vertex0, vertex1, vertex2, vertex3, color, color, color, color, blendMode, view, SpriteRenderType::Default);
}
void Renderer11::AddColoredQuad(const Vector3& vertex0, const Vector3& vertex1, const Vector3& vertex2, const Vector3& vertex3,
const Vector4& color0, const Vector4& color1, const Vector4& color2, const Vector4& color3,
BLEND_MODES blendMode, RenderView& view)
BLEND_MODES blendMode, RenderView& view, SpriteRenderType renderType)
{
if (m_Locked)
return;
@ -175,6 +179,7 @@ namespace TEN::Renderer
sprite.BlendMode = blendMode;
sprite.pos = (vertex0 + vertex1 + vertex2 + vertex3) / 4.0f;
sprite.SoftParticle = false;
sprite.renderType = renderType;
view.spritesToDraw.push_back(sprite);
}

View file

@ -6,6 +6,12 @@ namespace TEN::Renderer
struct RenderView;
struct RendererSprite;
enum SpriteRenderType
{
Default,
LaserBarrier
};
struct RendererSpriteToDraw
{
RENDERER_SPRITE_TYPE Type;
@ -28,5 +34,6 @@ namespace TEN::Renderer
Vector3 ConstrainAxis;
Vector3 LookAtAxis;
bool SoftParticle;
SpriteRenderType renderType = SpriteRenderType::Default;
};
}

Binary file not shown.

View file

@ -1938,7 +1938,7 @@ static const std::unordered_map<std::string, GAME_OBJECT_ID> kObjIDs {
{ "LARA_START_POS", ID_LARA_START_POS },
{ "TELEPORTER", ID_TELEPORTER },
{ "LIFT_TELEPORTER", ID_LIFT_TELEPORTER },
{ "LASERS", ID_LASERS },
{ "LASER_BARRIER", ID_LASER_BARRIER },
{ "STEAM_LASERS", ID_STEAM_LASERS },
{ "FLOOR_LASERS", ID_FLOOR_LASERS },
{ "KILL_ALL_TRIGGERS", ID_KILL_ALL_TRIGGERS },

View file

@ -18,15 +18,18 @@ cbuffer AnimatedBuffer : register(b6)
float2 CalculateUVRotate(float2 uv, unsigned int frame)
{
if (FPS == 0)
{
return uv;
}
else
{
float step = uv.y - AnimFrames[frame].TopLeft.y;
float vert = AnimFrames[frame].TopLeft.y + step / 2.0f;
float height = (AnimFrames[frame].BottomLeft.y - AnimFrames[frame].TopLeft.y) / 2.0f;
float relPos = 1.0f - (Frame % FPS) / float(FPS);
float newUV = vert + height * relPos;
float vert = AnimFrames[frame].TopLeft.y + (step / 2);
float height = (AnimFrames[frame].BottomLeft.y - AnimFrames[frame].TopLeft.y) / 2;
float relPos = 1.0f - (Frame % FPS) / (float)FPS;
float newUV = vert + height * relPos;
return float2(uv.x, newUV);
}
}
@ -34,7 +37,7 @@ float2 CalculateUVRotate(float2 uv, unsigned int frame)
float2 GetFrame(unsigned int index, unsigned int offset)
{
float speed = FPS / 30.0f;
int frame = (int)(Frame * speed + offset) % NumAnimFrames;
int frame = int(Frame * speed + offset) % NumAnimFrames;
float2 result = 0;
@ -43,16 +46,19 @@ float2 GetFrame(unsigned int index, unsigned int offset)
case 0:
result = AnimFrames[frame].TopLeft;
break;
case 1:
result = AnimFrames[frame].TopRight;
break;
case 2:
result = AnimFrames[frame].BottomRight;
break;
case 3:
result = AnimFrames[frame].BottomLeft;
break;
}
return result;
}
}

View file

@ -3,25 +3,29 @@
#include "./Math.hlsli"
#define ALPHA_TEST_NONE 0
#define ALPHA_TEST_NONE 0
#define ALPHA_TEST_GREATER_THAN 1
#define ALPHA_TEST_LESS_THAN 2
#define ALPHA_TEST_LESS_THAN 2
#define BLENDMODE_OPAQUE 0,
#define BLENDMODE_ALPHATEST 1
#define BLENDMODE_ADDITIVE 2
#define BLENDMODE_NOZTEST 4
#define BLENDMODE_OPAQUE 0,
#define BLENDMODE_ALPHATEST 1
#define BLENDMODE_ADDITIVE 2
#define BLENDMODE_NOZTEST 4
#define BLENDMODE_SUBTRACTIVE 5
#define BLENDMODE_WIREFRAME 6
#define BLENDMODE_EXCLUDE 8
#define BLENDMODE_SCREEN 9
#define BLENDMODE_LIGHTEN 10
#define BLENDMODE_ALPHABLEND 11
#define BLENDMODE_WIREFRAME 6
#define BLENDMODE_EXCLUDE 8
#define BLENDMODE_SCREEN 9
#define BLENDMODE_LIGHTEN 10
#define BLENDMODE_ALPHABLEND 11
#define ZERO float3(0.0f, 0.0f, 0.0f)
#define EIGHT_FIVE float3( 0.85f, 0.85f, 0.85f)
#define BLENDING 0.707f
cbuffer BlendingBuffer : register(b12)
{
uint BlendMode;
int AlphaTest;
uint BlendMode;
int AlphaTest;
float AlphaThreshold;
};
@ -48,30 +52,124 @@ float4 DoFog(float4 sourceColor, float4 fogColor, float value)
switch (BlendMode)
{
case BLENDMODE_ADDITIVE:
case BLENDMODE_SCREEN:
case BLENDMODE_LIGHTEN:
fogColor.xyz *= Luma(sourceColor.xyz);
break;
case BLENDMODE_ADDITIVE:
case BLENDMODE_SCREEN:
case BLENDMODE_LIGHTEN:
fogColor.xyz *= Luma(sourceColor.xyz);
break;
case BLENDMODE_SUBTRACTIVE:
case BLENDMODE_EXCLUDE:
fogColor.xyz *= 1.0f - Luma(sourceColor.xyz);
break;
case BLENDMODE_SUBTRACTIVE:
case BLENDMODE_EXCLUDE:
fogColor.xyz *= 1.0f - Luma(sourceColor.xyz);
break;
case BLENDMODE_ALPHABLEND:
fogColor.w = sourceColor.w;
break;
case BLENDMODE_ALPHABLEND:
fogColor.w = sourceColor.w;
break;
default:
break;
default:
break;
}
if (fogColor.w > sourceColor.w)
fogColor.w = sourceColor.w;
float4 result = lerp(sourceColor, fogColor, value);
return result;
}
#endif // BLENDINGSHADER
float4 DoLaserBarrierEffect(float3 input, float4 output, float2 uv, float faceFactor, float timeUniform)
{
float2 noiseTexture = input.xy / uv;
noiseTexture *= uv.x / uv.y;
float noiseValue = FractalNoise(noiseTexture * 8.0f - timeUniform);
float4 color = output;
float gradL = smoothstep(0.0, 1.0, uv.x);
float gradR = smoothstep(1.0, 0.0, uv.x);
float gradT = smoothstep(0.0, 0.25, uv.y);
float gradB = 1.0 - smoothstep(0.75, 1.0, uv.y);
float distortion = timeUniform / 1024;
float3 noisix = SimplexNoise
(
SimplexNoise(float3(input.r * distortion, input.g, input.b))
);
float3 shadowx = SimplexNoise
(
cos(SimplexNoise(sin(timeUniform + input.rgb * 400)))
);
noisix.x = noisix.x > 0.9 ? 0.7 : noisix.x;
noisix.y = noisix.y > 0.9 ? 0.7 : noisix.y;
noisix.z = noisix.z > 0.9 ? 0.7 : noisix.z;
color.rgb *= noisix + 1.3f;
color.rgb -= noisix + 0.2f;
float frequency = 0.1;
float amplitude = 0.8;
float persistence = 0.5;
float noiseValue2 = 0;
float noiseValue3 = 0;
float2 uv84 = (uv * 2.4);
uv84.y = (uv84.y - 1.3);
uv84.x = (uv84.x / 1.3);
float2 uv85 = (uv / 2.4);
noiseValue2 = AnimatedNebula(uv84, timeUniform * 0.1f);
frequency = 2.5;
amplitude = 0.2;
persistence = 4.7;
float2 uv83 = uv * 8;
uv83.y = (uv.y + (timeUniform * 0.02));
noiseValue3 = NebularNoise(uv83, frequency, amplitude, persistence);
noiseValue2 += AnimatedNebula(uv/2, timeUniform * 0.05f);
color.rgb -= noiseValue - 0.7f;
color.rgb *= noiseValue2 + 1.0f;
color.rgb += noiseValue3;
color.a *= noiseValue + 0.01f;
color.rgb -= shadowx + 0.1f;
color.a *= noiseValue2 + 0.9f;
color.a *= noiseValue3 + 2.0f;
float fade0 = faceFactor * max(0.0, 1.0 - dot(float2(BLENDING, BLENDING), float2(gradL, gradT)));
float fade1 = faceFactor * max(0.0, 1.0 - dot(float2(BLENDING, BLENDING), float2(gradL, gradB)));
float fade2 = faceFactor * max(0.0, 1.0 - dot(float2(BLENDING, BLENDING), float2(gradR, gradB)));
float fade3 = faceFactor * max(0.0, 1.0 - dot(float2(BLENDING, BLENDING), float2(gradR, gradT)));
float fadeL = 1.40f * faceFactor * faceFactor * (1.0 - gradL);
float fadeB = 2.75f * faceFactor * faceFactor * (1.0 - gradB);
float fadeR = 1.40f * faceFactor * faceFactor * (1.0 - gradR);
float fadeT = 2.75f * faceFactor * faceFactor * (1.0 - gradT);
float fade = max(
max(max(fade0, fade1), max(fade2, fade3)),
max(max(fadeL, fadeR), max(fadeB, fadeT)));
float scale = 1.0 - fade;
color *= scale;
float decayFactor = 1.0f;
if (uv.y > 0.5f && uv.y < 1.0f)
{
decayFactor = uv.y / 2;
}
if (uv.y < 0.5f && uv.y > 0.0f)
{
decayFactor = (1.0f - uv.y) / 2;
}
color *= decayFactor;
color.rgb = smoothstep(ZERO, EIGHT_FIVE, color.rgb);
return color;
}
#endif // BLENDINGSHADER

View file

@ -6,9 +6,12 @@
// NOTE: This shader is used for all 3D and alpha blended sprites, because we send aleady transformed vertices to the GPU
// instead of instances
#define FADE_FACTOR .789f
cbuffer SpriteBuffer : register(b9)
{
float IsSoftParticle;
int RenderType;
};
struct PixelShaderInput
@ -34,7 +37,7 @@ PixelShaderInput VS(VertexShaderInput input)
float4 worldPosition = float4(input.Position, 1.0f);
output.Position = mul(worldPosition, ViewProjection);
output.PositionCopy = output.Position;
output.PositionCopy = output.Position;
output.Normal = input.Normal;
output.Color = input.Color;
output.UV = input.UV;
@ -71,7 +74,12 @@ float4 PS(PixelShaderInput input) : SV_TARGET
output.w = min(output.w, fade);
}
if (RenderType == 1)
{
output = DoLaserBarrierEffect(input.Position, output, input.UV, FADE_FACTOR, Frame);
}
output = DoFog(output, float4(0.0f, 0.0f, 0.0f, 0.0f), input.Fog);
return output;
}
}

View file

@ -1,12 +1,13 @@
#ifndef MATH
#define MATH
#define PI 3.1415926535897932384626433832795028841971693993751058209749445923
#define PI2 6.2831853071795864769252867665590057683943387987502116419498891846
#define PI 3.1415926535897932384626433832795028841971693993751058209749445923
#define PI2 6.2831853071795864769252867665590057683943387987502116419498891846
#define OCTAVES 6
float Luma(float3 color)
{
// Use Rec.709 trichromat formula to get perceptive luma value
// Use Rec.709 trichromat formula to get perceptive luma value.
return float((color.x * 0.2126f) + (color.y * 0.7152f) + (color.z * 0.0722f));
}
@ -26,121 +27,257 @@ float3 Screen(float3 ambient, float3 tint)
float LinearizeDepth(float depth, float nearPlane, float farPlane)
{
return (2.0f * nearPlane) / (farPlane + nearPlane - depth * (farPlane - nearPlane));
return ((nearPlane * 2) / (farPlane + nearPlane - (depth * (farPlane - nearPlane))));
}
float3 Mod289(float3 x) {
return x - floor(x * (1.0 / 289.0)) * 289.0;
float3 Mod289(float3 x)
{
return (x - floor(x * (1 / 289.0f)) * 289.0f);
}
float4 Mod289(float4 x) {
return x - floor(x * (1.0 / 289.0)) * 289.0;
float4 Mod289(float4 x)
{
return (x - floor(x * (1 / 289.0f)) * 289.0f);
}
float4 Permute(float4 x) {
return Mod289(((x*34.0)+10.0)*x);
float4 Permute(float4 x)
{
return Mod289(((x * 34.0f) + 10.0f) * x);
}
float4 TaylorInvSqrt(float4 r)
{
return 1.79284291400159 - 0.85373472095314 * r;
return (1.79284291400159f - 0.85373472095314f * r);
}
float SimplexNoise(float3 v)
{
const float2 C = float2(1.0/6.0, 1.0/3.0) ;
const float4 D = float4(0.0, 0.5, 1.0, 2.0);
const float2 C = float2(1 / 6.0f, 1 / 3.0f) ;
const float4 D = float4(0.0f, 0.5f, 1.0f, 2.0f);
// First corner
float3 i = floor(v + dot(v, C.yyy) );
float3 x0 = v - i + dot(i, C.xxx) ;
// First corner.
float3 i = floor(v + dot(v, C.yyy));
float3 x0 = v - i + dot(i, C.xxx);
// Other corners
// Other corners.
float3 g = step(x0.yzx, x0.xyz);
float3 l = 1.0 - g;
float3 i1 = min( g.xyz, l.zxy );
float3 i2 = max( g.xyz, l.zxy );
float3 l = 1.0f - g;
float3 i1 = min(g.xyz, l.zxy);
float3 i2 = max(g.xyz, l.zxy);
// x0 = x0 - 0.0 + 0.0 * C.xxx;
// x1 = x0 - i1 + 1.0 * C.xxx;
// x2 = x0 - i2 + 2.0 * C.xxx;
// x3 = x0 - 1.0 + 3.0 * C.xxx;
// x0 = x0 - 0.0 + 0.0 * C.xxx;
// x1 = x0 - i1 + 1.0 * C.xxx;
// x2 = x0 - i2 + 2.0 * C.xxx;
// x3 = x0 - 1.0 + 3.0 * C.xxx;
float3 x1 = x0 - i1 + C.xxx;
float3 x2 = x0 - i2 + C.yyy;// 2.0*C.x = 1/3 = C.y
float3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y
float3 x2 = x0 - i2 + C.yyy;// 2.0 * C.x = 1 / 3 = C.y
float3 x3 = x0 - D.yyy; // -1.0 + 3.0 * C.x = -0.5 = -D.y
// Permutations
// Permutations.
i = Mod289(i);
float4 p = Permute( Permute( Permute(
i.z + float4(0.0, i1.z, i2.z, 1.0 )) +
i.y + float4(0.0, i1.y, i2.y, 1.0 )) +
i.x + float4(0.0, i1.x, i2.x, 1.0 ));
float4 p = Permute(
Permute(
Permute(
i.z + float4(0.0f, i1.z, i2.z, 1.0f)) +
i.y + float4(0.0f, i1.y, i2.y, 1.0f)) +
i.x + float4(0.0f, i1.x, i2.x, 1.0f));
// Gradients: 7x7 points over a square, mapped onto an octahedron.
// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
float n_ = 0.142857142857; // 1.0/7.0
// Gradients: 7x7 points over square, mapped onto octahedron.
// Ring size 17*17 = 289 is close to multiple of 49 (49 * 6 = 294).
float n_ = 0.142857142857f; // 1.0/7.0
float3 ns = n_ * D.wyz - D.xzx;
float4 j = p - 49.0 * floor(p * ns.z * ns.z);// mod(p,7*7)
float4 j = p - 49.0f * floor(p * ns.z * ns.z);// mod(p, 7 * 7)
float4 x_ = floor(j * ns.z);
float4 y_ = floor(j - 7.0 * x_ );// mod(j,N)
float4 y_ = floor(j - 7.0f * x_);// mod(j, N)
float4 x = x_ *ns.x + ns.yyyy;
float4 y = y_ *ns.x + ns.yyyy;
float4 h = 1.0 - abs(x) - abs(y);
float4 x = x_ * ns.x + ns.yyyy;
float4 y = y_ * ns.x + ns.yyyy;
float4 h = 1.0f - abs(x) - abs(y);
float4 b0 = float4( x.x, x.y, y.x, y.y );
float4 b1 = float4( x.z, x.w, y.z, y.w );
float4 b0 = float4(x.x, x.y, y.x, y.y);
float4 b1 = float4(x.z, x.w, y.z, y.w);
//float4 s0 = float4(lessThan(b0,0.0))*2.0 - 1.0;
//float4 s1 = float4(lessThan(b1,0.0))*2.0 - 1.0;
float4 s0 = floor(b0)*2.0 + 1.0;
float4 s1 = floor(b1)*2.0 + 1.0;
float4 sh = -step(h, float4(0.0f,0.0f,0.0f,0.0f));
float4 s0 = floor(b0) * 2.0 + 1.0;
float4 s1 = floor(b1) * 2.0 + 1.0;
float4 sh = -step(h, float4(0.0f, 0.0f, 0.0f, 0.0f));
float4 a0 = b0.xzyw + s0.xzyw*sh.xxyy;
float4 a1 = b1.xzyw + s1.xzyw*sh.zzww;
float4 a0 = b0.xzyw + s0.xzyw * sh.xxyy;
float4 a1 = b1.xzyw + s1.xzyw * sh.zzww;
float3 p0 = float3(a0.xy,h.x);
float3 p1 = float3(a0.zw,h.y);
float3 p2 = float3(a1.xy,h.z);
float3 p3 = float3(a1.zw,h.w);
float3 p0 = float3(a0.xy, h.x);
float3 p1 = float3(a0.zw, h.y);
float3 p2 = float3(a1.xy, h.z);
float3 p3 = float3(a1.zw, h.w);
//Normalise gradients
float4 norm = TaylorInvSqrt(float4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
// Normalize gradients.
float4 norm = TaylorInvSqrt(float4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));
p0 *= norm.x;
p1 *= norm.y;
p2 *= norm.z;
p3 *= norm.w;
// Mix final noise value
float4 m = max(0.5 - float4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);
// Mix final noise value.
float4 m = max(0.5 - float4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), 0.0);
m = m * m;
return 105.0 * dot( m*m, float4( dot(p0,x0), dot(p1,x1),
dot(p2,x2), dot(p3,x3) ) );
return 105.0 * dot(m*m, float4(dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3)));
}
float2 Gradient2D(float2 p)
{
float angle = 2 * 3.14159265359f * frac(sin(dot(p, float2(12.9898f, 78.233f))) * 43758.5453f);
return normalize(float2(cos(angle), sin(angle)));
}
float NebularNoise(float2 uv, float frequency, float amplitude, float persistence)
{
float noiseValue = 0.0f;
float scale = 1.0f;
float range = 1.0f;
float2 p = uv * frequency;
float2 floorP = floor(p);
float2 fracP = frac(p);
float4 v = float4(0.0f, 1.0f, 0.0f, 1.0f);
float2 bl = floorP;
float2 br = bl + float2(1.0f, 0.0f);
float2 tl = bl + float2(0.0f, 1.0f);
float2 tr = bl + float2(1.0f, 1.0f);
float2 v1 = fracP;
float2 v2 = v1 - float2(1.0f, 0.0f);
float2 v3 = v1 - float2(0.0f, 1.0f);
float2 v4 = v1 - float2(1.0f, 1.0f);
float dot1 = dot(Gradient2D(bl), v1);
float dot2 = dot(Gradient2D(br), v2);
float dot3 = dot(Gradient2D(tl), v3);
float dot4 = dot(Gradient2D(tr), v4);
float u = smoothstep(0.0f, 1.0f, v1.x);
float2 a = lerp(float2(dot1, dot3), float2(dot2, dot4), u);
float k = smoothstep(0.0f, 1.0f, v1.y);
float b = lerp(a.x, a.y, k);
noiseValue += b * scale / range;
range += amplitude;
scale *= persistence;
p *= 2.0f;
return noiseValue;
}
float Noise(float2 p)
{
return frac(sin(dot(p, float2(12.9898f, 78.233f))) * 43758.5453f);
}
float PerlinNoise(float2 p)
{
float2 i = floor(p);
float2 f = frac(p);
float a = Noise(i);
float b = Noise(i + float2(1.0f, 0.0f));
float c = Noise(i + float2(0.0f, 1.0f));
float d = Noise(i + float2(1.0, 1.0f));
float2 u = f * f * (3.0f - 2.0f * f);
return lerp(lerp(a, b, u.x), lerp(c, d, u.x), u.y);
}
float4 AnimatedNebula(float2 uv, float time)
{
// Scale UV coordinates.
float2 scaledUV = uv;
// Apply horizontal mirroring.
scaledUV.y = abs(scaledUV.y);
// Generate noise value using Perlin noise.
float noiseValue = PerlinNoise(scaledUV.xy + time);
// Apply turbulence to noise value.
float turbulence = noiseValue * 0.9;
float2 distortedUV = scaledUV + turbulence;
// Interpolate between two main colors based on distorted UV coordinates.
float4 color1 = float4(0.2f, 0.4f, 0.8f, 0.0f);
float4 color2 = float4(0.6f, 0.1f, 0.5f, 0.0f);
float4 interpolatedColor = lerp(color1, color2, saturate(distortedUV.y));
// Add some brightness flickering based on noise value.
interpolatedColor *= 1.0f + noiseValue * 1.3f;
return interpolatedColor;
}
float RandomValue(float2 input)
{
return frac(sin(dot(input, float2(12.9898, 78.233))) * 43758.5453123);
}
float Noise2D(float2 input)
{
float2 i = floor(input);
float2 f = frac(input);
// Four corners in 2D of a tile
float a = RandomValue(i);
float b = RandomValue(i + float2(1.0, 0.0));
float c = RandomValue(i + float2(0.0, 1.0));
float d = RandomValue(i + float2(1.0, 1.0));
float2 u = f * f * (3.0 - 2.0 * f);
return lerp(a, b, u.x) +
(c - a) * u.y * (1.0 - u.x) +
(d - b) * u.x * u.y;
}
float FractalNoise(float2 input)
{
float value = 0.0;
float amplitude = .5;
float frequency = 0.;
// Octave loop.
for (int i = 0; i < OCTAVES; i++)
{
value += amplitude * Noise2D(input);
input *= 2.0;
amplitude *= 0.5;
}
return value;
}
float3 NormalNoise(float3 v, float3 i, float3 n)
{
//the resulting vector
// Resulting vector.
float3 r = float3(.0f,.0f,.0f);
//interpolates lerp(v,i,dot(n,i))
//v, which is the reference of the pixel and
//i, a vector perturbed with SimpleNoise
//the threshold dot(n,i) is based on a dot product between
//n, the normal and each tuple from it (xy, xz and yz)
//and the same for the vector from the noise
// Interpolates lerp(v,i,dot(n,i))
//v, which is the reference of the pixel and
//i, a vector perturbed with SimpleNoise
//the threshold dot(n,i) is based on a dot product between
//n, the normal and each tuple from it (xy, xz and yz)
//and the same for the vector from the noise
r.x = lerp(v.x, i.x, dot(n.xy,i.xy))*.9f;
r.y = lerp(v.y, i.y, dot(n.xz,i.xz))*.75f;
r.z = lerp(v.z, i.z, dot(n.yz,i.yz))*.8f;
//c, is a threshold based on the tuples of the reference pixel
// c = threshold based on tuples of reference pixel.
float c = dot(v.xy,v.yz);
//returns the perturbed pixel based on the reference pixel
//and the resulting vector, with a threshold c attenuated by 2/5 times
return lerp(v,r,c*.3f);
// Return perturbed pixel based on reference pixel and resulting vector with threshold c attenuated by 2/5 times.
return lerp(v, r, c * 0.3f);
}
#endif // MATH

View file

@ -784,6 +784,9 @@ namespace TEN::Input
for (int i = 0; i < KEY_COUNT; i++)
g_Configuration.KeyboardLayout[i] = KeyboardLayout[1][i];
// Additionally turn on thumbstick camera and vibration.
g_Configuration.EnableRumble = g_Configuration.EnableThumbstickCameraControl = true;
return true;
}
else

View file

@ -462,6 +462,7 @@ CALL gen.bat</Command>
<ClInclude Include="Objects\TR5\Shatter\tr5_smashobject.h" />
<ClInclude Include="Objects\TR5\Switch\tr5_crowdove_switch.h" />
<ClInclude Include="Objects\TR5\Switch\tr5_raisingcog.h" />
<ClInclude Include="Objects\TR5\Trap\LaserBarrier.h" />
<ClInclude Include="Objects\TR5\Trap\tr5_explosion.h" />
<ClInclude Include="Objects\TR5\Trap\tr5_fallingceiling.h" />
<ClInclude Include="Objects\TR5\Trap\tr5_romehammer.h" />
@ -889,6 +890,7 @@ CALL gen.bat</Command>
<ClCompile Include="Objects\TR5\Switch\tr5_crowdove_switch.cpp" />
<ClCompile Include="Objects\TR5\Switch\tr5_raisingcog.cpp" />
<ClCompile Include="Objects\TR5\tr5_objects.cpp" />
<ClCompile Include="Objects\TR5\Trap\LaserBarrier.cpp" />
<ClCompile Include="Objects\TR5\Trap\tr5_explosion.cpp" />
<ClCompile Include="Objects\TR5\Trap\tr5_fallingceiling.cpp" />
<ClCompile Include="Objects\TR5\Trap\tr5_romehammer.cpp" />

File diff suppressed because it is too large Load diff

View file

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ShowAllFiles>true</ShowAllFiles>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)Build\$(Configuration)\</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerCommandArguments>/debug</LocalDebuggerCommandArguments>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)Build\$(Configuration)\</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
</Project>