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

1
.gitignore vendored
View file

@ -22,3 +22,4 @@ packages/
*.trc *.trc
*.str *.str
*.ten *.ten
Logs/

View file

@ -63,7 +63,7 @@ namespace TEN::Effects::Explosion
int numSprites = -Objects[ID_EXPLOSION_SPRITES].nmeshes - 1; int numSprites = -Objects[ID_EXPLOSION_SPRITES].nmeshes - 1;
float normalizedAge = e.age / e.life; float normalizedAge = e.age / e.life;
e.sprite = Lerp(0.0f, numSprites, normalizedAge); 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.gravity = -.1f;
s.affectedByWind = TestEnvironment(ENV_FLAG_WIND, pos.x, pos.y, pos.z, roomNumber); s.affectedByWind = TestEnvironment(ENV_FLAG_WIND, pos.x, pos.y, pos.z, roomNumber);
s.sourceColor = Vector4(0.4f, 0.4f, 0.4f, 1); s.sourceColor = Vector4(0.4f, 0.4f, 0.4f, 1);
s.destinationColor = Vector4(0, 0, 0, 0); s.destinationColor = Vector4::Zero;
if (initial) if (initial)
{ {
@ -207,7 +207,7 @@ namespace TEN::Effects::Smoke
s.velocity = Vector3(xVel, Random::GenerateFloat(-1, 4), zVel); s.velocity = Vector3(xVel, Random::GenerateFloat(-1, 4), zVel);
s.sourceColor = Vector4(1, 1, 1, 1); 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.sourceSize = Random::GenerateFloat(8,24);
s.active = true; s.active = true;
s.affectedByWind = true; s.affectedByWind = true;
@ -225,7 +225,7 @@ namespace TEN::Effects::Smoke
s = {}; 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.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.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.sourceSize = Random::GenerateFloat(32.0f, 64.0f);
s.active = true; s.active = true;
s.velocity = Random::GenerateDirection() * Random::GenerateFloat(1.0f, 3.0f); 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_LIFE = 40;
constexpr auto DUST_SPAWN_RADIUS = (10 * 1024); constexpr auto DUST_SPAWN_RADIUS = (10 * 1024);
constexpr auto SKY_POSITION_LIMIT = 9728;
EnvironmentController Weather; EnvironmentController Weather;
float WeatherParticle::Transparency() const float WeatherParticle::Transparency() const
@ -114,13 +112,13 @@ namespace TEN::Effects::Environment
continue; continue;
SkyCurrentPosition[i] += level->GetSkyLayerSpeed(i); SkyCurrentPosition[i] += level->GetSkyLayerSpeed(i);
if (SkyCurrentPosition[i] <= SKY_POSITION_LIMIT) if (SkyCurrentPosition[i] <= SKY_SIZE)
{ {
if (SkyCurrentPosition[i] < 0) if (SkyCurrentPosition[i] < 0)
SkyCurrentPosition[i] += SKY_POSITION_LIMIT; SkyCurrentPosition[i] += SKY_SIZE;
} }
else else
SkyCurrentPosition[i] -= SKY_POSITION_LIMIT; SkyCurrentPosition[i] -= SKY_SIZE;
} }
} }

View file

@ -1,16 +1,15 @@
#pragma once #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;
struct alignas(16) CCameraMatrixBuffer
{
alignas(16) Matrix ViewProjection; alignas(16) Matrix ViewProjection;
//-- //--
alignas(16) Matrix View; alignas(16) Matrix View;
@ -36,6 +35,7 @@ namespace TEN
alignas(4) float NearPlane; alignas(4) float NearPlane;
alignas(4) float FarPlane; 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

@ -3,49 +3,49 @@
namespace TEN::Renderer 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) 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 = {};
viewport.TopLeftX = 0; Viewport.TopLeftX = 0;
viewport.TopLeftY = 0; Viewport.TopLeftY = 0;
viewport.Width = w; Viewport.Width = w;
viewport.Height = h; Viewport.Height = h;
viewport.MinDepth = 0; Viewport.MinDepth = 0;
viewport.MaxDepth = 1; 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) 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 = {};
viewport.TopLeftX = 0; Viewport.TopLeftX = 0;
viewport.TopLeftY = 0; Viewport.TopLeftY = 0;
viewport.Width = w; Viewport.Width = w;
viewport.Height = h; Viewport.Height = h;
viewport.MinDepth = 0; Viewport.MinDepth = 0;
viewport.MaxDepth = 1; Viewport.MaxDepth = 1;
} }
void RenderView::fillConstantBuffer(CCameraMatrixBuffer& bufferToFill) void RenderView::fillConstantBuffer(CCameraMatrixBuffer& bufferToFill)
{ {
bufferToFill.Projection = camera.Projection; bufferToFill.Projection = Camera.Projection;
bufferToFill.View = camera.View; bufferToFill.View = Camera.View;
bufferToFill.ViewProjection = camera.ViewProjection; bufferToFill.ViewProjection = Camera.ViewProjection;
bufferToFill.InverseProjection = camera.Projection.Invert(); bufferToFill.InverseProjection = Camera.Projection.Invert();
bufferToFill.CamDirectionWS = Vector4(camera.WorldDirection); bufferToFill.CamDirectionWS = Vector4(Camera.WorldDirection);
bufferToFill.CamPositionWS = Vector4(camera.WorldPosition); bufferToFill.CamPositionWS = Vector4(Camera.WorldPosition);
bufferToFill.ViewSize = camera.ViewSize; bufferToFill.ViewSize = Camera.ViewSize;
bufferToFill.InvViewSize = camera.InvViewSize; bufferToFill.InvViewSize = Camera.InvViewSize;
bufferToFill.RoomNumber = camera.RoomNumber; bufferToFill.RoomNumber = Camera.RoomNumber;
bufferToFill.NearPlane = camera.NearPlane; bufferToFill.NearPlane = Camera.NearPlane;
bufferToFill.FarPlane = camera.FarPlane; bufferToFill.FarPlane = Camera.FarPlane;
} }
void RenderView::clear() void RenderView::clear()
{ {
roomsToDraw.clear(); RoomsToDraw.clear();
lightsToDraw.clear(); LightsToDraw.clear();
spritesToDraw.clear(); SpritesToDraw.clear();
StaticsToDraw.clear(); StaticsToDraw.clear();
} }

View file

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

View file

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

View file

@ -414,6 +414,16 @@ namespace TEN::Renderer
light->Type = LIGHT_TYPE_SPOT; light->Type = LIGHT_TYPE_SPOT;
light->Luma = Luma(light->Color); 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 // Monty's temp variables for sorting
light->LocalIntensity = 0; light->LocalIntensity = 0;

View file

@ -48,7 +48,7 @@ namespace TEN::Renderer
static const std::array<LARA_MESHES, 4> sphereMeshes = { LM_HIPS, LM_TORSO, LM_LFOOT, LM_RFOOT }; 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 }; 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) for (auto& i : room->ItemsToDraw)
{ {
@ -1015,8 +1015,8 @@ namespace TEN::Renderer
void Renderer11::DrawSortedFaces(RenderView& view) void Renderer11::DrawSortedFaces(RenderView& view)
{ {
std::for_each(std::execution::par_unseq, std::for_each(std::execution::par_unseq,
view.roomsToDraw.begin(), view.RoomsToDraw.begin(),
view.roomsToDraw.end(), view.RoomsToDraw.end(),
[](RendererRoom* room) [](RendererRoom* room)
{ {
std::sort( 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_transparentFacesVertices.clear();
m_transparentFacesIndices.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.Caustics = (int)(g_Configuration.EnableCaustics && (nativeRoom->flags & ENV_FLAG_WATER));
m_stRoom.AmbientColor = info->room->AmbientLight; m_stRoom.AmbientColor = info->room->AmbientLight;
m_stRoom.Water = (nativeRoom->flags & ENV_FLAG_WATER) != 0 ? 1 : 0; 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()); m_cbRoom.updateData(m_stRoom, m_context.Get());
BindConstantBufferVS(CB_ROOM, m_cbRoom.get()); BindConstantBufferVS(CB_ROOM, m_cbRoom.get());
BindConstantBufferPS(CB_ROOM, m_cbRoom.get()); BindConstantBufferPS(CB_ROOM, m_cbRoom.get());
@ -1432,20 +1432,17 @@ namespace TEN::Renderer
// Bind and clear render target // Bind and clear render target
m_context->ClearRenderTargetView(m_renderTarget.RenderTargetView.Get(), Colors::Black); m_context->ClearRenderTargetView(m_renderTarget.RenderTargetView.Get(), Colors::Black);
m_context->ClearDepthStencilView(m_renderTarget.DepthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, m_context->ClearDepthStencilView(m_renderTarget.DepthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
1.0f, 0);
m_context->ClearRenderTargetView(m_depthMap.RenderTargetView.Get(), Colors::White); m_context->ClearRenderTargetView(m_depthMap.RenderTargetView.Get(), Colors::White);
m_context->ClearDepthStencilView(m_depthMap.DepthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, m_context->ClearDepthStencilView(m_depthMap.DepthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
1.0f, 0);
ID3D11RenderTargetView* m_pRenderViews[2]; ID3D11RenderTargetView* m_pRenderViews[2];
m_pRenderViews[0] = m_renderTarget.RenderTargetView.Get(); m_pRenderViews[0] = m_renderTarget.RenderTargetView.Get();
m_pRenderViews[1] = m_depthMap.RenderTargetView.Get(); m_pRenderViews[1] = m_depthMap.RenderTargetView.Get();
m_context->OMSetRenderTargets(2, &m_pRenderViews[0], m_context->OMSetRenderTargets(2, &m_pRenderViews[0], m_renderTarget.DepthStencilView.Get());
m_renderTarget.DepthStencilView.Get());
m_context->RSSetViewports(1, &view.viewport); m_context->RSSetViewports(1, &view.Viewport);
ResetScissor(); ResetScissor();
// The camera constant buffer contains matrices, camera position, fog values and other // The camera constant buffer contains matrices, camera position, fog values and other
@ -1465,6 +1462,19 @@ namespace TEN::Renderer
else else
{ {
cameraConstantBuffer.FogMaxDistance = 0; 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()); m_cbCameraMatrices.updateData(cameraConstantBuffer, m_context.Get());
@ -1569,7 +1579,7 @@ namespace TEN::Renderer
m_context->ClearDepthStencilView(depthTarget, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0); m_context->ClearDepthStencilView(depthTarget, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
m_context->OMSetRenderTargets(1, &target, depthTarget); m_context->OMSetRenderTargets(1, &target, depthTarget);
m_context->RSSetViewports(1, &view.viewport); m_context->RSSetViewports(1, &view.Viewport);
ResetScissor(); ResetScissor();
// Opaque geometry // Opaque geometry
@ -1605,7 +1615,7 @@ namespace TEN::Renderer
m_context->VSSetShader(m_vsItems.Get(), nullptr, 0); m_context->VSSetShader(m_vsItems.Get(), nullptr, 0);
m_context->PSSetShader(m_psItems.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) for (auto itemToDraw : room->ItemsToDraw)
{ {
@ -1640,7 +1650,7 @@ namespace TEN::Renderer
if (g_Configuration.ShadowType != ShadowMode::None) if (g_Configuration.ShadowType != ShadowMode::None)
{ {
for (auto room : renderView.roomsToDraw) for (auto room : renderView.RoomsToDraw)
for (auto itemToDraw : room->ItemsToDraw) for (auto itemToDraw : room->ItemsToDraw)
RenderShadowMap(itemToDraw, renderView); RenderShadowMap(itemToDraw, renderView);
} }
@ -1898,7 +1908,7 @@ namespace TEN::Renderer
{ {
Vector3 cameraPosition = Vector3(Camera.pos.x, Camera.pos.y, Camera.pos.z); 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) for (auto& msh : view.StaticsToDraw)
{ {
@ -2000,10 +2010,10 @@ namespace TEN::Renderer
} }
m_numRoomsTransparentPolygons = 0; 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; int index = i;
RendererRoom* room = view.roomsToDraw[index]; RendererRoom* room = view.RoomsToDraw[index];
m_cbShadowMap.updateData(m_stShadowMap, m_context.Get()); m_cbShadowMap.updateData(m_stShadowMap, m_context.Get());
BindConstantBufferPS(CB_SHADOW_LIGHT, m_cbShadowMap.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.Caustics = (int)(g_Configuration.EnableCaustics && (nativeRoom->flags & ENV_FLAG_WATER));
m_stRoom.AmbientColor = room->AmbientLight; m_stRoom.AmbientColor = room->AmbientLight;
m_stRoom.Water = (nativeRoom->flags & ENV_FLAG_WATER) != 0 ? 1 : 0; 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()); m_cbRoom.updateData(m_stRoom, m_context.Get());
SetScissor(room->ClipBounds); SetScissor(room->ClipBounds);
@ -2152,9 +2162,9 @@ namespace TEN::Renderer
ScriptInterfaceLevel* level = g_GameFlow->GetLevel(CurrentLevel); ScriptInterfaceLevel* level = g_GameFlow->GetLevel(CurrentLevel);
bool anyOutsideRooms = false; 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) if (nativeRoom->flags & ENV_FLAG_OUTSIDE)
{ {
anyOutsideRooms = true; anyOutsideRooms = true;
@ -2174,65 +2184,25 @@ namespace TEN::Renderer
// Draw the sky // Draw the sky
Matrix rotation = Matrix::CreateRotationX(PI); 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->VSSetShader(m_vsSky.Get(), nullptr, 0);
m_context->PSSetShader(m_psSky.Get(), nullptr, 0); m_context->PSSetShader(m_psSky.Get(), nullptr, 0);
BindTexture(TEXTURE_COLOR_MAP, &m_skyTexture, SAMPLER_ANISOTROPIC_CLAMP); 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->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
m_context->IASetInputLayout(m_inputLayout.Get()); m_context->IASetInputLayout(m_inputLayout.Get());
m_context->IASetIndexBuffer(m_skyIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
SetBlendMode(BLENDMODE_ADDITIVE); SetBlendMode(BLENDMODE_ADDITIVE);
for (int s = 0; s < 2; s++) for (int s = 0; s < 2; s++)
{
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
{ {
auto weather = TEN::Effects::Environment::Weather; auto weather = TEN::Effects::Environment::Weather;
Matrix translation = Matrix::CreateTranslation(Camera.pos.x + weather.SkyPosition(s) - i * 9728.0f, Matrix translation = Matrix::CreateTranslation(Camera.pos.x + weather.SkyPosition(s) - i * SKY_SIZE,
Camera.pos.y - 1536.0f, Camera.pos.z); Camera.pos.y - 1536.0f, Camera.pos.z);
Matrix world = rotation * translation; Matrix world = rotation * translation;
@ -2245,10 +2215,10 @@ namespace TEN::Renderer
BindConstantBufferVS(CB_STATIC, m_cbStatic.get()); BindConstantBufferVS(CB_STATIC, m_cbStatic.get());
BindConstantBufferPS(CB_STATIC, m_cbStatic.get()); BindConstantBufferPS(CB_STATIC, m_cbStatic.get());
m_primitiveBatch->Begin(); DrawIndexedTriangles(SKY_INDICES_COUNT, 0, 0);
m_primitiveBatch->DrawQuad(vertices[0], vertices[1], vertices[2], vertices[3]);
m_primitiveBatch->End();
} }
}
m_context->ClearDepthStencilView(depthTarget, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0); m_context->ClearDepthStencilView(depthTarget, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0);
// Draw horizon // Draw horizon

View file

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

View file

@ -965,7 +965,7 @@ namespace TEN::Renderer
m_context->IASetInputLayout(m_inputLayout.Get()); m_context->IASetInputLayout(m_inputLayout.Get());
m_context->IASetIndexBuffer(m_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0); 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) for (auto* item : room->ItemsToDraw)
{ {
@ -1081,7 +1081,7 @@ namespace TEN::Renderer
{ {
case RENDERER_SPRITE_TYPE::SPRITE_TYPE_BILLBOARD: 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); spriteMatrix = scaleMatrix * Matrix::CreateRotationZ(sprite->Rotation) * Matrix::CreateBillboard(sprite->pos, Camera.pos.ToVector3(), cameraUp);
} }
break; break;
@ -1117,13 +1117,13 @@ namespace TEN::Renderer
void Renderer11::DrawSprites(RenderView& view) void Renderer11::DrawSprites(RenderView& view)
{ {
if (view.spritesToDraw.empty()) if (view.SpritesToDraw.empty())
return; return;
// Sort sprites by sprite and blend mode for faster batching. // Sort sprites by sprite and blend mode for faster batching.
std::sort( std::sort(
view.spritesToDraw.begin(), view.SpritesToDraw.begin(),
view.spritesToDraw.end(), view.SpritesToDraw.end(),
[](RendererSpriteToDraw& rDrawSprite0, RendererSpriteToDraw& rDrawSprite1) [](RendererSpriteToDraw& rDrawSprite0, RendererSpriteToDraw& rDrawSprite1)
{ {
if (rDrawSprite0.Sprite != rDrawSprite1.Sprite) if (rDrawSprite0.Sprite != rDrawSprite1.Sprite)
@ -1145,13 +1145,13 @@ namespace TEN::Renderer
std::vector<RendererSpriteBucket> spriteBuckets; std::vector<RendererSpriteBucket> spriteBuckets;
RendererSpriteBucket currentSpriteBucket; RendererSpriteBucket currentSpriteBucket;
currentSpriteBucket.Sprite = view.spritesToDraw[0].Sprite; currentSpriteBucket.Sprite = view.SpritesToDraw[0].Sprite;
currentSpriteBucket.BlendMode = view.spritesToDraw[0].BlendMode; currentSpriteBucket.BlendMode = view.SpritesToDraw[0].BlendMode;
currentSpriteBucket.IsBillboard = view.spritesToDraw[0].Type != RENDERER_SPRITE_TYPE::SPRITE_TYPE_3D; currentSpriteBucket.IsBillboard = view.SpritesToDraw[0].Type != RENDERER_SPRITE_TYPE::SPRITE_TYPE_3D;
currentSpriteBucket.IsSoftParticle = view.spritesToDraw[0].SoftParticle; currentSpriteBucket.IsSoftParticle = view.SpritesToDraw[0].SoftParticle;
currentSpriteBucket.RenderType = view.spritesToDraw[0].renderType; 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; 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.world = GetWorldMatrixForSprite(&rDrawSprite, view);
face.info.blendMode = rDrawSprite.BlendMode; 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)) 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; break;
} }
} }
@ -1433,7 +1433,7 @@ namespace TEN::Renderer
m_context->IASetInputLayout(m_inputLayout.Get()); m_context->IASetInputLayout(m_inputLayout.Get());
m_context->IASetIndexBuffer(m_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0); 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) for (auto effect : room->EffectsToDraw)
{ {

View file

@ -932,7 +932,7 @@ namespace TEN::Renderer
PrintDebugMessage(" Statics: %d", m_numStaticsDrawCalls); PrintDebugMessage(" Statics: %d", m_numStaticsDrawCalls);
PrintDebugMessage(" Sprites: %d", m_numSpritesDrawCalls); PrintDebugMessage(" Sprites: %d", m_numSpritesDrawCalls);
PrintDebugMessage("Triangles: %d", m_numPolygons); 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("Transparent faces draw calls: %d", m_numTransparentDrawCalls);
PrintDebugMessage(" Rooms: %d", m_numRoomsTransparentDrawCalls); PrintDebugMessage(" Rooms: %d", m_numRoomsTransparentDrawCalls);
PrintDebugMessage(" Movables: %d", m_numMoveablesTransparentDrawCalls); PrintDebugMessage(" Movables: %d", m_numMoveablesTransparentDrawCalls);
@ -940,7 +940,7 @@ namespace TEN::Renderer
PrintDebugMessage(" Sprites: %d", m_numSpritesTransparentDrawCalls); PrintDebugMessage(" Sprites: %d", m_numSpritesTransparentDrawCalls);
PrintDebugMessage("Biggest room's index buffer: %d", m_biggestRoomIndexBuffer); PrintDebugMessage("Biggest room's index buffer: %d", m_biggestRoomIndexBuffer);
PrintDebugMessage("Transparent room polys: %d", m_numRoomsTransparentPolygons); 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(" CheckPortal() calls: %d", m_numCheckPortalCalls);
PrintDebugMessage(" GetVisibleRooms() calls: %d", m_numGetVisibleRoomsCalls); PrintDebugMessage(" GetVisibleRooms() calls: %d", m_numGetVisibleRoomsCalls);
PrintDebugMessage(" Dot products: %d", m_dotProducts); PrintDebugMessage(" Dot products: %d", m_dotProducts);

View file

@ -36,7 +36,8 @@ enum LIGHT_TYPES
LIGHT_TYPE_SUN = 0, LIGHT_TYPE_SUN = 0,
LIGHT_TYPE_POINT = 1, LIGHT_TYPE_POINT = 1,
LIGHT_TYPE_SPOT = 2, LIGHT_TYPE_SPOT = 2,
LIGHT_TYPE_SHADOW = 3 LIGHT_TYPE_SHADOW = 3,
LIGHT_TYPE_FOG_BULB = 4
}; };
enum BLEND_MODES enum BLEND_MODES
@ -223,6 +224,7 @@ constexpr auto FADE_FACTOR = 0.0625f;
constexpr auto NUM_LIGHTS_PER_BUFFER = 48; constexpr auto NUM_LIGHTS_PER_BUFFER = 48;
constexpr auto MAX_LIGHTS_PER_ITEM = 8; constexpr auto MAX_LIGHTS_PER_ITEM = 8;
constexpr auto MAX_FOG_BULBS = 32;
constexpr auto MAX_LIGHTS = 100; constexpr auto MAX_LIGHTS = 100;
constexpr auto AMBIENT_LIGHT_INTERPOLATION_STEP = 1.0f / 10.0f; constexpr auto AMBIENT_LIGHT_INTERPOLATION_STEP = 1.0f / 10.0f;
constexpr auto MAX_DYNAMIC_SHADOWS = 1; 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 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 // FUTURE
/* /*
#define CBUFFER_CAMERA 0 #define CBUFFER_CAMERA 0

View file

@ -43,12 +43,12 @@ 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 // 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.left = (room->ViewPort.x + 1.0f) * m_screenWidth * 0.5f;
room->ClipBounds.bottom = (1.0f - room->ViewPort.y) * m_screenHeight * 0.5f; room->ClipBounds.bottom = (1.0f - room->ViewPort.y) * m_screenHeight * 0.5f;
@ -61,6 +61,46 @@ namespace TEN::Renderer
{ {
return a->ObjectNumber < b->ObjectNumber; 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) bool Renderer11::CheckPortal(short parentRoomNumber, RendererDoor* door, Vector4 viewPort, Vector4* clipPort, RenderView& renderView)
@ -79,7 +119,7 @@ namespace TEN::Renderer
{ {
if (!door->Visited) 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) if (p[i].w > 0.0f)
{ {
p[i].x *= (1.0f / p[i].w); p[i].x *= (1.0f / p[i].w);
@ -196,7 +236,7 @@ namespace TEN::Renderer
{ {
room->Visited = true; room->Visited = true;
renderView.roomsToDraw.push_back(room); renderView.RoomsToDraw.push_back(room);
CollectLightsForRoom(to, renderView); CollectLightsForRoom(to, renderView);
@ -316,7 +356,7 @@ namespace TEN::Renderer
bool inFrustum = false; bool inFrustum = false;
for (int i = 0; !inFrustum, i < cnt; i++) for (int i = 0; !inFrustum, i < cnt; i++)
// Blow up sphere radius by half for cases of too small calculated spheres. // 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; inFrustum = true;
if (!inFrustum) if (!inFrustum)
@ -391,7 +431,7 @@ namespace TEN::Renderer
} }
auto length = Vector3(mesh->VisibilityBox.Extents).Length(); 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; continue;
} }
@ -721,13 +761,13 @@ namespace TEN::Renderer
} }
// Light buffer is full // Light buffer is full
if (renderView.lightsToDraw.size() >= NUM_LIGHTS_PER_BUFFER) if (renderView.LightsToDraw.size() >= NUM_LIGHTS_PER_BUFFER)
{ {
break; break;
} }
// Light already on a list // 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; continue;
} }
@ -738,7 +778,7 @@ namespace TEN::Renderer
continue; continue;
} }
renderView.lightsToDraw.push_back(light); renderView.LightsToDraw.push_back(light);
room.LightsToDraw.push_back(light); room.LightsToDraw.push_back(light);
} }
} }

View file

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

View file

@ -229,6 +229,83 @@ void TEN::Renderer::Renderer11::Initialize(int w, int h, bool windowed, HWND han
InitializeGameBars(); InitializeGameBars();
initQuad(m_device.Get()); 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) 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.color = color;
spr.renderType = renderType; 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, void Renderer11::AddSpriteBillboardConstrained(RendererSprite* sprite, const Vector3& pos, const Vector4 &color, float orient2D,
@ -69,7 +69,7 @@ namespace TEN::Renderer
spr.color = color; spr.color = color;
spr.renderType = renderType; 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, void Renderer11::AddSpriteBillboardConstrainedLookAt(RendererSprite* sprite, const Vector3& pos, const Vector4& color, float orient2D,
@ -104,7 +104,7 @@ namespace TEN::Renderer
spr.color = color; spr.color = color;
spr.renderType = renderType; 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, 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.SoftParticle = isSoftParticle;
spr.renderType = renderType; 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, 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.SoftParticle = false;
sprite.renderType = renderType; 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

@ -45,11 +45,8 @@ void DoAlphaTest(float4 inputColor)
} }
} }
float4 DoFog(float4 sourceColor, float4 fogColor, float value) float4 DoDistanceFogForPixel(float4 sourceColor, float4 fogColor, float value)
{ {
if (FogMaxDistance == 0)
return sourceColor;
switch (BlendMode) switch (BlendMode)
{ {
case BLENDMODE_ADDITIVE: case BLENDMODE_ADDITIVE:
@ -78,6 +75,40 @@ float4 DoFog(float4 sourceColor, float4 fogColor, float value)
return result; 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) float4 DoLaserBarrierEffect(float3 input, float4 output, float2 uv, float faceFactor, float timeUniform)
{ {
float2 noiseTexture = input.xy / uv; float2 noiseTexture = input.xy / uv;

View file

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

View file

@ -2,6 +2,7 @@
#include "./Blending.hlsli" #include "./Blending.hlsli"
#include "./VertexInput.hlsli" #include "./VertexInput.hlsli"
#include "./Math.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 // NOTE: This shader is used for all opaque or not sorted transparent sprites, that can be instanced for a faster drawing
@ -12,8 +13,9 @@ struct PixelShaderInput
float4 Position: SV_POSITION; float4 Position: SV_POSITION;
float2 UV: TEXCOORD1; float2 UV: TEXCOORD1;
float4 Color: COLOR; float4 Color: COLOR;
float Fog : FOG;
float4 PositionCopy: TEXCOORD2; float4 PositionCopy: TEXCOORD2;
float4 FogBulbs : TEXCOORD3;
float DistanceFog : FOG;
}; };
struct InstancedSprite struct InstancedSprite
@ -57,11 +59,8 @@ PixelShaderInput VS(VertexShaderInput input, uint InstanceID : SV_InstanceID)
output.Color = Sprites[InstanceID].Color; output.Color = Sprites[InstanceID].Color;
output.UV = float2(Sprites[InstanceID].UV[0][input.PolyIndex], Sprites[InstanceID].UV[1][input.PolyIndex]); output.UV = float2(Sprites[InstanceID].UV[0][input.PolyIndex], Sprites[InstanceID].UV[1][input.PolyIndex]);
float4 d = length(CamPositionWS - worldPosition); output.FogBulbs = DoFogBulbsForVertex(worldPosition);
if (FogMaxDistance == 0) output.DistanceFog = DoDistanceFogForVertex(worldPosition);
output.Fog = 1;
else
output.Fog = clamp((d - FogMinDistance * 1024) / (FogMaxDistance * 1024 - FogMinDistance * 1024), 0, 1);
return output; return output;
} }
@ -105,7 +104,10 @@ float4 PS(PixelShaderInput input, uint InstanceID : SV_InstanceID) : SV_TARGET
output.w = min(output.w, fade); output.w = min(output.w, fade);
} }
output = DoFog(output, float4(0.0f, 0.0f, 0.0f, 0.0f), input.Fog); 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; return output;
} }

View file

@ -29,8 +29,9 @@ struct PixelShaderInput
float2 UV: TEXCOORD1; float2 UV: TEXCOORD1;
float4 Color: COLOR; float4 Color: COLOR;
float Sheen : SHEEN; float Sheen : SHEEN;
float Fog : FOG;
float4 PositionCopy: TEXCOORD2; float4 PositionCopy: TEXCOORD2;
float4 FogBulbs : TEXCOORD3;
float DistanceFog : FOG;
uint InstanceID : SV_InstanceID; uint InstanceID : SV_InstanceID;
}; };
@ -60,18 +61,13 @@ PixelShaderInput VS(VertexShaderInput input, uint InstanceID : SV_InstanceID)
output.Position = mul(worldPosition, ViewProjection); output.Position = mul(worldPosition, ViewProjection);
output.Color = float4(col, input.Color.w); output.Color = float4(col, input.Color.w);
output.Color *= StaticMeshes[InstanceID].Color; 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.PositionCopy = output.Position;
output.Sheen = input.Effects.w; output.Sheen = input.Effects.w;
output.InstanceID = InstanceID; output.InstanceID = InstanceID;
output.FogBulbs = DoFogBulbsForVertex(worldPosition);
output.DistanceFog = DoDistanceFogForVertex(worldPosition);
return output; return output;
} }
@ -94,16 +90,17 @@ PixelShaderOutput PS(PixelShaderInput input)
normalize(input.Normal), normalize(input.Normal),
input.Sheen, input.Sheen,
StaticMeshes[input.InstanceID].InstancedStaticLights, StaticMeshes[input.InstanceID].InstancedStaticLights,
numLights) : numLights,
StaticLight(input.Color.xyz, tex.xyz); input.FogBulbs.w) :
StaticLight(input.Color.xyz, tex.xyz, input.FogBulbs.w);
output.Color = float4(color, tex.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 ? output.Depth = tex.w > 0.0f ?
float4(input.PositionCopy.z / input.PositionCopy.w, 0.0f, 0.0f, 1.0f) : float4(input.PositionCopy.z / input.PositionCopy.w, 0.0f, 0.0f, 1.0f) :
float4(0.0f, 0.0f, 0.0f, 0.0f); float4(0.0f, 0.0f, 0.0f, 0.0f);
output.Color = DoFog(output.Color, FogColor, input.Fog);
return output; return output;
} }

View file

@ -5,7 +5,7 @@
#include "./VertexInput.hlsli" #include "./VertexInput.hlsli"
#include "./Blending.hlsli" #include "./Blending.hlsli"
#include "./AnimatedTextures.hlsli" #include "./AnimatedTextures.hlsli"
#include "./Shadows.hlsli" //#include "./Shadows.hlsli"
#define MAX_BONES 32 #define MAX_BONES 32
@ -25,12 +25,13 @@ struct PixelShaderInput
float4 Position: SV_POSITION; float4 Position: SV_POSITION;
float3 Normal: NORMAL; float3 Normal: NORMAL;
float3 WorldPosition: POSITION; float3 WorldPosition: POSITION;
float2 UV: TEXCOORD; float2 UV: TEXCOORD1;
float4 Color: COLOR; float4 Color: COLOR;
float Sheen: SHEEN; float Sheen: SHEEN;
float3x3 TBN: TBN; float3x3 TBN: TBN;
float Fog: FOG;
float4 PositionCopy: TEXCOORD2; float4 PositionCopy: TEXCOORD2;
float4 FogBulbs : TEXCOORD3;
float DistanceFog : FOG;
unsigned int Bone: BONE; unsigned int Bone: BONE;
}; };
@ -74,17 +75,13 @@ PixelShaderInput VS(VertexShaderInput input)
output.Position = mul(mul(float4(pos, 1.0f), world), ViewProjection); output.Position = mul(mul(float4(pos, 1.0f), world), ViewProjection);
output.Color = float4(col, input.Color.w); output.Color = float4(col, input.Color.w);
output.Color *= Color; 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.PositionCopy = output.Position;
output.Sheen = input.Effects.w; output.Sheen = input.Effects.w;
output.Bone = input.Bone; output.Bone = input.Bone;
output.FogBulbs = DoFogBulbsForVertex(worldPosition);
output.DistanceFog = DoDistanceFogForVertex(worldPosition);
return output; return output;
} }
@ -111,16 +108,17 @@ PixelShaderOutput PS(PixelShaderInput input)
normal, normal,
input.Sheen, input.Sheen,
ItemLights, ItemLights,
NumItemLights) : NumItemLights,
StaticLight(input.Color.xyz, tex.xyz); input.FogBulbs.w) :
StaticLight(input.Color.xyz, tex.xyz, input.FogBulbs.w);
output.Color = saturate(float4(color, tex.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 ? output.Depth = tex.w > 0.0f ?
float4(input.PositionCopy.z / input.PositionCopy.w, 0.0f, 0.0f, 1.0f) : float4(input.PositionCopy.z / input.PositionCopy.w, 0.0f, 0.0f, 1.0f) :
float4(0.0f, 0.0f, 0.0f, 0.0f); float4(0.0f, 0.0f, 0.0f, 0.0f);
output.Color = DoFog(output.Color, FogColor, input.Fog);
return output; return output;
} }

View file

@ -3,9 +3,9 @@
#include "./VertexEffects.hlsli" #include "./VertexEffects.hlsli"
#include "./Blending.hlsli" #include "./Blending.hlsli"
#include "./Math.hlsli" #include "./Math.hlsli"
#include "./ShaderLight.hlsli"
#include "./AnimatedTextures.hlsli" #include "./AnimatedTextures.hlsli"
#include "./Shadows.hlsli" #include "./Shadows.hlsli"
#include "./ShaderLight.hlsli"
cbuffer RoomBuffer : register(b5) cbuffer RoomBuffer : register(b5)
{ {
@ -27,8 +27,9 @@ struct PixelShaderInput
float2 UV: TEXCOORD0; float2 UV: TEXCOORD0;
float4 Color: COLOR; float4 Color: COLOR;
float3x3 TBN : TBN; float3x3 TBN : TBN;
float Fog : FOG;
float4 PositionCopy : TEXCOORD1; float4 PositionCopy : TEXCOORD1;
float4 FogBulbs : TEXCOORD2;
float DistanceFog : FOG;
}; };
Texture2D Texture : register(t0); Texture2D Texture : register(t0);
@ -90,12 +91,8 @@ PixelShaderInput VS(VertexShaderInput input)
float3x3 TBN = float3x3(input.Tangent, cross(input.Normal,input.Tangent), input.Normal); float3x3 TBN = float3x3(input.Tangent, cross(input.Normal,input.Tangent), input.Normal);
output.TBN = TBN; output.TBN = TBN;
// Apply distance fog output.FogBulbs = DoFogBulbsForVertex(output.WorldPosition);
float d = length(CamPositionWS.xyz - output.WorldPosition); output.DistanceFog = DoDistanceFogForVertex(output.WorldPosition);
if (FogMaxDistance == 0)
output.Fog = 1;
else
output.Fog = clamp((d - FogMinDistance * 1024) / (FogMaxDistance * 1024 - FogMinDistance * 1024), 0, 1);
return output; return output;
} }
@ -185,13 +182,16 @@ PixelShaderOutput PS(PixelShaderInput input)
lighting += float3((xaxis * blending.x + yaxis * blending.y + zaxis * blending.z).xyz) * attenuation * 2.0f; 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 ? output.Depth = output.Color.w > 0.0f ?
float4(input.PositionCopy.z / input.PositionCopy.w, 0.0f, 0.0f, 1.0f) : float4(input.PositionCopy.z / input.PositionCopy.w, 0.0f, 0.0f, 1.0f) :
float4(0.0f, 0.0f, 0.0f, 0.0f); float4(0.0f, 0.0f, 0.0f, 0.0f);
output.Color = DoFog(output.Color, FogColor, input.Fog); 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; return output;
} }

View file

@ -1,6 +1,8 @@
#include "./CameraMatrixBuffer.hlsli" #include "./CameraMatrixBuffer.hlsli"
#include "./Blending.hlsli" #include "./Blending.hlsli"
#include "./VertexInput.hlsli" #include "./VertexInput.hlsli"
#include "./Math.hlsli"
#include "./ShaderLight.hlsli"
cbuffer StaticMatrixBuffer : register(b8) cbuffer StaticMatrixBuffer : register(b8)
{ {
@ -16,6 +18,7 @@ struct PixelShaderInput
float3 Normal: NORMAL; float3 Normal: NORMAL;
float2 UV: TEXCOORD; float2 UV: TEXCOORD;
float4 Color: COLOR; float4 Color: COLOR;
float4 FogBulbs : TEXCOORD3;
}; };
Texture2D Texture : register(t0); Texture2D Texture : register(t0);
@ -25,10 +28,13 @@ PixelShaderInput VS(VertexShaderInput input)
{ {
PixelShaderInput output; PixelShaderInput output;
output.Position = mul(mul(float4(input.Position, 1.0f), World), ViewProjection); float4 worldPosition = mul(float4(input.Position, 1.0f), World);
output.Position = mul(worldPosition, ViewProjection);
output.Normal = input.Normal; output.Normal = input.Normal;
output.Color = input.Color; output.Color = input.Color;
output.UV = input.UV; output.UV = input.UV;
output.FogBulbs = DoFogBulbsForSky(worldPosition);
return output; return output;
} }
@ -40,6 +46,9 @@ float4 PS(PixelShaderInput input) : SV_TARGET
DoAlphaTest(output); DoAlphaTest(output);
output.xyz = output.xyz * Color; 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; return output;
} }

View file

@ -2,6 +2,7 @@
#include "./Blending.hlsli" #include "./Blending.hlsli"
#include "./VertexInput.hlsli" #include "./VertexInput.hlsli"
#include "./Math.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 // NOTE: This shader is used for all 3D and alpha blended sprites, because we send aleady transformed vertices to the GPU
// instead of instances // instead of instances
@ -20,8 +21,9 @@ struct PixelShaderInput
float3 Normal: NORMAL; float3 Normal: NORMAL;
float2 UV: TEXCOORD1; float2 UV: TEXCOORD1;
float4 Color: COLOR; float4 Color: COLOR;
float Fog : FOG;
float4 PositionCopy: TEXCOORD2; float4 PositionCopy: TEXCOORD2;
float4 FogBulbs : TEXCOORD3;
float DistanceFog : FOG;
}; };
Texture2D Texture : register(t0); Texture2D Texture : register(t0);
@ -42,11 +44,8 @@ PixelShaderInput VS(VertexShaderInput input)
output.Color = input.Color; output.Color = input.Color;
output.UV = input.UV; output.UV = input.UV;
float4 d = length(CamPositionWS - worldPosition); output.FogBulbs = DoFogBulbsForVertex(worldPosition);
if (FogMaxDistance == 0) output.DistanceFog = DoDistanceFogForVertex(worldPosition);
output.Fog = 1;
else
output.Fog = clamp((d - FogMinDistance * 1024) / (FogMaxDistance * 1024 - FogMinDistance * 1024), 0, 1);
return output; return output;
} }
@ -79,7 +78,10 @@ float4 PS(PixelShaderInput input) : SV_TARGET
output = DoLaserBarrierEffect(input.Position, output, input.UV, FADE_FACTOR, Frame); output = DoLaserBarrierEffect(input.Position, output, input.UV, FADE_FACTOR, Frame);
} }
output = DoFog(output, float4(0.0f, 0.0f, 0.0f, 0.0f), input.Fog); 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; return output;
} }

View file

@ -23,8 +23,9 @@ struct PixelShaderInput
float2 UV: TEXCOORD1; float2 UV: TEXCOORD1;
float4 Color: COLOR; float4 Color: COLOR;
float Sheen: SHEEN; float Sheen: SHEEN;
float Fog: FOG;
float4 PositionCopy: TEXCOORD2; float4 PositionCopy: TEXCOORD2;
float4 FogBulbs : TEXCOORD3;
float DistanceFog : FOG;
}; };
struct PixelShaderOutput struct PixelShaderOutput
@ -54,15 +55,12 @@ PixelShaderInput VS(VertexShaderInput input)
output.Color = float4(col, input.Color.w); output.Color = float4(col, input.Color.w);
output.Color *= Color; output.Color *= Color;
// Apply distance fog output.FogBulbs = DoFogBulbsForVertex(worldPosition);
float4 d = length(CamPositionWS - worldPosition); output.DistanceFog = DoDistanceFogForVertex(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.PositionCopy = output.Position;
output.Sheen = input.Effects.w; output.Sheen = input.Effects.w;
return output; return output;
} }
@ -82,16 +80,17 @@ PixelShaderOutput PS(PixelShaderInput input)
normalize(input.Normal), normalize(input.Normal),
input.Sheen, input.Sheen,
StaticLights, StaticLights,
NumStaticLights) : NumStaticLights,
StaticLight(input.Color.xyz, tex.xyz); input.FogBulbs.w) :
StaticLight(input.Color.xyz, tex.xyz, input.FogBulbs.w);
output.Color = float4(color, tex.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 ? output.Depth = tex.w > 0.0f ?
float4(input.PositionCopy.z / input.PositionCopy.w, 0.0f, 0.0f, 1.0f) : float4(input.PositionCopy.z / input.PositionCopy.w, 0.0f, 0.0f, 1.0f) :
float4(0.0f, 0.0f, 0.0f, 0.0f); float4(0.0f, 0.0f, 0.0f, 0.0f);
output.Color = DoFog(output.Color, FogColor, input.Fog);
return output; return output;
} }

View file

@ -5,6 +5,41 @@
#define PI2 6.2831853071795864769252867665590057683943387987502116419498891846 #define PI2 6.2831853071795864769252867665590057683943387987502116419498891846
#define OCTAVES 6 #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) float Luma(float3 color)
{ {
// Use Rec.709 trichromat formula to get perceptive luma value. // Use Rec.709 trichromat formula to get perceptive luma value.

View file

@ -1,28 +1,5 @@
#include "./Math.hlsli" #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) float3 DoSpecularPoint(float3 pos, float3 n, ShaderLight light, float strength)
{ {
if ((strength <= 0.0)) if ((strength <= 0.0))
@ -210,7 +187,215 @@ float3 DoDirectionalLight(float3 pos, float3 n, ShaderLight light)
return float3(0, 0, 0); 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 diffuse = 0;
float3 shadow = 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 ambTex = saturate(ambient - shadow) * tex;
float3 combined = ambTex + diffuse + spec; 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\Utils\object_helper.h" />
<ClInclude Include="Objects\game_object_ids.h" /> <ClInclude Include="Objects\game_object_ids.h" />
<ClInclude Include="Objects\objectslist.h" /> <ClInclude Include="Objects\objectslist.h" />
<ClInclude Include="Renderer\ConstantBuffers\ShaderFogBulb.h" />
<ClInclude Include="Renderer\ConstantBuffer\ConstantBuffer.h" /> <ClInclude Include="Renderer\ConstantBuffer\ConstantBuffer.h" />
<ClInclude Include="Renderer\ConstantBuffers\AnimatedBuffer.h" /> <ClInclude Include="Renderer\ConstantBuffers\AnimatedBuffer.h" />
<ClInclude Include="Renderer\ConstantBuffers\BlendingBuffer.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\RendererBone.h" />
<ClInclude Include="Renderer\Structures\RendererDisplayMode.h" /> <ClInclude Include="Renderer\Structures\RendererDisplayMode.h" />
<ClInclude Include="Renderer\Structures\RendererDoor.h" /> <ClInclude Include="Renderer\Structures\RendererDoor.h" />
<ClInclude Include="Renderer\Structures\RendererFogBulb.h" />
<ClInclude Include="Renderer\Structures\RendererLight.h" /> <ClInclude Include="Renderer\Structures\RendererLight.h" />
<ClInclude Include="Renderer\Structures\RendererRoom.h" /> <ClInclude Include="Renderer\Structures\RendererRoom.h" />
<ClInclude Include="Renderer\Structures\RendererStringToDraw.h" /> <ClInclude Include="Renderer\Structures\RendererStringToDraw.h" />

View file

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