Implemented fog bulb (#1110)

* Added fog bulbs

* WIP raymarch

* constant fog formula with simplex noise

* Improved fog formula and handling

* Raymarch less expansive;
Added fog bulbs to sprites;
Removed premultiplication of fog density by color at load time;

* Avoid raymarch if fog > 1

* Sorting fog bulbs front to back;
Performance improvements;

* Added frustum culling for fog bulbs

* Tryiing without raymarch

* Refactored fog code;
Added noise and wibble to fog;
Fixed sprites;

* Disabled wibble for fog

* Removed noise

* Fof bulbs like TR5

* Fixed Pascal Case in RenderView;
Fixed formatting things;
Fixed sprites;

* Optimizations

* Fixed sprites in fog bulbs

* Fixed project paths

* Fix compiler warning

* Fixed repository

* Fog bulbs for sky and horizon

* Sky tessellation

* Update Renderer11Draw.cpp

---------

Co-authored-by: MontyTRC89 <montyhammet@hotmail.it>
Co-authored-by: Raildex <n@a.com>
Co-authored-by: Lwmte <3331699+Lwmte@users.noreply.github.com>
This commit is contained in:
Jakub 2023-05-31 09:12:20 +01:00 committed by GitHub
parent 31544858c4
commit a668d49331
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
38 changed files with 15684 additions and 15234 deletions

49
.gitignore vendored
View file

@ -1,24 +1,25 @@
enc_temp_folder/
Build/
TombEngine/x64/
TombEngine/Debug/
TombEngine/Release/
packages/
.vs/
.vsconfig
*.dmp
*.id0
*.id1
*.id2
*.id3
*.obj
*.zip
*.db
*.opendb
.exp
.pdb
.ilk
*.wav
*.trc
*.str
*.ten
enc_temp_folder/
Build/
TombEngine/x64/
TombEngine/Debug/
TombEngine/Release/
packages/
.vs/
.vsconfig
*.dmp
*.id0
*.id1
*.id2
*.id3
*.obj
*.zip
*.db
*.opendb
.exp
.pdb
.ilk
*.wav
*.trc
*.str
*.ten
Logs/

View file

@ -63,7 +63,7 @@ namespace TEN::Effects::Explosion
int numSprites = -Objects[ID_EXPLOSION_SPRITES].nmeshes - 1;
float normalizedAge = e.age / e.life;
e.sprite = Lerp(0.0f, numSprites, normalizedAge);
e.tint = Vector4::Lerp(Vector4(2, 2, 2, 1), Vector4(0, 0, 0, 0), normalizedAge);
e.tint = Vector4::Lerp(Vector4(2, 2, 2, 1), Vector4::Zero, normalizedAge);
}
}

View file

@ -131,7 +131,7 @@ namespace TEN::Effects::Smoke
s.gravity = -.1f;
s.affectedByWind = TestEnvironment(ENV_FLAG_WIND, pos.x, pos.y, pos.z, roomNumber);
s.sourceColor = Vector4(0.4f, 0.4f, 0.4f, 1);
s.destinationColor = Vector4(0, 0, 0, 0);
s.destinationColor = Vector4::Zero;
if (initial)
{
@ -207,7 +207,7 @@ namespace TEN::Effects::Smoke
s.velocity = Vector3(xVel, Random::GenerateFloat(-1, 4), zVel);
s.sourceColor = Vector4(1, 1, 1, 1);
s.destinationColor = Vector4(0, 0, 0, 0);
s.destinationColor = Vector4::Zero;
s.sourceSize = Random::GenerateFloat(8,24);
s.active = true;
s.affectedByWind = true;
@ -225,7 +225,7 @@ namespace TEN::Effects::Smoke
s = {};
s.position = Vector3(x, y, z) + Vector3(Random::GenerateFloat(8.0f, 16.0f), Random::GenerateFloat(8.0f, 16.0f), Random::GenerateFloat(8.0f, 16.0f));
s.sourceColor = Vector4(0.8f, 0.8f, 1, 1);
s.destinationColor = Vector4(0, 0, 0, 0);
s.destinationColor = Vector4::Zero;
s.sourceSize = Random::GenerateFloat(32.0f, 64.0f);
s.active = true;
s.velocity = Random::GenerateDirection() * Random::GenerateFloat(1.0f, 3.0f);

View file

@ -39,8 +39,6 @@ namespace TEN::Effects::Environment
constexpr auto DUST_LIFE = 40;
constexpr auto DUST_SPAWN_RADIUS = (10 * 1024);
constexpr auto SKY_POSITION_LIMIT = 9728;
EnvironmentController Weather;
float WeatherParticle::Transparency() const
@ -114,13 +112,13 @@ namespace TEN::Effects::Environment
continue;
SkyCurrentPosition[i] += level->GetSkyLayerSpeed(i);
if (SkyCurrentPosition[i] <= SKY_POSITION_LIMIT)
if (SkyCurrentPosition[i] <= SKY_SIZE)
{
if (SkyCurrentPosition[i] < 0)
SkyCurrentPosition[i] += SKY_POSITION_LIMIT;
SkyCurrentPosition[i] += SKY_SIZE;
}
else
SkyCurrentPosition[i] -= SKY_POSITION_LIMIT;
SkyCurrentPosition[i] -= SKY_SIZE;
}
}

View file

@ -1,41 +1,41 @@
#pragma once
#include <SimpleMath.h>
namespace TEN
#include "SimpleMath.h"
#include "ShaderLight.h"
#include "Renderer/ConstantBuffers/ShaderFogBulb.h"
using DirectX::SimpleMath::Matrix;
using DirectX::SimpleMath::Vector3;
using DirectX::SimpleMath::Vector2;
struct alignas(16) CCameraMatrixBuffer
{
namespace Renderer
{
using DirectX::SimpleMath::Matrix;
using DirectX::SimpleMath::Vector3;
using DirectX::SimpleMath::Vector2;
alignas(16) Matrix ViewProjection;
//--
alignas(16) Matrix View;
//--
alignas(16) Matrix Projection;
//--
alignas(16) Matrix InverseProjection;
//--
alignas(16) Vector4 CamPositionWS;
//--
alignas(16) Vector4 CamDirectionWS;
//--
alignas(16) Vector2 ViewSize;
alignas(4) Vector2 InvViewSize;
//--
alignas(16) unsigned int Frame;
alignas(4) unsigned int RoomNumber;
alignas(4) unsigned int CameraUnderwater;
//--
alignas(16) Vector4 FogColor;
alignas(4) int FogMinDistance;
alignas(4) int FogMaxDistance;
struct alignas(16) CCameraMatrixBuffer
{
alignas(16) Matrix ViewProjection;
//--
alignas(16) Matrix View;
//--
alignas(16) Matrix Projection;
//--
alignas(16) Matrix InverseProjection;
//--
alignas(16) Vector4 CamPositionWS;
//--
alignas(16) Vector4 CamDirectionWS;
//--
alignas(16) Vector2 ViewSize;
alignas(4) Vector2 InvViewSize;
//--
alignas(16) unsigned int Frame;
alignas(4) unsigned int RoomNumber;
alignas(4) unsigned int CameraUnderwater;
//--
alignas(16) Vector4 FogColor;
alignas(4) int FogMinDistance;
alignas(4) int FogMaxDistance;
alignas(4) float NearPlane;
alignas(4) float FarPlane;
alignas(4) float NearPlane;
alignas(4) float FarPlane;
};
}
}
alignas(4) int NumFogBulbs;
ShaderFogBulb FogBulbs[32];
};

View file

@ -0,0 +1,13 @@
#pragma once
#include <SimpleMath.h>
struct alignas(16) ShaderFogBulb
{
Vector3 Position;
float Density;
Vector3 Color;
float SquaredRadius;
Vector3 FogBulbToCameraVector;
float SquaredCameraToFogBulbDistance;
Vector4 Padding2;
};

View file

@ -1,94 +1,94 @@
#include "framework.h"
#include "RenderView.h"
namespace TEN::Renderer
{
RenderView::RenderView(CAMERA_INFO* cam, float roll, float fov, float nearPlane, float farPlane, int w, int h) : camera(cam, roll, fov, nearPlane, farPlane, w, h)
{
viewport = {};
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = w;
viewport.Height = h;
viewport.MinDepth = 0;
viewport.MaxDepth = 1;
}
RenderView::RenderView(const Vector3& pos, const Vector3& dir, const Vector3& up, int w, int h, int room, float nearPlane, float farPlane, float fov) : camera(pos, dir, up, room, w, h, fov, nearPlane, farPlane)
{
viewport = {};
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = w;
viewport.Height = h;
viewport.MinDepth = 0;
viewport.MaxDepth = 1;
}
void RenderView::fillConstantBuffer(CCameraMatrixBuffer& bufferToFill)
{
bufferToFill.Projection = camera.Projection;
bufferToFill.View = camera.View;
bufferToFill.ViewProjection = camera.ViewProjection;
bufferToFill.InverseProjection = camera.Projection.Invert();
bufferToFill.CamDirectionWS = Vector4(camera.WorldDirection);
bufferToFill.CamPositionWS = Vector4(camera.WorldPosition);
bufferToFill.ViewSize = camera.ViewSize;
bufferToFill.InvViewSize = camera.InvViewSize;
bufferToFill.RoomNumber = camera.RoomNumber;
bufferToFill.NearPlane = camera.NearPlane;
bufferToFill.FarPlane = camera.FarPlane;
}
void RenderView::clear()
{
roomsToDraw.clear();
lightsToDraw.clear();
spritesToDraw.clear();
StaticsToDraw.clear();
}
RenderViewCamera::RenderViewCamera(CAMERA_INFO* cam, float roll, float fov, float n, float f, int w, int h)
{
RoomNumber = cam->pos.RoomNumber;
WorldPosition = Vector3(cam->pos.x, cam->pos.y, cam->pos.z);
Vector3 target = Vector3(cam->target.x, cam->target.y, cam->target.z);
if ((target - WorldPosition) == Vector3::Zero)
target.y -= 10;
WorldDirection = target - WorldPosition;
WorldDirection.Normalize();
Vector3 up = -Vector3::UnitY;
Matrix upRotation = Matrix::CreateFromYawPitchRoll(0.0f, 0.0f, roll);
up = Vector3::Transform(up, upRotation);
up.Normalize();
View = Matrix::CreateLookAt(WorldPosition, target, up);
Projection = Matrix::CreatePerspectiveFieldOfView(fov, w / (float)h, n, f);
ViewProjection = View * Projection;
ViewSize = { (float)w, (float)h };
InvViewSize = { 1.0f / w, 1.0f / h };
Frustum.Update(View, Projection);
NearPlane = n;
FarPlane = f;
}
RenderViewCamera::RenderViewCamera(const Vector3& pos, const Vector3& dir, const Vector3& up, int room, int width, int height, float fov, float n, float f)
{
RoomNumber = room;
WorldPosition = pos;
WorldDirection = dir;
View = Matrix::CreateLookAt(pos, pos + dir * 10240, up);
float aspect = (float)width / (float)height;
Projection = Matrix::CreatePerspectiveFieldOfView(fov, aspect, n, f);
ViewProjection = View * Projection;
ViewSize = { (float)width, (float)height };
InvViewSize = { 1.0f / width, 1.0f / height };
Frustum.Update(View, Projection);
NearPlane = n;
FarPlane = f;
}
}
#include "framework.h"
#include "RenderView.h"
namespace TEN::Renderer
{
RenderView::RenderView(CAMERA_INFO* cam, float roll, float fov, float nearPlane, float farPlane, int w, int h) : Camera(cam, roll, fov, nearPlane, farPlane, w, h)
{
Viewport = {};
Viewport.TopLeftX = 0;
Viewport.TopLeftY = 0;
Viewport.Width = w;
Viewport.Height = h;
Viewport.MinDepth = 0;
Viewport.MaxDepth = 1;
}
RenderView::RenderView(const Vector3& pos, const Vector3& dir, const Vector3& up, int w, int h, int room, float nearPlane, float farPlane, float fov) : Camera(pos, dir, up, room, w, h, fov, nearPlane, farPlane)
{
Viewport = {};
Viewport.TopLeftX = 0;
Viewport.TopLeftY = 0;
Viewport.Width = w;
Viewport.Height = h;
Viewport.MinDepth = 0;
Viewport.MaxDepth = 1;
}
void RenderView::fillConstantBuffer(CCameraMatrixBuffer& bufferToFill)
{
bufferToFill.Projection = Camera.Projection;
bufferToFill.View = Camera.View;
bufferToFill.ViewProjection = Camera.ViewProjection;
bufferToFill.InverseProjection = Camera.Projection.Invert();
bufferToFill.CamDirectionWS = Vector4(Camera.WorldDirection);
bufferToFill.CamPositionWS = Vector4(Camera.WorldPosition);
bufferToFill.ViewSize = Camera.ViewSize;
bufferToFill.InvViewSize = Camera.InvViewSize;
bufferToFill.RoomNumber = Camera.RoomNumber;
bufferToFill.NearPlane = Camera.NearPlane;
bufferToFill.FarPlane = Camera.FarPlane;
}
void RenderView::clear()
{
RoomsToDraw.clear();
LightsToDraw.clear();
SpritesToDraw.clear();
StaticsToDraw.clear();
}
RenderViewCamera::RenderViewCamera(CAMERA_INFO* cam, float roll, float fov, float n, float f, int w, int h)
{
RoomNumber = cam->pos.RoomNumber;
WorldPosition = Vector3(cam->pos.x, cam->pos.y, cam->pos.z);
Vector3 target = Vector3(cam->target.x, cam->target.y, cam->target.z);
if ((target - WorldPosition) == Vector3::Zero)
target.y -= 10;
WorldDirection = target - WorldPosition;
WorldDirection.Normalize();
Vector3 up = -Vector3::UnitY;
Matrix upRotation = Matrix::CreateFromYawPitchRoll(0.0f, 0.0f, roll);
up = Vector3::Transform(up, upRotation);
up.Normalize();
View = Matrix::CreateLookAt(WorldPosition, target, up);
Projection = Matrix::CreatePerspectiveFieldOfView(fov, w / (float)h, n, f);
ViewProjection = View * Projection;
ViewSize = { (float)w, (float)h };
InvViewSize = { 1.0f / w, 1.0f / h };
Frustum.Update(View, Projection);
NearPlane = n;
FarPlane = f;
}
RenderViewCamera::RenderViewCamera(const Vector3& pos, const Vector3& dir, const Vector3& up, int room, int width, int height, float fov, float n, float f)
{
RoomNumber = room;
WorldPosition = pos;
WorldDirection = dir;
View = Matrix::CreateLookAt(pos, pos + dir * 10240, up);
float aspect = (float)width / (float)height;
Projection = Matrix::CreatePerspectiveFieldOfView(fov, aspect, n, f);
ViewProjection = View * Projection;
ViewSize = { (float)width, (float)height };
InvViewSize = { 1.0f / width, 1.0f / height };
Frustum.Update(View, Projection);
NearPlane = n;
FarPlane = f;
}
}

View file

@ -8,6 +8,7 @@
#include "Specific/memory/LinearArrayBuffer.h"
#include "RendererSprites.h"
#include "RendererTransparentFace.h"
#include "Renderer/Structures/RendererFogBulb.h"
namespace TEN::Renderer
{
@ -47,11 +48,12 @@ namespace TEN::Renderer
struct RenderView
{
RenderViewCamera camera;
D3D11_VIEWPORT viewport;
std::vector<RendererRoom*> roomsToDraw;
std::vector<RendererLight*> lightsToDraw;
std::vector<RendererSpriteToDraw> spritesToDraw;
RenderViewCamera Camera;
D3D11_VIEWPORT Viewport;
std::vector<RendererRoom*> RoomsToDraw;
std::vector<RendererLight*> LightsToDraw;
std::vector<RendererFogBulb> FogBulbsToDraw;
std::vector<RendererSpriteToDraw> SpritesToDraw;
std::vector<RendererStatic*> StaticsToDraw;
std::map<int, std::vector<RendererStatic*>> SortedStatics;

View file

@ -278,7 +278,7 @@ namespace TEN::Renderer
m_context->PSSetShaderResources((UINT)registerType, 1, texture->ShaderResourceView.GetAddressOf());
ID3D11SamplerState* samplerState = nullptr;
switch (samplerType)
switch (samplerType)
{
case SAMPLER_ANISOTROPIC_CLAMP:
samplerState = m_states->AnisotropicClamp();

View file

@ -5,6 +5,7 @@
#include <PrimitiveBatch.h>
#include <d3d9types.h>
#include "Math/Math.h"
#include "Game/control/box.h"
#include "Game/items.h"
#include "Game/animation.h"
@ -16,6 +17,8 @@
#include "Specific/level.h"
#include "Specific/fast_vector.h"
#include "Renderer/Renderer11Enums.h"
#include "Renderer/Structures/RendererLight.h"
#include "RenderView/RenderView.h"
#include "Renderer/ConstantBuffers/StaticBuffer.h"
#include "Renderer/ConstantBuffers/LightBuffer.h"
#include "Renderer/ConstantBuffers/MiscBuffer.h"
@ -32,7 +35,6 @@
#include "Frustum.h"
#include "RendererBucket.h"
#include "Renderer/RenderTargetCube/RenderTargetCube.h"
#include "RenderView/RenderView.h"
#include "Specific/level.h"
#include "ConstantBuffer/ConstantBuffer.h"
#include "RenderTargetCubeArray/RenderTargetCubeArray.h"
@ -42,7 +44,6 @@
#include "Renderer/ConstantBuffers/InstancedSpriteBuffer.h"
#include "Renderer/ConstantBuffers/PostProcessBuffer.h"
#include "Renderer/Structures/RendererBone.h"
#include "Renderer/Structures/RendererLight.h"
#include "Renderer/Structures/RendererStringToDraw.h"
#include "Renderer/Structures/RendererRoom.h"
#include "Renderer/VertexBuffer/VertexBuffer.h"
@ -407,6 +408,9 @@ namespace TEN::Renderer
fast_vector<int> m_transparentFacesIndices;
std::vector<RendererTransparentFace> m_transparentFaces;
VertexBuffer m_skyVertexBuffer;
IndexBuffer m_skyIndexBuffer;
std::vector<RendererRoom> m_rooms;
bool m_invalidateCache;
@ -517,6 +521,7 @@ namespace TEN::Renderer
void InitializeCommonTextures();
void InitializeGameBars();
void InitializeMenuBars(int y);
void InitializeSky();
void DrawAllStrings();
void DrawLaserBarriers(RenderView& view);

View file

@ -406,7 +406,7 @@ namespace TEN::Renderer
light->Color = Vector3(oldLight->r, oldLight->g, oldLight->b) * oldLight->intensity;
light->Intensity = oldLight->intensity;
light->Direction = Vector3(oldLight->dx, oldLight->dy, oldLight->dz);
light->In = oldLight->length;
light->In = oldLight->length;
light->Out = oldLight->cutoff;
light->InRange = oldLight->in;
light->OutRange = oldLight->out;
@ -414,6 +414,16 @@ namespace TEN::Renderer
light->Type = LIGHT_TYPE_SPOT;
light->Luma = Luma(light->Color);
}
else if (oldLight->type == LIGHT_TYPE_FOG_BULB)
{
light->Position = Vector3(oldLight->x, oldLight->y, oldLight->z);
light->Color = Vector3(oldLight->r, oldLight->g, oldLight->b);
light->Intensity = oldLight->intensity;
light->In = oldLight->in;
light->Out = oldLight->out;
light->Type = LIGHT_TYPE_FOG_BULB;
light->Luma = Luma(light->Color);
}
// Monty's temp variables for sorting
light->LocalIntensity = 0;
@ -448,7 +458,7 @@ namespace TEN::Renderer
);
TENLog("Preparing object data...", LogLevel::Info);
bool isSkinPresent = false;
totalVertices = 0;
@ -486,9 +496,9 @@ namespace TEN::Renderer
moveable.Id = MoveablesIds[i];
moveable.DoNotDraw = (obj->drawRoutine == nullptr);
moveable.ShadowType = obj->shadowType;
for (int j = 0; j < obj->nmeshes; j++)
{
{
// HACK: mesh pointer 0 is the placeholder for Lara's body parts and is right hand with pistols
// We need to override the bone index because the engine will take mesh 0 while drawing pistols anim,
// and vertices have bone index 0 and not 10.

View file

@ -48,12 +48,12 @@ namespace TEN::Renderer
static const std::array<LARA_MESHES, 4> sphereMeshes = { LM_HIPS, LM_TORSO, LM_LFOOT, LM_RFOOT };
static const std::array<float, 4> sphereScaleFactors = { 6.0f, 3.2f, 2.8f, 2.8f };
for (auto& room : renderView.roomsToDraw)
for (auto& room : renderView.RoomsToDraw)
{
for (auto& i : room->ItemsToDraw)
{
auto& nativeItem = g_Level.Items[i->ItemNumber];
// Skip everything that isn't alive or a vehicle.
if (Objects[nativeItem.ObjectNumber].shadowType == ShadowMode::None)
continue;
@ -1015,8 +1015,8 @@ namespace TEN::Renderer
void Renderer11::DrawSortedFaces(RenderView& view)
{
std::for_each(std::execution::par_unseq,
view.roomsToDraw.begin(),
view.roomsToDraw.end(),
view.RoomsToDraw.begin(),
view.RoomsToDraw.end(),
[](RendererRoom* room)
{
std::sort(
@ -1030,9 +1030,9 @@ namespace TEN::Renderer
}
);
for (int r = (int)view.roomsToDraw.size() - 1; r >= 0; r--)
for (int r = (int)view.RoomsToDraw.size() - 1; r >= 0; r--)
{
RendererRoom& room = *view.roomsToDraw[r];
RendererRoom& room = *view.RoomsToDraw[r];
m_transparentFacesVertices.clear();
m_transparentFacesIndices.clear();
@ -1271,7 +1271,7 @@ namespace TEN::Renderer
m_stRoom.Caustics = (int)(g_Configuration.EnableCaustics && (nativeRoom->flags & ENV_FLAG_WATER));
m_stRoom.AmbientColor = info->room->AmbientLight;
m_stRoom.Water = (nativeRoom->flags & ENV_FLAG_WATER) != 0 ? 1 : 0;
BindRoomLights(view.lightsToDraw);
BindRoomLights(view.LightsToDraw);
m_cbRoom.updateData(m_stRoom, m_context.Get());
BindConstantBufferVS(CB_ROOM, m_cbRoom.get());
BindConstantBufferPS(CB_ROOM, m_cbRoom.get());
@ -1399,7 +1399,7 @@ namespace TEN::Renderer
{
ResetDebugVariables();
m_Locked = false;
using ns = std::chrono::nanoseconds;
using get_time = std::chrono::steady_clock;
@ -1432,20 +1432,17 @@ namespace TEN::Renderer
// Bind and clear render target
m_context->ClearRenderTargetView(m_renderTarget.RenderTargetView.Get(), Colors::Black);
m_context->ClearDepthStencilView(m_renderTarget.DepthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL,
1.0f, 0);
m_context->ClearDepthStencilView(m_renderTarget.DepthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
m_context->ClearRenderTargetView(m_depthMap.RenderTargetView.Get(), Colors::White);
m_context->ClearDepthStencilView(m_depthMap.DepthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL,
1.0f, 0);
m_context->ClearDepthStencilView(m_depthMap.DepthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
ID3D11RenderTargetView* m_pRenderViews[2];
m_pRenderViews[0] = m_renderTarget.RenderTargetView.Get();
m_pRenderViews[1] = m_depthMap.RenderTargetView.Get();
m_context->OMSetRenderTargets(2, &m_pRenderViews[0],
m_renderTarget.DepthStencilView.Get());
m_context->OMSetRenderTargets(2, &m_pRenderViews[0], m_renderTarget.DepthStencilView.Get());
m_context->RSSetViewports(1, &view.viewport);
m_context->RSSetViewports(1, &view.Viewport);
ResetScissor();
// The camera constant buffer contains matrices, camera position, fog values and other
@ -1465,15 +1462,28 @@ namespace TEN::Renderer
else
{
cameraConstantBuffer.FogMaxDistance = 0;
cameraConstantBuffer.FogColor = Vector4::Zero;
}
cameraConstantBuffer.NumFogBulbs = (int)view.FogBulbsToDraw.size();
for (int i = 0; i < view.FogBulbsToDraw.size(); i++)
{
cameraConstantBuffer.FogBulbs[i].Position = view.FogBulbsToDraw[i].Position;
cameraConstantBuffer.FogBulbs[i].Density = 1.0f / std::max(14.0f, ((90.0F - view.FogBulbsToDraw[i].Density) * 0.8F + 0.2F));
cameraConstantBuffer.FogBulbs[i].SquaredRadius = SQUARE(view.FogBulbsToDraw[i].Radius);
cameraConstantBuffer.FogBulbs[i].Color = view.FogBulbsToDraw[i].Color;
cameraConstantBuffer.FogBulbs[i].SquaredCameraToFogBulbDistance = SQUARE(view.FogBulbsToDraw[i].Distance);
cameraConstantBuffer.FogBulbs[i].FogBulbToCameraVector = view.FogBulbsToDraw[i].FogBulbToCameraVector;
}
m_cbCameraMatrices.updateData(cameraConstantBuffer, m_context.Get());
BindConstantBufferVS(CB_CAMERA, m_cbCameraMatrices.get());
BindConstantBufferPS(CB_CAMERA, m_cbCameraMatrices.get());
// Draw the horizon and the sky
DrawHorizonAndSky(view, m_renderTarget.DepthStencilView.Get());
// Draw opaque and alpha test faces
DrawRooms(view, false);
DrawItems(view, false);
@ -1569,7 +1579,7 @@ namespace TEN::Renderer
m_context->ClearDepthStencilView(depthTarget, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
m_context->OMSetRenderTargets(1, &target, depthTarget);
m_context->RSSetViewports(1, &view.viewport);
m_context->RSSetViewports(1, &view.Viewport);
ResetScissor();
// Opaque geometry
@ -1605,7 +1615,7 @@ namespace TEN::Renderer
m_context->VSSetShader(m_vsItems.Get(), nullptr, 0);
m_context->PSSetShader(m_psItems.Get(), nullptr, 0);
for (auto room : view.roomsToDraw)
for (auto room : view.RoomsToDraw)
{
for (auto itemToDraw : room->ItemsToDraw)
{
@ -1640,7 +1650,7 @@ namespace TEN::Renderer
if (g_Configuration.ShadowType != ShadowMode::None)
{
for (auto room : renderView.roomsToDraw)
for (auto room : renderView.RoomsToDraw)
for (auto itemToDraw : room->ItemsToDraw)
RenderShadowMap(itemToDraw, renderView);
}
@ -1898,7 +1908,7 @@ namespace TEN::Renderer
{
Vector3 cameraPosition = Vector3(Camera.pos.x, Camera.pos.y, Camera.pos.z);
for (auto room : view.roomsToDraw)
for (auto room : view.RoomsToDraw)
{
for (auto& msh : view.StaticsToDraw)
{
@ -2000,10 +2010,10 @@ namespace TEN::Renderer
}
m_numRoomsTransparentPolygons = 0;
for (int i = (int)view.roomsToDraw.size() - 1; i >= 0; i--)
for (int i = (int)view.RoomsToDraw.size() - 1; i >= 0; i--)
{
int index = i;
RendererRoom* room = view.roomsToDraw[index];
RendererRoom* room = view.RoomsToDraw[index];
m_cbShadowMap.updateData(m_stShadowMap, m_context.Get());
BindConstantBufferPS(CB_SHADOW_LIGHT, m_cbShadowMap.get());
@ -2017,7 +2027,7 @@ namespace TEN::Renderer
m_stRoom.Caustics = (int)(g_Configuration.EnableCaustics && (nativeRoom->flags & ENV_FLAG_WATER));
m_stRoom.AmbientColor = room->AmbientLight;
m_stRoom.Water = (nativeRoom->flags & ENV_FLAG_WATER) != 0 ? 1 : 0;
BindRoomLights(view.lightsToDraw);
BindRoomLights(view.LightsToDraw);
m_cbRoom.updateData(m_stRoom, m_context.Get());
SetScissor(room->ClipBounds);
@ -2152,9 +2162,9 @@ namespace TEN::Renderer
ScriptInterfaceLevel* level = g_GameFlow->GetLevel(CurrentLevel);
bool anyOutsideRooms = false;
for (int k = 0; k < renderView.roomsToDraw.size(); k++)
for (int k = 0; k < renderView.RoomsToDraw.size(); k++)
{
ROOM_INFO* nativeRoom = &g_Level.Rooms[renderView.roomsToDraw[k]->RoomNumber];
ROOM_INFO* nativeRoom = &g_Level.Rooms[renderView.RoomsToDraw[k]->RoomNumber];
if (nativeRoom->flags & ENV_FLAG_OUTSIDE)
{
anyOutsideRooms = true;
@ -2174,66 +2184,26 @@ namespace TEN::Renderer
// Draw the sky
Matrix rotation = Matrix::CreateRotationX(PI);
RendererVertex vertices[4];
float size = 9728.0f;
vertices[0].Position.x = -size / 2.0f;
vertices[0].Position.y = 0.0f;
vertices[0].Position.z = size / 2.0f;
vertices[0].UV.x = 0.0f;
vertices[0].UV.y = 0.0f;
vertices[0].Color.x = 1.0f;
vertices[0].Color.y = 1.0f;
vertices[0].Color.z = 1.0f;
vertices[0].Color.w = 1.0f;
vertices[1].Position.x = size / 2.0f;
vertices[1].Position.y = 0.0f;
vertices[1].Position.z = size / 2.0f;
vertices[1].UV.x = 1.0f;
vertices[1].UV.y = 0.0f;
vertices[1].Color.x = 1.0f;
vertices[1].Color.y = 1.0f;
vertices[1].Color.z = 1.0f;
vertices[1].Color.w = 1.0f;
vertices[2].Position.x = size / 2.0f;
vertices[2].Position.y = 0.0f;
vertices[2].Position.z = -size / 2.0f;
vertices[2].UV.x = 1.0f;
vertices[2].UV.y = 1.0f;
vertices[2].Color.x = 1.0f;
vertices[2].Color.y = 1.0f;
vertices[2].Color.z = 1.0f;
vertices[2].Color.w = 1.0f;
vertices[3].Position.x = -size / 2.0f;
vertices[3].Position.y = 0.0f;
vertices[3].Position.z = -size / 2.0f;
vertices[3].UV.x = 0.0f;
vertices[3].UV.y = 1.0f;
vertices[3].Color.x = 1.0f;
vertices[3].Color.y = 1.0f;
vertices[3].Color.z = 1.0f;
vertices[3].Color.w = 1.0f;
m_context->VSSetShader(m_vsSky.Get(), nullptr, 0);
m_context->PSSetShader(m_psSky.Get(), nullptr, 0);
BindTexture(TEXTURE_COLOR_MAP, &m_skyTexture, SAMPLER_ANISOTROPIC_CLAMP);
m_context->IASetVertexBuffers(0, 1, m_skyVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
m_context->IASetInputLayout(m_inputLayout.Get());
m_context->IASetIndexBuffer(m_skyIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
SetBlendMode(BLENDMODE_ADDITIVE);
for (int s = 0; s < 2; s++)
{
for (int i = 0; i < 2; i++)
{
auto weather = TEN::Effects::Environment::Weather;
Matrix translation = Matrix::CreateTranslation(Camera.pos.x + weather.SkyPosition(s) - i * 9728.0f,
Camera.pos.y - 1536.0f, Camera.pos.z);
Matrix translation = Matrix::CreateTranslation(Camera.pos.x + weather.SkyPosition(s) - i * SKY_SIZE,
Camera.pos.y - 1536.0f, Camera.pos.z);
Matrix world = rotation * translation;
m_stStatic.World = (rotation * translation);
@ -2245,10 +2215,10 @@ namespace TEN::Renderer
BindConstantBufferVS(CB_STATIC, m_cbStatic.get());
BindConstantBufferPS(CB_STATIC, m_cbStatic.get());
m_primitiveBatch->Begin();
m_primitiveBatch->DrawQuad(vertices[0], vertices[1], vertices[2], vertices[3]);
m_primitiveBatch->End();
DrawIndexedTriangles(SKY_INDICES_COUNT, 0, 0);
}
}
m_context->ClearDepthStencilView(depthTarget, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0);
// Draw horizon
@ -2260,7 +2230,7 @@ namespace TEN::Renderer
m_context->IASetIndexBuffer(m_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
RendererObject& moveableObj = *m_moveableObjects[ID_HORIZON];
m_stStatic.World = Matrix::CreateTranslation(Camera.pos.x, Camera.pos.y, Camera.pos.z);
m_stStatic.Color = Vector4::One;
m_stStatic.AmbientLight = Vector4::One;

View file

@ -310,7 +310,7 @@ namespace TEN::Renderer
m_context->ClearRenderTargetView(target, Colors::Black);
m_context->ClearDepthStencilView(depthTarget, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
m_context->OMSetRenderTargets(1, &target, depthTarget);
m_context->RSSetViewports(1, &view.viewport);
m_context->RSSetViewports(1, &view.Viewport);
ResetScissor();
RendererVertex vertices[4];

View file

@ -965,7 +965,7 @@ namespace TEN::Renderer
m_context->IASetInputLayout(m_inputLayout.Get());
m_context->IASetIndexBuffer(m_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
for (auto* room : view.roomsToDraw)
for (auto* room : view.RoomsToDraw)
{
for (auto* item : room->ItemsToDraw)
{
@ -1081,7 +1081,7 @@ namespace TEN::Renderer
{
case RENDERER_SPRITE_TYPE::SPRITE_TYPE_BILLBOARD:
{
auto cameraUp = Vector3(view.camera.View._12, view.camera.View._22, view.camera.View._32);
auto cameraUp = Vector3(view.Camera.View._12, view.Camera.View._22, view.Camera.View._32);
spriteMatrix = scaleMatrix * Matrix::CreateRotationZ(sprite->Rotation) * Matrix::CreateBillboard(sprite->pos, Camera.pos.ToVector3(), cameraUp);
}
break;
@ -1117,13 +1117,13 @@ namespace TEN::Renderer
void Renderer11::DrawSprites(RenderView& view)
{
if (view.spritesToDraw.empty())
if (view.SpritesToDraw.empty())
return;
// Sort sprites by sprite and blend mode for faster batching.
std::sort(
view.spritesToDraw.begin(),
view.spritesToDraw.end(),
view.SpritesToDraw.begin(),
view.SpritesToDraw.end(),
[](RendererSpriteToDraw& rDrawSprite0, RendererSpriteToDraw& rDrawSprite1)
{
if (rDrawSprite0.Sprite != rDrawSprite1.Sprite)
@ -1145,13 +1145,13 @@ namespace TEN::Renderer
std::vector<RendererSpriteBucket> spriteBuckets;
RendererSpriteBucket currentSpriteBucket;
currentSpriteBucket.Sprite = view.spritesToDraw[0].Sprite;
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;
currentSpriteBucket.Sprite = view.SpritesToDraw[0].Sprite;
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)
for (auto& rDrawSprite : view.SpritesToDraw)
{
bool isBillboard = rDrawSprite.Type != RENDERER_SPRITE_TYPE::SPRITE_TYPE_3D;
@ -1184,12 +1184,12 @@ namespace TEN::Renderer
face.info.world = GetWorldMatrixForSprite(&rDrawSprite, view);
face.info.blendMode = rDrawSprite.BlendMode;
for (int j = 0; j < view.roomsToDraw.size(); j++)
for (int j = 0; j < view.RoomsToDraw.size(); j++)
{
short roomNumber = view.roomsToDraw[j]->RoomNumber;
short roomNumber = view.RoomsToDraw[j]->RoomNumber;
if (g_Level.Rooms[roomNumber].Active() && IsPointInRoom(Vector3i(rDrawSprite.pos), roomNumber))
{
view.roomsToDraw[j]->TransparentFacesToDraw.push_back(face);
view.RoomsToDraw[j]->TransparentFacesToDraw.push_back(face);
break;
}
}
@ -1433,7 +1433,7 @@ namespace TEN::Renderer
m_context->IASetInputLayout(m_inputLayout.Get());
m_context->IASetIndexBuffer(m_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
for (auto room : view.roomsToDraw)
for (auto room : view.RoomsToDraw)
{
for (auto effect : room->EffectsToDraw)
{

View file

@ -932,7 +932,7 @@ namespace TEN::Renderer
PrintDebugMessage(" Statics: %d", m_numStaticsDrawCalls);
PrintDebugMessage(" Sprites: %d", m_numSpritesDrawCalls);
PrintDebugMessage("Triangles: %d", m_numPolygons);
PrintDebugMessage("Sprites: %d", view.spritesToDraw.size());
PrintDebugMessage("Sprites: %d", view.SpritesToDraw.size());
PrintDebugMessage("Transparent faces draw calls: %d", m_numTransparentDrawCalls);
PrintDebugMessage(" Rooms: %d", m_numRoomsTransparentDrawCalls);
PrintDebugMessage(" Movables: %d", m_numMoveablesTransparentDrawCalls);
@ -940,7 +940,7 @@ namespace TEN::Renderer
PrintDebugMessage(" Sprites: %d", m_numSpritesTransparentDrawCalls);
PrintDebugMessage("Biggest room's index buffer: %d", m_biggestRoomIndexBuffer);
PrintDebugMessage("Transparent room polys: %d", m_numRoomsTransparentPolygons);
PrintDebugMessage("Rooms: %d", view.roomsToDraw.size());
PrintDebugMessage("Rooms: %d", view.RoomsToDraw.size());
PrintDebugMessage(" CheckPortal() calls: %d", m_numCheckPortalCalls);
PrintDebugMessage(" GetVisibleRooms() calls: %d", m_numGetVisibleRoomsCalls);
PrintDebugMessage(" Dot products: %d", m_dotProducts);

View file

@ -36,7 +36,8 @@ enum LIGHT_TYPES
LIGHT_TYPE_SUN = 0,
LIGHT_TYPE_POINT = 1,
LIGHT_TYPE_SPOT = 2,
LIGHT_TYPE_SHADOW = 3
LIGHT_TYPE_SHADOW = 3,
LIGHT_TYPE_FOG_BULB = 4
};
enum BLEND_MODES
@ -223,6 +224,7 @@ constexpr auto FADE_FACTOR = 0.0625f;
constexpr auto NUM_LIGHTS_PER_BUFFER = 48;
constexpr auto MAX_LIGHTS_PER_ITEM = 8;
constexpr auto MAX_FOG_BULBS = 32;
constexpr auto MAX_LIGHTS = 100;
constexpr auto AMBIENT_LIGHT_INTERPOLATION_STEP = 1.0f / 10.0f;
constexpr auto MAX_DYNAMIC_SHADOWS = 1;
@ -252,6 +254,12 @@ constexpr auto DEFAULT_FAR_VIEW = 102400.0f;
constexpr auto INSTANCED_SPRITES_BUCKET_SIZE = 512;
constexpr auto SKY_TILES_COUNT = 20;
constexpr auto SKY_SIZE = 10240.0f;
constexpr auto SKY_VERTICES_COUNT = 4 * SKY_TILES_COUNT * SKY_TILES_COUNT;
constexpr auto SKY_INDICES_COUNT = 6 * SKY_TILES_COUNT * SKY_TILES_COUNT;
constexpr auto SKY_TRIANGLES_COUNT = 2 * SKY_TILES_COUNT * SKY_TILES_COUNT;
// FUTURE
/*
#define CBUFFER_CAMERA 0

View file

@ -24,10 +24,10 @@ namespace TEN::Renderer
void Renderer11::CollectRooms(RenderView& renderView, bool onlyRooms)
{
for (int i = 0; i < g_Level.Rooms.size(); i++)
{
{
RendererRoom* room = &m_rooms[i];
room->ItemsToDraw.clear();
room->ItemsToDraw.clear();
room->EffectsToDraw.clear();
room->TransparentFacesToDraw.clear();
room->StaticsToDraw.clear();
@ -43,24 +43,64 @@ namespace TEN::Renderer
}
}
GetVisibleRooms(NO_ROOM, renderView.camera.RoomNumber, Vector4(-1.0f, -1.0f, 1.0f, 1.0f), false, 0, onlyRooms, renderView);
GetVisibleRooms(NO_ROOM, renderView.Camera.RoomNumber, Vector4(-1.0f, -1.0f, 1.0f, 1.0f), false, 0, onlyRooms, renderView);
m_invalidateCache = false;
m_invalidateCache = false;
// Prepae the real DX scissor test rectangle
for (auto room : renderView.roomsToDraw)
for (auto room : renderView.RoomsToDraw)
{
room->ClipBounds.left = (room->ViewPort.x + 1.0f) * m_screenWidth * 0.5f;
room->ClipBounds.bottom = (1.0f - room->ViewPort.y) * m_screenHeight * 0.5f;
room->ClipBounds.right = (room->ViewPort.z + 1.0f) * m_screenWidth * 0.5f;
room->ClipBounds.top = (1.0f - room->ViewPort.w) * m_screenHeight * 0.5f;
}
}
// Sort statics for doing instancing later
std::sort(renderView.StaticsToDraw.begin(), renderView.StaticsToDraw.end(), [](const RendererStatic* a, const RendererStatic* b)
{
return a->ObjectNumber < b->ObjectNumber;
});
// Collect fog bulbs
renderView.FogBulbsToDraw.clear();
vector<RendererFogBulb> tempFogBulbs;
for (auto room : m_rooms)
{
for (RendererLight light : room.Lights)
{
if (light.Type == LIGHT_TYPE_FOG_BULB)
{
RendererFogBulb bulb;
if (renderView.Camera.Frustum.SphereInFrustum(light.Position, light.Out))
{
bulb.Position = light.Position;
bulb.Density = light.Intensity;
bulb.Color = light.Color;
bulb.Radius = light.Out;
bulb.FogBulbToCameraVector = bulb.Position - renderView.Camera.WorldPosition;
bulb.Distance = bulb.FogBulbToCameraVector.Length();
tempFogBulbs.push_back(bulb);
}
}
}
}
std::sort(
tempFogBulbs.begin(),
tempFogBulbs.end(),
[](RendererFogBulb a, RendererFogBulb b)
{
return a.Distance < b.Distance;
}
);
for (int i = 0; i < std::min(MAX_FOG_BULBS, (int)tempFogBulbs.size()); i++)
{
renderView.FogBulbsToDraw.push_back(tempFogBulbs[i]);
}
}
bool Renderer11::CheckPortal(short parentRoomNumber, RendererDoor* door, Vector4 viewPort, Vector4* clipPort, RenderView& renderView)
@ -79,7 +119,7 @@ namespace TEN::Renderer
{
if (!door->Visited)
{
p[i] = Vector4::Transform(door->AbsoluteVertices[i], renderView.camera.ViewProjection);
p[i] = Vector4::Transform(door->AbsoluteVertices[i], renderView.Camera.ViewProjection);
if (p[i].w > 0.0f)
{
p[i].x *= (1.0f / p[i].w);
@ -196,7 +236,7 @@ namespace TEN::Renderer
{
room->Visited = true;
renderView.roomsToDraw.push_back(room);
renderView.RoomsToDraw.push_back(room);
CollectLightsForRoom(to, renderView);
@ -316,7 +356,7 @@ namespace TEN::Renderer
bool inFrustum = false;
for (int i = 0; !inFrustum, i < cnt; i++)
// Blow up sphere radius by half for cases of too small calculated spheres.
if (renderView.camera.Frustum.SphereInFrustum(spheres[i].Center, spheres[i].Radius * 1.5f))
if (renderView.Camera.Frustum.SphereInFrustum(spheres[i].Center, spheres[i].Radius * 1.5f))
inFrustum = true;
if (!inFrustum)
@ -391,7 +431,7 @@ namespace TEN::Renderer
}
auto length = Vector3(mesh->VisibilityBox.Extents).Length();
if (!renderView.camera.Frustum.SphereInFrustum(mesh->VisibilityBox.Center, length))
if (!renderView.Camera.Frustum.SphereInFrustum(mesh->VisibilityBox.Center, length))
{
continue;
}
@ -721,13 +761,13 @@ namespace TEN::Renderer
}
// Light buffer is full
if (renderView.lightsToDraw.size() >= NUM_LIGHTS_PER_BUFFER)
if (renderView.LightsToDraw.size() >= NUM_LIGHTS_PER_BUFFER)
{
break;
}
// Light already on a list
if (std::find(renderView.lightsToDraw.begin(), renderView.lightsToDraw.end(), light) != renderView.lightsToDraw.end())
if (std::find(renderView.LightsToDraw.begin(), renderView.LightsToDraw.end(), light) != renderView.LightsToDraw.end())
{
continue;
}
@ -738,7 +778,7 @@ namespace TEN::Renderer
continue;
}
renderView.lightsToDraw.push_back(light);
renderView.LightsToDraw.push_back(light);
room.LightsToDraw.push_back(light);
}
}

View file

@ -311,7 +311,7 @@ namespace TEN::Renderer
void Renderer11::UpdateItemAnimations(RenderView& view)
{
for (const auto* room : view.roomsToDraw)
for (const auto* room : view.RoomsToDraw)
{
for (const auto* itemToDraw : room->ItemsToDraw)
{
@ -514,14 +514,14 @@ namespace TEN::Renderer
{
auto point = Vector4(pos.x, pos.y, pos.z, 1.0f);
auto cameraPos = Vector4(
gameCamera.camera.WorldPosition.x,
gameCamera.camera.WorldPosition.y,
gameCamera.camera.WorldPosition.z,
gameCamera.Camera.WorldPosition.x,
gameCamera.Camera.WorldPosition.y,
gameCamera.Camera.WorldPosition.z,
1.0f);
auto cameraDirection = Vector4(
gameCamera.camera.WorldDirection.x,
gameCamera.camera.WorldDirection.y,
gameCamera.camera.WorldDirection.z,
gameCamera.Camera.WorldDirection.x,
gameCamera.Camera.WorldDirection.y,
gameCamera.Camera.WorldDirection.z,
1.0f);
// Point is behind camera; return nullopt.
@ -529,7 +529,7 @@ namespace TEN::Renderer
return std::nullopt;
// Calculate clip space coords.
point = Vector4::Transform(point, gameCamera.camera.ViewProjection);
point = Vector4::Transform(point, gameCamera.Camera.ViewProjection);
// Calculate NDC.
point /= point.w;

View file

@ -229,6 +229,83 @@ void TEN::Renderer::Renderer11::Initialize(int w, int h, bool windowed, HWND han
InitializeGameBars();
initQuad(m_device.Get());
InitializeSky();
}
void TEN::Renderer::Renderer11::InitializeSky()
{
RendererVertex vertices[SKY_VERTICES_COUNT];
int indices[SKY_INDICES_COUNT];
int size = SKY_SIZE;
int lastVertex = 0;
int lastIndex = 0;
for (int x = 0; x < SKY_TILES_COUNT; x++)
{
for (int z = 0; z < SKY_TILES_COUNT; z++)
{
indices[lastIndex + 0] = lastVertex + 0;
indices[lastIndex + 1] = lastVertex + 1;
indices[lastIndex + 2] = lastVertex + 2;
indices[lastIndex + 3] = lastVertex + 0;
indices[lastIndex + 4] = lastVertex + 2;
indices[lastIndex + 5] = lastVertex + 3;
lastIndex += 6;
vertices[lastVertex].Position.x = -size / 2.0f + x * 512.0f;
vertices[lastVertex].Position.y = 0.0f;
vertices[lastVertex].Position.z = -size / 2.0f + (z + 1) * 512.0f;
vertices[lastVertex].UV.x = x / 20.0f;
vertices[lastVertex].UV.y = (z + 1) / 20.0f;
vertices[lastVertex].Color.x = 1.0f;
vertices[lastVertex].Color.y = 1.0f;
vertices[lastVertex].Color.z = 1.0f;
vertices[lastVertex].Color.w = 1.0f;
lastVertex++;
vertices[lastVertex].Position.x = -size / 2.0f + (x + 1) * 512.0f;
vertices[lastVertex].Position.y = 0.0f;
vertices[lastVertex].Position.z = -size / 2.0f + (z + 1) * 512.0f;
vertices[lastVertex].UV.x = (x + 1) / 20.0f;
vertices[lastVertex].UV.y = (z + 1) / 20.0f;
vertices[lastVertex].Color.x = 1.0f;
vertices[lastVertex].Color.y = 1.0f;
vertices[lastVertex].Color.z = 1.0f;
vertices[lastVertex].Color.w = 1.0f;
lastVertex++;
vertices[lastVertex].Position.x = -size / 2.0f + (x + 1) * 512.0f;
vertices[lastVertex].Position.y = 0.0f;
vertices[lastVertex].Position.z = -size / 2.0f + z * 512.0f;
vertices[lastVertex].UV.x = (x + 1) / 20.0f;
vertices[lastVertex].UV.y = z / 20.0f;
vertices[lastVertex].Color.x = 1.0f;
vertices[lastVertex].Color.y = 1.0f;
vertices[lastVertex].Color.z = 1.0f;
vertices[lastVertex].Color.w = 1.0f;
lastVertex++;
vertices[lastVertex].Position.x = -size / 2.0f + x * 512.0f;
vertices[lastVertex].Position.y = 0.0f;
vertices[lastVertex].Position.z = -size / 2.0f + z * 512.0f;
vertices[lastVertex].UV.x = x / 20.0f;
vertices[lastVertex].UV.y = z / 20.0f;
vertices[lastVertex].Color.x = 1.0f;
vertices[lastVertex].Color.y = 1.0f;
vertices[lastVertex].Color.z = 1.0f;
vertices[lastVertex].Color.w = 1.0f;
lastVertex++;
}
}
m_skyVertexBuffer = VertexBuffer(m_device.Get(), SKY_VERTICES_COUNT, vertices);
m_skyIndexBuffer = IndexBuffer(m_device.Get(), SKY_INDICES_COUNT, indices);
}
void TEN::Renderer::Renderer11::InitializeScreen(int w, int h, HWND handle, bool reset)

View file

@ -34,7 +34,7 @@ namespace TEN::Renderer
spr.color = color;
spr.renderType = renderType;
view.spritesToDraw.push_back(spr);
view.SpritesToDraw.push_back(spr);
}
void Renderer11::AddSpriteBillboardConstrained(RendererSprite* sprite, const Vector3& pos, const Vector4 &color, float orient2D,
@ -69,7 +69,7 @@ namespace TEN::Renderer
spr.color = color;
spr.renderType = renderType;
view.spritesToDraw.push_back(spr);
view.SpritesToDraw.push_back(spr);
}
void Renderer11::AddSpriteBillboardConstrainedLookAt(RendererSprite* sprite, const Vector3& pos, const Vector4& color, float orient2D,
@ -104,7 +104,7 @@ namespace TEN::Renderer
spr.color = color;
spr.renderType = renderType;
view.spritesToDraw.push_back(spr);
view.SpritesToDraw.push_back(spr);
}
void Renderer11::AddQuad(RendererSprite* sprite, const Vector3& vertex0, const Vector3& vertex1, const Vector3& vertex2, const Vector3& vertex3,
@ -148,7 +148,7 @@ namespace TEN::Renderer
spr.SoftParticle = isSoftParticle;
spr.renderType = renderType;
view.spritesToDraw.push_back(spr);
view.SpritesToDraw.push_back(spr);
}
void Renderer11::AddColoredQuad(const Vector3& vertex0, const Vector3& vertex1, const Vector3& vertex2, const Vector3& vertex3,
@ -181,7 +181,7 @@ namespace TEN::Renderer
sprite.SoftParticle = false;
sprite.renderType = renderType;
view.spritesToDraw.push_back(sprite);
view.SpritesToDraw.push_back(sprite);
}
}

View file

@ -0,0 +1,15 @@
#pragma once
#include <SimpleMath.h>
namespace TEN::Renderer
{
struct RendererFogBulb
{
Vector3 Position;
float Density;
Vector3 Color;
float Radius;
float Distance;
Vector3 FogBulbToCameraVector;
};
}

View file

@ -1,37 +1,37 @@
#pragma once
#include <vector>
#include <SimpleMath.h>
#include "Renderer/RendererRectangle.h"
struct MESH_INFO;
namespace TEN::Renderer
{
struct RendererItem;
struct RendererBucket;
struct RendererLight;
struct RendererEffect;
struct RendererTransparentFace;
struct RendererDoor;
struct RendererRoom
{
bool Visited;
short RoomNumber;
Vector4 AmbientLight;
Vector4 ViewPort;
std::vector<RendererBucket> Buckets;
std::vector<RendererLight> Lights;
std::vector<RendererStatic> Statics;
std::vector<RendererItem*> ItemsToDraw;
std::vector<RendererEffect*> EffectsToDraw;
std::vector<RendererStatic*> StaticsToDraw;
std::vector<RendererTransparentFace> TransparentFacesToDraw;
std::vector<RendererLight*> LightsToDraw;
std::vector<RendererDoor> Doors;
BoundingBox BoundingBox;
RendererRectangle ClipBounds;
std::vector<int> Neighbors;
};
}
#pragma once
#include <vector>
#include <SimpleMath.h>
#include "Renderer/RendererRectangle.h"
struct MESH_INFO;
namespace TEN::Renderer
{
struct RendererItem;
struct RendererBucket;
struct RendererLight;
struct RendererEffect;
struct RendererTransparentFace;
struct RendererDoor;
struct RendererRoom
{
bool Visited;
short RoomNumber;
Vector4 AmbientLight;
Vector4 ViewPort;
std::vector<RendererBucket> Buckets;
std::vector<RendererLight> Lights;
std::vector<RendererStatic> Statics;
std::vector<RendererItem*> ItemsToDraw;
std::vector<RendererEffect*> EffectsToDraw;
std::vector<RendererStatic*> StaticsToDraw;
std::vector<RendererTransparentFace> TransparentFacesToDraw;
std::vector<RendererLight*> LightsToDraw;
std::vector<RendererDoor> Doors;
BoundingBox BoundingBox;
RendererRectangle ClipBounds;
std::vector<int> Neighbors;
};
}

View file

@ -1,175 +1,206 @@
#ifndef BLENDINGSHADER
#define BLENDINGSHADER
#include "./Math.hlsli"
#define ALPHA_TEST_NONE 0
#define ALPHA_TEST_GREATER_THAN 1
#define ALPHA_TEST_LESS_THAN 2
#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 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;
float AlphaThreshold;
};
void DoAlphaTest(float4 inputColor)
{
if (AlphaTest == ALPHA_TEST_GREATER_THAN && inputColor.w < AlphaThreshold)
{
discard;
}
else if (AlphaTest == ALPHA_TEST_LESS_THAN && inputColor.w > AlphaThreshold)
{
discard;
}
else
{
return;
}
}
float4 DoFog(float4 sourceColor, float4 fogColor, float value)
{
if (FogMaxDistance == 0)
return sourceColor;
switch (BlendMode)
{
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_ALPHABLEND:
fogColor.w = sourceColor.w;
break;
default:
break;
}
if (fogColor.w > sourceColor.w)
fogColor.w = sourceColor.w;
float4 result = lerp(sourceColor, fogColor, value);
return result;
}
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
#ifndef BLENDINGSHADER
#define BLENDINGSHADER
#include "./Math.hlsli"
#define ALPHA_TEST_NONE 0
#define ALPHA_TEST_GREATER_THAN 1
#define ALPHA_TEST_LESS_THAN 2
#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 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;
float AlphaThreshold;
};
void DoAlphaTest(float4 inputColor)
{
if (AlphaTest == ALPHA_TEST_GREATER_THAN && inputColor.w < AlphaThreshold)
{
discard;
}
else if (AlphaTest == ALPHA_TEST_LESS_THAN && inputColor.w > AlphaThreshold)
{
discard;
}
else
{
return;
}
}
float4 DoDistanceFogForPixel(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_SUBTRACTIVE:
case BLENDMODE_EXCLUDE:
fogColor.xyz *= 1.0f - Luma(sourceColor.xyz);
break;
case BLENDMODE_ALPHABLEND:
fogColor.w = sourceColor.w;
break;
default:
break;
}
if (fogColor.w > sourceColor.w)
fogColor.w = sourceColor.w;
float4 result = lerp(sourceColor, fogColor, value);
return result;
}
float4 DoFogBulbsForPixel(float4 sourceColor, float4 fogColor)
{
switch (BlendMode)
{
case BLENDMODE_ADDITIVE:
case BLENDMODE_SCREEN:
case BLENDMODE_LIGHTEN:
fogColor.xyz *= Luma(sourceColor);
break;
case BLENDMODE_SUBTRACTIVE:
case BLENDMODE_EXCLUDE:
fogColor.xyz *= 1.0f - Luma(sourceColor.xyz);
break;
case BLENDMODE_ALPHABLEND:
fogColor.w = sourceColor.w;
break;
default:
break;
}
if (fogColor.w > sourceColor.w)
fogColor.w = sourceColor.w;
float4 result = sourceColor;
result.xyz += saturate(fogColor.xyz);
return result;
}
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

@ -1,3 +1,5 @@
#include "./Math.hlsli"
cbuffer CameraMatrixBuffer : register(b0)
{
float4x4 ViewProjection;
@ -15,5 +17,7 @@ cbuffer CameraMatrixBuffer : register(b0)
int FogMinDistance;
int FogMaxDistance;
float NearPlane;
float FarPlane;
float FarPlane;
int NumFogBulbs;
ShaderFogBulb FogBulbs[MAX_FOG_BULBS];
};

View file

@ -1,111 +1,113 @@
#include "./CameraMatrixBuffer.hlsli"
#include "./Blending.hlsli"
#include "./VertexInput.hlsli"
#include "./Math.hlsli"
// NOTE: This shader is used for all opaque or not sorted transparent sprites, that can be instanced for a faster drawing
#define INSTANCED_SPRITES_BUCKET_SIZE 512
struct PixelShaderInput
{
float4 Position: SV_POSITION;
float2 UV: TEXCOORD1;
float4 Color: COLOR;
float Fog : FOG;
float4 PositionCopy: TEXCOORD2;
};
struct InstancedSprite
{
float4x4 World;
float4 UV[2];
float4 Color;
float IsBillboard;
float IsSoftParticle;
};
cbuffer InstancedSpriteBuffer : register(b13)
{
InstancedSprite Sprites[INSTANCED_SPRITES_BUCKET_SIZE];
};
Texture2D Texture : register(t0);
SamplerState Sampler : register(s0);
Texture2D DepthMap : register(t6);
SamplerState DepthMapSampler : register(s6);
PixelShaderInput VS(VertexShaderInput input, uint InstanceID : SV_InstanceID)
{
PixelShaderInput output;
float4 worldPosition;
if (Sprites[InstanceID].IsBillboard == 1)
{
worldPosition = mul(float4(input.Position, 1.0f), Sprites[InstanceID].World);
output.Position = mul(mul(float4(input.Position, 1.0f), Sprites[InstanceID].World), ViewProjection);
}
else
{
worldPosition = float4(input.Position, 1.0f);
output.Position = mul(float4(input.Position, 1.0f), ViewProjection);
}
output.PositionCopy = output.Position;
output.Color = Sprites[InstanceID].Color;
output.UV = float2(Sprites[InstanceID].UV[0][input.PolyIndex], Sprites[InstanceID].UV[1][input.PolyIndex]);
float4 d = length(CamPositionWS - worldPosition);
if (FogMaxDistance == 0)
output.Fog = 1;
else
output.Fog = clamp((d - FogMinDistance * 1024) / (FogMaxDistance * 1024 - FogMinDistance * 1024), 0, 1);
return output;
}
// TODO: From NVIDIA SDK, check if it can be useful instead of linear ramp
float Contrast(float Input, float ContrastPower)
{
#if 1
//piecewise contrast function
bool IsAboveHalf = Input > 0.5;
float ToRaise = saturate(2 * (IsAboveHalf ? 1 - Input : Input));
float Output = 0.5 * pow(ToRaise, ContrastPower);
Output = IsAboveHalf ? 1 - Output : Output;
return Output;
#else
// another solution to create a kind of contrast function
return 1.0 - exp2(-2 * pow(2.0 * saturate(Input), ContrastPower));
#endif
}
float4 PS(PixelShaderInput input, uint InstanceID : SV_InstanceID) : SV_TARGET
{
float4 output = Texture.Sample(Sampler, input.UV) * input.Color;
//DoAlphaTest(output);
if (Sprites[InstanceID].IsSoftParticle == 1)
{
float particleDepth = input.PositionCopy.z / input.PositionCopy.w;
input.PositionCopy.xy /= input.PositionCopy.w;
float2 texCoord = 0.5f * (float2(input.PositionCopy.x, -input.PositionCopy.y) + 1);
float sceneDepth = DepthMap.Sample(DepthMapSampler, texCoord).r;
sceneDepth = LinearizeDepth(sceneDepth, NearPlane, FarPlane);
particleDepth = LinearizeDepth(particleDepth, NearPlane, FarPlane);
if (particleDepth - sceneDepth > 0.01f)
discard;
float fade = (sceneDepth - particleDepth) * 1024.0f;
output.w = min(output.w, fade);
}
output = DoFog(output, float4(0.0f, 0.0f, 0.0f, 0.0f), input.Fog);
return output;
#include "./CameraMatrixBuffer.hlsli"
#include "./Blending.hlsli"
#include "./VertexInput.hlsli"
#include "./Math.hlsli"
#include "./ShaderLight.hlsli"
// NOTE: This shader is used for all opaque or not sorted transparent sprites, that can be instanced for a faster drawing
#define INSTANCED_SPRITES_BUCKET_SIZE 512
struct PixelShaderInput
{
float4 Position: SV_POSITION;
float2 UV: TEXCOORD1;
float4 Color: COLOR;
float4 PositionCopy: TEXCOORD2;
float4 FogBulbs : TEXCOORD3;
float DistanceFog : FOG;
};
struct InstancedSprite
{
float4x4 World;
float4 UV[2];
float4 Color;
float IsBillboard;
float IsSoftParticle;
};
cbuffer InstancedSpriteBuffer : register(b13)
{
InstancedSprite Sprites[INSTANCED_SPRITES_BUCKET_SIZE];
};
Texture2D Texture : register(t0);
SamplerState Sampler : register(s0);
Texture2D DepthMap : register(t6);
SamplerState DepthMapSampler : register(s6);
PixelShaderInput VS(VertexShaderInput input, uint InstanceID : SV_InstanceID)
{
PixelShaderInput output;
float4 worldPosition;
if (Sprites[InstanceID].IsBillboard == 1)
{
worldPosition = mul(float4(input.Position, 1.0f), Sprites[InstanceID].World);
output.Position = mul(mul(float4(input.Position, 1.0f), Sprites[InstanceID].World), ViewProjection);
}
else
{
worldPosition = float4(input.Position, 1.0f);
output.Position = mul(float4(input.Position, 1.0f), ViewProjection);
}
output.PositionCopy = output.Position;
output.Color = Sprites[InstanceID].Color;
output.UV = float2(Sprites[InstanceID].UV[0][input.PolyIndex], Sprites[InstanceID].UV[1][input.PolyIndex]);
output.FogBulbs = DoFogBulbsForVertex(worldPosition);
output.DistanceFog = DoDistanceFogForVertex(worldPosition);
return output;
}
// TODO: From NVIDIA SDK, check if it can be useful instead of linear ramp
float Contrast(float Input, float ContrastPower)
{
#if 1
//piecewise contrast function
bool IsAboveHalf = Input > 0.5;
float ToRaise = saturate(2 * (IsAboveHalf ? 1 - Input : Input));
float Output = 0.5 * pow(ToRaise, ContrastPower);
Output = IsAboveHalf ? 1 - Output : Output;
return Output;
#else
// another solution to create a kind of contrast function
return 1.0 - exp2(-2 * pow(2.0 * saturate(Input), ContrastPower));
#endif
}
float4 PS(PixelShaderInput input, uint InstanceID : SV_InstanceID) : SV_TARGET
{
float4 output = Texture.Sample(Sampler, input.UV) * input.Color;
//DoAlphaTest(output);
if (Sprites[InstanceID].IsSoftParticle == 1)
{
float particleDepth = input.PositionCopy.z / input.PositionCopy.w;
input.PositionCopy.xy /= input.PositionCopy.w;
float2 texCoord = 0.5f * (float2(input.PositionCopy.x, -input.PositionCopy.y) + 1);
float sceneDepth = DepthMap.Sample(DepthMapSampler, texCoord).r;
sceneDepth = LinearizeDepth(sceneDepth, NearPlane, FarPlane);
particleDepth = LinearizeDepth(particleDepth, NearPlane, FarPlane);
if (particleDepth - sceneDepth > 0.01f)
discard;
float fade = (sceneDepth - particleDepth) * 1024.0f;
output.w = min(output.w, fade);
}
output.xyz -= float3(input.FogBulbs.w, input.FogBulbs.w, input.FogBulbs.w);
output.xyz = saturate(output.xyz);
output = DoDistanceFogForPixel(output, float4(0.0f, 0.0f, 0.0f, 0.0f), input.DistanceFog);
return output;
}

View file

@ -1,109 +1,106 @@
#include "./Math.hlsli"
#include "./CameraMatrixBuffer.hlsli"
#include "./ShaderLight.hlsli"
#include "./VertexEffects.hlsli"
#include "./VertexInput.hlsli"
#include "./Blending.hlsli"
#define INSTANCED_STATIC_MESH_BUCKET_SIZE 100
struct InstancedStaticMesh
{
float4x4 World;
float4 Color;
float4 AmbientLight;
ShaderLight InstancedStaticLights[MAX_LIGHTS_PER_ITEM];
uint4 LightInfo;
};
cbuffer InstancedStaticMeshBuffer : register(b3)
{
InstancedStaticMesh StaticMeshes[INSTANCED_STATIC_MESH_BUCKET_SIZE];
};
struct PixelShaderInput
{
float4 Position: SV_POSITION;
float3 Normal: NORMAL;
float3 WorldPosition: POSITION;
float2 UV: TEXCOORD1;
float4 Color: COLOR;
float Sheen : SHEEN;
float Fog : FOG;
float4 PositionCopy: TEXCOORD2;
uint InstanceID : SV_InstanceID;
};
struct PixelShaderOutput
{
float4 Color: SV_TARGET0;
float4 Depth: SV_TARGET1;
};
Texture2D Texture : register(t0);
SamplerState Sampler : register(s0);
PixelShaderInput VS(VertexShaderInput input, uint InstanceID : SV_InstanceID)
{
PixelShaderInput output;
float4 worldPosition = (mul(float4(input.Position, 1.0f), StaticMeshes[InstanceID].World));
float3 normal = (mul(float4(input.Normal, 0.0f), StaticMeshes[InstanceID].World).xyz);
output.Normal = normal;
output.UV = input.UV;
output.WorldPosition = worldPosition;
float3 pos = Move(input.Position, input.Effects.xyz, input.Hash);
float3 col = Glow(input.Color.xyz, input.Effects.xyz, input.Hash);
output.Position = mul(worldPosition, ViewProjection);
output.Color = float4(col, input.Color.w);
output.Color *= StaticMeshes[InstanceID].Color;
// Apply distance fog
float4 d = length(CamPositionWS - worldPosition);
if (FogMaxDistance == 0)
output.Fog = 1;
else
output.Fog = clamp((d - FogMinDistance * 1024) / (FogMaxDistance * 1024 - FogMinDistance * 1024), 0, 1);
output.PositionCopy = output.Position;
output.Sheen = input.Effects.w;
output.InstanceID = InstanceID;
return output;
}
PixelShaderOutput PS(PixelShaderInput input)
{
PixelShaderOutput output;
float4 tex = Texture.Sample(Sampler, input.UV);
DoAlphaTest(tex);
uint mode = StaticMeshes[input.InstanceID].LightInfo.y;
uint numLights = StaticMeshes[input.InstanceID].LightInfo.x;
float3 color = (mode == 0) ?
CombineLights(
StaticMeshes[input.InstanceID].AmbientLight.xyz,
input.Color.xyz,
tex.xyz,
input.WorldPosition,
normalize(input.Normal),
input.Sheen,
StaticMeshes[input.InstanceID].InstancedStaticLights,
numLights) :
StaticLight(input.Color.xyz, tex.xyz);
output.Color = float4(color, tex.w);
output.Depth = tex.w > 0.0f ?
float4(input.PositionCopy.z / input.PositionCopy.w, 0.0f, 0.0f, 1.0f) :
float4(0.0f, 0.0f, 0.0f, 0.0f);
output.Color = DoFog(output.Color, FogColor, input.Fog);
return output;
#include "./Math.hlsli"
#include "./CameraMatrixBuffer.hlsli"
#include "./ShaderLight.hlsli"
#include "./VertexEffects.hlsli"
#include "./VertexInput.hlsli"
#include "./Blending.hlsli"
#define INSTANCED_STATIC_MESH_BUCKET_SIZE 100
struct InstancedStaticMesh
{
float4x4 World;
float4 Color;
float4 AmbientLight;
ShaderLight InstancedStaticLights[MAX_LIGHTS_PER_ITEM];
uint4 LightInfo;
};
cbuffer InstancedStaticMeshBuffer : register(b3)
{
InstancedStaticMesh StaticMeshes[INSTANCED_STATIC_MESH_BUCKET_SIZE];
};
struct PixelShaderInput
{
float4 Position: SV_POSITION;
float3 Normal: NORMAL;
float3 WorldPosition: POSITION;
float2 UV: TEXCOORD1;
float4 Color: COLOR;
float Sheen : SHEEN;
float4 PositionCopy: TEXCOORD2;
float4 FogBulbs : TEXCOORD3;
float DistanceFog : FOG;
uint InstanceID : SV_InstanceID;
};
struct PixelShaderOutput
{
float4 Color: SV_TARGET0;
float4 Depth: SV_TARGET1;
};
Texture2D Texture : register(t0);
SamplerState Sampler : register(s0);
PixelShaderInput VS(VertexShaderInput input, uint InstanceID : SV_InstanceID)
{
PixelShaderInput output;
float4 worldPosition = (mul(float4(input.Position, 1.0f), StaticMeshes[InstanceID].World));
float3 normal = (mul(float4(input.Normal, 0.0f), StaticMeshes[InstanceID].World).xyz);
output.Normal = normal;
output.UV = input.UV;
output.WorldPosition = worldPosition;
float3 pos = Move(input.Position, input.Effects.xyz, input.Hash);
float3 col = Glow(input.Color.xyz, input.Effects.xyz, input.Hash);
output.Position = mul(worldPosition, ViewProjection);
output.Color = float4(col, input.Color.w);
output.Color *= StaticMeshes[InstanceID].Color;
output.PositionCopy = output.Position;
output.Sheen = input.Effects.w;
output.InstanceID = InstanceID;
output.FogBulbs = DoFogBulbsForVertex(worldPosition);
output.DistanceFog = DoDistanceFogForVertex(worldPosition);
return output;
}
PixelShaderOutput PS(PixelShaderInput input)
{
PixelShaderOutput output;
float4 tex = Texture.Sample(Sampler, input.UV);
DoAlphaTest(tex);
uint mode = StaticMeshes[input.InstanceID].LightInfo.y;
uint numLights = StaticMeshes[input.InstanceID].LightInfo.x;
float3 color = (mode == 0) ?
CombineLights(
StaticMeshes[input.InstanceID].AmbientLight.xyz,
input.Color.xyz,
tex.xyz,
input.WorldPosition,
normalize(input.Normal),
input.Sheen,
StaticMeshes[input.InstanceID].InstancedStaticLights,
numLights,
input.FogBulbs.w) :
StaticLight(input.Color.xyz, tex.xyz, input.FogBulbs.w);
output.Color = float4(color, tex.w);
output.Color = DoFogBulbsForPixel(output.Color, float4(input.FogBulbs.xyz, 1.0f));
output.Color = DoDistanceFogForPixel(output.Color, FogColor, input.DistanceFog);
output.Depth = tex.w > 0.0f ?
float4(input.PositionCopy.z / input.PositionCopy.w, 0.0f, 0.0f, 1.0f) :
float4(0.0f, 0.0f, 0.0f, 0.0f);
return output;
}

View file

@ -1,126 +1,124 @@
#include "./Math.hlsli"
#include "./CameraMatrixBuffer.hlsli"
#include "./ShaderLight.hlsli"
#include "./VertexEffects.hlsli"
#include "./VertexInput.hlsli"
#include "./Blending.hlsli"
#include "./AnimatedTextures.hlsli"
#include "./Shadows.hlsli"
#define MAX_BONES 32
cbuffer ItemBuffer : register(b1)
{
float4x4 World;
float4x4 Bones[MAX_BONES];
float4 Color;
float4 AmbientLight;
int4 BoneLightModes[MAX_BONES / 4];
ShaderLight ItemLights[MAX_LIGHTS_PER_ITEM];
int NumItemLights;
};
struct PixelShaderInput
{
float4 Position: SV_POSITION;
float3 Normal: NORMAL;
float3 WorldPosition: POSITION;
float2 UV: TEXCOORD;
float4 Color: COLOR;
float Sheen: SHEEN;
float3x3 TBN: TBN;
float Fog: FOG;
float4 PositionCopy: TEXCOORD2;
unsigned int Bone: BONE;
};
struct PixelShaderOutput
{
float4 Color: SV_TARGET0;
float4 Depth: SV_TARGET1;
};
Texture2D Texture : register(t0);
SamplerState Sampler : register(s0);
Texture2D NormalTexture : register(t1);
//TextureCube Reflection : register (t4);
PixelShaderInput VS(VertexShaderInput input)
{
PixelShaderInput output;
float4x4 world = mul(Bones[input.Bone], World);
float3 normal = (mul(float4(input.Normal, 0.0f), world).xyz);
float3 worldPosition = (mul(float4(input.Position, 1.0f), world).xyz);
output.Normal = normal;
output.UV = input.UV;
output.WorldPosition = worldPosition;
float3 Tangent = mul(float4(input.Tangent, 0), world).xyz;
float3 Bitangent = cross(normal, Tangent);
float3x3 TBN = float3x3(Tangent, Bitangent, normal);
output.TBN = transpose(TBN);
// Calculate vertex effects
float wibble = Wibble(input.Effects.xyz, input.Hash);
float3 pos = Move(input.Position, input.Effects.xyz, wibble);
float3 col = Glow(input.Color.xyz, input.Effects.xyz, wibble);
output.Position = mul(mul(float4(pos, 1.0f), world), ViewProjection);
output.Color = float4(col, input.Color.w);
output.Color *= Color;
// Apply distance fog
float d = distance(CamPositionWS.xyz, worldPosition);
if (FogMaxDistance == 0)
output.Fog = 1;
else
output.Fog = clamp((d - FogMinDistance * 1024) / (FogMaxDistance * 1024 - FogMinDistance * 1024), 0, 1);
output.PositionCopy = output.Position;
output.Sheen = input.Effects.w;
output.Bone = input.Bone;
return output;
}
PixelShaderOutput PS(PixelShaderInput input)
{
PixelShaderOutput output;
if (Type == 1)
input.UV = CalculateUVRotate(input.UV, 0);
float4 tex = Texture.Sample(Sampler, input.UV);
DoAlphaTest(tex);
float3 normal = NormalTexture.Sample(Sampler, input.UV).rgb;
normal = normal * 2 - 1;
normal = normalize(mul(input.TBN, normal));
float3 color = (BoneLightModes[input.Bone / 4][input.Bone % 4] == 0) ?
CombineLights(
AmbientLight.xyz,
input.Color.xyz,
tex.xyz,
input.WorldPosition,
normal,
input.Sheen,
ItemLights,
NumItemLights) :
StaticLight(input.Color.xyz, tex.xyz);
output.Color = saturate(float4(color, tex.w));
output.Depth = tex.w > 0.0f ?
float4(input.PositionCopy.z / input.PositionCopy.w, 0.0f, 0.0f, 1.0f) :
float4(0.0f, 0.0f, 0.0f, 0.0f);
output.Color = DoFog(output.Color, FogColor, input.Fog);
return output;
#include "./Math.hlsli"
#include "./CameraMatrixBuffer.hlsli"
#include "./ShaderLight.hlsli"
#include "./VertexEffects.hlsli"
#include "./VertexInput.hlsli"
#include "./Blending.hlsli"
#include "./AnimatedTextures.hlsli"
//#include "./Shadows.hlsli"
#define MAX_BONES 32
cbuffer ItemBuffer : register(b1)
{
float4x4 World;
float4x4 Bones[MAX_BONES];
float4 Color;
float4 AmbientLight;
int4 BoneLightModes[MAX_BONES / 4];
ShaderLight ItemLights[MAX_LIGHTS_PER_ITEM];
int NumItemLights;
};
struct PixelShaderInput
{
float4 Position: SV_POSITION;
float3 Normal: NORMAL;
float3 WorldPosition: POSITION;
float2 UV: TEXCOORD1;
float4 Color: COLOR;
float Sheen: SHEEN;
float3x3 TBN: TBN;
float4 PositionCopy: TEXCOORD2;
float4 FogBulbs : TEXCOORD3;
float DistanceFog : FOG;
unsigned int Bone: BONE;
};
struct PixelShaderOutput
{
float4 Color: SV_TARGET0;
float4 Depth: SV_TARGET1;
};
Texture2D Texture : register(t0);
SamplerState Sampler : register(s0);
Texture2D NormalTexture : register(t1);
//TextureCube Reflection : register (t4);
PixelShaderInput VS(VertexShaderInput input)
{
PixelShaderInput output;
float4x4 world = mul(Bones[input.Bone], World);
float3 normal = (mul(float4(input.Normal, 0.0f), world).xyz);
float3 worldPosition = (mul(float4(input.Position, 1.0f), world).xyz);
output.Normal = normal;
output.UV = input.UV;
output.WorldPosition = worldPosition;
float3 Tangent = mul(float4(input.Tangent, 0), world).xyz;
float3 Bitangent = cross(normal, Tangent);
float3x3 TBN = float3x3(Tangent, Bitangent, normal);
output.TBN = transpose(TBN);
// Calculate vertex effects
float wibble = Wibble(input.Effects.xyz, input.Hash);
float3 pos = Move(input.Position, input.Effects.xyz, wibble);
float3 col = Glow(input.Color.xyz, input.Effects.xyz, wibble);
output.Position = mul(mul(float4(pos, 1.0f), world), ViewProjection);
output.Color = float4(col, input.Color.w);
output.Color *= Color;
output.PositionCopy = output.Position;
output.Sheen = input.Effects.w;
output.Bone = input.Bone;
output.FogBulbs = DoFogBulbsForVertex(worldPosition);
output.DistanceFog = DoDistanceFogForVertex(worldPosition);
return output;
}
PixelShaderOutput PS(PixelShaderInput input)
{
PixelShaderOutput output;
if (Type == 1)
input.UV = CalculateUVRotate(input.UV, 0);
float4 tex = Texture.Sample(Sampler, input.UV);
DoAlphaTest(tex);
float3 normal = NormalTexture.Sample(Sampler, input.UV).rgb;
normal = normal * 2 - 1;
normal = normalize(mul(input.TBN, normal));
float3 color = (BoneLightModes[input.Bone / 4][input.Bone % 4] == 0) ?
CombineLights(
AmbientLight.xyz,
input.Color.xyz,
tex.xyz,
input.WorldPosition,
normal,
input.Sheen,
ItemLights,
NumItemLights,
input.FogBulbs.w) :
StaticLight(input.Color.xyz, tex.xyz, input.FogBulbs.w);
output.Color = saturate(float4(color, tex.w));
output.Color = DoFogBulbsForPixel(output.Color, float4(input.FogBulbs.xyz, 1.0f));
output.Color = DoDistanceFogForPixel(output.Color, FogColor, input.DistanceFog);
output.Depth = tex.w > 0.0f ?
float4(input.PositionCopy.z / input.PositionCopy.w, 0.0f, 0.0f, 1.0f) :
float4(0.0f, 0.0f, 0.0f, 0.0f);
return output;
}

View file

@ -1,197 +1,197 @@
#include "./CameraMatrixBuffer.hlsli"
#include "./VertexInput.hlsli"
#include "./VertexEffects.hlsli"
#include "./Blending.hlsli"
#include "./Math.hlsli"
#include "./ShaderLight.hlsli"
#include "./AnimatedTextures.hlsli"
#include "./Shadows.hlsli"
cbuffer RoomBuffer : register(b5)
{
float2 CausticsStartUV;
float2 CausticsScale;
float4 AmbientColor;
ShaderLight RoomLights[MAX_LIGHTS_PER_ROOM];
int NumRoomLights;
int Water;
int Caustics;
int Padding;
};
struct PixelShaderInput
{
float4 Position: SV_POSITION;
float3 WorldPosition: POSITION0;
float3 Normal: NORMAL;
float2 UV: TEXCOORD0;
float4 Color: COLOR;
float3x3 TBN : TBN;
float Fog : FOG;
float4 PositionCopy : TEXCOORD1;
};
Texture2D Texture : register(t0);
SamplerState Sampler : register(s0);
Texture2D NormalTexture : register(t1);
Texture2D CausticsTexture : register(t2);
struct PixelShaderOutput
{
float4 Color: SV_TARGET0;
float4 Depth: SV_TARGET1;
};
PixelShaderInput VS(VertexShaderInput input)
{
PixelShaderInput output;
// Setting effect weight on TE side prevents portal vertices from moving.
// Here we just read weight and decide if we should apply refraction or movement effect.
float weight = input.Effects.z;
// Calculate vertex effects
float wibble = Wibble(input.Effects.xyz, input.Hash);
float3 pos = Move(input.Position, input.Effects.xyz * weight, wibble);
float3 col = Glow(input.Color.xyz, input.Effects.xyz, wibble);
// Refraction
float4 screenPos = mul(float4(pos, 1.0f), ViewProjection);
float2 clipPos = screenPos.xy / screenPos.w;
if (CameraUnderwater != Water)
{
float factor = (Frame + clipPos.x * 320);
float xOffset = (sin(factor * PI / 20.0f)) * (screenPos.z / 1024) * 4;
float yOffset = (cos(factor * PI / 20.0f)) * (screenPos.z / 1024) * 4;
screenPos.x += xOffset * weight;
screenPos.y += yOffset * weight;
}
output.Position = screenPos;
output.Normal = input.Normal;
output.Color = float4(col, input.Color.w);
output.PositionCopy = screenPos;
#ifdef ANIMATED
if (Type == 0)
output.UV = GetFrame(input.PolyIndex, input.AnimationFrameOffset);
else
output.UV = input.UV; // TODO: true UVRotate in future?
#else
output.UV = input.UV;
#endif
output.WorldPosition = input.Position.xyz;
float3x3 TBN = float3x3(input.Tangent, cross(input.Normal,input.Tangent), input.Normal);
output.TBN = TBN;
// Apply distance fog
float d = length(CamPositionWS.xyz - output.WorldPosition);
if (FogMaxDistance == 0)
output.Fog = 1;
else
output.Fog = clamp((d - FogMinDistance * 1024) / (FogMaxDistance * 1024 - FogMinDistance * 1024), 0, 1);
return output;
}
float3 UnpackNormalMap(float3 compressedNormalMap)
{
float2 normalXY = compressedNormalMap.rg;
normalXY = normalXY * float2(2.0f, 2.0f) - float2(1.0f, 1.0f);
float normalZ = sqrt(saturate(1.0f - dot(normalXY, normalXY)));
return float3(normalXY.xy, normalZ);
}
PixelShaderOutput PS(PixelShaderInput input)
{
PixelShaderOutput output;
output.Color = Texture.Sample(Sampler, input.UV);
DoAlphaTest(output.Color);
float3 normal = UnpackNormalMap(NormalTexture.Sample(Sampler, input.UV).rgb);
normal = normalize(mul(normal, input.TBN));
float3 lighting = input.Color.xyz;
bool doLights = true;
if (CastShadows)
{
if (Light.Type == LT_POINT)
{
DoPointLightShadow(input.WorldPosition, lighting);
}
else if (Light.Type == LT_SPOT)
{
DoSpotLightShadow(input.WorldPosition, lighting);
}
}
DoBlobShadows(input.WorldPosition, lighting);
if (doLights)
{
for (int i = 0; i < NumRoomLights; i++)
{
float3 lightPos = RoomLights[i].Position.xyz;
float3 color = RoomLights[i].Color.xyz;
float radius = RoomLights[i].Out;
float3 lightVec = (lightPos - input.WorldPosition);
float distance = length(lightVec);
if (distance > radius)
continue;
lightVec = normalize(lightVec);
float d = saturate(dot(normal, -lightVec ));
if (d < 0)
continue;
float attenuation = pow(((radius - distance) / radius), 2);
lighting += color * attenuation * d;
}
}
if (Caustics)
{
float3 position = input.WorldPosition.xyz;
float fracX = position.x - floor(position.x / 2048.0f) * 2048.0f;
float fracY = position.y - floor(position.y / 2048.0f) * 2048.0f;
float fracZ = position.z - floor(position.z / 2048.0f) * 2048.0f;
float attenuation = saturate(dot(float3(0.0f, 1.0f, 0.0f), normal));
float3 blending = abs(normal);
blending = normalize(max(blending, 0.00001f));
float b = (blending.x + blending.y + blending.z);
blending /= float3(b, b, b);
float3 p = float3(fracX, fracY, fracZ) / 2048.0f;
float3 xaxis = CausticsTexture.Sample(Sampler, CausticsStartUV + float2(p.y * CausticsScale.x, p.z * CausticsScale.y)).xyz;
float3 yaxis = CausticsTexture.Sample(Sampler, CausticsStartUV + float2(p.x * CausticsScale.x, p.z * CausticsScale.y)).xyz;
float3 zaxis = CausticsTexture.Sample(Sampler, CausticsStartUV + float2(p.x * CausticsScale.x, p.y * CausticsScale.y)).xyz;
lighting += float3((xaxis * blending.x + yaxis * blending.y + zaxis * blending.z).xyz) * attenuation * 2.0f;
}
output.Color.xyz = saturate(output.Color.xyz * lighting);
output.Depth = output.Color.w > 0.0f ?
float4(input.PositionCopy.z / input.PositionCopy.w, 0.0f, 0.0f, 1.0f) :
float4(0.0f, 0.0f, 0.0f, 0.0f);
output.Color = DoFog(output.Color, FogColor, input.Fog);
return output;
}
#include "./CameraMatrixBuffer.hlsli"
#include "./VertexInput.hlsli"
#include "./VertexEffects.hlsli"
#include "./Blending.hlsli"
#include "./Math.hlsli"
#include "./AnimatedTextures.hlsli"
#include "./Shadows.hlsli"
#include "./ShaderLight.hlsli"
cbuffer RoomBuffer : register(b5)
{
float2 CausticsStartUV;
float2 CausticsScale;
float4 AmbientColor;
ShaderLight RoomLights[MAX_LIGHTS_PER_ROOM];
int NumRoomLights;
int Water;
int Caustics;
int Padding;
};
struct PixelShaderInput
{
float4 Position: SV_POSITION;
float3 WorldPosition: POSITION0;
float3 Normal: NORMAL;
float2 UV: TEXCOORD0;
float4 Color: COLOR;
float3x3 TBN : TBN;
float4 PositionCopy : TEXCOORD1;
float4 FogBulbs : TEXCOORD2;
float DistanceFog : FOG;
};
Texture2D Texture : register(t0);
SamplerState Sampler : register(s0);
Texture2D NormalTexture : register(t1);
Texture2D CausticsTexture : register(t2);
struct PixelShaderOutput
{
float4 Color: SV_TARGET0;
float4 Depth: SV_TARGET1;
};
PixelShaderInput VS(VertexShaderInput input)
{
PixelShaderInput output;
// Setting effect weight on TE side prevents portal vertices from moving.
// Here we just read weight and decide if we should apply refraction or movement effect.
float weight = input.Effects.z;
// Calculate vertex effects
float wibble = Wibble(input.Effects.xyz, input.Hash);
float3 pos = Move(input.Position, input.Effects.xyz * weight, wibble);
float3 col = Glow(input.Color.xyz, input.Effects.xyz, wibble);
// Refraction
float4 screenPos = mul(float4(pos, 1.0f), ViewProjection);
float2 clipPos = screenPos.xy / screenPos.w;
if (CameraUnderwater != Water)
{
float factor = (Frame + clipPos.x * 320);
float xOffset = (sin(factor * PI / 20.0f)) * (screenPos.z / 1024) * 4;
float yOffset = (cos(factor * PI / 20.0f)) * (screenPos.z / 1024) * 4;
screenPos.x += xOffset * weight;
screenPos.y += yOffset * weight;
}
output.Position = screenPos;
output.Normal = input.Normal;
output.Color = float4(col, input.Color.w);
output.PositionCopy = screenPos;
#ifdef ANIMATED
if (Type == 0)
output.UV = GetFrame(input.PolyIndex, input.AnimationFrameOffset);
else
output.UV = input.UV; // TODO: true UVRotate in future?
#else
output.UV = input.UV;
#endif
output.WorldPosition = input.Position.xyz;
float3x3 TBN = float3x3(input.Tangent, cross(input.Normal,input.Tangent), input.Normal);
output.TBN = TBN;
output.FogBulbs = DoFogBulbsForVertex(output.WorldPosition);
output.DistanceFog = DoDistanceFogForVertex(output.WorldPosition);
return output;
}
float3 UnpackNormalMap(float3 compressedNormalMap)
{
float2 normalXY = compressedNormalMap.rg;
normalXY = normalXY * float2(2.0f, 2.0f) - float2(1.0f, 1.0f);
float normalZ = sqrt(saturate(1.0f - dot(normalXY, normalXY)));
return float3(normalXY.xy, normalZ);
}
PixelShaderOutput PS(PixelShaderInput input)
{
PixelShaderOutput output;
output.Color = Texture.Sample(Sampler, input.UV);
DoAlphaTest(output.Color);
float3 normal = UnpackNormalMap(NormalTexture.Sample(Sampler, input.UV).rgb);
normal = normalize(mul(normal, input.TBN));
float3 lighting = input.Color.xyz;
bool doLights = true;
if (CastShadows)
{
if (Light.Type == LT_POINT)
{
DoPointLightShadow(input.WorldPosition, lighting);
}
else if (Light.Type == LT_SPOT)
{
DoSpotLightShadow(input.WorldPosition, lighting);
}
}
DoBlobShadows(input.WorldPosition, lighting);
if (doLights)
{
for (int i = 0; i < NumRoomLights; i++)
{
float3 lightPos = RoomLights[i].Position.xyz;
float3 color = RoomLights[i].Color.xyz;
float radius = RoomLights[i].Out;
float3 lightVec = (lightPos - input.WorldPosition);
float distance = length(lightVec);
if (distance > radius)
continue;
lightVec = normalize(lightVec);
float d = saturate(dot(normal, -lightVec ));
if (d < 0)
continue;
float attenuation = pow(((radius - distance) / radius), 2);
lighting += color * attenuation * d;
}
}
if (Caustics)
{
float3 position = input.WorldPosition.xyz;
float fracX = position.x - floor(position.x / 2048.0f) * 2048.0f;
float fracY = position.y - floor(position.y / 2048.0f) * 2048.0f;
float fracZ = position.z - floor(position.z / 2048.0f) * 2048.0f;
float attenuation = saturate(dot(float3(0.0f, 1.0f, 0.0f), normal));
float3 blending = abs(normal);
blending = normalize(max(blending, 0.00001f));
float b = (blending.x + blending.y + blending.z);
blending /= float3(b, b, b);
float3 p = float3(fracX, fracY, fracZ) / 2048.0f;
float3 xaxis = CausticsTexture.Sample(Sampler, CausticsStartUV + float2(p.y * CausticsScale.x, p.z * CausticsScale.y)).xyz;
float3 yaxis = CausticsTexture.Sample(Sampler, CausticsStartUV + float2(p.x * CausticsScale.x, p.z * CausticsScale.y)).xyz;
float3 zaxis = CausticsTexture.Sample(Sampler, CausticsStartUV + float2(p.x * CausticsScale.x, p.y * CausticsScale.y)).xyz;
lighting += float3((xaxis * blending.x + yaxis * blending.y + zaxis * blending.z).xyz) * attenuation * 2.0f;
}
output.Depth = output.Color.w > 0.0f ?
float4(input.PositionCopy.z / input.PositionCopy.w, 0.0f, 0.0f, 1.0f) :
float4(0.0f, 0.0f, 0.0f, 0.0f);
lighting -= float3(input.FogBulbs.w, input.FogBulbs.w, input.FogBulbs.w);
lighting = saturate(lighting);
output.Color.xyz = output.Color.xyz * lighting;
output.Color = DoFogBulbsForPixel(output.Color, float4(input.FogBulbs.xyz, 1.0f));
output.Color = DoDistanceFogForPixel(output.Color, FogColor, input.DistanceFog);
return output;
}

View file

@ -1,45 +1,54 @@
#include "./CameraMatrixBuffer.hlsli"
#include "./Blending.hlsli"
#include "./VertexInput.hlsli"
cbuffer StaticMatrixBuffer : register(b8)
{
float4x4 World;
float4 Color;
float4 AmbientLight;
int LightType;
};
struct PixelShaderInput
{
float4 Position: SV_POSITION;
float3 Normal: NORMAL;
float2 UV: TEXCOORD;
float4 Color: COLOR;
};
Texture2D Texture : register(t0);
SamplerState Sampler : register(s0);
PixelShaderInput VS(VertexShaderInput input)
{
PixelShaderInput output;
output.Position = mul(mul(float4(input.Position, 1.0f), World), ViewProjection);
output.Normal = input.Normal;
output.Color = input.Color;
output.UV = input.UV;
return output;
}
float4 PS(PixelShaderInput input) : SV_TARGET
{
float4 output = Texture.Sample(Sampler, input.UV);
DoAlphaTest(output);
output.xyz = output.xyz * Color;
return output;
#include "./CameraMatrixBuffer.hlsli"
#include "./Blending.hlsli"
#include "./VertexInput.hlsli"
#include "./Math.hlsli"
#include "./ShaderLight.hlsli"
cbuffer StaticMatrixBuffer : register(b8)
{
float4x4 World;
float4 Color;
float4 AmbientLight;
int LightType;
};
struct PixelShaderInput
{
float4 Position: SV_POSITION;
float3 Normal: NORMAL;
float2 UV: TEXCOORD;
float4 Color: COLOR;
float4 FogBulbs : TEXCOORD3;
};
Texture2D Texture : register(t0);
SamplerState Sampler : register(s0);
PixelShaderInput VS(VertexShaderInput input)
{
PixelShaderInput output;
float4 worldPosition = mul(float4(input.Position, 1.0f), World);
output.Position = mul(worldPosition, ViewProjection);
output.Normal = input.Normal;
output.Color = input.Color;
output.UV = input.UV;
output.FogBulbs = DoFogBulbsForSky(worldPosition);
return output;
}
float4 PS(PixelShaderInput input) : SV_TARGET
{
float4 output = Texture.Sample(Sampler, input.UV);
DoAlphaTest(output);
output.xyz = output.xyz * Color;
output.xyz -= float3(input.FogBulbs.w, input.FogBulbs.w, input.FogBulbs.w) * 2.0f;
output.xyz = saturate(output.xyz);
output.xyz += saturate(input.FogBulbs.xyz);
return output;
}

View file

@ -1,85 +1,87 @@
#include "./CameraMatrixBuffer.hlsli"
#include "./Blending.hlsli"
#include "./VertexInput.hlsli"
#include "./Math.hlsli"
// 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
{
float4 Position: SV_POSITION;
float3 Normal: NORMAL;
float2 UV: TEXCOORD1;
float4 Color: COLOR;
float Fog : FOG;
float4 PositionCopy: TEXCOORD2;
};
Texture2D Texture : register(t0);
SamplerState Sampler : register(s0);
Texture2D DepthMap : register(t6);
SamplerState DepthMapSampler : register(s6);
PixelShaderInput VS(VertexShaderInput input)
{
PixelShaderInput output;
float4 worldPosition = float4(input.Position, 1.0f);
output.Position = mul(worldPosition, ViewProjection);
output.PositionCopy = output.Position;
output.Normal = input.Normal;
output.Color = input.Color;
output.UV = input.UV;
float4 d = length(CamPositionWS - worldPosition);
if (FogMaxDistance == 0)
output.Fog = 1;
else
output.Fog = clamp((d - FogMinDistance * 1024) / (FogMaxDistance * 1024 - FogMinDistance * 1024), 0, 1);
return output;
}
float4 PS(PixelShaderInput input) : SV_TARGET
{
float4 output = Texture.Sample(Sampler, input.UV) * input.Color;
DoAlphaTest(output);
if (IsSoftParticle == 1)
{
float particleDepth = input.PositionCopy.z / input.PositionCopy.w;
input.PositionCopy.xy /= input.PositionCopy.w;
float2 texCoord = 0.5f * (float2(input.PositionCopy.x, -input.PositionCopy.y) + 1);
float sceneDepth = DepthMap.Sample(DepthMapSampler, texCoord).r;
sceneDepth = LinearizeDepth(sceneDepth, NearPlane, FarPlane);
particleDepth = LinearizeDepth(particleDepth, NearPlane, FarPlane);
if (particleDepth - sceneDepth > 0.01f)
discard;
float fade = (sceneDepth - particleDepth) * 1024.0f;
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;
}
#include "./CameraMatrixBuffer.hlsli"
#include "./Blending.hlsli"
#include "./VertexInput.hlsli"
#include "./Math.hlsli"
#include "./ShaderLight.hlsli"
// 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
{
float4 Position: SV_POSITION;
float3 Normal: NORMAL;
float2 UV: TEXCOORD1;
float4 Color: COLOR;
float4 PositionCopy: TEXCOORD2;
float4 FogBulbs : TEXCOORD3;
float DistanceFog : FOG;
};
Texture2D Texture : register(t0);
SamplerState Sampler : register(s0);
Texture2D DepthMap : register(t6);
SamplerState DepthMapSampler : register(s6);
PixelShaderInput VS(VertexShaderInput input)
{
PixelShaderInput output;
float4 worldPosition = float4(input.Position, 1.0f);
output.Position = mul(worldPosition, ViewProjection);
output.PositionCopy = output.Position;
output.Normal = input.Normal;
output.Color = input.Color;
output.UV = input.UV;
output.FogBulbs = DoFogBulbsForVertex(worldPosition);
output.DistanceFog = DoDistanceFogForVertex(worldPosition);
return output;
}
float4 PS(PixelShaderInput input) : SV_TARGET
{
float4 output = Texture.Sample(Sampler, input.UV) * input.Color;
DoAlphaTest(output);
if (IsSoftParticle == 1)
{
float particleDepth = input.PositionCopy.z / input.PositionCopy.w;
input.PositionCopy.xy /= input.PositionCopy.w;
float2 texCoord = 0.5f * (float2(input.PositionCopy.x, -input.PositionCopy.y) + 1);
float sceneDepth = DepthMap.Sample(DepthMapSampler, texCoord).r;
sceneDepth = LinearizeDepth(sceneDepth, NearPlane, FarPlane);
particleDepth = LinearizeDepth(particleDepth, NearPlane, FarPlane);
if (particleDepth - sceneDepth > 0.01f)
discard;
float fade = (sceneDepth - particleDepth) * 1024.0f;
output.w = min(output.w, fade);
}
if (RenderType == 1)
{
output = DoLaserBarrierEffect(input.Position, output, input.UV, FADE_FACTOR, Frame);
}
output.xyz -= float3(input.FogBulbs.w, input.FogBulbs.w, input.FogBulbs.w);
output.xyz = saturate(output.xyz);
output = DoDistanceFogForPixel(output, float4(0.0f, 0.0f, 0.0f, 0.0f), input.DistanceFog);
return output;
}

View file

@ -1,97 +1,96 @@
#include "./Math.hlsli"
#include "./CameraMatrixBuffer.hlsli"
#include "./ShaderLight.hlsli"
#include "./VertexEffects.hlsli"
#include "./VertexInput.hlsli"
#include "./Blending.hlsli"
cbuffer StaticMatrixBuffer : register(b8)
{
float4x4 World;
float4 Color;
float4 AmbientLight;
ShaderLight StaticLights[MAX_LIGHTS_PER_ITEM];
int NumStaticLights;
int LightType;
};
struct PixelShaderInput
{
float4 Position: SV_POSITION;
float3 Normal: NORMAL;
float3 WorldPosition: POSITION;
float2 UV: TEXCOORD1;
float4 Color: COLOR;
float Sheen: SHEEN;
float Fog: FOG;
float4 PositionCopy: TEXCOORD2;
};
struct PixelShaderOutput
{
float4 Color: SV_TARGET0;
float4 Depth: SV_TARGET1;
};
Texture2D Texture : register(t0);
SamplerState Sampler : register(s0);
PixelShaderInput VS(VertexShaderInput input)
{
PixelShaderInput output;
float4 worldPosition = (mul(float4(input.Position, 1.0f), World));
float3 normal = (mul(float4(input.Normal, 0.0f), World).xyz);
output.Normal = normal;
output.UV = input.UV;
output.WorldPosition = worldPosition;
float3 pos = Move(input.Position, input.Effects.xyz, input.Hash);
float3 col = Glow(input.Color.xyz, input.Effects.xyz, input.Hash);
output.Position = mul(worldPosition, ViewProjection);
output.Color = float4(col, input.Color.w);
output.Color *= Color;
// Apply distance fog
float4 d = length(CamPositionWS - worldPosition);
if (FogMaxDistance == 0)
output.Fog = 1;
else
output.Fog = clamp((d - FogMinDistance * 1024) / (FogMaxDistance * 1024 - FogMinDistance * 1024), 0, 1);
output.PositionCopy = output.Position;
output.Sheen = input.Effects.w;
return output;
}
PixelShaderOutput PS(PixelShaderInput input)
{
PixelShaderOutput output;
float4 tex = Texture.Sample(Sampler, input.UV);
DoAlphaTest(tex);
float3 color = (LightType == 0) ?
CombineLights(
AmbientLight.xyz,
input.Color.xyz,
tex.xyz,
input.WorldPosition,
normalize(input.Normal),
input.Sheen,
StaticLights,
NumStaticLights) :
StaticLight(input.Color.xyz, tex.xyz);
output.Color = float4(color, tex.w);
output.Depth = tex.w > 0.0f ?
float4(input.PositionCopy.z / input.PositionCopy.w, 0.0f, 0.0f, 1.0f) :
float4(0.0f, 0.0f, 0.0f, 0.0f);
output.Color = DoFog(output.Color, FogColor, input.Fog);
return output;
#include "./Math.hlsli"
#include "./CameraMatrixBuffer.hlsli"
#include "./ShaderLight.hlsli"
#include "./VertexEffects.hlsli"
#include "./VertexInput.hlsli"
#include "./Blending.hlsli"
cbuffer StaticMatrixBuffer : register(b8)
{
float4x4 World;
float4 Color;
float4 AmbientLight;
ShaderLight StaticLights[MAX_LIGHTS_PER_ITEM];
int NumStaticLights;
int LightType;
};
struct PixelShaderInput
{
float4 Position: SV_POSITION;
float3 Normal: NORMAL;
float3 WorldPosition: POSITION;
float2 UV: TEXCOORD1;
float4 Color: COLOR;
float Sheen: SHEEN;
float4 PositionCopy: TEXCOORD2;
float4 FogBulbs : TEXCOORD3;
float DistanceFog : FOG;
};
struct PixelShaderOutput
{
float4 Color: SV_TARGET0;
float4 Depth: SV_TARGET1;
};
Texture2D Texture : register(t0);
SamplerState Sampler : register(s0);
PixelShaderInput VS(VertexShaderInput input)
{
PixelShaderInput output;
float4 worldPosition = (mul(float4(input.Position, 1.0f), World));
float3 normal = (mul(float4(input.Normal, 0.0f), World).xyz);
output.Normal = normal;
output.UV = input.UV;
output.WorldPosition = worldPosition;
float3 pos = Move(input.Position, input.Effects.xyz, input.Hash);
float3 col = Glow(input.Color.xyz, input.Effects.xyz, input.Hash);
output.Position = mul(worldPosition, ViewProjection);
output.Color = float4(col, input.Color.w);
output.Color *= Color;
output.FogBulbs = DoFogBulbsForVertex(worldPosition);
output.DistanceFog = DoDistanceFogForVertex(worldPosition);
output.PositionCopy = output.Position;
output.Sheen = input.Effects.w;
return output;
}
PixelShaderOutput PS(PixelShaderInput input)
{
PixelShaderOutput output;
float4 tex = Texture.Sample(Sampler, input.UV);
DoAlphaTest(tex);
float3 color = (LightType == 0) ?
CombineLights(
AmbientLight.xyz,
input.Color.xyz,
tex.xyz,
input.WorldPosition,
normalize(input.Normal),
input.Sheen,
StaticLights,
NumStaticLights,
input.FogBulbs.w) :
StaticLight(input.Color.xyz, tex.xyz, input.FogBulbs.w);
output.Color = float4(color, tex.w);
output.Color = DoFogBulbsForPixel(output.Color, float4(input.FogBulbs.xyz, 1.0f));
output.Color = DoDistanceFogForPixel(output.Color, FogColor, input.DistanceFog);
output.Depth = tex.w > 0.0f ?
float4(input.PositionCopy.z / input.PositionCopy.w, 0.0f, 0.0f, 1.0f) :
float4(0.0f, 0.0f, 0.0f, 0.0f);
return output;
}

View file

@ -5,6 +5,41 @@
#define PI2 6.2831853071795864769252867665590057683943387987502116419498891846
#define OCTAVES 6
#define LT_SUN 0
#define LT_POINT 1
#define LT_SPOT 2
#define LT_SHADOW 3
#define MAX_LIGHTS_PER_ROOM 48
#define MAX_LIGHTS_PER_ITEM 8
#define MAX_FOG_BULBS 32
#define SPEC_FACTOR 64
struct ShaderLight
{
float3 Position;
unsigned int Type;
float3 Color;
float Intensity;
float3 Direction;
float In;
float Out;
float InRange;
float OutRange;
float Padding;
};
struct ShaderFogBulb
{
float3 Position;
float Density;
float3 Color;
float SquaredRadius;
float3 FogBulbToCameraVector;
float SquaredCameraToFogBulbDistance;
float4 Padding2;
};
float Luma(float3 color)
{
// Use Rec.709 trichromat formula to get perceptive luma value.

View file

@ -1,28 +1,5 @@
#include "./Math.hlsli"
#define LT_SUN 0
#define LT_POINT 1
#define LT_SPOT 2
#define LT_SHADOW 3
#define MAX_LIGHTS_PER_ROOM 48
#define MAX_LIGHTS_PER_ITEM 8
#define SPEC_FACTOR 64
struct ShaderLight
{
float3 Position;
unsigned int Type;
float3 Color;
float Intensity;
float3 Direction;
float In;
float Out;
float InRange;
float OutRange;
float Padding;
};
float3 DoSpecularPoint(float3 pos, float3 n, ShaderLight light, float strength)
{
if ((strength <= 0.0))
@ -210,7 +187,215 @@ float3 DoDirectionalLight(float3 pos, float3 n, ShaderLight light)
return float3(0, 0, 0);
}
float3 CombineLights(float3 ambient, float3 vertex, float3 tex, float3 pos, float3 normal, float sheen, const ShaderLight lights[MAX_LIGHTS_PER_ITEM], int numLights)
float DoFogBulb(float3 pos, ShaderFogBulb bulb)
{
// We find the intersection points p0 and p1 between the sphere of the fog bulb and the ray from camera to vertex.
// The magnitude of (p2 - p1) is used as the fog factor.
// We need to consider different cases for getting the correct points.
// We use the geometric solution as in legacy engines. An analytic solution also exists.
float3 p0;
float3 p1;
p0 = p1 = float3(0, 0, 0);
float3 bulbToVertex = pos - bulb.Position;
float bulbToVertexSquaredDistance = pow(pos.x - bulb.Position.x, 2) + pow(pos.y - bulb.Position.y, 2) + pow(pos.z - bulb.Position.z, 2);
float3 cameraToVertexDirection = normalize(pos - CamPositionWS);
float cameraToVertexSquaredDistance = pow(pos.x - CamPositionWS.x, 2) + pow(pos.y - CamPositionWS.y, 2) + pow(pos.z - CamPositionWS.z, 2);
if (bulb.SquaredCameraToFogBulbDistance < bulb.SquaredRadius)
{
// Camera is INSIDE the bulb
if (bulbToVertexSquaredDistance < bulb.SquaredRadius)
{
// Vertex is INSIDE the bulb
p0 = CamPositionWS;
p1 = pos;
}
else
{
// Vertex is OUTSIDE the bulb
float Tca = dot(bulb.FogBulbToCameraVector, cameraToVertexDirection);
float d2 = bulb.SquaredCameraToFogBulbDistance - Tca * Tca;
float Thc = sqrt(bulb.SquaredRadius - d2);
float t1 = Tca + Thc;
p0 = CamPositionWS;
p1 = CamPositionWS + cameraToVertexDirection * t1;
}
}
else
{
// Camera is OUTSIDE the bulb
if (bulbToVertexSquaredDistance < bulb.SquaredRadius)
{
// Vertex is INSIDE the bulb
float Tca = dot(bulb.FogBulbToCameraVector, cameraToVertexDirection);
float d2 = bulb.SquaredCameraToFogBulbDistance - Tca * Tca;
float Thc = sqrt(bulb.SquaredRadius - d2);
float t0 = Tca - Thc;
p0 = CamPositionWS + cameraToVertexDirection * t0;
p1 = pos;
}
else
{
// Vertex is OUTSIDE the bulb
float Tca = dot(bulb.FogBulbToCameraVector, cameraToVertexDirection);
if (Tca > 0 && cameraToVertexSquaredDistance > Tca * Tca)
{
float d2 = bulb.SquaredCameraToFogBulbDistance - Tca * Tca;
if (d2 < bulb.SquaredRadius)
{
float Thc = sqrt(bulb.SquaredRadius - d2);
float t0 = Tca - Thc;
float t1 = Tca + Thc;
p0 = CamPositionWS + cameraToVertexDirection * t0;
p1 = CamPositionWS + cameraToVertexDirection * t1;
}
else
{
return 0;
}
}
else
{
return 0;
}
}
}
float fog = length(p1 - p0) * bulb.Density / 255.0f;
return fog;
}
float DoFogBulbForSky(float3 pos, ShaderFogBulb bulb)
{
// We find the intersection points p0 and p1 between the sphere of the fog bulb and the ray from camera to vertex.
// The magnitude of (p2 - p1) is used as the fog factor.
// We need to consider different cases for getting the correct points.
// We use the geometric solution as in legacy engines. An analytic solution also exists.
float3 p0;
float3 p1;
p0 = p1 = float3(0, 0, 0);
float3 cameraToVertexDirection = normalize(pos - CamPositionWS);
if (bulb.SquaredCameraToFogBulbDistance < bulb.SquaredRadius)
{
// Camera is INSIDE the bulb
// Vertex is ALWAYS OUTSIDE the bulb
float Tca = dot(bulb.FogBulbToCameraVector, cameraToVertexDirection);
float d2 = bulb.SquaredCameraToFogBulbDistance - Tca * Tca;
float Thc = sqrt(bulb.SquaredRadius - d2);
float t1 = Tca + Thc;
p0 = CamPositionWS;
p1 = CamPositionWS + cameraToVertexDirection * t1;
}
else
{
// Camera is OUTSIDE the bulb
// Vertex is ALWAYS OUTSIDE the bulb
float Tca = dot(bulb.FogBulbToCameraVector, cameraToVertexDirection);
if (Tca > 0)
{
float d2 = bulb.SquaredCameraToFogBulbDistance - Tca * Tca;
if (d2 < bulb.SquaredRadius)
{
float Thc = sqrt(bulb.SquaredRadius - d2);
float t0 = Tca - Thc;
float t1 = Tca + Thc;
p0 = CamPositionWS + cameraToVertexDirection * t0;
p1 = CamPositionWS + cameraToVertexDirection * t1;
}
else
{
return 0;
}
}
else
{
return 0;
}
}
float fog = length(p1 - p0) * bulb.Density / 255.0f;
return fog;
}
float DoDistanceFogForVertex(float3 pos)
{
float fog = 0.0f;
if (FogMaxDistance > 0.0f)
{
float d = length(CamPositionWS.xyz - pos);
fog = clamp((d - FogMinDistance * 1024) / (FogMaxDistance * 1024 - FogMinDistance * 1024), 0, 1);
}
return fog;
}
float4 DoFogBulbsForVertex(float3 pos)
{
float4 fog = float4(0.0f, 0.0f, 0.0f, 0.0f);
for (int i = 0; i < NumFogBulbs; i++)
{
float fogFactor = DoFogBulb(pos, FogBulbs[i]);
fog.xyz += FogBulbs[i].Color.xyz * fogFactor;
fog.w += fogFactor;
if (fog.w >= 1.0f)
{
break;
}
}
return fog;
}
float4 DoFogBulbsForSky(float3 pos)
{
float4 fog = float4(0.0f, 0.0f, 0.0f, 0.0f);
for (int i = 0; i < NumFogBulbs; i++)
{
float fogFactor = DoFogBulbForSky(pos, FogBulbs[i]);
fog.xyz += FogBulbs[i].Color.xyz * fogFactor;
fog.w += fogFactor;
if (fog.w >= 1.0f)
{
break;
}
}
return fog;
}
float3 CombineLights(float3 ambient, float3 vertex, float3 tex, float3 pos, float3 normal, float sheen,
const ShaderLight lights[MAX_LIGHTS_PER_ITEM], int numLights, float fogBulbsDensity)
{
float3 diffuse = 0;
float3 shadow = 0;
@ -247,10 +432,16 @@ float3 CombineLights(float3 ambient, float3 vertex, float3 tex, float3 pos, floa
float3 ambTex = saturate(ambient - shadow) * tex;
float3 combined = ambTex + diffuse + spec;
return (combined * vertex);
combined -= float3(fogBulbsDensity, fogBulbsDensity, fogBulbsDensity);
return saturate(combined * vertex);
}
float3 StaticLight(float3 vertex, float3 tex)
float3 StaticLight(float3 vertex, float3 tex, float fogBulbsDensity)
{
return saturate(tex * vertex);
}
float3 result = tex * vertex;
result -= float3(fogBulbsDensity, fogBulbsDensity, fogBulbsDensity);
return saturate(result);
}

View file

@ -0,0 +1,41 @@
<<<<<<< HEAD
<?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>
=======
<?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)\Bin\x86</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerCommandArguments>/debug</LocalDebuggerCommandArguments>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)Build\$(Configuration)\Bin\x64</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerCommandArguments>/debug</LocalDebuggerCommandArguments>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)Build\$(Configuration)\Bin\x86</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)Build\$(Configuration)\Bin\x64</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
>>>>>>> develop
</Project>

View file

@ -645,6 +645,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"</Command>
<ClInclude Include="Objects\Utils\object_helper.h" />
<ClInclude Include="Objects\game_object_ids.h" />
<ClInclude Include="Objects\objectslist.h" />
<ClInclude Include="Renderer\ConstantBuffers\ShaderFogBulb.h" />
<ClInclude Include="Renderer\ConstantBuffer\ConstantBuffer.h" />
<ClInclude Include="Renderer\ConstantBuffers\AnimatedBuffer.h" />
<ClInclude Include="Renderer\ConstantBuffers\BlendingBuffer.h" />
@ -681,6 +682,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"</Command>
<ClInclude Include="Renderer\Structures\RendererBone.h" />
<ClInclude Include="Renderer\Structures\RendererDisplayMode.h" />
<ClInclude Include="Renderer\Structures\RendererDoor.h" />
<ClInclude Include="Renderer\Structures\RendererFogBulb.h" />
<ClInclude Include="Renderer\Structures\RendererLight.h" />
<ClInclude Include="Renderer\Structures\RendererRoom.h" />
<ClInclude Include="Renderer\Structures\RendererStringToDraw.h" />

View file

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