diff --git a/Engine/Engine.vcxproj b/Engine/Engine.vcxproj
index b9d767d..1df1b2a 100644
--- a/Engine/Engine.vcxproj
+++ b/Engine/Engine.vcxproj
@@ -281,6 +281,8 @@
+
+
@@ -304,6 +306,11 @@
Compute
4.0
+
+ Compute
+ 5.0
+ Compute
+
Compute
5.0
@@ -544,16 +551,6 @@
Compute
/O2 /Gpp %(AdditionalOptions)
-
- Compute
- 5.0
- Compute
- 4.0
- Compute
- 5.0
- Compute
- 4.0
-
Compute
5.0
@@ -583,6 +580,26 @@
Compute
5.0
+
+ Compute
+ Compute
+ 5.0
+
+
+ Compute
+ 5.0
+ Compute
+
+
+ Compute
+ Compute
+ 5.0
+
+
+ Compute
+ Compute
+ 5.0
+
Compute
5.0
diff --git a/Engine/Engine.vcxproj.filters b/Engine/Engine.vcxproj.filters
index 368f0a1..1781cb9 100644
--- a/Engine/Engine.vcxproj.filters
+++ b/Engine/Engine.vcxproj.filters
@@ -72,6 +72,12 @@
{bf606861-2003-454a-ab74-7da83189dc71}
+
+ {9096dc46-36a8-4493-a27e-62a0f4af9708}
+
+
+ {2a4aab81-82e6-49c4-87e3-12d55f5bcc26}
+
@@ -436,6 +442,12 @@
Engine\Core\Shaders\Common
+
+ Engine\Core\Shaders\RayTrace
+
+
+ Engine\Core\Shaders\RayTrace
+
@@ -534,9 +546,6 @@
Engine\Core\Shaders\Particles
-
- Engine\Core\Shaders\RayTrace
-
Engine\Core\Shaders\ComputeShaders
@@ -576,23 +585,38 @@
Engine\Core\Shaders\ComputeShaders
-
- Engine\Core\Shaders\RayTrace
-
-
- Engine\Core\Shaders\RayTrace
-
Engine\Core\Shaders\ComputeShaders
+
+ Engine\Core\Shaders\ComputeShaders
+
- Engine\Core\Shaders\RayTrace
+ Engine\Core\Shaders\RayTrace\GI
- Engine\Core\Shaders\RayTrace
+ Engine\Core\Shaders\RayTrace\GI
+
+
+ Engine\Core\Shaders\RayTrace\GI
+
+
+ Engine\Core\Shaders\RayTrace\GI
+
+
+ Engine\Core\Shaders\RayTrace\GI
+
+
+ Engine\Core\Shaders\RayTrace\Reflex
+
+
+ Engine\Core\Shaders\RayTrace\Reflex
- Engine\Core\Shaders\RayTrace
+ Engine\Core\Shaders\RayTrace\Reflex
+
+
+ Engine\Core\Shaders\RayTrace\Reflex
\ No newline at end of file
diff --git a/Engine/Engine/Components/Lights.h b/Engine/Engine/Components/Lights.h
index 6773c75..ada001a 100644
--- a/Engine/Engine/Components/Lights.h
+++ b/Engine/Engine/Components/Lights.h
@@ -122,11 +122,14 @@ namespace HotBite {
D3D11_VIEWPORT shadow_vp = {};
public:
+
DirectionalLight();
DirectionalLight(const DirectionalLight& other) :DirectionalLight() {
assert(!other.init && "Non copyable after init.");
*this = other;
}
+
+ void SetDirty() { dirty = true; }
void SetPosition(const float3& pos) { data.position = pos; }
const float3& GetPosition() const { return data.position; }
void SetFog(bool enable) {
diff --git a/Engine/Engine/Core/BVH.cpp b/Engine/Engine/Core/BVH.cpp
index c76c0f7..f6bfedd 100644
--- a/Engine/Engine/Core/BVH.cpp
+++ b/Engine/Engine/Core/BVH.cpp
@@ -171,7 +171,14 @@ namespace HotBite {
int right_count = 0;
int left_offset = 0;
int right_offset = 0;
- if (LENGHT_F3(extent) > FLT_EPSILON)
+
+ if (nidx.index_count == 2) {
+ left_count = 1;
+ right_count = 1;
+ left_offset = nidx.index_offset;
+ right_offset = left_offset + left_count;
+
+ } else if (LENGHT_F3(extent) > FLT_EPSILON)
{
// in-place partition
int i = nidx.index_offset;
diff --git a/Engine/Engine/Core/BVH.h b/Engine/Engine/Core/BVH.h
index 79b136c..d9392c9 100644
--- a/Engine/Engine/Core/BVH.h
+++ b/Engine/Engine/Core/BVH.h
@@ -140,7 +140,8 @@ namespace HotBite {
return size;
}
- HRESULT Prepare(int size, DXGI_FORMAT format) {
+ HRESULT Prepare(int size) {
+ Unprepare();
HRESULT hr = S_OK;
ID3D11Device* device = Core::DXCore::Get()->device;
@@ -155,53 +156,35 @@ namespace HotBite {
bd.ByteWidth = data_size;
bd.CPUAccessFlags = 0;
bd.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS;
- bd.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS;
+ bd.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
bd.StructureByteStride = sizeof(T);
uint8_t* nullData = new uint8_t[data_size];
memset(nullData, 0, data_size);
initialData.pSysMem = nullData;
hr = device->CreateBuffer(&bd, &initialData, &buffer);
+ assert(SUCCEEDED(hr));
delete[] nullData;
- if (FAILED(hr)) { goto end; }
-
- srvDesc.Format = format;
+
+ srvDesc.Format = DXGI_FORMAT_UNKNOWN;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
srvDesc.Buffer.FirstElement = 0;
srvDesc.Buffer.NumElements = size;
hr = device->CreateShaderResourceView(buffer, &srvDesc, &srv);
-
+ assert(SUCCEEDED(hr));
srv->GetResource(&resource);
uav_desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
- uav_desc.Format = format;
+ uav_desc.Format = DXGI_FORMAT_UNKNOWN;
uav_desc.Buffer.FirstElement = 0;
uav_desc.Buffer.NumElements = size;
hr = device->CreateUnorderedAccessView(resource, &uav_desc, &uav);
+ assert(SUCCEEDED(hr));
+
this->size = size;
-
- end:
return hr;
}
- void Clear(T val, uint32_t start = 0, uint32_t len = 0) {
- return;
- if (len == 0) {
- len = (uint32_t)size;
- }
- if (len > 0 && start < (uint32_t)size) {
- ID3D11DeviceContext* context = Core::DXCore::Get()->context;
- D3D11_MAPPED_SUBRESOURCE resource;
- context->Map(buffer, 0, D3D11_MAP_WRITE, 0, &resource);
- T* data = (T*)resource.pData;
- for (uint32_t i = start; i < len; ++i) {
- data[i] = val;
- }
- context->Unmap(buffer, 0);
- }
- }
-
-
HRESULT Unprepare() {
ID3D11DeviceContext* context = Core::DXCore::Get()->context;
HRESULT hr = S_OK;
@@ -221,8 +204,8 @@ namespace HotBite {
return hr;
}
- ID3D11ShaderResourceView* SRV() const {
- return srv;
+ ID3D11ShaderResourceView*const* SRV() const {
+ return &srv;
}
ID3D11UnorderedAccessView*const* UAV() const {
diff --git a/Engine/Engine/Core/DXCore.cpp b/Engine/Engine/Core/DXCore.cpp
index afa38e5..84d5a34 100644
--- a/Engine/Engine/Core/DXCore.cpp
+++ b/Engine/Engine/Core/DXCore.cpp
@@ -38,6 +38,126 @@ using namespace HotBite::Engine::ECS;
DXCore* DXCore::DXCoreInstance = nullptr;
Direct2D* Direct2D::instance = nullptr;
+#include
+#include
+#include
+
+#include
+
+
+HRESULT _D3D11CreateDevice(
+ IDXGIAdapter* pAdapter,
+ D3D_DRIVER_TYPE DriverType,
+ HMODULE Software,
+ UINT Flags,
+ const D3D_FEATURE_LEVEL* pFeatureLevels,
+ UINT FeatureLevels,
+ UINT SDKVersion,
+ ID3D11Device** ppDevice,
+ D3D_FEATURE_LEVEL* pFeatureLevel,
+ ID3D11DeviceContext** ppImmediateContext,
+ ID3D12Device** ppd3d12device) {
+
+
+ HRESULT hr = D3D12CreateDevice(pAdapter,
+ D3D_FEATURE_LEVEL_12_0,
+ IID_PPV_ARGS(ppd3d12device));
+
+ if (FAILED(hr))
+ return hr;
+
+ D3D12_COMMAND_QUEUE_DESC desc;
+ desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
+ desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL;
+ desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
+ desc.NodeMask = 0;
+
+ ID3D12CommandQueue* d3d12queue;
+
+ hr = (*ppd3d12device)->CreateCommandQueue(&desc,
+ IID_PPV_ARGS(&d3d12queue));
+
+ if (FAILED(hr))
+ return hr;
+
+ hr = D3D11On12CreateDevice((*ppd3d12device),
+ Flags, pFeatureLevels, FeatureLevels,
+ reinterpret_cast(&d3d12queue),
+ 1, 0, ppDevice, ppImmediateContext, pFeatureLevel);
+
+ return hr;
+}
+
+
+HRESULT _D3D11CreateDeviceAndSwapChain(
+ IDXGIAdapter* pAdapter,
+ D3D_DRIVER_TYPE DriverType,
+ HMODULE Software,
+ UINT Flags,
+ const D3D_FEATURE_LEVEL* pFeatureLevels,
+ UINT FeatureLevels,
+ UINT SDKVersion,
+ const DXGI_SWAP_CHAIN_DESC* pSwapChainDesc,
+ IDXGISwapChain** ppSwapChain,
+ ID3D11Device** ppDevice,
+ D3D_FEATURE_LEVEL* pFeatureLevel,
+ ID3D11DeviceContext** ppImmediateContext,
+ ID3D12Device** ppd3d12device) {
+ if (ppSwapChain && !pSwapChainDesc)
+ return E_INVALIDARG;
+
+ ID3D11Device* d3d11Device;
+ ID3D11DeviceContext* d3d11Context;
+
+ HRESULT status = _D3D11CreateDevice(pAdapter, DriverType,
+ Software, Flags, pFeatureLevels, FeatureLevels,
+ SDKVersion, &d3d11Device, pFeatureLevel, &d3d11Context, ppd3d12device);
+
+ if (FAILED(status))
+ return status;
+
+ if (ppSwapChain) {
+ IDXGIDevice* dxgiDevice = nullptr;
+ IDXGIAdapter* dxgiAdapter = nullptr;
+ IDXGIFactory* dxgiFactory = nullptr;
+
+ HRESULT hr = d3d11Device->QueryInterface(IID_PPV_ARGS(&dxgiDevice));
+
+ if (FAILED(hr))
+ return E_INVALIDARG;
+
+ hr = dxgiDevice->GetParent(IID_PPV_ARGS(&dxgiAdapter));
+ dxgiDevice->Release();
+
+ if (FAILED(hr))
+ return E_INVALIDARG;
+
+ hr = dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory));
+ dxgiAdapter->Release();
+
+ if (FAILED(hr))
+ return E_INVALIDARG;
+
+ DXGI_SWAP_CHAIN_DESC desc = *pSwapChainDesc;
+ hr = dxgiFactory->CreateSwapChain(d3d11Device, &desc, ppSwapChain);
+ dxgiFactory->Release();
+
+ if (FAILED(hr))
+ return hr;
+ }
+
+ if (ppDevice != nullptr)
+ *ppDevice = d3d11Device;
+ else
+ d3d11Device->Release();
+
+ if (ppImmediateContext != nullptr)
+ *ppImmediateContext = d3d11Context;
+ else
+ d3d11Context->Release();
+
+ return S_OK;
+}
LRESULT DXCore::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
@@ -122,6 +242,7 @@ DXCore::~DXCore()
}
#endif
if (device) { device->Release(); }
+ if (d12device) { d12device->Release(); }
}
HRESULT DXCore::InitWindow(HWND parent)
diff --git a/Engine/Engine/Core/DXCore.h b/Engine/Engine/Core/DXCore.h
index b3e3473..0c9e719 100644
--- a/Engine/Engine/Core/DXCore.h
+++ b/Engine/Engine/Core/DXCore.h
@@ -27,6 +27,7 @@ SOFTWARE.
#include
#include
#include
+#include
#include
#include "../Defines.h"
@@ -38,6 +39,7 @@ SOFTWARE.
#include
#pragma comment(lib, "d3d11.lib")
+#pragma comment(lib, "d3d12.lib")
#pragma comment(lib, "d2d1.lib")
#pragma comment(lib, "dwrite.lib")
@@ -141,7 +143,7 @@ namespace HotBite {
float GetScreenHeight() const { return screen_dimensions.y; }
public:
-
+ ID3D12Device* d12device = nullptr;
ID3D11Device* device = nullptr;
ID3D11DeviceContext* context = nullptr;
ID3D11SamplerState* basic_sampler = nullptr;
diff --git a/Engine/Engine/Core/Material.cpp b/Engine/Engine/Core/Material.cpp
index 2da3333..6331634 100644
--- a/Engine/Engine/Core/Material.cpp
+++ b/Engine/Engine/Core/Material.cpp
@@ -204,6 +204,9 @@ namespace HotBite {
if (j.value("parallax_shadows", false)) {
props.flags |= PARALLAX_SHADOW_ENABLED_FLAG;
}
+ props.alphaColor = parseColorStringF3(j.value("alpha_color", "#00000000"));
+ props.alphaThreshold = j.value("alpha_threshold", 0.4f);
+
SetTexture(diffuse, texture_names.diffuse_texname, root, j.value("diffuse_textname", ""));
SetTexture(high, texture_names.high_textname, root, j.value("high_textname", ""));
SetTexture(normal, texture_names.normal_textname, root, j.value("normal_textname", ""));
diff --git a/Engine/Engine/Core/Material.h b/Engine/Engine/Core/Material.h
index 9decd76..41579b2 100644
--- a/Engine/Engine/Core/Material.h
+++ b/Engine/Engine/Core/Material.h
@@ -48,7 +48,8 @@ namespace HotBite {
float3 emission_color = {};
float rt_reflex = 0.2f;
- float3 padding;
+ float alphaThreshold = 0.4f;
+ float2 padding;
float3 alphaColor = {};
#define NORMAL_MAP_ENABLED_FLAG 1
diff --git a/Engine/Engine/Core/Shaders/Common/MultiTexture.hlsli b/Engine/Engine/Core/Shaders/Common/MultiTexture.hlsli
index b617046..d1f6b1a 100644
--- a/Engine/Engine/Core/Shaders/Common/MultiTexture.hlsli
+++ b/Engine/Engine/Core/Shaders/Common/MultiTexture.hlsli
@@ -80,7 +80,7 @@ void getValues(out float output_values[MAX_MULTI_TEXTURE], SamplerState basicSam
}
}
-float3 getMutliTextureValue(SamplerState basicSampler, uint type, uint count, const uint op[MAX_MULTI_TEXTURE], const float val[MAX_MULTI_TEXTURE],
+float4 getMutliTextureValue(SamplerState basicSampler, uint type, uint count, const uint op[MAX_MULTI_TEXTURE], const float val[MAX_MULTI_TEXTURE],
const float uv_scales[MAX_MULTI_TEXTURE], float2 uv, const Texture2D text[MAX_MULTI_TEXTURE]) {
float3 color = { 0.0f, 0.0f, 0.0f };
uint i;
@@ -119,7 +119,7 @@ float3 getMutliTextureValue(SamplerState basicSampler, uint type, uint count, co
}break;
}
}
- return color;
+ return float4(color, 1.0f);
}
float3 getMutliTextureValueLevel(SamplerState basicSampler, uint level, uint type,
diff --git a/Engine/Engine/Core/Shaders/Common/PixelCommon.hlsli b/Engine/Engine/Core/Shaders/Common/PixelCommon.hlsli
index b5c6a9b..1a55917 100644
--- a/Engine/Engine/Core/Shaders/Common/PixelCommon.hlsli
+++ b/Engine/Engine/Core/Shaders/Common/PixelCommon.hlsli
@@ -97,7 +97,8 @@ struct MaterialColor
float3 emission_color;
float rt_reflex;
- float3 padding;
+ float alphaThreshold;
+ float2 padding;
float3 alphaColor;
#define NORMAL_MAP_ENABLED_FLAG 1 << 0
diff --git a/Engine/Engine/Core/Shaders/Common/PixelFunctions.hlsli b/Engine/Engine/Core/Shaders/Common/PixelFunctions.hlsli
index c37b3ac..da5bfaf 100644
--- a/Engine/Engine/Core/Shaders/Common/PixelFunctions.hlsli
+++ b/Engine/Engine/Core/Shaders/Common/PixelFunctions.hlsli
@@ -232,7 +232,7 @@ float3 DirVolumetricLight(float4 position, DirLight light, int index, float time
float3 lcolor = light.Color.rgb * light.intensity;
float3 color = { 0.f, 0.f, 0.f };
- float step = 0.5f;
+ float step = 0.4f;
float max_vol = 1.0f;
float3 ToEye = cameraPosition.xyz - position.xyz;
@@ -329,7 +329,7 @@ float3 DirVolumetricLight(float4 position, DirLight light, int index, float time
float3 VolumetricLight(float3 position, PointLight light, int index) {
float3 color = { 0.f, 0.f, 0.f };
float3 step_color = light.Color.rgb;
- float step = 0.5f;
+ float step = 0.4f;
float max_vol = 0.3f;
step_color.rgb *= (light.density * step);
float3 intersection_position;
diff --git a/Engine/Engine/Core/Shaders/Common/RayDefines.hlsli b/Engine/Engine/Core/Shaders/Common/RayDefines.hlsli
index 38c19bc..2692f7b 100644
--- a/Engine/Engine/Core/Shaders/Common/RayDefines.hlsli
+++ b/Engine/Engine/Core/Shaders/Common/RayDefines.hlsli
@@ -26,11 +26,17 @@ SOFTWARE.
#define RAY_DEFINES_
#define MAX_OBJECTS 100
-#define MAX_STACK_SIZE 50
+#define MAX_STACK_SIZE 20
+
+#define GI_SCREEN 0
+#define GI_WORLD 1
+
+#define REFLEX_SCREEN 0
+#define REFLEX_WORLD 1
//#define PACK_RAYS_8
-#define RAY_W_SCALE 2.0f
-#define RAY_W_BIAS 0.0001f
+#define RAY_W_SCALE 1.0f
+#define RAY_W_BIAS 0.01f
#ifdef PACK_RAYS_8
#define MAX_RAYS 8
@@ -50,6 +56,14 @@ struct BVHNode
float4 reg1; // aabb_max + index;
};
+#define MAX_RAY_INPUTS 4
+#define MAX_RAY_INPUTS_POS MAX_RAY_INPUTS / 2
+static const float MAX_RAY_POLAR_DIR = 2.0f * PI; //Maximum polar angle 2.0 * PI
+
+struct InputRays {
+ float4 dir2[MAX_RAY_INPUTS_POS];
+};
+
struct Ray {
float4 orig;
float3 dir;
@@ -68,14 +82,16 @@ struct RayObject {
struct IntersectionResult
{
float3 v0;
+ float distance;
+
float3 v1;
+ uint object;
+
float3 v2;
-
- float distance;
- float2 uv;
+ float u;
uint3 vindex;
- uint object;
+ float v;
};
struct ObjectInfo
diff --git a/Engine/Engine/Core/Shaders/Common/RayFunctions.hlsli b/Engine/Engine/Core/Shaders/Common/RayFunctions.hlsli
index a166111..756562a 100644
--- a/Engine/Engine/Core/Shaders/Common/RayFunctions.hlsli
+++ b/Engine/Engine/Core/Shaders/Common/RayFunctions.hlsli
@@ -23,6 +23,10 @@ SOFTWARE.
*/
#include "RayDefines.hlsli"
+ByteAddressBuffer vertexBuffer : register(t4);
+ByteAddressBuffer indicesBuffer: register(t5);
+Texture2D DiffuseTextures[MAX_OBJECTS];
+
bool is_leaf(BVHNode node)
{
return (asuint(node.reg0.w) == 0);
@@ -53,6 +57,15 @@ uint index(BVHNode node)
return asuint(node.reg1.w);
}
+float node_distance(BVHNode node, float3 pos)
+{
+ float3 aabb0 = aabb_min(node);
+ float3 aabb1 = aabb_max(node);
+ float extent = length(aabb0 - aabb1) * 0.5f;
+ float3 center = (aabb0 + aabb1) * 0.5f;
+ float dist = max(length(center - pos) - extent, 0.0f);
+ return dist;
+}
bool IntersectTri(RayObject ray, uint indexOffset, uint vertexOffset, out IntersectionResult result)
{
@@ -108,7 +121,8 @@ bool IntersectTri(RayObject ray, uint indexOffset, uint vertexOffset, out Inters
result.vindex = vindex;
result.object = 0;
result.distance = t;
- result.uv = float2(u, v);
+ result.u = u;
+ result.v = v;
return true;
}
@@ -278,7 +292,19 @@ float3 GetDiffuseColor(uint object, float2 uv)
}
}
-Ray GetReflectedRayFromSource(RaySource source)
+Ray GetRayInfoFromSourceWithNoDir(RaySource source)
+{
+ Ray ray;
+ ray.orig = float4(source.orig, 1.0f);
+ ray.dir = float3(0.0f, 1.0f, 0.0f);
+ ray.density = source.density;
+ ray.bounces = 0;
+ ray.ratio = 1.0f;
+ ray.t = FLT_MAX;
+ return ray;
+}
+
+Ray GetReflectedRayFromSource(RaySource source, float3 cameraPosition)
{
Ray ray;
ray.orig = float4(source.orig, 1.0f);
@@ -294,7 +320,7 @@ Ray GetReflectedRayFromSource(RaySource source)
return ray;
}
-Ray GetRefractedRayFromSource(RaySource source)
+Ray GetRefractedRayFromSource(RaySource source, float3 cameraPosition)
{
Ray ray;
ray.orig = float4(source.orig, 1.0f);
diff --git a/Engine/Engine/Core/Shaders/Common/Utils.hlsli b/Engine/Engine/Core/Shaders/Common/Utils.hlsli
index 970feca..032b620 100644
--- a/Engine/Engine/Core/Shaders/Common/Utils.hlsli
+++ b/Engine/Engine/Core/Shaders/Common/Utils.hlsli
@@ -27,7 +27,63 @@ SOFTWARE.
#ifndef __UTILS_HLSLI__
#define __UTILS_HLSLI__
-float Epsilon = 1e-4;
+static const float Epsilon = 1e-4;
+
+// Divide the 2D-Dispatch_Grid into tiles of dimension [N, DipatchGridDim.y]
+// “CTA” (Cooperative Thread Array) == Thread Group in DirectX terminology
+uint2 ThreadGroupTilingX(
+ const uint2 dipatchGridDim, // Arguments of the Dispatch call (typically from a ConstantBuffer)
+ const uint2 ctaDim, // Already known in HLSL, eg:[numthreads(8, 8, 1)] -> uint2(8, 8)
+ const uint maxTileWidth, // User parameter (N). Recommended values: 8, 16 or 32.
+ const uint2 groupThreadID, // SV_GroupThreadID
+ const uint2 groupId // SV_GroupID
+)
+{
+ // A perfect tile is one with dimensions = [maxTileWidth, dipatchGridDim.y]
+ const uint Number_of_CTAs_in_a_perfect_tile = maxTileWidth * dipatchGridDim.y;
+
+ // Possible number of perfect tiles
+ const uint Number_of_perfect_tiles = dipatchGridDim.x / maxTileWidth;
+
+ // Total number of CTAs present in the perfect tiles
+ const uint Total_CTAs_in_all_perfect_tiles = Number_of_perfect_tiles * maxTileWidth * dipatchGridDim.y;
+ const uint vThreadGroupIDFlattened = dipatchGridDim.x * groupId.y + groupId.x;
+
+ // Tile_ID_of_current_CTA : current CTA to TILE-ID mapping.
+ const uint Tile_ID_of_current_CTA = vThreadGroupIDFlattened / Number_of_CTAs_in_a_perfect_tile;
+ const uint Local_CTA_ID_within_current_tile = vThreadGroupIDFlattened % Number_of_CTAs_in_a_perfect_tile;
+ uint Local_CTA_ID_y_within_current_tile;
+ uint Local_CTA_ID_x_within_current_tile;
+
+ if (Total_CTAs_in_all_perfect_tiles <= vThreadGroupIDFlattened)
+ {
+ // Path taken only if the last tile has imperfect dimensions and CTAs from the last tile are launched.
+ uint X_dimension_of_last_tile = dipatchGridDim.x % maxTileWidth;
+ X_dimension_of_last_tile = max(1, X_dimension_of_last_tile);
+ Local_CTA_ID_y_within_current_tile = Local_CTA_ID_within_current_tile / X_dimension_of_last_tile;
+ Local_CTA_ID_x_within_current_tile = Local_CTA_ID_within_current_tile % X_dimension_of_last_tile;
+ }
+ else
+ {
+ Local_CTA_ID_y_within_current_tile = Local_CTA_ID_within_current_tile / maxTileWidth;
+ Local_CTA_ID_x_within_current_tile = Local_CTA_ID_within_current_tile % maxTileWidth;
+ }
+
+ const uint Swizzled_vThreadGroupIDFlattened =
+ Tile_ID_of_current_CTA * maxTileWidth +
+ Local_CTA_ID_y_within_current_tile * dipatchGridDim.x +
+ Local_CTA_ID_x_within_current_tile;
+
+ uint2 SwizzledvThreadGroupID;
+ SwizzledvThreadGroupID.y = Swizzled_vThreadGroupIDFlattened / dipatchGridDim.x;
+ SwizzledvThreadGroupID.x = Swizzled_vThreadGroupIDFlattened % dipatchGridDim.x;
+
+ uint2 SwizzledvThreadID;
+ SwizzledvThreadID.x = ctaDim.x * SwizzledvThreadGroupID.x + groupThreadID.x;
+ SwizzledvThreadID.y = ctaDim.y * SwizzledvThreadGroupID.y + groupThreadID.y;
+
+ return SwizzledvThreadID.xy;
+}
float3 climit3(float3 color) {
float m = max(color.r, max(color.g, color.b));
@@ -50,7 +106,36 @@ float4 climit4(float4 color) {
float2 GetCloserPixel(float2 pixel, float ratio) {
return round(round(pixel / ratio) * ratio);
}
+
float4 GetInterpolatedColor(float2 uv, Texture2D text, float2 dimension) {
+ uv = saturate(uv);
+ // Calculate the texture coordinates in the range [0, 1]
+ float2 texCoords = uv * dimension;
+
+ // Calculate the integer coordinates of the four surrounding pixels
+ int2 p00 = (int2)floor(texCoords);
+ int2 p11 = (int2)ceil(texCoords);
+ int2 p01 = int2(p00.x, p11.y);
+ int2 p10 = int2(p11.x, p00.y);
+
+ // Calculate the fractional part of the coordinates
+ float2 f = frac(texCoords);
+
+ // Calculate the weights for bilinear interpolation
+ float w00 = (1.0f - f.x) * (1.0f - f.y);
+ float w11 = f.x * f.y;
+ float w01 = (1.0f - f.x) * f.y;
+ float w10 = f.x * (1.0f - f.y);
+
+ // Perform the bilinear interpolation
+ return (text[p00] * w00 +
+ text[p11] * w11 +
+ text[p01] * w01 +
+ text[p10] * w10);
+}
+
+float4 GetInterpolatedColor(float2 uv, RWTexture2D text, float2 dimension) {
+ uv = saturate(uv);
// Calculate the texture coordinates in the range [0, 1]
float2 texCoords = uv * dimension;
@@ -116,6 +201,61 @@ float3 GenerateDirection(int i, int N) {
return float3(x, y, z);
}
+float2 GetPolarCoordinates(float3 dir) {
+ float theta = atan2(dir.z, dir.x);
+ float phi = acos(dir.y);
+ return float2(phi, theta);
+}
+
+float3 GetCartesianCoordinates(float phi, float theta) {
+ float sinPhi = sin(phi);
+ float cosPhi = cos(phi);
+ float sinTheta = sin(theta);
+ float cosTheta = cos(theta);
+
+ return float3(sinPhi * cosTheta, cosPhi, sinPhi * sinTheta);
+}
+
+float3 GetCartesianCoordinates(float2 coords) {
+ return GetCartesianCoordinates(coords.x, coords.y);
+}
+
+float2 GenerateHemisphereDispersedRay(float3 dir, float3 tangent, float3 bitangent, float dispersion, float N, float NLevels, float rX)
+{
+ float index = (rX * dispersion) % N;
+
+ //index = (frame_count) % N;
+ float N_SQRT = sqrt(N);
+ float cumulativePoints = 1.0f;
+ float level = 1.0f;
+ float c = 1.0f;
+ float phi;
+ while (c < index) {
+ phi = (level * M_PI * 0.5f) / NLevels;
+ c = cumulativePoints + N_SQRT * sin(phi);
+ cumulativePoints = c;
+ level++;
+ };
+ level--;
+
+ phi = (level * M_PI * 0.5f) / NLevels;
+
+ float pointsAtLevel = 1.0f + N_SQRT * sin(phi);
+
+ float localIndex = index - cumulativePoints;
+ float theta = (2.0f * M_PI) * localIndex / pointsAtLevel;
+
+ float3 localRay = GetCartesianCoordinates(phi, theta);
+
+ float3 globalRay = localRay.x * tangent + localRay.y * dir + localRay.z * bitangent;
+
+ return GetPolarCoordinates(normalize(dir + globalRay));
+}
+
+bool ValidUVCoord(float2 uv_coord) {
+ return (uv_coord.x >= 0.0f && uv_coord.x < 1.0f &&
+ uv_coord.y >= 0.0f && uv_coord.y < 1.0f);
+}
void GetSpaceVectors(in float3 dir, out float3 tangent, out float3 bitangent) {
float3 up = abs(dir.z) < 0.999f ? float3(0.0f, 0.0f, 1.0f) : float3(1.0f, 0.0f, 0.0f);
@@ -144,6 +284,64 @@ uint ToByte(float val, float range)
return (uint)val;
}
+float FromByte(uint val, float range)
+{
+ float fval = (float)val;
+ fval = range * clamp(fval, 0.0f, 255.0f) / 255.0f;
+ return fval;
+}
+
+int ToI16(float val, float range)
+{
+ val = 32768.0f * clamp(val, -range, range) / range;
+ return (int)val;
+}
+
+float FromI16(int val, float range)
+{
+ float fval = (float)val;
+ fval = range * clamp(fval, -32768.0f, 32768.0f) / 32768.0f;
+ return fval;
+}
+
+uint PackTwoInt16(int low, int high) {
+ return ( ((low & 0xFFFF) << 16) | (high & 0xFFFF) );
+}
+
+void UnpackTwoInt16(uint packedValue, out int low, out int high) {
+ int intPackedValue = asint(packedValue);
+ low = (intPackedValue >> 16);
+ high = (intPackedValue << 16) >> 16;
+}
+
+uint4 Pack4Float2ToI16(float2 values[4], float max_value)
+{
+ uint4 data;
+ data.r = PackTwoInt16(ToI16(values[0].x, max_value), ToI16(values[0].y, max_value));
+ data.g = PackTwoInt16(ToI16(values[1].x, max_value), ToI16(values[1].y, max_value));
+ data.b = PackTwoInt16(ToI16(values[2].x, max_value), ToI16(values[2].y, max_value));
+ data.a = PackTwoInt16(ToI16(values[3].x, max_value), ToI16(values[3].y, max_value));
+ return data;
+}
+
+void Unpack4Float2FromI16(uint4 data, float max_value, out float2 values[4])
+{
+ int low;
+ int high;
+ UnpackTwoInt16(data.r, low, high);
+ values[0].x = FromI16(low, max_value);
+ values[0].y = FromI16(high, max_value);
+ UnpackTwoInt16(data.g, low, high);
+ values[1].x = FromI16(low, max_value);
+ values[1].y = FromI16(high, max_value);
+ UnpackTwoInt16(data.b, low, high);
+ values[2].x = FromI16(low, max_value);
+ values[2].y = FromI16(high, max_value);
+ UnpackTwoInt16(data.a, low, high);
+ values[3].x = FromI16(low, max_value);
+ values[3].y = FromI16(high, max_value);
+}
+
uint4 Pack8Bytes(float values[8], float max_value)
{
uint4 data;
@@ -164,13 +362,6 @@ uint4 Pack16Bytes(float values[16], float max_value)
return data;
}
-float FromByte(uint val, float range)
-{
- float fval = (float)val;
- fval = range * clamp(fval, 0.0f, 255.0f) / 255.0f;
- return fval;
-}
-
void Unpack8Bytes(uint4 data, float max_value, out float values[8])
{
uint d0 = data.r;
diff --git a/Engine/Engine/Core/Shaders/ComputeShaders/BlurCS.hlsl b/Engine/Engine/Core/Shaders/ComputeShaders/BlurCS.hlsl
index aad5eaf..ae0f86f 100644
--- a/Engine/Engine/Core/Shaders/ComputeShaders/BlurCS.hlsl
+++ b/Engine/Engine/Core/Shaders/ComputeShaders/BlurCS.hlsl
@@ -7,7 +7,7 @@ Texture2D vol_data: register(t0);
#define EPSILON 1e-6
#define VERTICAL 1
#define HORIZONTAL 2
-#define KERNEL_SIZE 19
+#define KERNEL_SIZE 1
#define HALF_KERNEL KERNEL_SIZE/2
cbuffer externalData : register(b0)
{
@@ -15,38 +15,24 @@ cbuffer externalData : register(b0)
float variance;
}
-void FillGaussianArray(out float array[KERNEL_SIZE])
+static const float BlurWeights32[33] =
{
- float sum = 0.0;
- int halfSize = KERNEL_SIZE / 2;
- int i;
- float v = 5.0f;
- for (i = -HALF_KERNEL; i <= HALF_KERNEL; ++i)
- {
- int x = i;
- array[i + halfSize] = exp(-(x * x) / (2.0f * v * v)) / sqrt(2.0f * 3.14159265358979323846f * v * v);
- sum += array[i + halfSize];
- }
+ 0.0216771440357829, 0.023030174945629842, 0.024372268162712405, 0.0256920167211696, 0.026977641631473703, 0.028217160189400764, 0.02939856710486361, 0.030510024758829798, 0.03154005846550627, 0.032477752297221024, 0.033312940837257485, 0.03403639217321265, 0.034639977537105585, 0.03511682323976621, 0.035461440931519074, 0.035669832738636206, 0.03573956845982569, 0.035669832738636206, 0.035461440931519074, 0.03511682323976621, 0.034639977537105585, 0.03403639217321265, 0.033312940837257485, 0.032477752297221024, 0.03154005846550627, 0.030510024758829798, 0.02939856710486361, 0.028217160189400764, 0.026977641631473703, 0.0256920167211696, 0.024372268162712405, 0.023030174945629842, 0.0216771440357829
+};
- // Normalize the array
- for (i = 0; i < KERNEL_SIZE; ++i)
- {
- array[i] /= sum;
+float4 blur32(RWTexture2D t, float2 pos, int type) {
+ float4 color = float4(0.f, 0.f, 0.f, 1.f);
+ if (type == HORIZONTAL) {
+ for (int dx = -16; dx <= 16; ++dx) {
+ color += t.Load(float3(pos.x + dx, pos.y, 0)) * BlurWeights32[dx + 16];
+ }
}
-}
-
-float4 getColor(float2 pixel, float2 dir)
-{
-
- float BlurWeights[KERNEL_SIZE];
- FillGaussianArray(BlurWeights);
- float4 color = float4(0.f, 0.f, 0.f, 0.f);
- float2 tpos;
- for (int i = -HALF_KERNEL; i <= HALF_KERNEL; ++i) {
- tpos = pixel + dir * i;
- color += input[tpos] * BlurWeights[i + HALF_KERNEL];
+ else {
+ for (int dy = -16; dy <= 16; ++dy) {
+ color += t.Load(float3(pos.x, pos.y + dy, 0)) * BlurWeights32[dy + 16];
}
- return color;
+ }
+ return color;
}
@@ -55,28 +41,21 @@ float4 getColor(float2 pixel, float2 dir)
[numthreads(NTHREADS, NTHREADS, 1)]
void main(uint3 DTid : SV_DispatchThreadID)
{
- uint2 dir = { 0, 0 };
- if (type == VERTICAL) {
- dir = uint2(0, 1);
- }
- else if (type == HORIZONTAL) {
- dir = uint2(1, 0);
- }
-
uint2 dimensions;
uint w, h;
input.GetDimensions(w, h);
float2 pixel = float2(DTid.x, DTid.y);
float global = (float)vol_data[uint2(0, 0)] / (float)(w * h * 1000);
//Linear function for global atenuation y = −x + (1 + (MAX_GLOBAL_ILLUMINATION)
-#define MAX_GLOBAL_ILLUMINATION 0.5f
+#define MAX_GLOBAL_ILLUMINATION 0.4f
float att = 1.0f;
global *= global;
global *= global;
att = -global + (1.0f + MAX_GLOBAL_ILLUMINATION);
- float4 color = getColor(pixel, dir);
+ //float4 color = blur32(input, pixel, type);
+ float4 color = input.Load(float3(pixel.x, pixel.y, 0));
if (type == HORIZONTAL) {
- color *= att;
+ //color *= att;
}
output[pixel] = max(color, 0);
}
diff --git a/Engine/Engine/Core/Shaders/ComputeShaders/HiZDownSample.hlsl b/Engine/Engine/Core/Shaders/ComputeShaders/HiZDownSample.hlsl
new file mode 100644
index 0000000..ce3ebaf
--- /dev/null
+++ b/Engine/Engine/Core/Shaders/ComputeShaders/HiZDownSample.hlsl
@@ -0,0 +1,76 @@
+/*
+The HotBite Game Engine
+
+Copyright(c) 2024 Vicente Sirvent Orts
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include "..\Common\Defines.hlsli"
+cbuffer externalData : register(b0)
+{
+ uint ratio;
+ uint type;
+}
+
+Texture2D input : register(t0);
+RWTexture2D output : register(u0);
+
+#define NTHREADS 32
+#define VERTICAL 1
+#define HORIZONTAL 2
+
+[numthreads(NTHREADS, NTHREADS, 1)]
+void main(uint3 DTid : SV_DispatchThreadID)
+{
+ float2 input_dimensions = { 0, 0 };
+ input.GetDimensions(input_dimensions.x, input_dimensions.y);
+
+ float2 in_pixel;
+ float2 out_pixel = float2(DTid.x, DTid.y);
+ float depth = FLT_MAX;
+ uint2 dir = { 0, 0 };
+ int kernel_size = ratio / 2;
+
+ if (type == VERTICAL) {
+ dir = uint2(0, 1);
+ in_pixel = float2(DTid.x, DTid.y * ratio);
+ }
+ else if (type == HORIZONTAL) {
+ dir = uint2(1, 0);
+ in_pixel = float2(DTid.x * ratio, DTid.y);
+ }
+
+ uint2 tpos = in_pixel;
+ for (int i = -kernel_size; i <= kernel_size; ++i) {
+ tpos += dir;
+ if (tpos.x >= 0 && tpos.x < input_dimensions.x && tpos.y >= 0 && tpos.y < input_dimensions.y) {
+ float tmp_depth = input[tpos];
+ if (tmp_depth < FLT_MAX) {
+ depth = min(depth, tmp_depth);
+ }
+ }
+ }
+
+ if (depth < 0.0f) {
+ depth = FLT_MAX;
+ }
+
+ output[out_pixel] = depth;
+}
diff --git a/Engine/Engine/Core/Shaders/ComputeShaders/RenderDustCS.hlsl b/Engine/Engine/Core/Shaders/ComputeShaders/RenderDustCS.hlsl
index 7c82ce7..d11a41e 100644
--- a/Engine/Engine/Core/Shaders/ComputeShaders/RenderDustCS.hlsl
+++ b/Engine/Engine/Core/Shaders/ComputeShaders/RenderDustCS.hlsl
@@ -146,7 +146,7 @@ void main(uint3 DTid : SV_DispatchThreadID)
color += CalcPoint(normal, wpos.xyz, pointLights[i], i);
}
}
-#define MAX_GLOBAL_ILLUMINATION 1.0f
+#define MAX_GLOBAL_ILLUMINATION 0.4f
float global = (float)vol_data[uint2(0, 0)] / (float)(dimensions.x * dimensions.y * 1000);
float att = 1.0f;
global *= global;
diff --git a/Engine/Engine/Core/Shaders/ComputeShaders/TextureMixerCS.hlsl b/Engine/Engine/Core/Shaders/ComputeShaders/TextureMixerCS.hlsl
index 6c2a60f..01fbf8b 100644
--- a/Engine/Engine/Core/Shaders/ComputeShaders/TextureMixerCS.hlsl
+++ b/Engine/Engine/Core/Shaders/ComputeShaders/TextureMixerCS.hlsl
@@ -78,6 +78,7 @@ float4 Get3dInterpolatedColor(float2 uv, Texture2D text, float2 dimension, Textu
float3 wp10 = positions[pos_p10].xyz;
float3 wpxx = positions[in_pos].xyz;
+ [branch]
if (wp00.x >= FLT_MAX || wp11.x >= FLT_MAX || wp01.x >= FLT_MAX || wp10.x >= FLT_MAX || wpxx.x >= FLT_MAX) {
return GetInterpolatedColor(uv, text, dimension);
}
@@ -89,6 +90,7 @@ float4 Get3dInterpolatedColor(float2 uv, Texture2D text, float2 dimension, Textu
float all_dist = d00 + d11 + d01 + d10;
+ [branch]
if (all_dist < epsilon) {
return GetInterpolatedColor(uv, text, dimension);
}
@@ -130,6 +132,7 @@ float4 Get3dInterpolatedColor(float2 uv, Texture2D text, float2 dimension, Textu
// Normalize weights
float totalWeight = w00 + w11 + w01 + w10;
+ [branch]
if (totalWeight < epsilon) {
return GetInterpolatedColor(uv, text, dimension);
}
@@ -145,29 +148,11 @@ float4 Get3dInterpolatedColor(float2 uv, Texture2D text, float2 dimension, Textu
float4 readColor(float2 pixel, texture2D text, uint w, uint h) {
uint w2, h2;
text.GetDimensions(w2, h2);
- if (w2 == w && h2 == h) {
- return text.SampleLevel(basicSampler, pixel, 0);
+ if (w2 == w && h2 == h) {
+ return text[round(pixel * float2(w2, h2))];
}
else {
-#if 0
- float ratioW = ((float)w * 0.5f) / w2;
- float ratioH = ((float)h * 0.5f) / h2;
- uint n = 2;
- float x = 0;
- float y = 0;
- float4 c = 2 * Get3dInterpolatedColor(pixel, text, float2(w2, h2), positions, normals, float2(w, h));
- for (x = -ratioW; x < ratioW; x++) {
- for (y = -ratioH; y < ratioH; y++) {
- c += text.SampleLevel(basicSampler, pixel + float2(x * 0.5f / w2, y * 0.5f / h2), 0);
- //c += Get3dInterpolatedColor(pixel + float2(x / w, y / h), text, float2(w2, h2), positions, normals, float2(w, h));
- n++;
- }
- }
- c /= n;
- return c;
-#else
return Get3dInterpolatedColor(pixel, text, float2(w2, h2), positions, normals, float2(w, h));
-#endif
}
}
@@ -194,17 +179,8 @@ void main(uint3 DTid : SV_DispatchThreadID)
float4 dust = readColor(tpos, dustTexture, w, h);
float4 lens_flare = readColor(tpos, lensFlareTexture, w, h);
- if (rt_enabled) {
- if (true) { //debug == 0) {
- color = color * (l + rt0 + rt2) + rt1 + b + dust + lens_flare + vol;
- }
- else {
- color = rt0 + rt1 + rt2;
- }
- }
- else {
- color = color * l + b + dust + lens_flare + vol;
- }
+ color = color* (l + rt0 + rt2) + rt1 + b + dust + lens_flare + vol;
+
#if 1
output[pixel] = climit4(color);
#else
@@ -212,4 +188,5 @@ void main(uint3 DTid : SV_DispatchThreadID)
float r = 1.0f + (0.1f * rgba_tnoise(p));
output[pixel] = climit4(color * r);
#endif
+
}
diff --git a/Engine/Engine/Core/Shaders/Effects/Lava/LavaPS.hlsl b/Engine/Engine/Core/Shaders/Effects/Lava/LavaPS.hlsl
index cea11de..4b1b93e 100644
--- a/Engine/Engine/Core/Shaders/Effects/Lava/LavaPS.hlsl
+++ b/Engine/Engine/Core/Shaders/Effects/Lava/LavaPS.hlsl
@@ -120,7 +120,7 @@ float3 CalcLavaPoint(float3 normal, float3 position, float2 uv, PointLight light
return finalColor;
}
-RenderTarget main(GSOutput input)
+RenderTargetRT main(GSOutput input)
{
int i = 0;
matrix worldViewProj = mul(view, projection);
@@ -135,7 +135,7 @@ RenderTarget main(GSOutput input)
float dz_pcf = depthTexture.SampleCmpLevelZero(PCFSampler, pos, depth_test);
if (dz_pcf == 0.0f) { discard; }
- RenderTarget output;
+ RenderTargetRT output;
float depth = length(input.worldPos.xyz - cameraPosition);
float dz = depthTexture.Sample(basicSampler, pos);
@@ -209,6 +209,17 @@ RenderTarget main(GSOutput input)
output.scene = finalColor * 0.6f * dz_pcf;
lightColor += output.scene;
output.light_map = saturate(lightColor);
+
+ RaySource ray;
+ ray.orig = input.worldPos.xyz;
+ ray.dispersion = 0.0f;
+ ray.reflex = 1.0f;
+ ray.normal = normalize(float3(0.0f, 1.0f, 0.0f) + 0.1f * normal);
+ ray.density = material.density;
+ ray.opacity = 1.0f;
+
+ output.rt_ray0_map = getColor0(ray);
+ output.rt_ray1_map = getColor1(ray);
return output;
}
diff --git a/Engine/Engine/Core/Shaders/MainRender/MainRenderGS.hlsl b/Engine/Engine/Core/Shaders/MainRender/MainRenderGS.hlsl
index 635172c..8715648 100644
--- a/Engine/Engine/Core/Shaders/MainRender/MainRenderGS.hlsl
+++ b/Engine/Engine/Core/Shaders/MainRender/MainRenderGS.hlsl
@@ -30,11 +30,19 @@ cbuffer externalData : register(b0)
int screenH;
matrix world;
matrix inv_world;
- matrix view;
- matrix projection;
+ matrix view_projection;
float3 cameraPosition;
}
+float4 frustumPlanes[6] = {
+ float4(1, 0, 0, 1),
+ float4(-1, 0, 0, 1),
+ float4(0, 1, 0, 1),
+ float4(0, -1, 0, 1),
+ float4(0, 0, 1, 1),
+ float4(0, 0, -1, 1)
+};
+
[maxvertexcount(3)]
void main(
triangle DomainOutput input[3],
@@ -45,31 +53,64 @@ void main(
bool process = false;
float4 p[3];
-
+ float2 dimensions = { screenW , screenH };
+
uint i = 0;
for (i = 0; i < 3; i++) {
- p[i] = mul(input[i].worldPos, mul(view, projection));
+ p[i] = mul(input[i].worldPos, view_projection);
}
+
+ bool behind = true;
for (i = 0; i < 3; i++) {
- float2 pos;
- pos = p[i].xy;
- pos.x /= p[i].w;
- pos.y /= -p[i].w;
- pos.x = (pos.x + 1.0f) * 0.5f;
- pos.y = (pos.y + 1.0f) * 0.5f;
- if (pos.x > -screenW && pos.x < screenW && pos.y > -screenH && pos.y < screenH) {
- process = true;
+ if (p[i].z >= 0.0f) {
+ behind = false;
break;
}
}
+
+ if (!behind) {
+ for (i = 0; i < 3; i++) {
+ float2 pos;
+ pos = p[i].xy;
+ pos.xy /= p[i].w;
+ pos.y *= -1.0f;
+
+ pos.xy = (pos.xy + 1.0f) * 0.5f;
+ if (pos.x >= 0.0f && pos.x <= 1.0f && pos.y >= 0.0f && pos.y <= 1.0f) {
+ process = true;
+ break;
+ }
+ }
+ }
+
+ if (!process) {
+ float3 pp[3];
+ for (i = 0; i < 3; ++i) {
+ pp[i] = p[i].xyz / p[i].w;
+ }
+
+ float3 normal = cross(pp[1].xyz - pp[0].xyz, pp[2].xyz - pp[0].xyz);
+ float d = dot(normal, pp[0].xyz);
+ float3 frustumCenter = float3(0.0f, 0.0f, 0.0f);
+
+ for (int i = 0; i < 6; i++) {
+ frustumCenter += float3(frustumPlanes[i].x, frustumPlanes[i].y, frustumPlanes[i].z) * frustumPlanes[i].w;
+ }
+ frustumCenter /= 6.0f;
+
+ if (abs(dot(normal, frustumCenter) + d) < length(normal)) {
+ process = true;
+ }
+ }
#else
bool process = true;
float4 p[3];
uint i = 0;
for (i = 0; i < 3; i++) {
- p[i] = mul(input[i].worldPos, mul(view, projection));
+ p[i] = mul(input[i].worldPos, view_projection);
}
#endif
+
if (process) {
// Edges of the triangle : postion delta
float3 edge1 = input[1].position.xyz - input[0].position.xyz;
@@ -92,7 +133,6 @@ void main(
bitangent.y = r * (-deltaUV2.x * edge1.y + deltaUV1.x * edge2.y);
bitangent.z = r * (-deltaUV2.x * edge1.z + deltaUV1.x * edge2.z);
}
- matrix worldViewProj = mul(view, projection);
for (uint i = 0; i < 3; i++)
{
GSOutput element;
diff --git a/Engine/Engine/Core/Shaders/MainRender/MainRenderPS.hlsli b/Engine/Engine/Core/Shaders/MainRender/MainRenderPS.hlsli
index 9e6eab9..b6d8767 100644
--- a/Engine/Engine/Core/Shaders/MainRender/MainRenderPS.hlsli
+++ b/Engine/Engine/Core/Shaders/MainRender/MainRenderPS.hlsli
@@ -57,7 +57,7 @@ RenderTargetRT MainRenderPS(GSOutput input)
PointLightParallaxAtt[i] = 1.0f;
}
//wpos without parallax displacement
- float3 wpos2 = wpos.xyz;
+ float3 wpos2 = wpos.xyz / wpos.w;
if (material.flags & NORMAL_MAP_ENABLED_FLAG || multi_texture_count > 0) {
// Build orthonormal basis.
float3 N = normal;
@@ -81,8 +81,8 @@ RenderTargetRT MainRenderPS(GSOutput input)
}
scale = abs(scale);
+ matrix global_to_tbn = inverse(tbn);
if ((material.flags & PARALLAX_MAP_ENABLED_FLAG || multi_texture_count > 0 ) && scale != 0.0f) {
- matrix global_to_tbn = inverse(tbn);
float h = 0;
float3 tbn_cam_pos = mul(float4(cameraPosition, 0.0f), global_to_tbn).xyz;
float3 tbn_fragment_pos = mul(input.worldPos, global_to_tbn).xyz;
@@ -122,11 +122,12 @@ RenderTargetRT MainRenderPS(GSOutput input)
texture_normal = normalTexture.Sample(basicSampler, input.uv);
}
texture_normal = texture_normal * 2.0f - 1.0f;
- normal = normalize(mul(texture_normal, (float3x3)tbn) + normal);
+ normal = normalize(mul(texture_normal, (float3x3)tbn) + normal);
+
}
#if 1
- float4 lumColor = float4(0.0f, 0.0f, 0.0f, 0.0f);
+ float4 lumColor = float4(0.0f, 0.0f, 0.0f, 1.0f);
// Calculate the ambient light
lumColor.rgb += CalcAmbient(normal);
#endif
@@ -148,30 +149,32 @@ RenderTargetRT MainRenderPS(GSOutput input)
#if 1
// Apply textures
if (material.flags & DIFFUSSE_MAP_ENABLED_FLAG || multi_texture_count > 0) {
- float3 text_color;
+ float4 text_color;
if (multi_texture_count > 0) {
text_color = getMutliTextureValue(basicSampler, MULTITEXT_DIFF, multi_texture_count, multi_texture_operations,
- calculated_values, multi_texture_uv_scales, input.uv, multi_diffuseTexture).rgb;
+ calculated_values, multi_texture_uv_scales, input.uv, multi_diffuseTexture);
}
else {
- text_color = diffuseTexture.Sample(basicSampler, input.uv).rgb;
+ text_color = diffuseTexture.Sample(basicSampler, input.uv);
}
if (material.flags & ALPHA_ENABLED_FLAG) {
- if (length(material.alphaColor - text_color) > 0.4f) {
- finalColor.rgb = text_color;
+ if (length(material.alphaColor - text_color) > material.alphaThreshold) {
+ finalColor = text_color;
}
else {
discard;
}
}
else {
- finalColor.rgb = text_color;
+ finalColor = text_color;
}
}
else {
finalColor = material.diffuseColor;
}
+
#endif
+ lumColor.a = finalColor.a;
// Apply ambient occlusion
if (multi_texture_count > 0) {
@@ -205,13 +208,12 @@ RenderTargetRT MainRenderPS(GSOutput input)
}
opacity = saturate(opacity);
finalColor *= opacity;
-
output.scene = finalColor;
- output.light_map = lumColor + prevLightTexture[input.position.xy];
+ output.light_map = lerp(prevLightTexture[input.position.xy], lumColor, lumColor.a);
output.bloom_map = saturate(lightColor);
RaySource ray;
- ray.orig = wpos2.xyz;
+ ray.orig = wpos2;
if (disable_rt == 0 && (material.flags & RAYTRACING_ENABLED)) {
ray.dispersion = saturate(1.0f - spec_intensity);
ray.reflex = material.rt_reflex;
diff --git a/Engine/Engine/Core/Shaders/PostProcess/PostBlur.hlsl b/Engine/Engine/Core/Shaders/PostProcess/PostBlur.hlsl
index 606f5f0..e1231f5 100644
--- a/Engine/Engine/Core/Shaders/PostProcess/PostBlur.hlsl
+++ b/Engine/Engine/Core/Shaders/PostProcess/PostBlur.hlsl
@@ -34,7 +34,7 @@ SamplerState basicSampler;
static const float BlurWeights32[33] =
{
-0.0216771440357829, 0.023030174945629842, 0.024372268162712405, 0.0256920167211696, 0.026977641631473703, 0.028217160189400764, 0.02939856710486361, 0.030510024758829798, 0.03154005846550627, 0.032477752297221024, 0.033312940837257485, 0.03403639217321265, 0.034639977537105585, 0.03511682323976621, 0.035461440931519074, 0.035669832738636206, 0.03573956845982569, 0.035669832738636206, 0.035461440931519074, 0.03511682323976621, 0.034639977537105585, 0.03403639217321265, 0.033312940837257485, 0.032477752297221024, 0.03154005846550627, 0.030510024758829798, 0.02939856710486361, 0.028217160189400764, 0.026977641631473703, 0.0256920167211696, 0.024372268162712405, 0.023030174945629842, 0.0216771440357829
+ 0.0216771440357829, 0.023030174945629842, 0.024372268162712405, 0.0256920167211696, 0.026977641631473703, 0.028217160189400764, 0.02939856710486361, 0.030510024758829798, 0.03154005846550627, 0.032477752297221024, 0.033312940837257485, 0.03403639217321265, 0.034639977537105585, 0.03511682323976621, 0.035461440931519074, 0.035669832738636206, 0.03573956845982569, 0.035669832738636206, 0.035461440931519074, 0.03511682323976621, 0.034639977537105585, 0.03403639217321265, 0.033312940837257485, 0.032477752297221024, 0.03154005846550627, 0.030510024758829798, 0.02939856710486361, 0.028217160189400764, 0.026977641631473703, 0.0256920167211696, 0.024372268162712405, 0.023030174945629842, 0.0216771440357829
};
static const float BlurWeights16[17] =
diff --git a/Engine/Engine/Core/Shaders/Radiance/GIAverageCS.hlsl b/Engine/Engine/Core/Shaders/Radiance/GIAverageCS.hlsl
index 6549568..93d454d 100644
--- a/Engine/Engine/Core/Shaders/Radiance/GIAverageCS.hlsl
+++ b/Engine/Engine/Core/Shaders/Radiance/GIAverageCS.hlsl
@@ -5,39 +5,41 @@ cbuffer externalData : register(b0)
{
uint debug;
uint type;
- matrix view;
- matrix projection;
+ matrix prev_view_proj;
float3 cameraPosition;
uint frame_count;
int kernel_size;
}
Texture2D input : register(t0);
+Texture2D orig_input : register(t1);
RWTexture2D output : register(u0);
Texture2D positions : register(t2);
Texture2D normals : register(t3);
Texture2D prev_output : register(t4);
Texture2D motion_texture : register(t5);
Texture2D prev_position_map: register(t6);
+Texture2D tiles_output: register(t7);
+
+
+float GetPosW(int pos, float wk) {
+ return cos(pos * wk);
+}
+
+//#define DEBUG
+#define MIN_W 0.00001f
#define NTHREADS 32
[numthreads(NTHREADS, NTHREADS, 1)]
-void main(uint3 DTid : SV_DispatchThreadID)
+void main(uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint3 Gid : SV_GroupID)
{
- float2 pixel = float2(DTid.x, DTid.y);
-
- if (debug == 1) {
- output[pixel] = input[pixel];
- return;
- }
-
- uint2 input_dimensions;
- uint2 info_dimensions;
+ float2 input_dimensions;
+ float2 info_dimensions;
{
- uint w = 0;
- uint h = 0;
- uint w2 = 0;
- uint h2 = 0;
+ int w = 0;
+ int h = 0;
+ int w2 = 0;
+ int h2 = 0;
input.GetDimensions(w, h);
output.GetDimensions(w2, h2);
input_dimensions.x = min(w, w2);
@@ -47,129 +49,182 @@ void main(uint3 DTid : SV_DispatchThreadID)
info_dimensions.x = w;
info_dimensions.y = h;
}
+
+ float2 pixel = ThreadGroupTilingX(input_dimensions / NTHREADS, uint2(NTHREADS, NTHREADS), 32, GTid.xy, Gid.xy);
+
+#ifdef DEBUG
+ if (debug == 1) {
+ output[pixel] = input[pixel];
+ return;
+ }
+#endif
+
float2 infoRatio = info_dimensions / input_dimensions;
float2 rpixel = pixel * infoRatio;
- //rpixel.x += frame_count % (infoRatio.x * 0.5f);
- //rpixel.y += frame_count % (infoRatio.y * 0.5f) / 2.0f;
float2 info_pixel = round(rpixel);
float3 p0_position = positions[info_pixel].xyz;
float3 p0_normal = normals[info_pixel].xyz;
- float pixelMaxDist = 0.0f;
- float worldMaxDist = 0.0f;
-
+ float dist_to_cam = dist2(p0_position - cameraPosition);
int x;
int y;
- float sigma = 1.0f;
+ static const float NORMAL_RATIO = 10.0f;
+ static const float sigma = 0.1f;
+
float total_w = 0.0f;
float ww = 1.0f;
float4 c = float4(0.0f, 0.0f, 0.0f, 0.0f);
int full_kernel = 2 * kernel_size + 1;
- int k = kernel_size + full_kernel * 2;
-
-#if 1
- //Convolution type
- float2 dir = lerp(float2(1.0f, 0.0f), float2(0.0f, 1.0f), step(1.5, type));
- for (x = -k; x <= k; ++x) {
- int2 p = pixel + x * dir;
-
- float2 p1_info_pixel = round(p * infoRatio);
- ww = 1.0f;
- if (abs(x) > k) {
- float3 p1_position = positions[p1_info_pixel].xyz;
- if (p1_position.x == FLT_MAX) continue;
- float world_dist = dist2(p1_position - p0_position);
- ww = exp(-world_dist / (2.0f * sigma * sigma));
+
+ [branch]
+ if (tiles_output[pixel / full_kernel] != 0) {
+
+ float input_mix = 0.0f;
+
+ int k = kernel_size + kernel_size + full_kernel;
+ float prev_w = input[pixel].a;
+ float wk = (M_PI / (2.0f * (float)k));
+
+ [branch]
+ if (prev_w < 0.0f) {
+ return;
}
- float3 p1_normal = normals[p1_info_pixel].xyz;
- float n = saturate(dot(p1_normal, p0_normal));
- ww *= pow(n, max(5.0f / infoRatio.x, 1.0f));
+ uint count = 0;
+
+ [branch]
+ switch (type)
+ {
+
+ //Execute pass 1
+ case 1: {
+ //Pass 1 horizontal convolution
+ float2 dir = float2(1.0f, 0.0f);
+
+ for (x = -k; x <= k; ++x) {
+ int2 p = (pixel + x * dir);
+ p.x += step(Epsilon, -p.x) * k;
+ p.x += step(Epsilon, p.x - input_dimensions.x) * -k;
+
+ float2 p1_info_pixel = round(p * infoRatio);
+ ww = 1.0f;
+
+ float3 p1_position = positions[p1_info_pixel].xyz;
+ float world_dist = dist2(p1_position - p0_position) / (dist_to_cam);
+ ww = exp(-world_dist / (2.0f * sigma * sigma));
+
+ float3 p1_normal = normals[p1_info_pixel].xyz;
+ float n = saturate(dot(p1_normal, p0_normal));
+ ww *= pow(n, max(NORMAL_RATIO / infoRatio.x, 1.0f));
+ ww *= GetPosW(x, wk);
+ ww = max(ww, MIN_W);
+
+ c += input[p] * ww;
+ total_w += ww;
+ count++;
+ }
+ } break;
+
+ //Execute pass 2
+ case 2: {
+ float2 dir = float2(0.0f, 1.0f);
+ for (x = -k; x <= k; ++x) {
+ int2 p = (pixel + x * dir);
+ p.y += step(Epsilon, -p.y) * k;
+ p.y += step(Epsilon, p.y - input_dimensions.y) * -k;
+
+ float2 p1_info_pixel = round(p * infoRatio);
+ ww = 1.0f;
+
+ float3 p1_position = positions[p1_info_pixel].xyz;
+ float world_dist = dist2(p1_position - p0_position) / (dist_to_cam);
+ ww = exp(-world_dist / (2.0f * sigma * sigma));
+
+ float3 p1_normal = normals[p1_info_pixel].xyz;
+ float n = saturate(dot(p1_normal, p0_normal));
+ ww *= pow(n, max(NORMAL_RATIO / infoRatio.x, 1.0f));
+ ww *= GetPosW(x, wk);
+ ww = max(ww, MIN_W);
+ c.rgb += input[p].rgb * ww;
+
+ total_w += ww;
+ count++;
+ }
+ } break;
+
+ //Execute pass 3
+ case 3: {
+ //Pass 2 convolution failed again, make a minimal 2D pass
+ [branch]
+ if (prev_w < 1.0f) {
+ k = kernel_size + kernel_size;
+ for (x = -k; x <= k; ++x) {
+ for (y = -k; y <= k; ++y) {
+ int2 p = pixel + int2(x, y);
+ p.x += step(Epsilon, -p.x) * k;
+ p.x += step(Epsilon, p.x - input_dimensions.x) * -k;
+ p.y += step(Epsilon, -p.y) * k;
+ p.y += step(Epsilon, p.y - input_dimensions.y) * -k;
+ float2 p1_info_pixel = round(p * infoRatio);
+ ww = 1.0f;
+
+ float3 p1_position = positions[p1_info_pixel].xyz;
+ float world_dist = dist2(p1_position - p0_position) / (dist_to_cam);
+ ww = exp(-world_dist / (2.0f * sigma * sigma));
+
+ float3 p1_normal = normals[p1_info_pixel].xyz;
+ float n = saturate(dot(p1_normal, p0_normal));
+ ww *= pow(n, max(NORMAL_RATIO / infoRatio.x, 1.0f));
+ ww *= GetPosW(x, wk) * GetPosW(y, wk);
+
+ c.rgb += orig_input[p].rgb * ww;
+ //c.rgb += float3(orig_input[p].r * ww, 0.0f, 1.0f);
+ total_w += ww;
+ count++;
+ }
+ }
+ input_mix = saturate(prev_w - 0.2f);
+ }
+ else {
+ // Pass2 convolution finished already, nothing to do in this pixel, just copy it
+ input_mix = 1.0f;
+ total_w = 1.0f;
+ c.a = 0.0f;
+ }
+ } break;
+ }
- c += input[p] * ww;
- total_w += ww;
- }
- static const float epsilon = 10e-4;
- c = c * step(epsilon, total_w);
- c = c / max(total_w, epsilon);
+ c = c / max(total_w, 1.0f);
+
+ total_w /= k;
+ if (type == 1) {
+ c.a = total_w;
+ }
+ else {
+ c.a = prev_w + total_w;
+ }
-#if 1
- if (type == 1) {
+ c = lerp(c, input[pixel], input_mix);
+ }
+#if 0
+ if (type < 3) {
output[pixel] = c;
}
else {
- matrix worldViewProj = mul(view, projection);
- float4 prev_pos = mul(prev_position_map[info_pixel], worldViewProj);
+ float4 prev_pos = mul(prev_position_map[info_pixel], prev_view_proj);
prev_pos.x /= prev_pos.w;
prev_pos.y /= -prev_pos.w;
- prev_pos.xy = (prev_pos.xy + 1.0f) * info_dimensions.xy / 2.0f;
-#if 0
- float motion = length(motion_texture[prev_pos.xy].xy);
- float2 mvector = motion_texture[info_pixel].xy;
- if (mvector.x == -FLT_MAX) {
- motion = 0.0f;
- }
- else {
- motion = length(mvector);
- }
- if (motion < 0.005f) {
- prev_pos.xy = pixel.xy;
- }
- else {
- prev_pos.xy /= infoRatio;
- }
- float w = saturate(0.8f - motion * 100.0f);
-#else
- prev_pos.xy /= infoRatio;
- float w = 0.3f;
-#endif
+ prev_pos.xy = (prev_pos.xy + 1.0f) * input_dimensions.xy / 2.0f;
+ float w = 0.8f;
float4 prev_color = prev_output[round(prev_pos.xy)];
- output[pixel] = prev_color * w + c * (1.0f - w);
- }
-#else
- output[pixel] = c;
-#endif
-
-#else
- //Single pass type
- for (x = -k; x <= k; ++x) {
- for (y = -k; y <= k; ++y) {
- int2 p = pixel + int2(x, y);
- float2 p1_info_pixel = round(p * infoRatio);
- float3 p1_position = positions[p1_info_pixel].xyz;
- if (p1_position.x == FLT_MAX) continue;
-
- float world_dist = dist2(p1_position - p0_position);
- ww = exp(-world_dist / (2.0f * sigma * sigma));
-
- float3 p1_normal = normals[p1_info_pixel].xyz;
- float n = saturate(dot(p1_normal, p0_normal));
- ww *= pow(n, 5.0f / infoRatio.x);
- c += input[p] * ww;
- total_w += ww;
- }
+ output[pixel] = lerp(prev_color, c, w);
}
- static const float epsilon = 10e-4;
- c = c * step(epsilon, total_w);
- c = c / max(total_w, epsilon);
-
-#if 1
- matrix worldViewProj = mul(view, projection);
- float4 prev_pos = mul(prev_position_map[info_pixel], worldViewProj);
- prev_pos.x /= prev_pos.w;
- prev_pos.y /= -prev_pos.w;
- prev_pos.xy = (prev_pos.xy + 1.0f) * info_dimensions.xy / 2.0f;
- prev_pos.xy /= infoRatio;
- float4 prev_color = prev_output[floor(prev_pos.xy)];
- float w = 0.5f;
- output[pixel] = prev_color * w + c * (1.0f - w);
#else
output[pixel] = c;
#endif
-#endif
}
diff --git a/Engine/Engine/Core/Shaders/RayTrace/DenoiserCS.hlsl b/Engine/Engine/Core/Shaders/RayTrace/DenoiserCS.hlsl
index 08845f6..b424395 100644
--- a/Engine/Engine/Core/Shaders/RayTrace/DenoiserCS.hlsl
+++ b/Engine/Engine/Core/Shaders/RayTrace/DenoiserCS.hlsl
@@ -7,9 +7,9 @@ cbuffer externalData : register(b0)
uint count;
float3 cameraPosition;
uint light_type;
- matrix view;
- matrix projection;
+ matrix view_projection;
uint debug;
+ int kernel_size;
}
Texture2D input : register(t0);
@@ -19,14 +19,12 @@ Texture2D positions : register(t2);
Texture2D prev_output : register(t3);
Texture2D motion_texture : register(t4);
Texture2D prev_position_map: register(t5);
-Texture2D dispersion: register(t6);
+Texture2D tiles_output : register(t7);
#define NTHREADS 32
[numthreads(NTHREADS, NTHREADS, 1)]
-void main(uint3 DTid : SV_DispatchThreadID)
+void main(uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint3 Gid : SV_GroupID)
{
- float2 pixel = float2(DTid.x, DTid.y);
-
uint2 input_dimensions;
uint2 normals_dimensions;
{
@@ -43,6 +41,8 @@ void main(uint3 DTid : SV_DispatchThreadID)
normals_dimensions.x = w;
normals_dimensions.y = h;
}
+ float2 pixel = ThreadGroupTilingX(input_dimensions / NTHREADS, uint2(NTHREADS, NTHREADS), 32, GTid.xy, Gid.xy);
+
uint2 normalRatio = normals_dimensions / input_dimensions;
float2 info_pixel = round(pixel * normalRatio);
@@ -51,7 +51,7 @@ void main(uint3 DTid : SV_DispatchThreadID)
RaySource ray_source = fromColor(positions[info_pixel], normals[info_pixel]);
float4 c = float4(0.0f, 0.0f, 0.0f, 0.0f);
-#define HARD_MAX_KERNEL 40
+#define HARD_MAX_KERNEL 30
uint MAX_KERNEL = min(normals_dimensions.x / 32, HARD_MAX_KERNEL);
float count = 0.0f;
@@ -63,34 +63,25 @@ void main(uint3 DTid : SV_DispatchThreadID)
float disp = -1.0f;
uint min_dispersion = 0;
- if (dist2(ray_source.orig) <= Epsilon) {
- output[pixel] = float4(0.0f, 0.0f, 0.0f, 0.0f);
- return;
- }
-
-
+ bool skip = false;
+ uint tile_info = tiles_output[pixel / kernel_size];
+ disp = (ray_source.dispersion);
switch (light_type) {
- case 0: {
- disp = sqrt(ray_source.dispersion);
- //disp = sqrt(dispersion[pixel].r);
- break;
- }
- case 1: {
- //disp = ray_source.dispersion;
- disp = dispersion[pixel].a;
- break;
+ case 0: skip = ((tile_info & 0x01) == 0); break;
+ case 1: skip = (((tile_info >> 1) & 0x01) == 0); break;
}
- }
- if (disp < Epsilon) {
- output[pixel] = float4(0.0f, 0.0f, 0.0f, 0.0f);
+ [branch]
+ if (disp < Epsilon || skip) {
+ output[pixel] = input[pixel];
return;
}
- uint min_k = max(normalRatio.x * 0.25f, 0);
+ uint min_k = max(normalRatio.x * 0.5f, 0);
int kernel = clamp(floor(max(MAX_KERNEL * disp, min_dispersion)), min_k, MAX_KERNEL);
float motion = 0.0f;
float camDist = dist2(cameraPosition - p0_position);
uint2 ipixel = pixel;
+
for (int i = -kernel; i <= kernel; ++i) {
float2 p = ipixel + dir * i;
if ((p.x < 0 || p.x >= input_dimensions.x) && (p.y < 0 || p.y >= input_dimensions.y)) {
@@ -101,10 +92,11 @@ void main(uint3 DTid : SV_DispatchThreadID)
float3 p1_normal = normals[p1_info_pixel].xyz;
float n = saturate(dot(p1_normal, p0_normal));
float dist = max(dist2(p1_position - p0_position) / camDist, 0.1f);
- float w = pow(n, 20.0f / normalRatio) / dist;
+ float w = pow(n, 5.0f / normalRatio.x) / dist;
if (kernel > 1) {
w *= cos((M_PI * abs((float)i)) / (2.0 * (float)kernel));
}
+ w = max(w, 0.1f);
count += w;
c0 += input[p] * w;
}
@@ -115,13 +107,12 @@ void main(uint3 DTid : SV_DispatchThreadID)
else {
c0 *= 0.0f;
}
-#if 1
+#if 0
if (type == 1) {
output[pixel] = c0;
}
else {
- matrix worldViewProj = mul(view, projection);
- float4 prev_pos = mul(prev_position_map[info_pixel], worldViewProj);
+ float4 prev_pos = mul(prev_position_map[info_pixel], view_projection);
prev_pos.x /= prev_pos.w;
prev_pos.y /= -prev_pos.w;
prev_pos.xy = (prev_pos.xy + 1.0f) * normals_dimensions.xy / 2.0f;
@@ -146,8 +137,8 @@ void main(uint3 DTid : SV_DispatchThreadID)
prev_pos.xy /= normalRatio;
}
- float4 prev_color = prev_output[floor(prev_pos.xy)];
- float w = saturate(0.5f - motion * 50.0f);
+ float4 prev_color = prev_output[(prev_pos.xy)];
+ float w = saturate(0.8f - motion * 100.0f);
output[pixel] = prev_color * w + c0 * (1.0f - w);
}
#else
diff --git a/Engine/Engine/Core/Shaders/RayTrace/DispersionCS.hlsl b/Engine/Engine/Core/Shaders/RayTrace/DispersionCS.hlsl
deleted file mode 100644
index 6a95a39..0000000
--- a/Engine/Engine/Core/Shaders/RayTrace/DispersionCS.hlsl
+++ /dev/null
@@ -1,59 +0,0 @@
-
-#include "../Common/ShaderStructs.hlsli"
-#include "../Common/Utils.hlsli"
-
-cbuffer externalData : register(b0)
-{
- uint type;
-}
-
-Texture2D input : register(t0);
-RWTexture2D output : register(u0);
-
-static const float kw[21] = { 0.000514f,0.001478f,0.003800f,0.008744f,0.018005f,0.033174f,0.054694f,0.080692f,0.106529f,0.125850f,0.133039f,0.125850f,0.106529f,0.080692f,0.054694f,0.033174f,0.018005f,0.008744f,0.003800f,0.001478f,0.000514f };
-
-#define NTHREADS 32
-[numthreads(NTHREADS, NTHREADS, 1)]
-void main(uint3 DTid : SV_DispatchThreadID)
-{
- uint2 input_dimensions;
- uint w = 0;
- uint h = 0;
- input.GetDimensions(w, h);
- input_dimensions.x = w;
- input_dimensions.y = h;
-
- float2 pixel = float2(DTid.x, DTid.y);
-
- float2 dir = lerp(float2(1.0f, 0.0f), float2(0.0f, 1.0f), step(1.5, type));
-
-
- int kernel = type <= 2?5:10;
- if (type <= 2) {
- float3 max_disp = float3(-1.0f, -1.0f, -1.0f);
- for (int i = -kernel; i <= kernel; ++i) {
- float2 p = pixel + dir * i;
- if ((p.x < 0 || p.x >= input_dimensions.x) && (p.y < 0 || p.y >= input_dimensions.y)) {
- break;
- }
- float3 c = input[p].rgb;
- max_disp = max(max_disp, c);
- }
- float4 c0 = input[pixel];
- c0.rgb = max_disp;
- output[pixel] = c0;
- }
- else {
- float3 max_disp = float3(0.0f, 0.0f, 0.0f);
- for (int i = -kernel; i <= kernel; ++i) {
- float2 p = pixel + dir * i;
- if ((p.x < 0 || p.x >= input_dimensions.x) && (p.y < 0 || p.y >= input_dimensions.y)) {
- break;
- }
- max_disp += input[p].rgb * kw[i + 10];
- }
- float4 c0 = input[pixel];
- c0.rgb = max_disp;
- output[pixel] = c0;
- }
-}
diff --git a/Engine/Engine/Core/Shaders/RayTrace/GIRayTraceCS.hlsl b/Engine/Engine/Core/Shaders/RayTrace/GIRayTraceCS.hlsl
index b754c0d..f0b6c69 100644
--- a/Engine/Engine/Core/Shaders/RayTrace/GIRayTraceCS.hlsl
+++ b/Engine/Engine/Core/Shaders/RayTrace/GIRayTraceCS.hlsl
@@ -31,89 +31,46 @@ SOFTWARE.
#define INDIRECT_ENABLED 4
#define USE_OBH 0
-#define DISABLE_RESTIR
+//#define BOUNCES
+//#define DISABLE_RESTIR
cbuffer externalData : register(b0)
{
uint frame_count;
float time;
float3 cameraPosition;
- float3 cameraDirection;
-
- uint ray_count;
+ uint divider;
+ matrix view_proj;
int kernel_size;
-
- //Lights
- AmbientLight ambientLight;
- DirLight dirLights[MAX_LIGHTS];
- PointLight pointLights[MAX_LIGHTS];
- uint dirLightsCount;
- uint pointLightsCount;
-
- matrix view;
- matrix projection;
-
- float4 LightPerspectiveValues[MAX_LIGHTS / 2];
- matrix DirPerspectiveMatrix[MAX_LIGHTS];
}
-cbuffer objectData : register(b1)
-{
- uint nobjects;
- ObjectInfo objectInfos[MAX_OBJECTS];
- MaterialColor objectMaterials[MAX_OBJECTS];
-}
-
-RWTexture2D output;
Texture2D ray0;
Texture2D ray1;
-StructuredBuffer objects: register(t2);
-StructuredBuffer objectBVH: register(t3);
-
-ByteAddressBuffer vertexBuffer : register(t4);
-ByteAddressBuffer indicesBuffer : register(t5);
-Texture2D position_map : register(t6);
Texture2D motion_texture : register(t8);
Texture2D prev_position_map: register(t9);
+Texture2D restir_pdf_0: register(t10);
+Texture2D restir_w_0: register(t11);
+RWTexture2D ray_inputs: register(u2);
+RWTexture2D restir_pdf_mask: register(u3);
-Texture2D DiffuseTextures[MAX_OBJECTS];
-Texture2D DirShadowMapTexture[MAX_LIGHTS];
-TextureCube PointShadowMapTexture[MAX_LIGHTS];
-
-Texture2D restir_pdf_0;
-Texture2D restir_w_0;
-RWTexture2D restir_pdf_1;
-
-//Packed array
-static float2 lps[MAX_LIGHTS] = (float2[MAX_LIGHTS])LightPerspectiveValues;
-
-#include "../Common/SimpleLight.hlsli"
#include "../Common/RayFunctions.hlsli"
-#define max_distance 100.0f
-
-static const float inv_ray_count = 1.0f / (float)ray_count;
-static const uint stride = kernel_size * ray_count;
+static const float inv_ray_count = 1.0f / (float)MAX_RAYS;
+static const uint stride = kernel_size * MAX_RAYS;
-static const uint max_x = ray_count * kernel_size;
-static const uint max_y = stride * kernel_size;
+static const uint N = MAX_RAYS * kernel_size * kernel_size;
+static const float space_size = (float)N / (float)MAX_RAYS;
-static const uint N = ray_count * kernel_size * kernel_size;
-static const float space_size = (float)N / (float)ray_count;
-static const float ray_enery_unit = inv_ray_count;
-#define LEVEL_RATIO level
-
-uint GetRayIndex(float2 pixel, float pdf_cache[MAX_RAYS], Texture2D w_data, float index) {
+uint GetRayIndex(float pdf_cache[MAX_RAYS], float w, float index) {
#ifdef DISABLE_RESTIR
return index;
#endif
- float w = max(w_data[pixel], RAY_W_BIAS * ray_count);
float tmp_w = 0.0f;
- index = index * w * inv_ray_count;
+ index = (index + 1.0f) * w * inv_ray_count;
- for (uint i = 0; i < ray_count; i++) {
+ for (uint i = 0; i < MAX_RAYS; i++) {
tmp_w += pdf_cache[i];
if (tmp_w > index) {
break;
@@ -122,31 +79,34 @@ uint GetRayIndex(float2 pixel, float pdf_cache[MAX_RAYS], Texture2D w_dat
return i;
}
-float3 GenerateHemisphereRay(float3 dir, float3 tangent, float3 bitangent, float dispersion, float N, float NLevels, float rX)
+#if 0
+float2 GenerateHemisphereRay(float3 dir, float3 tangent, float3 bitangent, float dispersion, float N, float NLevels, float rX)
{
float index = (rX * dispersion) % N;
- //index = (frame_count / 5) % N;
+ //index = (frame_count) % N;
+ float N_SQRT = sqrt(N);
float cumulativePoints = 1.0f;
float level = 1.0f;
float c = 1.0f;
+ float phi;
while (c < index) {
- c = cumulativePoints + level * LEVEL_RATIO;
+ phi = (level * M_PI * 0.5f) / NLevels;
+ c = cumulativePoints + N_SQRT * sin(phi);
cumulativePoints = c;
level++;
};
level--;
- float pointsAtLevel = level * LEVEL_RATIO;
+
+ float pointsAtLevel = 1.0f + ceil(N_SQRT * sin(phi));
+ phi = (level * M_PI) / NLevels;
// Calculate local index within the current level
float localIndex = index - cumulativePoints;
-
- float phi = (level * M_PI) / NLevels;
-
+
// Azimuthal angle (theta) based on number of points at this level
- float theta = (2.0f * M_PI) * localIndex / pointsAtLevel; // Spread points evenly in azimuthal direction
-
+ float theta = (2.0f * M_PI) * localIndex / pointsAtLevel; // Spread points evenly in azimuthal direction
// Convert spherical coordinates to Cartesian coordinates
float sinPhi = sin(phi);
@@ -160,223 +120,72 @@ float3 GenerateHemisphereRay(float3 dir, float3 tangent, float3 bitangent, float
// Convert local ray to global coordinates (tangent space to world space)
float3 globalRay = localRay.x * tangent + localRay.y * dir + localRay.z * bitangent;
-
- return normalize(dir + globalRay);
+ return GetPolarCoordinates(normalize(dir + globalRay));
}
-
-struct RayTraceColor {
- float3 color;
- bool hit;
-};
-
-void GetColor(Ray origRay, float rX, float level, uint max_bounces, out RayTraceColor out_color, float dispersion, bool mix, bool refract)
-{
- out_color.color = float3(0.0f, 0.0f, 0.0f);
- out_color.hit = false;
-
- float collision_dist = 0.0f;
-#if USE_OBH
- uint volumeStack[MAX_STACK_SIZE];
-#endif
- uint stack[MAX_STACK_SIZE];
- RayObject oray;
- IntersectionResult object_result;
-
- bool collide = false;
- IntersectionResult result;
- Ray ray = origRay;
- float att_dist = 1.0f;
- bool end = false;
-
- result.distance = FLT_MAX;
- end = true;
- collide = false;
-#if USE_OBH
- uint volumeStackSize = 0;
- volumeStack[volumeStackSize++] = 0;
- uint i = 0;
- while (volumeStackSize > 0 && volumeStackSize < MAX_STACK_SIZE)
- {
#else
- for (uint i = 0; i < nobjects; ++i)
- {
- uint objectIndex = i;
-#endif
-
-#if USE_OBH
- uint currentVolume = volumeStack[--volumeStackSize];
- BVHNode volumeNode = objectBVH[currentVolume];
- if (is_leaf(volumeNode))
- {
- uint objectIndex = index(volumeNode);
- ObjectInfo o = objectInfos[objectIndex];
+#define LEVEL_RATIO 3
+float2 GenerateHemisphereRay(float3 dir, float3 tangent, float3 bitangent, float dispersion, float N, float NLevels, float rX)
+{
+ float index = (rX * dispersion) % N;
- float objectExtent = length(o.aabb_max - o.aabb_min);
- float distanceToObject = length(o.position - origRay.orig.xyz) - objectExtent;
+ //index = (frame_count) % N;
+ float cumulativePoints = 1.0f;
+ float level = 1.0f;
+ float c = 1.0f;
+ while (c < index) {
+ c = cumulativePoints + level * LEVEL_RATIO;
+ cumulativePoints = c;
+ level++;
+ };
+ level--;
- if (distanceToObject < max_distance && distanceToObject < result.distance && IntersectAABB(ray, o.aabb_min, o.aabb_max))
- {
-#else
- ObjectInfo o = objectInfos[i];
- float objectExtent = length(o.aabb_max - o.aabb_min);
- float distanceToObject = length(o.position - origRay.orig.xyz) - objectExtent;
- if (distanceToObject < max_distance && distanceToObject < result.distance && IntersectAABB(ray, o.aabb_min, o.aabb_max))
- {
-#endif
- object_result.distance = FLT_MAX;
-
- // Transform the ray direction from world space to object space
- oray.orig = mul(ray.orig, o.inv_world);
- oray.orig /= oray.orig.w;
- oray.dir = normalize(mul(ray.dir, (float3x3) o.inv_world));
- oray.t = FLT_MAX;
-
- uint stackSize = 0;
- stack[stackSize++] = 0;
-
- while (stackSize > 0 && stackSize < MAX_STACK_SIZE)
- {
- uint current = stack[--stackSize];
-
- BVHNode node = objects[o.objectOffset + current];
- if (is_leaf(node))
- {
- float t;
- uint idx = index(node);
- idx += o.indexOffset;
-
- IntersectionResult tmp_result;
- tmp_result.distance = FLT_MAX;
- if (IntersectTri(oray, idx, o.vertexOffset, tmp_result))
- {
- if (tmp_result.distance < object_result.distance) {
- object_result.v0 = tmp_result.v0;
- object_result.v1 = tmp_result.v1;
- object_result.v2 = tmp_result.v2;
- object_result.vindex = tmp_result.vindex;
- object_result.distance = tmp_result.distance;
- object_result.uv = tmp_result.uv;
- object_result.object = objectIndex;
- }
- }
- }
- else if (IntersectAABB(oray, node))
- {
- stack[stackSize++] = left_child(node);
- stack[stackSize++] = right_child(node);
- }
- }
-
- if (object_result.distance < FLT_MAX) {
- float3 opos = (1.0f - object_result.uv.x - object_result.uv.y) * object_result.v0 + object_result.uv.x * object_result.v1 + object_result.uv.y * object_result.v2;
- float4 pos = mul(float4(opos, 1.0f), o.world);
- float distance = length(pos - ray.orig);
- if (distance < result.distance)
- {
- collide = true;
- collision_dist = distance;
- ray.t = distance;
- result.v0 = object_result.v0;
- result.v1 = object_result.v1;
- result.v2 = object_result.v2;
- result.vindex = object_result.vindex;
- result.distance = distance;
- result.uv = object_result.uv;
- result.object = objectIndex;
- }
- }
- }
-#if USE_OBH
- } else if (IntersectAABB(ray, volumeNode)) {
- volumeStack[volumeStackSize++] = left_child(volumeNode);
- volumeStack[volumeStackSize++] = right_child(volumeNode);
- }
- ++i;
-#endif
- }
+ float pointsAtLevel = 1.0f + level * LEVEL_RATIO;
- //At this point we have the ray collision distance and a collision result
- if (collide) {
- // Calculate space position
- ObjectInfo o = objectInfos[result.object];
- float3 normal0 = asfloat(vertexBuffer.Load3(result.vindex.x + 12));
- float3 normal1 = asfloat(vertexBuffer.Load3(result.vindex.y + 12));
- float3 normal2 = asfloat(vertexBuffer.Load3(result.vindex.z + 12));
- float3 opos = (1.0f - result.uv.x - result.uv.y) * result.v0 + result.uv.x * result.v1 + result.uv.y * result.v2;
- float3 normal = (1.0f - result.uv.x - result.uv.y) * normal0 + result.uv.x * normal1 + result.uv.y * normal2;
- normal = normalize(mul(normal, (float3x3)o.world));
- float4 pos = mul(float4(opos, 1.0f), o.world);
- pos /= pos.w;
- MaterialColor material = objectMaterials[result.object];
-
- float3 color = float3(0.0f, 0.0f, 0.0f);
-
- color += CalcAmbient(normal) * 0.5f;
- color *= o.opacity;
-
- uint i = 0;
- for (i = 0; i < dirLightsCount; ++i) {
- color += CalcDirectional(normal, pos.xyz, dirLights[i], i);
- }
+ // Calculate local index within the current level
+ float localIndex = index - cumulativePoints;
+ float phi = (level * M_PI * 0.8f) / NLevels;
+ // Azimuthal angle (theta) based on number of points at this level
+ float theta = (2.0f * M_PI) * localIndex / pointsAtLevel; // Spread points evenly in azimuthal direction
- // Calculate the point lights
- for (i = 0; i < pointLightsCount; ++i) {
- if (length(pos.xyz - pointLights[i].Position) < pointLights[i].Range) {
- color += CalcPoint(normal, pos.xyz, pointLights[i], i);
- }
- }
- //Calculate material color
- if (material.flags & DIFFUSSE_MAP_ENABLED_FLAG) {
- float2 uv0 = asfloat(vertexBuffer.Load2(result.vindex.x + 24));
- float2 uv1 = asfloat(vertexBuffer.Load2(result.vindex.y + 24));
- float2 uv2 = asfloat(vertexBuffer.Load2(result.vindex.z + 24));
- float2 uv = uv0 * (1.0f - result.uv.x - result.uv.y) + uv1 * result.uv.x + uv2 * result.uv.y;
- color *= GetDiffuseColor(result.object, uv);
- }
- else {
- color *= material.diffuseColor.rgb;
- }
+ // Convert spherical coordinates to Cartesian coordinates
+ float sinPhi = sin(phi);
+ float cosPhi = cos(phi);
+ float sinTheta = sin(theta);
+ float cosTheta = cos(theta);
- float3 emission = material.emission * material.emission_color;
- color += emission;
+ // Local ray direction in spherical coordinates
+ float3 localRay = float3(sinPhi * cosTheta, cosPhi, sinPhi * sinTheta);
- att_dist *= max(collision_dist * collision_dist, 1.0f);
+ // Convert local ray to global coordinates (tangent space to world space)
+ float3 globalRay = localRay.x * tangent + localRay.y * dir + localRay.z * bitangent;
- out_color.color += color * ray.ratio / att_dist;
-
- ray.orig = pos;
- out_color.hit = true;
- }
- }
+ return GetPolarCoordinates(normalize(dir + globalRay));
+}
- bool IsLowEnergy(float pdf[MAX_RAYS], uint len) {
+#endif
+bool IsLowEnergy(float pdf[MAX_RAYS], uint len) {
- float total_enery = 0.0f;
-
- for (int i = 0; i < len; ++i) {
- total_enery += pdf[i];
- }
- float threshold = len * RAY_W_BIAS;
+ float total_enery = 0.0f;
- return (total_enery <= threshold);
+ for (uint i = 0; i < len; ++i) {
+ total_enery += pdf[i];
}
+ float threshold = len * 0.01f;
+
+ return (total_enery < threshold);
+}
#define NTHREADS 32
[numthreads(NTHREADS, NTHREADS, 1)]
void main(uint3 DTid : SV_DispatchThreadID, uint3 group : SV_GroupID, uint3 thread : SV_GroupThreadID)
{
-
float2 dimensions;
float2 ray_map_dimensions;
{
uint w, h;
- output.GetDimensions(w, h);
- dimensions.x = w;
- dimensions.y = h;
-
ray0.GetDimensions(w, h);
ray_map_dimensions.x = w;
ray_map_dimensions.y = h;
@@ -384,40 +193,39 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 group : SV_GroupID, uint3 thre
float x = (float)DTid.x;
float y = (float)DTid.y;
- float2 rayMapRatio = ray_map_dimensions / dimensions;
-
+ float rayMapRatio = divider;
+ dimensions = ray_map_dimensions / divider;
float2 pixel = float2(x, y);
-
float2 rpixel = pixel * rayMapRatio;
- //rpixel.x += frame_count % (rayMapRatio.x * 0.5f);
- //rpixel.y += frame_count % (rayMapRatio.y * 0.5f) / 2.0f;
float2 ray_pixel = round(rpixel);
RaySource ray_source = fromColor(ray0[ray_pixel], ray1[ray_pixel]);
- if (ray_source.reflex <= Epsilon || dist2(ray_source.normal) <= Epsilon)
- {
- return;
- }
+ bool end = (ray_source.reflex <= Epsilon || dist2(ray_source.normal) <= Epsilon);
float3 orig_pos = ray_source.orig.xyz;
float toCamDistance = dist2(orig_pos - cameraPosition);
float3 tangent;
float3 bitangent;
- RayTraceColor rc;
- Ray ray = GetReflectedRayFromSource(ray_source);
-
- if (dist2(ray.dir) <= Epsilon)
- {
- return;
- }
+ Ray ray = GetReflectedRayFromSource(ray_source, cameraPosition);
+
+ float pdf_cache[MAX_RAYS];
- matrix worldViewProj = mul(view, projection);
- float4 prev_pos = mul(prev_position_map[ray_pixel], worldViewProj);
+ float4 prev_pos = mul(prev_position_map[ray_pixel], view_proj);
prev_pos.x /= prev_pos.w;
prev_pos.y /= -prev_pos.w;
- prev_pos.xy = round((prev_pos.xy + 1.0f) * dimensions.xy / 2.0f);
+ prev_pos.xy = (prev_pos.xy + 1.0f) * dimensions.xy * 0.5f;
+ UnpackRays(restir_pdf_0[prev_pos.xy], RAY_W_SCALE, pdf_cache);
+ uint i = 0;
+
+ end = end || (dist2(ray.dir) <= Epsilon);
+ [branch]
+ if (end)
+ {
+ return;
+ }
+
float3 normal = ray_source.normal;
float3 orig_dir = ray.dir;
@@ -429,79 +237,87 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 group : SV_GroupID, uint3 thre
cumulativePoints = c;
level++;
};
-
GetSpaceVectors(normal, tangent, bitangent);
float color_w = 0.0f;
-
- float pdf_cache[MAX_RAYS];
- UnpackRays(restir_pdf_0[pixel], RAY_W_SCALE, pdf_cache);
-
- uint i;
-
- for (i = 0; i < ray_count; i++) {
- pdf_cache[i] = max(pdf_cache[i], RAY_W_BIAS);
- }
float wis[MAX_RAYS];
int wis_size = 0;
+
uint last_wi = MAX_RAYS + 1;
-
- //Check if this is a low enery pixel
- uint low_energy = IsLowEnergy(pdf_cache, ray_count);
- float2 mvector = motion_texture[ray_pixel].xy;
- float motion = 0.0f;
- if (mvector.x > -FLT_MAX) {
- motion = dist2(mvector);
+ for (i = 0; i < MAX_RAYS; i++) {
+ pdf_cache[i] = max(pdf_cache[i], RAY_W_BIAS);
}
-#ifdef DISABLE_RESTIR
- uint start = 0;
- uint step = 1;
-#else
- float motion_ratio = 1.0f / max(sqrt(motion) * toCamDistance, 0.01f);
- uint start = (((pixel.x + pixel.y + frame_count)) % ray_count) * low_energy * motion_ratio;
- uint step = ray_count / 4 + (ray_count * motion_ratio) * low_energy;
-#endif
+ uint restir_mask = 0;
+ float w_pixel = max(restir_w_0[pixel], RAY_W_BIAS * MAX_RAYS);
- for (i = start; i < ray_count; i += step) {
- uint wi = GetRayIndex(prev_pos.xy, pdf_cache, restir_w_0, i);
- wis[wis_size] = wi;
- wis_size += (last_wi != wi);
- last_wi = wi;
+ float unordered_wis[MAX_RAYS];
+ for (i = 0; i < MAX_RAYS; ++i) {
+ uint wi = GetRayIndex(pdf_cache, w_pixel, i);
+ if (last_wi != wi) {
+ unordered_wis[wis_size] = wi;
+ wis_size++;
+ last_wi = wi;
+ }
}
-
- float4 color_diffuse = float4(0.0f, 0.0f, 0.0f, 1.0f);
- float offset = (pixel.x % kernel_size) * ray_count + (pixel.y % kernel_size) * stride;
- float offset2 = space_size;
-
- for (i = 0; i < wis_size; ++i) {
-
- uint wi = wis[i];
- float n = fmod(offset + (float)wi * offset2, N);
- ray.dir = GenerateHemisphereRay(normal, tangent, bitangent, 1.0f, N, level * 1.2f, n);
- ray.orig.xyz = orig_pos.xyz + ray.dir * 0.001f;
- float dist = FLT_MAX;
- GetColor(ray, n, level, 0, rc, ray_source.dispersion, true, false);
- color_diffuse.rgb += rc.color;
- last_wi = wi;
+ for (i = 0; i < 3 && i < wis_size; ++i) {
+ float max_wi = 0.0f;
+ uint max_wi_pos = 0;
+ uint max_unordered_wis_pos = 0;
+ for (int j = 0; j < wis_size; ++j) {
+ if (max_wi < pdf_cache[unordered_wis[j]]) {
+ max_wi_pos = unordered_wis[j];
+ max_wi = pdf_cache[max_wi_pos];
+ max_unordered_wis_pos = j;
+ }
+ }
- float w = length(rc.color.rgb);
+ wis[i] = max_wi_pos;
+ unordered_wis[max_unordered_wis_pos] = 0.0f;
+ restir_mask = (restir_mask << 4) | max_wi_pos;
+ }
-#ifdef DISABLE_RESTIR
- pdf_cache[wi] = 1.0f;
-#else
- pdf_cache[wi] = RAY_W_BIAS + w;
-#endif
+ for (i = wis_size; i < 3; ++i) {
+ wis[i] = 0xF;
+ restir_mask = (restir_mask << 4) | 0xF;
}
- wis_size = max(wis_size, 1);
- restir_pdf_1[pixel] = PackRays(pdf_cache, RAY_W_SCALE);
- color_diffuse = color_diffuse / wis_size;
-
- output[pixel] = sqrt(color_diffuse) * !low_energy;
- //float r = wis_size / ray_count;
- //output[pixel] = float4(wis_size, 0.0f, 0.0f, 1.0f);
+ //Add scan line in ray 4
+ uint scan_ray = frame_count% MAX_RAYS;
+ bool found;
+ do {
+ found = false;
+ for (i = 0; i < 3; ++i) {
+ if (wis[i] == scan_ray) {
+ scan_ray = (scan_ray + 1) % MAX_RAYS;
+ found = true;
+ break;
+ }
+ }
+
+ } while (found);
+ wis[3] = scan_ray;
+ restir_mask = (restir_mask << 4) | scan_ray;
+
+ float4 color_diffuse = float4(0.0f, 0.0f, 0.0f, 1.0f);
+ float offset = ((pixel.x) % kernel_size) * MAX_RAYS + ((pixel.y) % kernel_size) * stride;
+ float offset2 = space_size;
+
+ float2 ray_input[4];
+ for (i = 0; i < 4; ++i) {
+ uint wi = wis[i];
+ if (wi < 0xF) {
+ float n = fmod(offset + (float)wi * offset2, N);
+ ray_input[i] = GenerateHemisphereRay(normal, tangent, bitangent, 1.0f, N, level, n);
+ }
+ else {
+ ray_input[i] = float2(MAX_RAY_POLAR_DIR, MAX_RAY_POLAR_DIR);
+ }
+ }
+ uint4 data = Pack4Float2ToI16(ray_input, MAX_RAY_POLAR_DIR);
+ ray_inputs[pixel] = data;
+ restir_pdf_mask[pixel] = restir_mask;
}
diff --git a/Engine/Engine/Core/Shaders/RayTrace/RayGIScreenSolverCS.hlsl b/Engine/Engine/Core/Shaders/RayTrace/RayGIScreenSolverCS.hlsl
new file mode 100644
index 0000000..bae8c01
--- /dev/null
+++ b/Engine/Engine/Core/Shaders/RayTrace/RayGIScreenSolverCS.hlsl
@@ -0,0 +1,192 @@
+/*
+The HotBite Game Engine
+
+Copyright(c) 2023 Vicente Sirvent Orts
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+#include "RayScreenSolver.hlsli"
+
+cbuffer externalData : register(b0)
+{
+ uint frame_count;
+ float time;
+ uint type;
+ float hiz_ratio;
+ uint divider;
+ int kernel_size;
+ float3 cameraPosition;
+ matrix view;
+ matrix projection;
+ matrix inv_projection;
+ matrix prev_view_proj;
+}
+
+#include "../Common/RayFunctions.hlsli"
+
+RWTexture2D ray_inputs: register(u0);
+RWTexture2D output : register(u1);
+RWTexture2D tiles_output: register(u2);
+RWTexture2D restir_pdf_1: register(u3);
+
+Texture2D ray0: register(t1);
+Texture2D ray1: register(t2);
+Texture2D colorTexture: register(t3);
+Texture2D lightTexture: register(t4);
+Texture2D bloomTexture: register(t5);
+Texture2D restir_pdf_mask: register(t6);
+Texture2D restir_pdf_0: register(t7);
+Texture2D restir_w_0: register(t11);
+
+Texture2D prev_position_map: register(t8);
+Texture2D hiz_textures[HIZ_TEXTURES];
+
+#define NTHREADS 11
+[numthreads(NTHREADS, NTHREADS, 1)]
+void main(uint3 DTid : SV_DispatchThreadID, uint3 group : SV_GroupID, uint3 thread : SV_GroupThreadID)
+{
+#if GI_SCREEN
+ float2 dimensions;
+ float2 ray_map_dimensions;
+ {
+ uint w, h;
+ output.GetDimensions(w, h);
+ dimensions.x = w;
+ dimensions.y = h;
+
+ ray0.GetDimensions(w, h);
+ ray_map_dimensions.x = w;
+ ray_map_dimensions.y = h;
+ }
+ float x = (float)DTid.x;
+ float y = (float)DTid.y;
+
+ float2 rayMapRatio = divider;
+
+ float2 pixel = float2(x, y);
+
+ float2 ray_pixel = round(pixel * rayMapRatio);
+
+ RaySource ray_source = fromColor(ray0[ray_pixel], ray1[ray_pixel]);
+
+ float2 color_uv = float2(0.0f, 0.0f);
+ float z_diff = FLT_MAX;
+
+ float hit_distance;
+ //Get rays to be solved in the pixel
+ float2 ray_input[4];
+ Unpack4Float2FromI16(ray_inputs[pixel], MAX_RAY_POLAR_DIR, ray_input);
+
+ float3 final_color = float3(0.0f, 0.0f, 0.0f);
+ float n = 0.0f;
+ float ratio = 0.0f;
+ ratio = ray_source.dispersion;
+
+ uint i = 0;
+ float pdf_cache[MAX_RAYS];
+ UnpackRays(restir_pdf_0[pixel], RAY_W_SCALE, pdf_cache);
+
+ float wis[MAX_RAYS];
+ int wis_size = 0;
+ uint mask = restir_pdf_mask[pixel];
+ for (i = 0; i < 4; ++i) {
+ uint wi = (mask & 0xF000) >> 12;
+ wis[wis_size++] = wi;
+ mask <<= 4;
+ }
+
+ for (i = 0; i < 4; ++i) {
+ uint wi = wis[i];
+ if (wi == 0xF) continue;
+
+ z_diff = FLT_MAX;
+ Ray ray = GetRayInfoFromSourceWithNoDir(ray_source);
+ if (abs(ray_input[i].x) < MAX_RAY_POLAR_DIR && dist2(ray_input[i]) > Epsilon) {
+ ray.dir = GetCartesianCoordinates(ray_input[i]);
+ ray.dir = normalize(mul(ray.dir, (float3x3)view));
+ ray.orig = mul(ray.orig, view);
+ ray.orig /= ray.orig.w;
+ ray.orig.xyz += ray.dir * 0.5f;
+ float reflex_ratio = (1.0f - ray_source.dispersion);
+ color_uv = GetColor(ray, projection, inv_projection, hiz_textures, hiz_ratio, ray_map_dimensions, dimensions, z_diff, hit_distance);
+
+ float max_diff = GetMaxDiff(hiz_textures[0], color_uv, ray_map_dimensions);
+ float3 color = float3(0.0f, 0.0f, 0.0f);
+ if (z_diff < max_diff && ValidUVCoord(color_uv)) {
+#if 1
+ float4 c = GetInterpolatedColor(color_uv, colorTexture, ray_map_dimensions);
+ float4 l = GetInterpolatedColor(color_uv, lightTexture, ray_map_dimensions);
+ float4 b = GetInterpolatedColor(color_uv, bloomTexture, ray_map_dimensions);
+#else
+ color_uv *= ray_map_dimensions;
+ float4 c = colorTexture[color_uv];
+ float4 l = lightTexture[color_uv];
+ float4 b = bloomTexture[color_uv];
+#endif
+ float diff_ratio = (z_diff / 0.05f);
+ //Disable world resolve
+ ray_input[i] = float2(FLT_MAX, FLT_MAX);
+ color = ((c * l + b) * ray_source.opacity).rgb;
+
+ //Do not paint scan ray
+ if (i < 3) {
+ final_color += color;
+ n += pdf_cache[wi];
+ }
+ }
+ pdf_cache[wi] = RAY_W_BIAS + length(color);
+
+ //Disable world resolve if hit distance is greater than 20
+ if (hit_distance > 10.0f) {
+ ray_input[i] = float2(FLT_MAX, FLT_MAX);
+ }
+ }
+ }
+ float w_ratio = 1.0f;
+ if (n > 0) {
+ final_color = (final_color * ray_source.opacity);
+ w_ratio = restir_w_0[pixel] / n;
+ }
+
+ restir_pdf_1[pixel] = PackRays(pdf_cache, RAY_W_SCALE);
+
+ float4 prev_pos = mul(prev_position_map[ray_pixel], prev_view_proj);
+ prev_pos.x /= prev_pos.w;
+ prev_pos.y /= -prev_pos.w;
+ prev_pos.xy = (prev_pos.xy + 1.0f) * 0.5f;
+ float w = 0.2f;
+ float4 prev_color = GetInterpolatedColor(prev_pos.xy, output, dimensions);
+
+ output[pixel] = lerp(prev_color, float4(sqrt(final_color * w_ratio / 3) , 1.0f), w);
+ //output[pixel] = float4(sqrt(final_color * w_ratio / 3), 1.0f);
+ ray_inputs[pixel] = Pack4Float2ToI16(ray_input, MAX_RAY_POLAR_DIR);
+
+ if (n > 0) {
+ [unroll]
+ for (int x = -2; x <= 2; ++x) {
+ [unroll]
+ for (int y = -2; y <= 2; ++y) {
+ int2 p = pixel / kernel_size + int2(x, y);
+ tiles_output[p] = 1;
+ }
+ }
+ }
+#endif
+
+}
diff --git a/Engine/Engine/Core/Shaders/RayTrace/RayGIWorldSolverCS.hlsl b/Engine/Engine/Core/Shaders/RayTrace/RayGIWorldSolverCS.hlsl
new file mode 100644
index 0000000..cec9329
--- /dev/null
+++ b/Engine/Engine/Core/Shaders/RayTrace/RayGIWorldSolverCS.hlsl
@@ -0,0 +1,187 @@
+/*
+The HotBite Game Engine
+
+Copyright(c) 2023 Vicente Sirvent Orts
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include "../Common/ShaderStructs.hlsli"
+#include "../Common/PixelCommon.hlsli"
+#include "../Common/RayDefines.hlsli"
+#include "../Common/RGBANoise.hlsli"
+
+#define REFLEX_ENABLED 1
+#define REFRACT_ENABLED 2
+#define USE_OBH 0
+
+cbuffer externalData : register(b0)
+{
+ uint frame_count;
+ float time;
+ uint enabled;
+ int kernel_size;
+ float3 cameraPosition;
+
+ //Lights
+ AmbientLight ambientLight;
+ DirLight dirLights[MAX_LIGHTS];
+ PointLight pointLights[MAX_LIGHTS];
+ uint dirLightsCount;
+ uint pointLightsCount;
+
+ float4 LightPerspectiveValues[MAX_LIGHTS / 2];
+ matrix DirPerspectiveMatrix[MAX_LIGHTS];
+}
+
+cbuffer objectData : register(b1)
+{
+ uint nobjects;
+ ObjectInfo objectInfos[MAX_OBJECTS];
+ MaterialColor objectMaterials[MAX_OBJECTS];
+}
+
+RWTexture2D output : register(u0);
+RWTexture2D tiles_output: register(u2);
+RWTexture2D restir_pdf_1: register(u3);
+
+Texture2D restir_pdf_0: register(t7);
+Texture2D ray0;
+Texture2D ray1;
+Texture2D ray_inputs: register(t0);
+
+Texture2D restir_pdf_mask: register(t6);
+Texture2D restir_w_0: register(t11);
+
+StructuredBuffer objects: register(t2);
+StructuredBuffer objectBVH: register(t3);
+
+Texture2D DirShadowMapTexture[MAX_LIGHTS];
+TextureCube PointShadowMapTexture[MAX_LIGHTS];
+
+//Packed array
+static float2 lps[MAX_LIGHTS] = (float2[MAX_LIGHTS])LightPerspectiveValues;
+
+#include "../Common/SimpleLight.hlsli"
+#include "../Common/RayFunctions.hlsli"
+#include "RayWorldSolver.hlsli"
+
+#define NTHREADS 11
+
+[numthreads(NTHREADS, NTHREADS, 1)]
+void main(uint3 DTid : SV_DispatchThreadID, uint3 group : SV_GroupID, uint3 thread : SV_GroupThreadID)
+{
+#if GI_WORLD
+ float2 dimensions;
+ float2 ray_map_dimensions;
+ {
+ uint w, h;
+ output.GetDimensions(w, h);
+ dimensions.x = w;
+ dimensions.y = h;
+
+ ray0.GetDimensions(w, h);
+ ray_map_dimensions.x = w;
+ ray_map_dimensions.y = h;
+ }
+ float x = (float)DTid.x;
+ float y = (float)DTid.y;
+
+ float2 rayMapRatio = ray_map_dimensions / dimensions;
+
+ float2 pixel = float2(x, y);
+
+
+ float2 ray_pixel = round(pixel * rayMapRatio);
+
+ RaySource ray_source = fromColor(ray0[ray_pixel], ray1[ray_pixel]);
+
+ float4 color_reflex = float4(0.0f, 0.0f, 0.0f, 1.0f);
+ float4 color_refrac = float4(0.0f, 0.0f, 0.0f, 1.0f);
+ uint2 hits = uint2(0, 0);
+ Ray ray = GetRayInfoFromSourceWithNoDir(ray_source);
+ float3 orig = ray.orig.xyz;
+
+ //Get rays to be solved in the pixel
+ RayTraceColor rc;
+ float2 ray_input[4];
+ Unpack4Float2FromI16(ray_inputs[pixel], MAX_RAY_POLAR_DIR, ray_input);
+ float reflex_ratio = (1.0f - ray_source.dispersion);
+
+ float pdf_cache[MAX_RAYS];
+ UnpackRays(restir_pdf_1[pixel], RAY_W_SCALE, pdf_cache);
+ uint i = 0;
+
+ float wis[MAX_RAYS];
+ uint mask = restir_pdf_mask[pixel];
+ for (i = 0; i < 4; ++i) {
+ uint wi = (mask & 0xF000) >> 12;
+ wis[i] = wi;
+ mask <<= 4;
+ }
+
+ float n = 0.0f;
+ float4 final_color = float4(0.0f, 0.0f, 0.0f, 1.0f);
+ for (i = 0; i < 4; ++i) {
+ uint wi = wis[i];
+ if (wi == 0xF) continue;
+
+ Ray ray = GetRayInfoFromSourceWithNoDir(ray_source);
+ ray.dir = GetCartesianCoordinates(ray_input[i]);
+ ray.orig.xyz += ray.dir * 0.05f;
+ if (abs(ray_input[i].x) < MAX_RAY_POLAR_DIR && dist2(ray_input[i]) > Epsilon) {
+ ray.orig.xyz += ray.dir * 0.5f;
+ if (GetColor(ray, 0, rc, ray_source.dispersion, false)) {
+ hits.x = rc.hit != 0;
+ if (i < 3) {
+ final_color.rgb += rc.color.rgb;
+ n += pdf_cache[wi];
+ }
+ }
+ pdf_cache[wi] = RAY_W_BIAS + length(rc.color.rgb);
+ }
+ }
+ float w_ratio = 1.0f;
+ if (n > Epsilon) {
+ final_color = (final_color * ray_source.opacity);
+ w_ratio = restir_w_0[pixel] / n;
+#if GI_SCREEN
+ float4 gi_screen_color = output[pixel];
+ final_color = ((final_color * w_ratio) / 3);
+ gi_screen_color.rgb += final_color.rgb;
+ output[pixel] = gi_screen_color;
+#endif
+ }
+#if !GI_SCREEN
+ output[pixel] = ((final_color * w_ratio) / 3);
+#endif
+ restir_pdf_1[pixel] = PackRays(pdf_cache, RAY_W_SCALE);
+
+ uint hit = (hits.y & 0x01) << 1 | (hits.x & 0x01);
+ if (hit != 0) {
+ for (int x = -2; x <= 2; ++x) {
+ for (int y = -2; y <= 2; ++y) {
+ int2 p = pixel / kernel_size + int2(x, y);
+ tiles_output[p] = tiles_output[p] | hit;
+ }
+ }
+ }
+#endif
+}
+
\ No newline at end of file
diff --git a/Engine/Engine/Core/Shaders/RayTrace/RayReflexScreenSolverCS.hlsl b/Engine/Engine/Core/Shaders/RayTrace/RayReflexScreenSolverCS.hlsl
new file mode 100644
index 0000000..c364674
--- /dev/null
+++ b/Engine/Engine/Core/Shaders/RayTrace/RayReflexScreenSolverCS.hlsl
@@ -0,0 +1,139 @@
+/*
+The HotBite Game Engine
+
+Copyright(c) 2023 Vicente Sirvent Orts
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+#include "RayScreenSolver.hlsli"
+
+cbuffer externalData : register(b0)
+{
+ uint frame_count;
+ float time;
+ uint type;
+ float hiz_ratio;
+ uint divider;
+ int kernel_size;
+ float3 cameraPosition;
+ matrix view;
+ matrix projection;
+ matrix inv_projection;
+}
+
+#include "../Common/RayFunctions.hlsli"
+
+RWTexture2D ray_inputs: register(u0);
+RWTexture2D output : register(u1);
+RWTexture2D tiles_output: register(u2);
+
+Texture2D ray0: register(t1);
+Texture2D ray1: register(t2);
+Texture2D colorTexture: register(t3);
+Texture2D lightTexture: register(t4);
+Texture2D bloomTexture: register(t5);
+
+Texture2D hiz_textures[HIZ_TEXTURES];
+
+#define NTHREADS 16
+[numthreads(NTHREADS, NTHREADS, 1)]
+void main(uint3 DTid : SV_DispatchThreadID, uint3 group : SV_GroupID, uint3 thread : SV_GroupThreadID)
+{
+#if REFLEX_SCREEN
+ float2 dimensions;
+ float2 ray_map_dimensions;
+ {
+ uint w, h;
+ output.GetDimensions(w, h);
+ dimensions.x = w;
+ dimensions.y = h;
+
+ ray0.GetDimensions(w, h);
+ ray_map_dimensions.x = w;
+ ray_map_dimensions.y = h;
+ }
+ float x = (float)DTid.x;
+ float y = (float)DTid.y;
+
+ float2 rayMapRatio = divider;
+
+ float2 pixel = float2(x, y);
+
+ float2 ray_pixel = round(pixel * rayMapRatio);
+
+ RaySource ray_source = fromColor(ray0[ray_pixel], ray1[ray_pixel]);
+
+ float2 color_uv = float2(0.0f, 0.0f);
+ float z_diff = FLT_MAX;
+
+ float hit_distance;
+ //Get rays to be solved in the pixel
+ float2 ray_input[4];
+ Unpack4Float2FromI16(ray_inputs[pixel], MAX_RAY_POLAR_DIR, ray_input);
+
+ float3 final_color = float3(0.0f, 0.0f, 0.0f);
+ float n = 0.0f;
+ float ratio = 0.0f;
+ ratio = (1.0f - ray_source.dispersion);
+
+ //Only work with 1 ray for DI
+ float reflex_ratio = (1.0f - ray_source.dispersion);
+ z_diff = FLT_MAX;
+ Ray ray = GetRayInfoFromSourceWithNoDir(ray_source);
+ if (abs(ray_input[0].x) < MAX_RAY_POLAR_DIR && dist2(ray_input[0]) > Epsilon) {
+ ray.dir = GetCartesianCoordinates(ray_input[0]);
+ ray.dir = normalize(mul(ray.dir, (float3x3)view));
+ ray.orig = mul(ray.orig, view);
+ ray.orig /= ray.orig.w;
+ ray.orig.xyz += ray.dir * 0.1f;
+ float reflex_ratio = (1.0f - ray_source.dispersion);
+ color_uv = GetColor(ray, projection, inv_projection, hiz_textures, hiz_ratio, ray_map_dimensions, dimensions, z_diff, hit_distance);
+
+ float max_diff = GetMaxDiff(hiz_textures[0], color_uv, ray_map_dimensions);
+ if (z_diff < max_diff && ValidUVCoord(color_uv)) {
+#if 0
+ float4 c = GetInterpolatedColor(color_uv, colorTexture, ray_map_dimensions);
+ float4 l = GetInterpolatedColor(color_uv, lightTexture, ray_map_dimensions);
+ float4 b = GetInterpolatedColor(color_uv, bloomTexture, ray_map_dimensions);
+#else
+ color_uv *= ray_map_dimensions;
+ float4 c = colorTexture[color_uv];
+ float4 l = lightTexture[color_uv];
+ float4 b = bloomTexture[color_uv];
+#endif
+ ray_input[0] = float2(FLT_MAX, FLT_MAX);
+ final_color += ((c * l + b) * reflex_ratio * ray_source.opacity).rgb;
+ n++;
+ }
+ }
+ output[pixel] = float4(sqrt(final_color), 1.0f);
+
+ if (n > 0) {
+ [unroll]
+ for (int x = -2; x <= 2; ++x) {
+ [unroll]
+ for (int y = -2; y <= 2; ++y) {
+ int2 p = pixel / kernel_size + int2(x, y);
+ tiles_output[p] = 1;
+ }
+ }
+ }
+ ray_inputs[pixel] = Pack4Float2ToI16(ray_input, MAX_RAY_POLAR_DIR);
+#endif
+}
diff --git a/Engine/Engine/Core/Shaders/RayTrace/RayReflexWorldSolverCS.hlsl b/Engine/Engine/Core/Shaders/RayTrace/RayReflexWorldSolverCS.hlsl
new file mode 100644
index 0000000..509e72b
--- /dev/null
+++ b/Engine/Engine/Core/Shaders/RayTrace/RayReflexWorldSolverCS.hlsl
@@ -0,0 +1,176 @@
+/*
+The HotBite Game Engine
+
+Copyright(c) 2023 Vicente Sirvent Orts
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include "../Common/ShaderStructs.hlsli"
+#include "../Common/PixelCommon.hlsli"
+#include "../Common/RayDefines.hlsli"
+#include "../Common/RGBANoise.hlsli"
+
+#define REFLEX_ENABLED 1
+#define REFRACT_ENABLED 2
+#define USE_OBH 0
+
+cbuffer externalData : register(b0)
+{
+ uint frame_count;
+ float time;
+ uint enabled;
+ int kernel_size;
+ float3 cameraPosition;
+ uint type;
+
+ //Lights
+ AmbientLight ambientLight;
+ DirLight dirLights[MAX_LIGHTS];
+ PointLight pointLights[MAX_LIGHTS];
+ uint dirLightsCount;
+ uint pointLightsCount;
+
+ float4 LightPerspectiveValues[MAX_LIGHTS / 2];
+ matrix DirPerspectiveMatrix[MAX_LIGHTS];
+}
+
+cbuffer objectData : register(b1)
+{
+ uint nobjects;
+ ObjectInfo objectInfos[MAX_OBJECTS];
+ MaterialColor objectMaterials[MAX_OBJECTS];
+}
+
+RWTexture2D output0 : register(u0);
+RWTexture2D output1 : register(u1);
+RWTexture2D tiles_output: register(u2);
+RWTexture2D restir_pdf_1: register(u3);
+
+Texture2D restir_pdf_0: register(t7);
+Texture2D ray0;
+Texture2D ray1;
+Texture2D ray_inputs: register(t0);
+
+Texture2D restir_pdf_mask: register(t6);
+Texture2D restir_w_0: register(t11);
+
+StructuredBuffer objects: register(t2);
+StructuredBuffer objectBVH: register(t3);
+
+Texture2D DirShadowMapTexture[MAX_LIGHTS];
+TextureCube PointShadowMapTexture[MAX_LIGHTS];
+
+//Packed array
+static float2 lps[MAX_LIGHTS] = (float2[MAX_LIGHTS])LightPerspectiveValues;
+
+#include "../Common/SimpleLight.hlsli"
+#include "../Common/RayFunctions.hlsli"
+#include "RayWorldSolver.hlsli"
+
+#define NTHREADS 11
+
+[numthreads(NTHREADS, NTHREADS, 1)]
+void main(uint3 DTid : SV_DispatchThreadID, uint3 group : SV_GroupID, uint3 thread : SV_GroupThreadID)
+{
+#if REFLEX_WORLD
+ float2 dimensions;
+ float2 ray_map_dimensions;
+ {
+ uint w, h;
+ output0.GetDimensions(w, h);
+ dimensions.x = w;
+ dimensions.y = h;
+
+ ray0.GetDimensions(w, h);
+ ray_map_dimensions.x = w;
+ ray_map_dimensions.y = h;
+ }
+ float x = (float)DTid.x;
+ float y = (float)DTid.y;
+
+ float2 rayMapRatio = ray_map_dimensions / dimensions;
+
+ float2 pixel = float2(x, y);
+
+
+ float2 ray_pixel = round(pixel * rayMapRatio);
+
+ RaySource ray_source = fromColor(ray0[ray_pixel], ray1[ray_pixel]);
+
+ float4 color_reflex = float4(0.0f, 0.0f, 0.0f, 1.0f);
+ float4 color_refrac = float4(0.0f, 0.0f, 0.0f, 1.0f);
+ uint2 hits = uint2(0, 0);
+ Ray ray = GetRayInfoFromSourceWithNoDir(ray_source);
+ float3 orig = ray.orig.xyz;
+
+ //Get rays to be solved in the pixel
+ RayTraceColor rc;
+ float2 ray_input[4];
+ Unpack4Float2FromI16(ray_inputs[pixel], MAX_RAY_POLAR_DIR, ray_input);
+ float reflex_ratio = (1.0f - ray_source.dispersion);
+
+#if 1
+#if !REFLEX_SCREEN
+ output0[pixel] = float4(0.0f, 0.0f, 0.0f, 1.0f);
+#endif
+ if (abs(ray_input[0].x) < MAX_RAY_POLAR_DIR) {
+ if (dist2(ray_input[0]) <= Epsilon) {
+ color_reflex.rgb = float3(1.0f, 0.0f, 0.0f);
+ }
+ else {
+ ray.dir = GetCartesianCoordinates(ray_input[0]);
+ ray.orig.xyz = orig + ray.dir * 0.01f;
+ GetColor(ray, 0, rc, ray_source.dispersion, false);
+ color_reflex.rgb += rc.color * reflex_ratio * ray_source.opacity;
+ hits.x = rc.hit != 0;
+ }
+ output0[pixel] = color_reflex;
+ }
+#endif
+#if 1
+ if (abs(ray_input[1].x) < MAX_RAY_POLAR_DIR) {
+ if (dist2(ray_input[1]) <= Epsilon) {
+ color_reflex.rgb = float3(1.0f, 0.0f, 0.0f);
+ }
+ else {
+ ray.dir = GetCartesianCoordinates(ray_input[1]);
+ ray.orig.xyz = orig + ray.dir * 0.01f;
+
+ GetColor(ray, 0, rc, ray_source.dispersion, true);
+ color_refrac.rgb += rc.color * (1.0f - ray_source.opacity);
+ hits.y = rc.hit != 0;
+ }
+ output1[pixel] = color_refrac;
+ }
+#endif
+
+ uint hit = (hits.y & 0x01) << 1 | hits.x & 0x01;
+ if (hit != 0) {
+ [unroll]
+ for (int x = -2; x <= 2; ++x) {
+ [unroll]
+ for (int y = -2; y <= 2; ++y) {
+ int2 p = pixel / kernel_size + int2(x, y);
+ tiles_output[p] = tiles_output[p] | hit;
+ }
+ }
+ }
+#endif
+}
diff --git a/Engine/Engine/Core/Shaders/RayTrace/RayScreenSolver.hlsli b/Engine/Engine/Core/Shaders/RayTrace/RayScreenSolver.hlsli
new file mode 100644
index 0000000..9931d6c
--- /dev/null
+++ b/Engine/Engine/Core/Shaders/RayTrace/RayScreenSolver.hlsli
@@ -0,0 +1,200 @@
+/*
+The HotBite Game Engine
+
+Copyright(c) 2023 Vicente Sirvent Orts
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+#include "../Common/ShaderStructs.hlsli"
+#include "../Common/PixelCommon.hlsli"
+#include "../Common/RayDefines.hlsli"
+#include "../Common/RGBANoise.hlsli"
+
+#define HIZ_TEXTURES 4
+
+struct Line {
+ float3 P0; // Point on the line
+ float3 d; // Direction vector of the line
+};
+
+struct Plane {
+ float3 Q; // Point on the plane
+ float3 n; // Normal vector of the plane
+};
+
+float3 IntersectLinePlane(Line l, Plane p) {
+ float3 P0 = l.P0;
+ float3 d = l.d;
+ float3 Q = p.Q;
+ float3 n = p.n;
+
+ float denom = dot(n, d);
+ denom = max(abs(denom), 1e-6) * sign(denom);
+ float t = dot(n, Q - P0) / denom;
+ return (P0 + t * d);
+}
+
+float GetRayDepth(in matrix inv_projection, Plane rayPlane, float2 grid_pos, out float3 intersection_point) {
+ float4 H = float4(grid_pos.x * 2.0f - 1.0f, (1.0f - grid_pos.y) * 2.0f - 1.0f, 0.0f, 1.0f);
+ float4 D = mul(H, inv_projection);
+ float4 eyepos = D / D.w;
+
+ Line eyeLine;
+ eyeLine.P0 = eyepos.xyz;
+ eyeLine.d = eyepos.xyz;
+ intersection_point = IntersectLinePlane(eyeLine, rayPlane);
+ return length(intersection_point);
+}
+
+float2 GetNextGrid(float2 dir, float2 pixel) {
+ float2 p0 = pixel;
+ float2 invDir = 1.0f / dir;
+ float2 currentGrid = floor(p0);
+ float2 nextGrid;
+
+ // Calculate initial intersection points with the grid lines
+ nextGrid.x = currentGrid.x + sign(dir.x);
+ nextGrid.y = currentGrid.y + sign(dir.y);
+
+ // Calculate the step size to the next grid for x and y
+ float2 tMax;
+ tMax.x = (nextGrid.x - p0.x) * invDir.x;
+ tMax.y = (nextGrid.y - p0.y) * invDir.y;
+
+ if (tMax.x < tMax.y) {
+ return float2(nextGrid.x, p0.y + (nextGrid.x - p0.x) * dir.y / dir.x);
+ }
+ else {
+ return float2(p0.x + (nextGrid.y - p0.y) * dir.x / dir.y, nextGrid.y);
+ }
+}
+
+float GetHiZ(Texture2D hiz_textures[HIZ_TEXTURES], uint level, float2 pixel) {
+ switch (level) {
+ case 0: return hiz_textures[0][pixel];
+ case 1: return hiz_textures[1][pixel];
+ case 2: return hiz_textures[2][pixel];
+ case 3: return hiz_textures[3][pixel];
+ }
+ return FLT_MAX;
+}
+
+float2 GetColor(Ray ray, in matrix projection, in matrix inv_projection, Texture2D hiz_textures[HIZ_TEXTURES], float hiz_ratio, float2 depth_dimensions, float2 output_dimensions, out float z_diff, out float hit_distance) {
+
+ float4 pixel0 = mul(ray.orig, projection);
+ pixel0 /= pixel0.w;
+ pixel0.y *= -1.0f;
+ pixel0.xy = (pixel0.xy + 1.0f) * 0.5f;
+ float2 pStartProj = pixel0.xy;
+
+ float4 p1 = ray.orig;
+ p1.xyz += ray.dir;
+
+ float4 pixel1 = mul(p1, projection);
+ pixel1 /= pixel1.w;
+ pixel1.y *= -1.0f;
+ pixel1.xy = (pixel1.xy + 1.0f) * 0.5f;
+ float2 pEndProj = pixel1.xy;
+
+ float2 dir = normalize((pixel1.xy - pStartProj) * depth_dimensions);
+
+
+ float2 screen_pixel = pixel0.xy * depth_dimensions;
+ float3 color = float3(0.0f, 0.0f, 0.0f);
+ int current_level = HIZ_TEXTURES - 1;
+ float current_divider = pow(hiz_ratio, current_level);
+
+ float2 grid_pixel = screen_pixel / current_divider;
+ float2 grid_pos = pixel0.xy;
+ float2 last_valid_grid_pos = grid_pos;
+
+ float grid_high_z = 0.0f;
+
+ float3 intersection_point;
+
+ float ray_z = 0.0f;
+
+ float n = 0.0f;
+
+ float3 up = float3(0.0f, 1.0f, 0.0f);
+ float3 normal = normalize(cross(up, ray.dir));
+ float2 grid_size = current_divider / depth_dimensions;
+
+ Plane rayPlane;
+ rayPlane.Q = ray.orig.xyz;
+ rayPlane.n = normal;
+
+ z_diff = FLT_MAX;
+ hit_distance = FLT_MAX;
+
+ while (current_level >= 0) {
+ //Calculate ray z, grid_pos in NDC coords
+
+ grid_pos = grid_pixel * grid_size;
+ if (!ValidUVCoord(grid_pos)) {
+ return float2(-1, -1);
+ }
+ grid_high_z = GetHiZ(hiz_textures, current_level, grid_pixel);
+ ray_z = GetRayDepth(inv_projection, rayPlane, grid_pos, intersection_point);
+ if (grid_high_z <= ray_z) {
+ current_level--;
+ current_divider = pow(hiz_ratio, current_level);
+ grid_pos = last_valid_grid_pos;
+ grid_size = current_divider / depth_dimensions;
+ grid_pixel = (grid_pos * depth_dimensions) / current_divider;
+ }
+ last_valid_grid_pos = grid_pos;
+ grid_pixel = GetNextGrid(dir, grid_pixel);
+ }
+
+ z_diff = abs(ray_z - grid_high_z);
+ hit_distance = length(intersection_point - ray.orig.xyz);
+
+ return last_valid_grid_pos + dir * grid_size * 0.5f;
+}
+
+//Max diff depends on the distance gap between adyacent pixels and distance to camera
+float GetMaxDiff(in Texture2D hiz_texture, float2 uv, float2 dimension) {
+ float2 texCoords = uv * dimension;
+
+ int2 p00 = (int2)floor(texCoords);
+ int2 p11 = (int2)ceil(texCoords);
+ int2 p01 = int2(p00.x, p11.y);
+ int2 p10 = int2(p11.x, p00.y);
+
+ p00 += int2(-1, -1);
+ p11 += int2(1, 1);
+ p01 += int2(-1, 1);
+ p10 += int2(1, -1);
+
+ float z00 = (hiz_texture[p00]);
+ float z11 = (hiz_texture[p11]);
+ float z01 = (hiz_texture[p10]);
+ float z10 = (hiz_texture[p01]);
+
+ float d00_11 = abs(z00 - z11);
+ float d00_10 = abs(z00 - z10);
+ float d00_01 = abs(z00 - z01);
+ float d11_01 = abs(z11 - z01);
+ float d11_10 = abs(z11 - z10);
+ float d01_10 = abs(z01 - z10);
+
+ float diff = min(max(d00_11, max(d00_10, max(d00_01, max(d11_01, max(d11_10, d01_10))))), 0.299f);
+ return saturate(0.3f - diff);
+}
diff --git a/Engine/Engine/Core/Shaders/RayTrace/RayTraceCS.hlsl b/Engine/Engine/Core/Shaders/RayTrace/RayTraceCS.hlsl
index 473f491..48a60d4 100644
--- a/Engine/Engine/Core/Shaders/RayTrace/RayTraceCS.hlsl
+++ b/Engine/Engine/Core/Shaders/RayTrace/RayTraceCS.hlsl
@@ -34,452 +34,81 @@ SOFTWARE.
cbuffer externalData : register(b0)
{
uint frame_count;
+ uint enabled;
+ uint divider;
float time;
float3 cameraPosition;
- float3 cameraDirection;
- uint enabled;
-
- //Lights
- AmbientLight ambientLight;
- DirLight dirLights[MAX_LIGHTS];
- PointLight pointLights[MAX_LIGHTS];
- uint dirLightsCount;
- uint pointLightsCount;
-
- float4 LightPerspectiveValues[MAX_LIGHTS / 2];
- matrix DirPerspectiveMatrix[MAX_LIGHTS];
}
-cbuffer objectData : register(b1)
-{
- uint nobjects;
- ObjectInfo objectInfos[MAX_OBJECTS];
- MaterialColor objectMaterials[MAX_OBJECTS];
-}
-
-RWTexture2D output0 : register(u0);
-RWTexture2D output1 : register(u1);
-RWTexture2D dispersion : register(u3);
-RWTexture2D bloom : register(u7);
-
-Texture2D ray0;
-Texture2D ray1;
-
-StructuredBuffer objects: register(t2);
-StructuredBuffer objectBVH: register(t3);
-
-ByteAddressBuffer vertexBuffer : register(t4);
-ByteAddressBuffer indicesBuffer : register(t5);
-Texture2D position_map : register(t6);
-Texture2D motion_texture : register(t8);
-
-Texture2D DiffuseTextures[MAX_OBJECTS];
-Texture2D DirShadowMapTexture[MAX_LIGHTS];
-TextureCube PointShadowMapTexture[MAX_LIGHTS];
+Texture2D ray0: register(t0);
+Texture2D ray1: register(t1);
+RWTexture2D ray_inputs: register(u0);
-//Packed array
-static float2 lps[MAX_LIGHTS] = (float2[MAX_LIGHTS])LightPerspectiveValues;
-
-#include "../Common/SimpleLight.hlsli"
+#include "../Common/Utils.hlsli"
#include "../Common/RayFunctions.hlsli"
-#define max_distance 100.0f
-
-float3 GenerateHemisphereRay(float3 dir, float3 tangent, float3 bitangent, float dispersion, float N, float NLevels, float rX)
-{
- float index = rX * N * dispersion;
-
- // First point at the top (up direction)
- if (index < 1.0f) {
- return dir; // The first point is directly at the top
- }
-
- float cumulativePoints = 1;
- float level = 1;
- while (true) {
- float c = cumulativePoints + level * 2;
- if (c < index) {
- cumulativePoints = c;
- }
- else {
- break;
- }
- level++;
- };
-
- float pointsAtLevel = level * 2; // Quadratic growth
-
- // Calculate local index within the current level
- float localIndex = index - cumulativePoints;
-
- float phi = level / NLevels * M_PI * (0.4 + rX);
-
- // Azimuthal angle (theta) based on number of points at this level
- float theta = (2.0f * M_PI + rX) * localIndex / pointsAtLevel; // Spread points evenly in azimuthal direction
-
- // Convert spherical coordinates to Cartesian coordinates
- float sinPhi = sin(phi);
- float cosPhi = cos(phi);
- float sinTheta = sin(theta);
- float cosTheta = cos(theta);
-
- // Local ray direction in spherical coordinates
- float3 localRay = float3(sinPhi * cosTheta, sinPhi * sinTheta, cosPhi);
-
- // Convert local ray to global coordinates (tangent space to world space)
- float3 globalRay = localRay.x * tangent + localRay.y * bitangent + localRay.z * dir;
-
-
- return normalize(dir + globalRay);
-}
-
static float NCOUNT = 32.0f;
static uint N2 = 32;
static float N = N2 * NCOUNT;
+static float max_distance = 50.0f;
+#define NTHREADS 32
-struct RayTraceColor {
- float3 color[2];
- float dispersion[2];
- float3 bloom;
- bool hit;
-};
-
-bool GetColor(Ray origRay, float rX, float level, uint max_bounces, out RayTraceColor out_color, float dispersion, bool mix, bool refract)
+[numthreads(NTHREADS, NTHREADS, 1)]
+void main(uint3 DTid : SV_DispatchThreadID, uint3 group : SV_GroupID, uint3 thread : SV_GroupThreadID)
{
- out_color.color[0] = float3(0.0f, 0.0f, 0.0f);
- out_color.color[1] = float3(0.0f, 0.0f, 0.0f);
- out_color.bloom = float3(0.0f, 0.0f, 0.0f);
- out_color.dispersion[0] = -1.0f;
- out_color.dispersion[1] = -1.0f;
-
- float last_dispersion = dispersion;
- float acc_dispersion = dispersion;
- float collision_dist = 0.0f;
- float att_dist = 0.0f;
-#if USE_OBH
- uint volumeStack[MAX_STACK_SIZE];
-#endif
- uint stack[MAX_STACK_SIZE];
- RayObject oray;
- IntersectionResult object_result;
-
- bool collide = false;
- IntersectionResult result;
- Ray ray = origRay;
- bool end = false;
-
- for (uint bounce = 0; !end; ++bounce)
+ float2 ray_input_dimension;
+ float2 ray_map_dimensions;
{
- result.distance = FLT_MAX;
- end = true;
- collide = false;
-#if USE_OBH
- uint volumeStackSize = 0;
- volumeStack[volumeStackSize++] = 0;
- uint i = 0;
- while (volumeStackSize > 0 && volumeStackSize < MAX_STACK_SIZE)
- {
-#else
- for (uint i = 0; i < nobjects; ++i)
- {
- uint objectIndex = i;
-#endif
-
-#if USE_OBH
- uint currentVolume = volumeStack[--volumeStackSize];
-
- BVHNode volumeNode = objectBVH[currentVolume];
- if (is_leaf(volumeNode))
- {
- uint objectIndex = index(volumeNode);
- ObjectInfo o = objectInfos[objectIndex];
-
- float objectExtent = length(o.aabb_max - o.aabb_min);
- float distanceToObject = length(o.position - origRay.orig.xyz) - objectExtent;
-
- if (distanceToObject < max_distance && distanceToObject < result.distance && IntersectAABB(ray, o.aabb_min, o.aabb_max))
- {
-#else
- ObjectInfo o = objectInfos[i];
- float objectExtent = length(o.aabb_max - o.aabb_min);
- float distanceToObject = length(o.position - origRay.orig.xyz) - objectExtent;
- if (distanceToObject < max_distance && distanceToObject < result.distance && IntersectAABB(ray, o.aabb_min, o.aabb_max))
- {
-#endif
- object_result.distance = FLT_MAX;
-
- // Transform the ray direction from world space to object space
- oray.orig = mul(ray.orig, o.inv_world);
- oray.orig /= oray.orig.w;
- oray.dir = normalize(mul(ray.dir, (float3x3) o.inv_world));
- oray.t = FLT_MAX;
-
- uint stackSize = 0;
- stack[stackSize++] = 0;
-
- while (stackSize > 0 && stackSize < MAX_STACK_SIZE)
- {
- uint current = stack[--stackSize];
-
- BVHNode node = objects[o.objectOffset + current];
- if (is_leaf(node))
- {
- float t;
- uint idx = index(node);
- idx += o.indexOffset;
-
- IntersectionResult tmp_result;
- tmp_result.distance = FLT_MAX;
- if (IntersectTri(oray, idx, o.vertexOffset, tmp_result))
- {
- if (tmp_result.distance < object_result.distance) {
- object_result.v0 = tmp_result.v0;
- object_result.v1 = tmp_result.v1;
- object_result.v2 = tmp_result.v2;
- object_result.vindex = tmp_result.vindex;
- object_result.distance = tmp_result.distance;
- object_result.uv = tmp_result.uv;
- object_result.object = objectIndex;
- }
- }
- }
- else if (IntersectAABB(oray, node))
- {
- stack[stackSize++] = left_child(node);
- stack[stackSize++] = right_child(node);
- }
- }
-
- if (object_result.distance < FLT_MAX) {
- float3 opos = (1.0f - object_result.uv.x - object_result.uv.y) * object_result.v0 + object_result.uv.x * object_result.v1 + object_result.uv.y * object_result.v2;
- float4 pos = mul(float4(opos, 1.0f), o.world);
- float distance = length(pos - ray.orig);
- if (distance < result.distance)
- {
- collide = true;
- collision_dist = length(pos - ray.orig);
- ray.t = distance;
- result.v0 = object_result.v0;
- result.v1 = object_result.v1;
- result.v2 = object_result.v2;
- result.vindex = object_result.vindex;
- result.distance = distance;
- result.uv = object_result.uv;
- result.object = objectIndex;
- }
- }
- }
-#if USE_OBH
- }
- else if (IntersectAABB(ray, volumeNode)) {
- volumeStack[volumeStackSize++] = left_child(volumeNode);
- volumeStack[volumeStackSize++] = right_child(volumeNode);
- }
- ++i;
-#endif
- }
-
- //At this point we have the ray collision distance and a collision result
- if (collide) {
- // Calculate space position
- ObjectInfo o = objectInfos[result.object];
- float3 normal0 = asfloat(vertexBuffer.Load3(result.vindex.x + 12));
- float3 normal1 = asfloat(vertexBuffer.Load3(result.vindex.y + 12));
- float3 normal2 = asfloat(vertexBuffer.Load3(result.vindex.z + 12));
- float3 opos = (1.0f - result.uv.x - result.uv.y) * result.v0 + result.uv.x * result.v1 + result.uv.y * result.v2;
- float3 normal = (1.0f - result.uv.x - result.uv.y) * normal0 + result.uv.x * normal1 + result.uv.y * normal2;
- normal = normalize(mul(normal, (float3x3)o.world));
- float4 pos = mul(float4(opos, 1.0f), o.world);
- pos /= pos.w;
- MaterialColor material = objectMaterials[result.object];
-
- float3 color = float3(0.0f, 0.0f, 0.0f);
-
- color += CalcAmbient(normal) * 0.5f;
- color *= o.opacity;
-
- uint i = 0;
- for (i = 0; i < dirLightsCount; ++i) {
- color += CalcDirectional(normal, pos.xyz, dirLights[i], i);
- }
-
- // Calculate the point lights
- for (i = 0; i < pointLightsCount; ++i) {
- if (length(pos.xyz - pointLights[i].Position) < pointLights[i].Range) {
- color += CalcPoint(normal, pos.xyz, pointLights[i], i);
- }
- }
-
- //Calculate material color
- if (material.flags & DIFFUSSE_MAP_ENABLED_FLAG) {
- float2 uv0 = asfloat(vertexBuffer.Load2(result.vindex.x + 24));
- float2 uv1 = asfloat(vertexBuffer.Load2(result.vindex.y + 24));
- float2 uv2 = asfloat(vertexBuffer.Load2(result.vindex.z + 24));
- float2 uv = uv0 * (1.0f - result.uv.x - result.uv.y) + uv1 * result.uv.x + uv2 * result.uv.y;
- color *= GetDiffuseColor(result.object, uv);
- }
- else {
- color *= material.diffuseColor.rgb;
- }
-
- float3 emission = material.emission * material.emission_color;
- color += emission;
-
- float material_dispersion = saturate(1.0f - material.specIntensity);
- att_dist += collision_dist * material_dispersion;
- if (refract) {
- att_dist = 1.0f;
- }
- float curr_att_dist = max(att_dist, 1.0f);
- if (ray.bounces == 0 || mix) {
- out_color.color[0] += color * ray.ratio / curr_att_dist;
- out_color.dispersion[0] = acc_dispersion;
- if (!refract) {
- out_color.bloom += emission / curr_att_dist;
- }
- }
- else {
- out_color.color[1] += color * ray.ratio / curr_att_dist;
- out_color.dispersion[1] = acc_dispersion;
- }
- acc_dispersion += material_dispersion;
- last_dispersion = material_dispersion;
- ray.orig = pos;
- out_color.hit = true;
- //If not opaque surface, generate a refraction ray
- if (ray.bounces < 5 && o.opacity < 1.0f) {
- if (ray.bounces % 2 == 0) {
- normal = -normal;
- }
- ray = GetRefractedRayFromRay(ray, ray.density,
- ray.density != 1.0 ? 1.0f : o.density,
- normal, ray.ratio * (1.0f - o.opacity));
- end = false;
- }
+ uint w, h;
+ ray0.GetDimensions(w, h);
+ ray_map_dimensions.x = w;
+ ray_map_dimensions.y = h;
+ ray_input_dimension.x = w / divider;
+ ray_input_dimension.y = h / divider;
}
- else {
- //Color background
-
+ int i = 0;
+ float x = (float)DTid.x;
+ float y = (float)DTid.y;
+ float2 pixel = float2(x, y);
+ float2 ray_pixel = round(pixel * divider);
+
+ RaySource ray_source = fromColor(ray0[ray_pixel], ray1[ray_pixel]);
+
+ float3 orig_pos = ray_source.orig.xyz;
+ bool process = length(orig_pos - cameraPosition) < max_distance;
+
+ float3 normal;
+ float3 tangent;
+ float3 bitangent;
+ int count = 0;
+
+ float cumulativePoints = 0;
+ float level = NCOUNT;
+
+ float2 dirs[4];
+ for (i = 0; i < 4; ++i) {
+ dirs[i] = float2(MAX_RAY_POLAR_DIR, MAX_RAY_POLAR_DIR);
}
- }
-return out_color.hit;
- }
-
-#define DENSITY 1.0f
-#define NTHREADS 32
- [numthreads(NTHREADS, NTHREADS, 1)]
- void main(uint3 DTid : SV_DispatchThreadID, uint3 group : SV_GroupID, uint3 thread : SV_GroupThreadID)
+ //Reflected ray
+ if (ray_source.opacity > Epsilon && ray_source.dispersion < 1.0f && (enabled & REFLEX_ENABLED)) {
+ Ray ray = GetReflectedRayFromSource(ray_source, cameraPosition);
+ float3 seed = DTid + float3(frame_count, frame_count, frame_count);
+ float rX = rgba_tnoise(seed);
+ rX = pow(rX, 1.0f + (1.0f - ray_source.dispersion));
+ normal = ray.dir;
+ GetSpaceVectors(normal, tangent, bitangent);
+ dirs[0] = GenerateHemisphereDispersedRay(normal, tangent, bitangent, ray_source.dispersion, N, level, rX);
+
+ }
+ //Refracted ray
+ if (ray_source.opacity < 0.99f && (enabled & REFRACT_ENABLED)) {
+ Ray ray = GetRefractedRayFromSource(ray_source, cameraPosition);
+ if (dist2(ray.dir) > Epsilon)
{
- float2 dimensions;
- float2 ray_map_dimensions;
- float2 bloom_dimensions;
- {
- uint w, h;
- output0.GetDimensions(w, h);
- dimensions.x = w;
- dimensions.y = h;
-
- ray0.GetDimensions(w, h);
- ray_map_dimensions.x = w;
- ray_map_dimensions.y = h;
-
- bloom.GetDimensions(w, h);
- bloom_dimensions.x = w;
- bloom_dimensions.y = h;
- }
- float x = (float)DTid.x;
- float y = (float)DTid.y;
-
- float2 rayMapRatio = ray_map_dimensions / dimensions;
- float2 bloomRatio = bloom_dimensions / dimensions;
-
- float4 color_reflex = float4(0.0f, 0.0f, 0.0f, 1.0f);
- float4 color_reflex2 = float4(0.0f, 0.0f, 0.0f, 1.0f);
- float4 color_refrac = float4(0.0f, 0.0f, 0.0f, 1.0f);
-
- float2 pixel = float2(x, y);
-
- float2 ray_pixel = round(pixel * rayMapRatio);
-
- RaySource ray_source = fromColor(ray0[ray_pixel], ray1[ray_pixel]);
- if (ray_source.reflex <= Epsilon || dist2(ray_source.normal) <= Epsilon || ray_source.dispersion < 0.0f)
- {
- return;
- }
-
- //Reflected ray
- float3 orig_pos = ray_source.orig.xyz;
- bool process = length(orig_pos - cameraPosition) < max_distance;
-
- float3 tangent;
- float3 bitangent;
- RayTraceColor rc;
- Ray ray = GetReflectedRayFromSource(ray_source);
- if (dist2(ray.dir) > Epsilon)
- {
- float3 normal = ray_source.normal;
- float3 orig_dir = ray.dir;
- int count = 0;
-
- float cumulativePoints = 0;
- float level = 1;
- while (true) {
- float c = cumulativePoints + level * 2;
- if (c < N) {
- cumulativePoints = c;
- }
- else {
- break;
- }
- level++;
- };
-
- rc.hit = false;
+ dirs[1] = GetPolarCoordinates(ray.dir);
+ }
+ }
- if (DTid.z == 0) {
- float3 seed = orig_pos * 100.0f;
- float rX = rgba_tnoise(seed);
- rX = pow(rX, 5.0f);
- GetSpaceVectors(orig_dir, tangent, bitangent);
- ray.dir = GenerateHemisphereRay(orig_dir, tangent, bitangent, ray_source.dispersion, N, level, rX);
- ray.orig.xyz = orig_pos.xyz + ray.dir * 0.001f;
- float dist = FLT_MAX;
- if (GetColor(ray, rX, level, 0, rc, ray_source.dispersion, true, false)) {
- color_reflex.rgb += rc.color[0] * ray_source.opacity;
- color_reflex2.rgb += rc.color[1] * ray_source.opacity;
- }
- float2 rc_disp = float2(rc.dispersion[0], rc.dispersion[1]);
- float reflex_ratio = (1.0f - ray_source.dispersion);
- output0[pixel] = color_reflex * reflex_ratio;
- float4 d = dispersion[pixel];
- if (rc.hit) {
- rc_disp = float2(max(rc_disp.x, rc.dispersion[0]), max(rc_disp.y, rc.dispersion[1]));
- dispersion[pixel] = float4(rc_disp.x, rc_disp.y, d.b, d.a);
- }
- else {
- dispersion[pixel] = float4(-1.0f, -1.0f, d.b, d.a);
- }
- }
- else {
- //Refracted ray
- if (ray_source.opacity < 1.0f && (enabled & REFRACT_ENABLED)) {
- float3 seed = orig_pos * 100.0f;
- float rX = rgba_tnoise(seed);
- Ray ray = GetRefractedRayFromSource(ray_source);
- if (dist2(ray.dir) > Epsilon)
- {
- if (GetColor(ray, rX, level, 0, rc, ray_source.dispersion, true, true)) {
- color_refrac.rgb += rc.color[0] * (1.0f - ray_source.opacity);
- }
- }
- }
- output1[pixel] = color_refrac;
- float4 d = dispersion[pixel];
- dispersion[pixel] = float4(d.r, d.g, d.b, ray_source.dispersion);
- }
- }
- else {
- dispersion[pixel] = float4(-1.0f, -1.0f, -1.0f, -1.0f);
- }
- }
\ No newline at end of file
+ ray_inputs[pixel] = Pack4Float2ToI16(dirs, MAX_RAY_POLAR_DIR);
+}
\ No newline at end of file
diff --git a/Engine/Engine/Core/Shaders/RayTrace/RayWorldSolver.hlsli b/Engine/Engine/Core/Shaders/RayTrace/RayWorldSolver.hlsli
new file mode 100644
index 0000000..6abb1c3
--- /dev/null
+++ b/Engine/Engine/Core/Shaders/RayTrace/RayWorldSolver.hlsli
@@ -0,0 +1,288 @@
+/*
+The HotBite Game Engine
+
+Copyright(c) 2023 Vicente Sirvent Orts
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#define USE_OBH 0
+#define max_distance 50.0f
+
+struct RayTraceColor {
+ float3 color;
+ bool hit;
+};
+
+bool GetColor(Ray origRay, uint max_bounces, out RayTraceColor out_color, float dispersion, bool refract)
+{
+ out_color.color = float3(0.0f, 0.0f, 0.0f);
+ out_color.hit = false;
+
+ float last_dispersion = dispersion;
+ float acc_dispersion = dispersion;
+ float att_dist = 0.0f;
+#if USE_OBH
+ uint volumeStack[MAX_STACK_SIZE];
+#endif
+ uint stack[MAX_STACK_SIZE];
+ RayObject oray;
+ IntersectionResult object_result;
+
+ bool collide = false;
+ IntersectionResult result;
+ Ray ray = origRay;
+ bool end = false;
+
+ while (!end)
+ {
+ result.distance = FLT_MAX;
+ end = true;
+ collide = false;
+#if USE_OBH
+ uint volumeStackSize = 0;
+ volumeStack[volumeStackSize++] = 0;
+ uint i = 0;
+ while (volumeStackSize > 0 && volumeStackSize < MAX_STACK_SIZE)
+ {
+#else
+ for (uint i = 0; i < nobjects; ++i)
+ {
+ uint objectIndex = i;
+#endif
+
+#if USE_OBH
+ uint currentVolume = volumeStack[--volumeStackSize];
+
+ BVHNode volumeNode = objectBVH[currentVolume];
+
+ if (is_leaf(volumeNode))
+ {
+ uint objectIndex = index(volumeNode);
+ ObjectInfo o = objectInfos[objectIndex];
+
+ if (IntersectAABB(ray, o.aabb_min, o.aabb_max))
+ {
+#else
+ ObjectInfo o = objectInfos[i];
+ float objectExtent = length(o.aabb_max - o.aabb_min);
+ float distanceToObject = length(o.position - origRay.orig.xyz) - objectExtent;
+
+ if (distanceToObject < max_distance && distanceToObject < result.distance && IntersectAABB(ray, o.aabb_min, o.aabb_max))
+ {
+#endif
+ object_result.distance = FLT_MAX;
+
+ // Transform the ray direction from world space to object space
+ oray.orig = mul(ray.orig, o.inv_world);
+ oray.orig /= oray.orig.w;
+ oray.dir = normalize(mul(ray.dir, (float3x3) o.inv_world));
+ oray.t = FLT_MAX;
+
+ uint stackSize = 0;
+ stack[stackSize++] = 0;
+
+ while (stackSize > 0 && stackSize < MAX_STACK_SIZE)
+ {
+ uint current = stack[--stackSize];
+
+ BVHNode node = objects[o.objectOffset + current];
+ if (is_leaf(node))
+ {
+ float t;
+ uint idx = index(node);
+ idx += o.indexOffset;
+
+ IntersectionResult tmp_result;
+ tmp_result.distance = FLT_MAX;
+ if (IntersectTri(oray, idx, o.vertexOffset, tmp_result))
+ {
+ if (tmp_result.distance < object_result.distance) {
+ object_result.v0 = tmp_result.v0;
+ object_result.v1 = tmp_result.v1;
+ object_result.v2 = tmp_result.v2;
+ object_result.vindex = tmp_result.vindex;
+ object_result.distance = tmp_result.distance;
+ object_result.u = tmp_result.u;
+ object_result.v = tmp_result.v;
+ object_result.object = objectIndex;
+ }
+ }
+ }
+ else if (IntersectAABB(oray, node))
+ {
+ uint left_node_index = left_child(node);
+ uint right_node_index = right_child(node);
+
+ BVHNode left_node = objects[o.objectOffset + left_node_index];
+ BVHNode right_node = objects[o.objectOffset + right_node_index];
+
+ float left_dist = node_distance(left_node, oray.orig.xyz);
+ float right_dist = node_distance(right_node, oray.orig.xyz);
+
+ if (left_dist < right_dist) {
+ if (right_dist < object_result.distance && right_dist < max_distance) {
+ stack[stackSize++] = right_node_index;
+ }
+ if (left_dist < object_result.distance && left_dist < max_distance) {
+ stack[stackSize++] = left_node_index;
+ }
+ }
+ else {
+ if (left_dist < object_result.distance && left_dist < max_distance) {
+ stack[stackSize++] = left_node_index;
+ }
+ if (right_dist < object_result.distance && right_dist < max_distance) {
+ stack[stackSize++] = right_node_index;
+ }
+ }
+ }
+ }
+
+ if (object_result.distance < FLT_MAX) {
+ float3 opos = (1.0f - object_result.u - object_result.v) * object_result.v0 + object_result.u * object_result.v1 + object_result.v * object_result.v2;
+ float4 pos = mul(float4(opos, 1.0f), o.world);
+ float distance = length(pos - ray.orig);
+ if (distance < result.distance)
+ {
+ collide = true;
+ ray.t = distance;
+ result.v0 = object_result.v0;
+ result.v1 = object_result.v1;
+ result.v2 = object_result.v2;
+ result.vindex = object_result.vindex;
+ result.distance = distance;
+ result.u = object_result.u;
+ result.v = object_result.v;
+ result.object = objectIndex;
+ }
+ }
+ }
+#if USE_OBH
+ }
+ else
+
+ if (IntersectAABB(ray, volumeNode)) {
+
+ uint left_node_index = left_child(volumeNode);
+ uint right_node_index = right_child(volumeNode);
+
+ BVHNode left_node = objectBVH[left_node_index];
+ BVHNode right_node = objectBVH[right_node_index];
+
+ float left_dist = node_distance(left_node, ray.orig.xyz);
+ float right_dist = node_distance(right_node, ray.orig.xyz);
+
+ if (left_dist < right_dist) {
+ if (right_dist < result.distance && right_dist < max_distance) {
+ volumeStack[volumeStackSize++] = right_node_index;
+ }
+ if (left_dist < result.distance && left_dist < max_distance) {
+ volumeStack[volumeStackSize++] = left_node_index;
+ }
+ }
+ else {
+ if (left_dist < result.distance && left_dist < max_distance) {
+ volumeStack[volumeStackSize++] = left_node_index;
+ }
+ if (right_dist < result.distance && right_dist < max_distance) {
+ volumeStack[volumeStackSize++] = right_node_index;
+ }
+ }
+ }
+ ++i;
+#endif
+ }
+
+ //At this point we have the ray collision distance and a collision result
+ if (collide) {
+ // Calculate space position
+ ObjectInfo o = objectInfos[result.object];
+ float3 normal0 = asfloat(vertexBuffer.Load3(result.vindex.x + 12));
+ float3 normal1 = asfloat(vertexBuffer.Load3(result.vindex.y + 12));
+ float3 normal2 = asfloat(vertexBuffer.Load3(result.vindex.z + 12));
+ float3 opos = (1.0f - result.u - result.v) * result.v0 + result.u * result.v1 + result.v * result.v2;
+ float3 normal = (1.0f - result.u - result.v) * normal0 + result.u * normal1 + result.v * normal2;
+ normal = normalize(mul(normal, (float3x3)o.world));
+ float4 pos = mul(float4(opos, 1.0f), o.world);
+ pos /= pos.w;
+ MaterialColor material = objectMaterials[result.object];
+
+ float3 color = float3(0.0f, 0.0f, 0.0f);
+
+ color += CalcAmbient(normal) * 0.5f;
+
+
+ uint i = 0;
+ for (i = 0; i < dirLightsCount; ++i) {
+ color += CalcDirectional(normal, pos.xyz, dirLights[i], i);
+ }
+
+ // Calculate the point lights
+ for (i = 0; i < pointLightsCount; ++i) {
+ if (length(pos.xyz - pointLights[i].Position) < pointLights[i].Range) {
+ color += CalcPoint(normal, pos.xyz, pointLights[i], i);
+ }
+ }
+
+ bool use_mat_texture = material.flags & DIFFUSSE_MAP_ENABLED_FLAG;
+ float3 mat_color = material.diffuseColor.rgb * !use_mat_texture;
+
+ float2 uv0 = asfloat(vertexBuffer.Load2(result.vindex.x + 24));
+ float2 uv1 = asfloat(vertexBuffer.Load2(result.vindex.y + 24));
+ float2 uv2 = asfloat(vertexBuffer.Load2(result.vindex.z + 24));
+ float2 uv = uv0 * (1.0f - result.u - result.v) + uv1 * result.u + uv2 * result.v;
+
+ mat_color += GetDiffuseColor(result.object, uv) * use_mat_texture;
+
+ color.rgb *= mat_color * o.opacity;
+
+ float3 emission = material.emission * material.emission_color;
+ color += emission;
+
+ float material_dispersion = saturate(1.0f - material.specIntensity);
+
+ if (refract) {
+ att_dist = 1.0f;
+ }
+ float curr_att_dist = max(att_dist, 1.0f);
+ out_color.color += color * ray.ratio;
+ acc_dispersion += material_dispersion;
+ last_dispersion = material_dispersion;
+ ray.orig = pos;
+ out_color.hit = true;
+
+ //If not opaque surface, generate a refraction ray
+ if (ray.bounces < 5 && o.opacity < 1.0f) {
+ if (ray.bounces % 2 == 0) {
+ normal = -normal;
+ }
+ ray = GetRefractedRayFromRay(ray, ray.density,
+ ray.density != 1.0 ? 1.0f : o.density,
+ normal, ray.ratio * (1.0f - o.opacity));
+ end = false;
+ }
+ }
+ else {
+ //Color background
+
+ }
+ }
+return out_color.hit;
+ }
diff --git a/Engine/Engine/Core/SimpleShader.cpp b/Engine/Engine/Core/SimpleShader.cpp
index fc3e933..55ab228 100644
--- a/Engine/Engine/Core/SimpleShader.cpp
+++ b/Engine/Engine/Core/SimpleShader.cpp
@@ -198,7 +198,7 @@ namespace HotBite {
break;
}
}
-
+ uint32_t realConstantBufferCount = 0;
// Loop through all constant buffers
for (unsigned int b = 0; b < constantBufferCount; b++)
{
@@ -215,6 +215,10 @@ namespace HotBite {
D3D11_SHADER_INPUT_BIND_DESC bindDesc;
refl->GetResourceBindingDescByName(bufferDesc.Name, &bindDesc);
+ if (bindDesc.Type != D3D_SIT_CBUFFER) {
+ continue;
+ }
+ realConstantBufferCount++;
// Set up the buffer and put its pointer in the table
constantBuffers[b].BindIndex = bindDesc.BindPoint;
constantBuffers[b].Name = bufferDesc.Name;
@@ -260,6 +264,7 @@ namespace HotBite {
constantBuffers[b].Variables.push_back(varStruct);
}
}
+ constantBufferCount = realConstantBufferCount;
// All set
refl->Release();
diff --git a/Engine/Engine/Core/Texture.cpp b/Engine/Engine/Core/Texture.cpp
index fa88b50..890f762 100644
--- a/Engine/Engine/Core/Texture.cpp
+++ b/Engine/Engine/Core/Texture.cpp
@@ -376,6 +376,7 @@ namespace HotBite {
ID3D11Device* device = DXCore::Get()->device;
HRESULT hr = S_OK;
init = true;
+
width = w;
height = h;
//Description of each face
@@ -439,7 +440,6 @@ namespace HotBite {
renderTargetViewDesc.Texture2D.MipSlice = 0;
// Create the render target view.
hr = device->CreateRenderTargetView(texture, &renderTargetViewDesc, &render_view);
-
return hr;
}
diff --git a/Engine/Engine/Core/Utils.h b/Engine/Engine/Core/Utils.h
index 095c3f4..8cc1725 100644
--- a/Engine/Engine/Core/Utils.h
+++ b/Engine/Engine/Core/Utils.h
@@ -97,61 +97,7 @@ namespace HotBite {
}
};
- template
- class SpaceTree {
- public:
- struct Cube {
- float3 p0;
- float3 p1;
-
- bool operator>(const Cube& other) {
- return DIST2(p0) > DIST2(other.p0);
- }
-
- bool operator==(const Cube& other) {
- return DIST2(p0) == DIST2(other.p0);
- }
-
- static Cube Get(const float3& pos) {
- p0 = pos.x / grid_value;
- p0 = pos.y / grid_value;
- p0 = pos.z / grid_value;
- p1.x = p0.x + 1;
- p1.y = p0.y + 1;
- p1.z = p0.z + 1;
- return { p0, p1 };
- }
-
- static bool Inside(const float3& p) {
- return ((p.x >= p0.x && p.x < p0.x + p1.x) &&
- (p.y >= p0.y && p.y < p0.y + p1.y) &&
- (p.z >= p0.z && p.z < p0.z + p1.z));
- }
- };
-
- private:
- using SpaceMap = std::unordered_map>;
- SpaceMap data;
-
- public:
- void Insert(const float3& position, const T& v) {
- auto k = Cube::Get(position);
- data[k].push_back(v);
- }
-
- void Remove(const float3& position) {
- for (auto& quad: data) {
- for (auto it = quad.being(); it != quad.end(); ++it) {
- if (it->p0 == position) {
- quad.erase(position);
- return;
- }
- }
- }
- }
-
- const std::unordered_map>& Data() { return data; }
- };
+
/**
* This is an map that stores data in vectors in order to allow fast access and
* and be cache friendly.
diff --git a/Engine/Engine/Defines.h b/Engine/Engine/Defines.h
index 786da81..9513f1b 100644
--- a/Engine/Engine/Defines.h
+++ b/Engine/Engine/Defines.h
@@ -183,6 +183,11 @@ namespace HotBite {
return (a.x == b.x && a.y == b.y);
}
+ // MAX
+ inline float3 MAX_F3_F3(const float3& a, const float3& b) {
+ return { max(a.x, b.x), max(a.y, b.y), max(a.z, b.z) };
+ }
+
// ADD
inline float4 ADD_F4_F4(const float4& a, const float4& b) {
__m128 va = _mm_load_ps(&a.x);
diff --git a/Engine/Engine/Systems/RenderSystem.cpp b/Engine/Engine/Systems/RenderSystem.cpp
index aead8f2..2d0357e 100644
--- a/Engine/Engine/Systems/RenderSystem.cpp
+++ b/Engine/Engine/Systems/RenderSystem.cpp
@@ -38,6 +38,8 @@ using namespace DirectX;
static const float zero[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
static const float ones[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
+static const float max_floats[4] = { FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX };
+static const uint32_t max_uint[4] = { UINT_MAX, UINT_MAX, UINT_MAX, UINT_MAX };
static const float minus_one[4] = { -1.0f, -1.0f, -1.0f, -1.0f };
@@ -246,11 +248,11 @@ bool RenderSystem::Init(DXCore* dx_core, Core::VertexBuffer* vb, Core::B
vertex_buffer = vb;
bvh_buffer = bvh;
tbvh_buffer.Prepare(MAX_OBJECTS * 2 - 1);
- first_pass_target = dxcore;
+ first_pass_target = dxcore;
depth_target = dxcore;
int w = dxcore->GetWidth();
int h = dxcore->GetHeight();
-
+
for (int i = 0; i < 2; ++i)
{
if (FAILED(light_map[i].Init(w, h, DXGI_FORMAT::DXGI_FORMAT_R32G32B32A32_FLOAT, nullptr, 0, D3D11_BIND_UNORDERED_ACCESS))) {
@@ -266,7 +268,7 @@ bool RenderSystem::Init(DXCore* dx_core, Core::VertexBuffer* vb, Core::B
if (FAILED(dust_render_map.Init(w / 2, h / 2, DXGI_FORMAT::DXGI_FORMAT_R11G11B10_FLOAT, nullptr, 0, D3D11_BIND_UNORDERED_ACCESS))) {
throw std::exception("dust_render_map.Init failed");
}
- if (FAILED(vol_light_map2.Init(w / 2, h / 2, DXGI_FORMAT::DXGI_FORMAT_R11G11B10_FLOAT, nullptr, 0, D3D11_BIND_UNORDERED_ACCESS))) {
+ if (FAILED(vol_light_map2.Init(w, h, DXGI_FORMAT::DXGI_FORMAT_R11G11B10_FLOAT, nullptr, 0, D3D11_BIND_UNORDERED_ACCESS))) {
throw std::exception("vol_light_map2.Init failed");
}
if (FAILED(position_map.Init(w, h, DXGI_FORMAT::DXGI_FORMAT_R32G32B32A32_FLOAT))) {
@@ -284,6 +286,23 @@ bool RenderSystem::Init(DXCore* dx_core, Core::VertexBuffer* vb, Core::B
if (FAILED(depth_map.Init(w, h, DXGI_FORMAT::DXGI_FORMAT_R32_FLOAT, nullptr, 0, D3D11_BIND_UNORDERED_ACCESS))) {
throw std::exception("depth_map.Init failed");
}
+
+ if (FAILED(high_z_tmp_map.Init(w, h, DXGI_FORMAT::DXGI_FORMAT_R32_FLOAT, nullptr, 0, D3D11_BIND_UNORDERED_ACCESS))) {
+ throw std::exception("high_z_tmp_map.Init failed");
+ }
+
+ uint32_t hiz_w = w;
+ uint32_t hiz_h = h;
+ high_z_maps[0] = depth_map.SRV();
+ for (int i = 0; i < HIZ_DOWNSAMPLED_NTEXTURES; ++i) {
+ hiz_w = (uint32_t)ceil((float)hiz_w / (float)HIZ_RATIO);
+ hiz_h = (uint32_t)ceil((float)hiz_h / (float)HIZ_RATIO);
+ if (FAILED(high_z_downsampled_map[i].Init(hiz_w, hiz_h, DXGI_FORMAT::DXGI_FORMAT_R32_FLOAT, nullptr, 0, D3D11_BIND_UNORDERED_ACCESS))) {
+ throw std::exception("high_z_downsampled_map.Init failed");
+ }
+ high_z_maps[i + 1] = high_z_downsampled_map[i].SRV();
+ }
+
if (FAILED(depth_view.Init(w, h))) {
throw std::exception("depth_view.Init failed");
}
@@ -346,10 +365,6 @@ bool RenderSystem::Init(DXCore* dx_core, Core::VertexBuffer* vb, Core::B
if (rt_di_denoiser == nullptr) {
throw std::exception("DenoiserCS shader.Init failed");
}
- rt_disp = ShaderFactory::Get()->GetShader("DispersionCS.cso");
- if (rt_disp == nullptr) {
- throw std::exception("DispersionCS shader.Init failed");
- }
gi_average = ShaderFactory::Get()->GetShader("GIAverageCS.cso");
if (gi_average == nullptr) {
throw std::exception("GIAverageCS shader.Init failed");
@@ -378,6 +393,30 @@ bool RenderSystem::Init(DXCore* dx_core, Core::VertexBuffer* vb, Core::B
if (copy_texture == nullptr) {
throw std::exception("Copy textures shader.Init failed");
}
+ high_z_shader = ShaderFactory::Get()->GetShader("HiZDownSample.cso");
+ if (high_z_shader == nullptr) {
+ throw std::exception("HiZDownSample shader.Init failed");
+ }
+
+ ray_reflex_screen_solver = ShaderFactory::Get()->GetShader("RayReflexScreenSolverCS.cso");
+ if (ray_reflex_screen_solver == nullptr) {
+ throw std::exception("RayReflexScreenSolverCS shader.Init failed");
+ }
+
+ ray_reflex_world_solver = ShaderFactory::Get()->GetShader("RayReflexWorldSolverCS.cso");
+ if (ray_reflex_world_solver == nullptr) {
+ throw std::exception("RayReflexWorldSolverCS shader.Init failed");
+ }
+
+ ray_gi_screen_solver = ShaderFactory::Get()->GetShader("RayGIScreenSolverCS.cso");
+ if (ray_gi_screen_solver == nullptr) {
+ throw std::exception("RayGIScreenSolverCS shader.Init failed");
+ }
+
+ ray_gi_world_solver = ShaderFactory::Get()->GetShader("RayGIWorldSolverCS.cso");
+ if (ray_gi_world_solver == nullptr) {
+ throw std::exception("RayGIWorldSolverCS shader.Init failed");
+ }
LoadRTResources();
@@ -427,21 +466,30 @@ RenderSystem::~RenderSystem() {
rgba_noise_texture.Release();
motion_texture.Release();
depth_map.Release();
+ high_z_tmp_map.Release();
+ for (int i = 0; i < HIZ_DOWNSAMPLED_NTEXTURES; ++i) {
+ high_z_downsampled_map[i].Release();
+ }
for (int i = 0; i < RT_NTEXTURES; ++i) {
for (int x = 0; x < 2; ++x) {
- rt_textures[x][i].Release();
+ rt_textures_di[x][i].Release();
}
}
+ for (int x = 0; x < RT_GI_NTEXTURES; ++x) {
+ rt_textures_gi[x].Release();
+ }
+
+ rt_textures_gi_tiles.Release();
for (int x = 0; x < 2; ++x) {
restir_pdf[x].Release();
}
+ restir_pdf_mask.Release();
restir_w.Release();
texture_tmp.Release();
rt_texture_props.Release();
- rt_dispersion.Release();
rt_ray_sources0.Release();
rt_ray_sources1.Release();
vol_data.Release();
@@ -453,24 +501,47 @@ void RenderSystem::LoadRTResources() {
int h = dxcore->GetHeight();
for (int x = 0; x < RT_NTEXTURES; ++x) {
int div = RT_TEXTURE_RESOLUTION_DIVIDER;
- if (x == RT_TEXTURE_INDIRECT) {
- div = max(RT_TEXTURE_RESOLUTION_DIVIDER, 2);
- }
for (int n = 0; n < 2; ++n) {
- rt_textures[n][x].Release();
- if (FAILED(rt_textures[n][x].Init(w / div, h / div, DXGI_FORMAT::DXGI_FORMAT_R11G11B10_FLOAT, nullptr, 0, D3D11_BIND_UNORDERED_ACCESS))) {
+ rt_textures_di[n][x].Release();
+ if (FAILED(rt_textures_di[n][x].Init(w / div, h / div, DXGI_FORMAT::DXGI_FORMAT_R16G16B16A16_FLOAT, nullptr, 0, D3D11_BIND_UNORDERED_ACCESS))) {
throw std::exception("rt_texture.Init failed");
}
+ rt_textures_di[n][x].Clear(zero);
}
}
- int restir_div = max(RT_TEXTURE_RESOLUTION_DIVIDER, 2);
+ input_rays.Release();
+ if (FAILED(input_rays.Init(w / RT_TEXTURE_RESOLUTION_DIVIDER, h / RT_TEXTURE_RESOLUTION_DIVIDER, DXGI_FORMAT::DXGI_FORMAT_R32G32B32A32_UINT, nullptr, 0, D3D11_BIND_UNORDERED_ACCESS))) {
+ throw std::exception("input_rays.Init failed");
+ }
+
+ uint32_t restir_div = GI_TEXTURE_RESOLUTION_DIVIDER;
+
+ for (int n = 0; n < RT_GI_NTEXTURES; ++n) {
+ rt_textures_gi[n].Release();
+ if (FAILED(rt_textures_gi[n].Init(w / restir_div, h / restir_div, DXGI_FORMAT::DXGI_FORMAT_R16G16B16A16_FLOAT, nullptr, 0, D3D11_BIND_UNORDERED_ACCESS))) {
+ throw std::exception("rt_texture.Init failed");
+ }
+ rt_textures_gi[n].Clear(zero);
+ }
+
+ uint32_t tile_div = min(restir_div, RT_TEXTURE_RESOLUTION_DIVIDER) * RESTIR_KERNEL;
+ rt_textures_gi_tiles.Release();
+ if (FAILED(rt_textures_gi_tiles.Init(w / tile_div + 1, h/ tile_div + 1, DXGI_FORMAT::DXGI_FORMAT_R8_UINT, nullptr, 0, D3D11_BIND_UNORDERED_ACCESS))) {
+ throw std::exception("rt_texture.Init failed");
+ }
+
for (int n = 0; n < 2; ++n) {
restir_pdf[n].Release();
if (FAILED(restir_pdf[n].Init(w / restir_div, h / restir_div, DXGI_FORMAT_R32G32B32A32_UINT, nullptr, 0, D3D11_BIND_UNORDERED_ACCESS))) {
throw std::exception("restir_pdf.Init failed");
}
}
+
+ restir_pdf_mask.Release();
+ if (FAILED(restir_pdf_mask.Init(w / restir_div, h / restir_div, DXGI_FORMAT::DXGI_FORMAT_R16_UINT, nullptr, 0, D3D11_BIND_UNORDERED_ACCESS))) {
+ throw std::exception("restir_w.Init failed");
+ }
restir_w.Release();
if (FAILED(restir_w.Init(w / restir_div, h / restir_div, DXGI_FORMAT::DXGI_FORMAT_R32_FLOAT, nullptr, 0, D3D11_BIND_UNORDERED_ACCESS))) {
throw std::exception("restir_w.Init failed");
@@ -486,10 +557,6 @@ void RenderSystem::LoadRTResources() {
throw std::exception("rt_texture_props.Init failed");
}
- rt_dispersion.Release();
- if (FAILED(rt_dispersion.Init(w / RT_TEXTURE_RESOLUTION_DIVIDER, h / RT_TEXTURE_RESOLUTION_DIVIDER, DXGI_FORMAT::DXGI_FORMAT_R32G32B32A32_FLOAT, nullptr, 0, D3D11_BIND_UNORDERED_ACCESS))) {
- throw std::exception("rt_dispersion.Init failed");
- }
ResetRTBBuffers();
}
@@ -1263,8 +1330,7 @@ void RenderSystem::DrawScene(int w, int h, const float3& camera_position, const
gs->SetInt(SCREEN_W, w);
gs->SetInt(SCREEN_H, h);
gs->SetFloat3(CAMERA_POSITION, cam_entity.camera->world_position);
- gs->SetMatrix4x4(VIEW, cam_entity.camera->view);
- gs->SetMatrix4x4(PROJECTION, cam_entity.camera->projection);
+ gs->SetMatrix4x4("view_projection", cam_entity.camera->view_projection);
gs->SetFloat(TIME, time);
gs->SetShader();
}
@@ -1408,7 +1474,8 @@ void RenderSystem::ProcessMix() {
if (post_process_pipeline == nullptr) {
return;
}
-
+ ID3D11RenderTargetView* rv_zero[1] = { nullptr };
+ dxcore->context->OMSetRenderTargets(1, rv_zero, nullptr);
ID3D11UnorderedAccessView* image = temp_map.UAV();
int32_t groupsX = (int32_t)(ceil((float)temp_map.Width() / 32.0f));
@@ -1422,12 +1489,16 @@ void RenderSystem::ProcessMix() {
mixer_shader->SetShaderResourceView("lightTexture", current_light_map->SRV());
mixer_shader->SetShaderResourceView("volLightTexture", vol_light_map.SRV());
mixer_shader->SetShaderResourceView("bloomTexture", bloom_map.SRV());
- mixer_shader->SetShaderResourceView("emissionTexture", rt_texture_curr[RT_TEXTURE_EMISSION].SRV());
mixer_shader->SetShaderResourceView("dustTexture", dust_render_map.SRV());
mixer_shader->SetShaderResourceView("lensFlareTexture", lens_flare_map.SRV());
- mixer_shader->SetShaderResourceView("rtTexture0", rt_texture_curr[RT_TEXTURE_REFLEX].SRV());
- mixer_shader->SetShaderResourceView("rtTexture1", rt_texture_curr[RT_TEXTURE_REFRACT].SRV());
- mixer_shader->SetShaderResourceView("rtTexture2", rt_texture_curr[RT_TEXTURE_INDIRECT].SRV());
+ if (rt_texture_di_curr != nullptr) {
+ mixer_shader->SetShaderResourceView("emissionTexture", rt_texture_di_curr[RT_TEXTURE_EMISSION].SRV());
+ mixer_shader->SetShaderResourceView("rtTexture0", rt_texture_di_curr[RT_TEXTURE_REFLEX].SRV());
+ mixer_shader->SetShaderResourceView("rtTexture1", rt_texture_di_curr[RT_TEXTURE_REFRACT].SRV());
+ }
+ if (rt_texture_gi_curr != nullptr) {
+ mixer_shader->SetShaderResourceView("rtTexture2", rt_texture_gi_curr->SRV());
+ }
mixer_shader->SetShaderResourceView("positions", rt_ray_sources0.SRV());
mixer_shader->SetShaderResourceView("normals", rt_ray_sources1.SRV());
mixer_shader->SetShaderResourceView("input", post_process_pipeline->RenderResource());
@@ -1444,11 +1515,14 @@ void RenderSystem::ProcessMix() {
mixer_shader->SetShaderResourceView("rtTexture1", nullptr);
mixer_shader->SetShaderResourceView("rtTexture2", nullptr);
mixer_shader->SetShaderResourceView("rtTexture3", nullptr);
+ mixer_shader->SetShaderResourceView("rtTextureUV", nullptr);
mixer_shader->SetShaderResourceView("volLightTexture", nullptr);
mixer_shader->SetShaderResourceView("dustTexture", nullptr);
mixer_shader->SetShaderResourceView("input", nullptr);
mixer_shader->SetShaderResourceView("lensFlareTexture", nullptr);
mixer_shader->SetShaderResourceView("rgbaNoise", nullptr);
+ mixer_shader->SetShaderResourceView("positions", nullptr);
+ mixer_shader->SetShaderResourceView("normals", nullptr);
mixer_shader->CopyAllBufferData();
}
@@ -1627,6 +1701,47 @@ void RenderSystem::ProcessMotion() {
}
}
+void RenderSystem::ProcessHighZ() {
+
+ high_z_shader->SetInt("ratio", HIZ_RATIO);
+ high_z_shader->SetShader();
+
+ Core::RenderTexture2D* input;
+ Core::RenderTexture2D* output;
+
+ for (uint32_t i = 0; i < HIZ_DOWNSAMPLED_NTEXTURES; ++i) {
+ if (i == 0) {
+ input = &depth_map;
+ }
+ else {
+ input = &high_z_downsampled_map[i - 1];
+ }
+ output = &high_z_downsampled_map[i];
+
+ int32_t groupsX = (int32_t)(ceil((float)input->Width() / 32.0f));
+ int32_t groupsY = (int32_t)(ceil((float)output->Height() / 32.0f));
+
+ high_z_shader->SetInt("type", 1);
+ high_z_shader->SetShaderResourceView("input", input->SRV());
+ high_z_shader->SetUnorderedAccessView("output", high_z_tmp_map.UAV());
+ high_z_shader->CopyAllBufferData();
+ dxcore->context->Dispatch(groupsX, groupsY, 1);
+
+ groupsX = (int32_t)(ceil((float)output->Width() / 32.0f));
+ groupsY = (int32_t)(ceil((float)input->Height() / 32.0f));
+
+ high_z_shader->SetInt("type", 2);
+ high_z_shader->SetShaderResourceView("input", nullptr);
+ high_z_shader->SetUnorderedAccessView("output", nullptr);
+ high_z_shader->SetShaderResourceView("input", high_z_tmp_map.SRV());
+ high_z_shader->SetUnorderedAccessView("output", output->UAV());
+ high_z_shader->CopyAllBufferData();
+ dxcore->context->Dispatch(groupsX, groupsY, 1);
+ high_z_shader->SetShaderResourceView("input", nullptr);
+ high_z_shader->SetUnorderedAccessView("output", nullptr);
+ }
+}
+
void RenderSystem::PrepareRT() {
if (rt_quality != eRtQuality::OFF && rt_enabled && bvh_buffer != nullptr) {
auto& device = dxcore->device;
@@ -1648,7 +1763,13 @@ void RenderSystem::PrepareRT() {
for (const auto& mat : shaders.second) {
for (const auto& de : mat.second.second.GetConstData()) {
if (de.base->visible && de.mesh->GetData()->skeletons.empty()) {
- float distance = LENGHT_F3(de.transform->position - (ADD_F3_F3(ca->camera->world_position, ca->camera->direction)));
+
+ // Get the center and extents of the oriented box
+ const float3& orientedBoxCenter = de.bounds->final_box.Center;
+ const float3& orientedBoxExtents = de.bounds->final_box.Extents;
+
+ //float distance = LENGHT_F3(de.transform->position - (ADD_F3_F3(ca->camera->world_position, ca->camera->direction)));
+ float distance = LENGHT_F3(MAX_F3_F3(SUB_F3_F3(orientedBoxCenter - ca->transform->position, orientedBoxExtents), { 0.0f, 0.0f, 0.0f }));
MaterialProps mo = de.mat->data->props;
@@ -1656,10 +1777,6 @@ void RenderSystem::PrepareRT() {
ObjectInfo o;
- // Get the center and extents of the oriented box
- const float3& orientedBoxCenter = de.bounds->final_box.Center;
- const float3& orientedBoxExtents = de.bounds->final_box.Extents;
-
// Calculate the minimum and maximum points of the AABB
o.aabb_min = { orientedBoxCenter.x - orientedBoxExtents.x,
orientedBoxCenter.y - orientedBoxExtents.y,
@@ -1692,7 +1809,7 @@ void RenderSystem::PrepareRT() {
break;
}
else {
- distance += 0.001f;
+ distance += 1.0f;
}
}
}
@@ -1724,81 +1841,184 @@ void RenderSystem::PrepareRT() {
}
void RenderSystem::ProcessGI() {
+
if (rt_enabled & RT_INDIRECT_ENABLE && rt_quality != eRtQuality::OFF && rt_enabled && bvh_buffer != nullptr && nobjects > 0) {
+ ID3D11ShaderResourceView* nullsrc = nullptr;
restir_pdf_curr = &restir_pdf[0];
restir_pdf_prev = &restir_pdf[1];
- rt_texture_curr = rt_textures[current];
- rt_texture_prev = rt_textures[prev];
+ rt_texture_gi_curr = &rt_textures_gi[current];
+ rt_texture_gi_prev = &rt_textures_gi[prev];
+ rt_texture_gi_tmp[0] = &rt_textures_gi[2];
+ rt_texture_gi_tmp[1] = &rt_textures_gi[3];
+ rt_texture_gi_trace = &rt_textures_gi[4];
+ rt_textures_gi_tiles.Clear(zero);
std::lock_guard lock(rt_mutex);
CameraEntity& cam_entity = cameras.GetData()[0];
+ input_rays.Clear((float*)max_uint);
+ restir_pdf_mask.Clear(zero);
gi_shader->SetInt("kernel_size", RESTIR_KERNEL);
gi_shader->SetInt("ray_count", RESTIR_PIXEL_RAYS);
+ gi_shader->SetFloat(TIME, time);
+ gi_shader->SetFloat3(CAMERA_POSITION, cam_entity.camera->world_position);
- gi_shader->SetInt("nobjects", nobjects);
- gi_shader->SetInt("enabled", rt_enabled & (rt_quality != eRtQuality::OFF ? 0xFF : 0x00));
gi_shader->SetMatrix4x4("view_proj", cam_entity.camera->view_projection);
- gi_shader->SetMatrix4x4("prev_view_proj", cam_entity.camera->prev_view_projection);
gi_shader->SetInt("frame_count", frame_count);
- gi_shader->SetData("objectMaterials", objectMaterials, nobjects * sizeof(MaterialProps));
- gi_shader->SetData("objectInfos", objects, nobjects * sizeof(ObjectInfo));
- gi_shader->SetMatrix4x4(VIEW, cam_entity.camera->view);
- gi_shader->SetMatrix4x4(PROJECTION, cam_entity.camera->projection);
- gi_shader->SetShaderResourceView("position_map", position_map.SRV());
- gi_shader->SetShaderResourceView("depth_map", depth_map.SRV());
+ gi_shader->SetInt("divider", GI_TEXTURE_RESOLUTION_DIVIDER);
+
+ gi_shader->SetUnorderedAccessView("restir_pdf_mask", restir_pdf_mask.UAV());
+ gi_shader->SetUnorderedAccessView("ray_inputs", input_rays.UAV());
gi_shader->SetShaderResourceView("motion_texture", motion_texture.SRV());
gi_shader->SetShaderResourceView("prev_position_map", prev_position_map.SRV());
gi_shader->SetShaderResourceView("ray0", rt_ray_sources0.SRV());
gi_shader->SetShaderResourceView("ray1", rt_ray_sources1.SRV());
- gi_shader->SetUnorderedAccessView("props", rt_texture_props.UAV());
-
- float3 dir;
- XMStoreFloat3(&dir, cam_entity.camera->xm_direction);
- gi_shader->SetFloat(TIME, time);
- gi_shader->SetFloat3(CAMERA_POSITION, cam_entity.camera->world_position);
- gi_shader->SetFloat3("cameraDirection", dir);
- gi_shader->SetSamplerState(PCF_SAMPLER, dxcore->shadow_sampler);
- gi_shader->SetSamplerState(BASIC_SAMPLER, dxcore->basic_sampler);
- gi_shader->SetShaderResourceViewArray("DiffuseTextures[0]", diffuseTextures, nobjects);
-
- PrepareLights(gi_shader);
+ gi_shader->SetShaderResourceView("restir_pdf_0", restir_pdf_prev->SRV());
+ gi_shader->SetShaderResourceView("restir_w_0", restir_w.SRV());
gi_shader->CopyAllBufferData();
gi_shader->SetShader();
+
+ int groupsX = (int32_t)(ceil((float)rt_texture_gi_curr->Width() / (32.0f)));
+ int groupsY = (int32_t)(ceil((float)rt_texture_gi_curr->Height() / (32.0f)));
+ dxcore->context->Dispatch((uint32_t)ceil((float)groupsX), (uint32_t)ceil((float)groupsY), 1);
+
+ gi_shader->SetUnorderedAccessView("restir_pdf_mask", nullptr);
+ gi_shader->SetUnorderedAccessView("ray_inputs", nullptr);
+ gi_shader->SetShaderResourceView("motion_texture", nullptr);
+ gi_shader->SetShaderResourceView("prev_position_map", nullptr);
+ gi_shader->SetShaderResourceView("ray0", nullptr);
+ gi_shader->SetShaderResourceView("ray1", nullptr);
+ gi_shader->SetShaderResourceView("restir_pdf_0", nullptr);
+ gi_shader->SetShaderResourceView("restir_w_0", nullptr);
+
+#if 1
+ //Resolve rays with screen space Ray Tracing
+ ray_gi_screen_solver->SetInt("enabled", rt_enabled & (rt_quality != eRtQuality::OFF ? 0xFF : 0x00));
+ ray_gi_screen_solver->SetInt("frame_count", frame_count);
+ ray_gi_screen_solver->SetFloat(TIME, time);
+ ray_gi_screen_solver->SetInt("kernel_size", RESTIR_KERNEL);
+ ray_gi_screen_solver->SetInt("type", 2);
+ ray_gi_screen_solver->SetInt("divider", GI_TEXTURE_RESOLUTION_DIVIDER);
+ ray_gi_screen_solver->SetFloat("hiz_ratio", HIZ_RATIO);
+ ray_gi_screen_solver->SetFloat3(CAMERA_POSITION, cam_entity.camera->world_position);
+ ray_gi_screen_solver->SetMatrix4x4("view", cam_entity.camera->view);
+ ray_gi_screen_solver->SetMatrix4x4("projection", cam_entity.camera->projection);
+ ray_gi_screen_solver->SetMatrix4x4("inv_projection", cam_entity.camera->inverse_projection);
+ ray_gi_screen_solver->SetMatrix4x4("prev_view_proj", cam_entity.camera->prev_view_projection);
+
+ ray_gi_screen_solver->SetShaderResourceView("ray0", rt_ray_sources0.SRV());
+ ray_gi_screen_solver->SetShaderResourceView("ray1", rt_ray_sources1.SRV());
+ ray_gi_screen_solver->SetUnorderedAccessView("ray_inputs", input_rays.UAV());
+ ray_gi_screen_solver->SetUnorderedAccessView("output", rt_texture_gi_trace->UAV());
+ ray_gi_screen_solver->SetUnorderedAccessView("tiles_output", rt_textures_gi_tiles.UAV());
+ ray_gi_screen_solver->SetShaderResourceViewArray("hiz_textures[0]", high_z_maps, HIZ_NTEXTURES);
+ ray_gi_screen_solver->SetShaderResourceView("prev_position_map", prev_position_map.SRV());
+ ray_gi_screen_solver->SetShaderResourceView("restir_pdf_mask", restir_pdf_mask.SRV());
+ ray_gi_screen_solver->SetShaderResourceView("restir_pdf_0", restir_pdf_prev->SRV());
+ ray_gi_screen_solver->SetUnorderedAccessView("restir_pdf_1", restir_pdf_curr->UAV());
+ ray_gi_screen_solver->SetShaderResourceView("restir_w_0", restir_w.SRV());
+
+ ray_gi_screen_solver->SetShaderResourceView("colorTexture", post_process_pipeline->RenderResource());
+ ray_gi_screen_solver->SetShaderResourceView("lightTexture", current_light_map->SRV());
+ ray_gi_screen_solver->SetShaderResourceView("bloomTexture", bloom_map.SRV());
+
+ groupsX = (int32_t)(ceil((float)rt_texture_gi_curr->Width() / (RESTIR_KERNEL)));
+ groupsY = (int32_t)(ceil((float)rt_texture_gi_curr->Height() / (RESTIR_KERNEL)));
+ ray_gi_screen_solver->CopyAllBufferData();
+ ray_gi_screen_solver->SetShader();
+ dxcore->context->Dispatch(groupsX, groupsY, 1);
+
+ ray_gi_screen_solver->SetShaderResourceView("ray0", nullptr);
+ ray_gi_screen_solver->SetShaderResourceView("ray1", nullptr);
+ ray_gi_screen_solver->SetUnorderedAccessView("ray_inputs", nullptr);
+ ray_gi_screen_solver->SetUnorderedAccessView("output", nullptr);
+ ray_gi_screen_solver->SetUnorderedAccessView("tiles_output", nullptr);
+
+
+ ID3D11ShaderResourceView* no_data[MAX_OBJECTS] = {};
+ ray_gi_screen_solver->SetShaderResourceViewArray("hiz_textures[0]", no_data, HIZ_NTEXTURES);
+ ray_gi_screen_solver->SetShaderResourceView("prev_position_map", nullptr);
+ ray_gi_screen_solver->SetShaderResourceView("restir_pdf_mask", nullptr);
+ ray_gi_screen_solver->SetShaderResourceView("restir_pdf_0", nullptr);
+ ray_gi_screen_solver->SetUnorderedAccessView("restir_pdf_1", nullptr);
+
+ ray_gi_screen_solver->SetShaderResourceView("colorTexture", nullptr);
+ ray_gi_screen_solver->SetShaderResourceView("lightTexture", nullptr);
+ ray_gi_screen_solver->SetShaderResourceView("bloomTexture", nullptr);
+ ray_gi_screen_solver->SetShaderResourceView("restir_w_0", nullptr);
+
+ ray_gi_screen_solver->CopyAllBufferData();
+#endif
+#if 1
+ // Resolve rays with world space Ray Tracing
+ ray_gi_world_solver->SetInt("enabled", rt_enabled& (rt_quality != eRtQuality::OFF ? 0xFF : 0x00));
+ ray_gi_world_solver->SetInt("frame_count", frame_count);
+ ray_gi_world_solver->SetInt("type", 2);
+ ray_gi_world_solver->SetFloat(TIME, time);
+ ray_gi_world_solver->SetInt("kernel_size", RESTIR_KERNEL);
+ ray_gi_world_solver->SetInt("nobjects", nobjects);
+ ray_gi_world_solver->SetData("objectMaterials", objectMaterials, nobjects * sizeof(MaterialProps));
+ ray_gi_world_solver->SetData("objectInfos", objects, nobjects * sizeof(ObjectInfo));
+ ray_gi_world_solver->SetFloat3(CAMERA_POSITION, cam_entity.camera->world_position);
+
+ ray_gi_world_solver->SetUnorderedAccessView("output", rt_texture_gi_trace->UAV());
+ ray_gi_world_solver->SetUnorderedAccessView("tiles_output", rt_textures_gi_tiles.UAV());
+ ray_gi_world_solver->SetShaderResourceView("ray0", rt_ray_sources0.SRV());
+ ray_gi_world_solver->SetShaderResourceView("ray1", rt_ray_sources1.SRV());
+ ray_gi_world_solver->SetShaderResourceView("ray_inputs", input_rays.SRV());
+ ray_gi_world_solver->SetShaderResourceViewArray("DiffuseTextures[0]", diffuseTextures, nobjects);
+ ray_gi_world_solver->SetSamplerState(PCF_SAMPLER, dxcore->shadow_sampler);
+ ray_gi_world_solver->SetSamplerState(BASIC_SAMPLER, dxcore->basic_sampler);
+
+ ray_gi_world_solver->SetShaderResourceView("restir_pdf_mask", restir_pdf_mask.SRV());
+ ray_gi_world_solver->SetUnorderedAccessView("restir_pdf_1", restir_pdf_curr->UAV());
+ ray_gi_world_solver->SetShaderResourceView("restir_pdf_0", restir_pdf_prev->SRV());
+ ray_gi_world_solver->SetShaderResourceView("restir_w_0", restir_w.SRV());
+
+ PrepareLights(ray_gi_world_solver);
+
+ ray_gi_world_solver->CopyAllBufferData();
+
dxcore->context->CSSetShaderResources(2, 1, bvh_buffer->SRV());
dxcore->context->CSSetShaderResources(3, 1, tbvh_buffer.SRV());
dxcore->context->CSSetShaderResources(4, 1, vertex_buffer->VertexSRV());
dxcore->context->CSSetShaderResources(5, 1, vertex_buffer->IndexSRV());
+ ray_gi_world_solver->SetShader();
- gi_shader->SetShaderResourceView("restir_pdf_0", restir_pdf_prev->SRV());
- gi_shader->SetShaderResourceView("restir_w_0", restir_w.SRV());
- gi_shader->SetUnorderedAccessView("restir_pdf_1", restir_pdf_curr->UAV());
+ groupsX = (int32_t)(ceil((float)rt_texture_gi_trace->Width() / (RESTIR_KERNEL)));
+ groupsY = (int32_t)(ceil((float)rt_texture_gi_trace->Height() / (RESTIR_KERNEL)));
+ dxcore->context->Dispatch(groupsX, groupsY, 1);
- gi_shader->SetUnorderedAccessView("output", rt_texture_curr[RT_TEXTURE_INDIRECT].UAV());
+ ray_gi_world_solver->SetUnorderedAccessView("output", nullptr);
+ ray_gi_world_solver->SetShaderResourceView("ray0", nullptr);
+ ray_gi_world_solver->SetShaderResourceView("ray1", nullptr);
+ ray_gi_world_solver->SetUnorderedAccessView("bloom", nullptr);
+ ray_gi_world_solver->SetUnorderedAccessView("tiles_output", nullptr);
+ ray_gi_world_solver->SetShaderResourceView("ray_inputs", nullptr);
- int groupsX = (int32_t)(ceil((float)rt_texture_curr[RT_TEXTURE_INDIRECT].Width() / (32.0f)));
- int groupsY = (int32_t)(ceil((float)rt_texture_curr[RT_TEXTURE_INDIRECT].Height() / (32.0f)));
- dxcore->context->Dispatch((uint32_t)ceil((float)groupsX), (uint32_t)ceil((float)groupsY), 1);
+ dxcore->context->CSSetShaderResources(2, 1, &nullsrc);
+ dxcore->context->CSSetShaderResources(3, 1, &nullsrc);
+ dxcore->context->CSSetShaderResources(4, 1, &nullsrc);
+ dxcore->context->CSSetShaderResources(5, 1, &nullsrc);
- gi_shader->SetShaderResourceView("restir_pdf_0", nullptr);
- gi_shader->SetShaderResourceView("restir_w_0", nullptr);
- gi_shader->SetUnorderedAccessView("restir_pdf_1", nullptr);
+ ray_gi_world_solver->SetShaderResourceView("restir_pdf_mask", nullptr);
+ ray_gi_world_solver->SetUnorderedAccessView("restir_pdf_1", nullptr);
+ ray_gi_world_solver->SetShaderResourceView("restir_pdf_0", nullptr);
+ ray_gi_world_solver->SetShaderResourceView("restir_w_0", nullptr);
- gi_shader->SetUnorderedAccessView("output", nullptr);
- gi_shader->SetShaderResourceView("position_map", nullptr);
- gi_shader->SetShaderResourceView("motion_texture", nullptr);
- gi_shader->SetShaderResourceView("ray0", nullptr);
- gi_shader->SetShaderResourceView("ray1", nullptr);
- gi_shader->SetUnorderedAccessView("props", nullptr);
- gi_shader->SetShaderResourceView("prev_position_map", nullptr);
+ ray_gi_world_solver->SetShaderResourceViewArray("DiffuseTextures[0]", no_data, nobjects);
- UnprepareLights(gi_shader);
- gi_shader->CopyAllBufferData();
+ UnprepareLights(ray_gi_world_solver);
+ ray_gi_world_solver->CopyAllBufferData();
+#endif
+#if 1
+ groupsX = (int32_t)(ceil((float)rt_texture_gi_curr->Width() / (32.0f)));
+ groupsY = (int32_t)(ceil((float)rt_texture_gi_curr->Height() / (32.0f)));
gi_weights->SetShader();
gi_weights->SetInt("ray_count", RESTIR_PIXEL_RAYS);
@@ -1816,41 +2036,81 @@ void RenderSystem::ProcessGI() {
gi_weights->CopyAllBufferData();
gi_average->SetInt("debug", rt_debug);
- gi_average->SetMatrix4x4(VIEW, cam_entity.camera->view);
- gi_average->SetMatrix4x4(PROJECTION, cam_entity.camera->projection);
+ gi_average->SetMatrix4x4("prev_view_proj", cam_entity.camera->prev_view_projection);
gi_average->SetFloat3(CAMERA_POSITION, cam_entity.camera->world_position);
gi_average->SetShaderResourceView("positions", rt_ray_sources0.SRV());
gi_average->SetShaderResourceView("normals", rt_ray_sources1.SRV());
- gi_average->SetShaderResourceView("prev_output", rt_texture_prev[RT_TEXTURE_INDIRECT].SRV());
+ gi_average->SetShaderResourceView("prev_output", rt_texture_gi_prev->SRV());
gi_average->SetShaderResourceView("motion_texture", motion_texture.SRV());
gi_average->SetShaderResourceView("prev_position_map", prev_position_map.SRV());
+ gi_average->SetShaderResourceView("tiles_output", rt_textures_gi_tiles.SRV());
gi_average->SetInt("kernel_size", RESTIR_HALF_KERNEL);
gi_average->SetInt("frame_count", frame_count);
+#if 1
+ //Pass 1
gi_average->SetInt("type", 1);
- gi_average->SetShaderResourceView("input", rt_texture_curr[RT_TEXTURE_INDIRECT].SRV());
- gi_average->SetUnorderedAccessView("output", texture_tmp.UAV());
+ gi_average->SetShaderResourceView("input", rt_texture_gi_trace->SRV());
+ gi_average->SetUnorderedAccessView("output", rt_texture_gi_tmp[0]->UAV());
gi_average->CopyAllBufferData();
gi_average->SetShader();
dxcore->context->Dispatch(groupsX, groupsY, 1);
-
gi_average->SetShaderResourceView("input", nullptr);
gi_average->SetUnorderedAccessView("output", nullptr);
gi_average->CopyAllBufferData();
+#if 1
+ //Pass 2
gi_average->SetInt("type", 2);
- gi_average->SetShaderResourceView("input", texture_tmp.SRV());
- gi_average->SetUnorderedAccessView("output", rt_texture_curr[RT_TEXTURE_INDIRECT].UAV());
+ gi_average->SetShaderResourceView("orig_input", rt_texture_gi_trace->SRV());
+ gi_average->SetShaderResourceView("input", rt_texture_gi_tmp[0]->SRV());
+ gi_average->SetUnorderedAccessView("output", rt_texture_gi_tmp[1]->UAV());
gi_average->CopyAllBufferData();
gi_average->SetShader();
dxcore->context->Dispatch(groupsX, groupsY, 1);
+ gi_average->SetShaderResourceView("input", nullptr);
+ gi_average->SetUnorderedAccessView("output", nullptr);
+ gi_average->CopyAllBufferData();
+ //Pass 3
+ gi_average->SetInt("type", 3);
+ gi_average->SetShaderResourceView("input", rt_texture_gi_tmp[1]->SRV());
+ gi_average->SetUnorderedAccessView("output", rt_texture_gi_curr->UAV());
+ gi_average->CopyAllBufferData();
+ gi_average->SetShader();
+ dxcore->context->Dispatch(groupsX, groupsY, 1);
+#else
+ //Pass 2
+ gi_average->SetInt("type", 2);
+ gi_average->SetShaderResourceView("orig_input", rt_texture_gi_trace->SRV());
+ gi_average->SetShaderResourceView("input", rt_texture_gi_tmp[0]->SRV());
+ gi_average->SetUnorderedAccessView("output", rt_texture_gi_curr->UAV());
+ gi_average->CopyAllBufferData();
+ gi_average->SetShader();
+ dxcore->context->Dispatch(groupsX, groupsY, 1);
gi_average->SetShaderResourceView("input", nullptr);
gi_average->SetUnorderedAccessView("output", nullptr);
+ gi_average->CopyAllBufferData();
+#endif
+#else
+ //Pass 3
+ gi_average->SetInt("type", 3);
+ gi_average->SetShaderResourceView("orig_input", rt_texture_gi_trace->SRV());
+ gi_average->SetShaderResourceView("input", rt_texture_gi_tmp[1]->SRV());
+ gi_average->SetUnorderedAccessView("output", rt_texture_gi_curr->UAV());
+ gi_average->CopyAllBufferData();
+ gi_average->SetShader();
+ dxcore->context->Dispatch(groupsX, groupsY, 1);
+#endif
+ gi_average->SetShaderResourceView("input", nullptr);
+ gi_average->SetUnorderedAccessView("output", nullptr);
+ gi_average->SetShaderResourceView("tiles_output", nullptr);
+ gi_average->SetShaderResourceView("orig_input", nullptr);
gi_average->SetShaderResourceView("positions", nullptr);
gi_average->SetShaderResourceView("normals", nullptr);
gi_average->SetShaderResourceView("prev_output", nullptr);
gi_average->SetShaderResourceView("motion_texture", nullptr);
gi_average->SetShaderResourceView("prev_position_map", nullptr);
gi_average->CopyAllBufferData();
+#endif
}
}
@@ -1858,150 +2118,184 @@ void RenderSystem::ProcessRT() {
if (rt_enabled & (RT_REFLEX_ENABLE || RT_REFRACT_ENABLE)) {
- rt_texture_curr = rt_textures[current];
- rt_texture_prev = rt_textures[prev];
+ rt_texture_di_curr = rt_textures_di[current];
+ rt_texture_di_prev = rt_textures_di[prev];
if (rt_quality != eRtQuality::OFF && rt_enabled && bvh_buffer != nullptr && nobjects > 0) {
- std::lock_guard lock(rt_mutex);
- CameraEntity& cam_entity = cameras.GetData()[0];
+ //Reset tiles (that avoid denoising tiles with no ray color)
+ rt_textures_gi_tiles.Clear(zero);
+ input_rays.Clear((float*)max_uint);
- rt_dispersion.Clear(minus_one);
- tbvh_buffer.Refresh(tbvh.Root(), 0, tbvh.Size());
+ ID3D11ShaderResourceView* nullsrc = nullptr;
+ ID3D11ShaderResourceView* no_data[MAX_OBJECTS] = {};
ID3D11RenderTargetView* nullRenderTargetViews[1] = { nullptr };
dxcore->context->OMSetRenderTargets(1, nullRenderTargetViews, nullptr);
- rt_di_shader->SetInt("kernel_size", RESTIR_KERNEL);
- rt_di_shader->SetInt("ray_count", RESTIR_PIXEL_RAYS);
-
- rt_di_shader->SetInt("nobjects", nobjects);
- rt_di_shader->SetInt("enabled", rt_enabled & (rt_quality != eRtQuality::OFF ? 0xFF : 0x00));
- rt_di_shader->SetMatrix4x4("view_proj", cam_entity.camera->view_projection);
- rt_di_shader->SetMatrix4x4("prev_view_proj", cam_entity.camera->prev_view_projection);
- rt_di_shader->SetInt("frame_count", frame_count);
- rt_di_shader->SetData("objectMaterials", objectMaterials, nobjects * sizeof(MaterialProps));
- rt_di_shader->SetData("objectInfos", objects, nobjects * sizeof(ObjectInfo));
-
- rt_di_shader->SetUnorderedAccessView("output0", rt_texture_curr[RT_TEXTURE_REFLEX].UAV());
- rt_di_shader->SetUnorderedAccessView("output1", rt_texture_curr[RT_TEXTURE_REFRACT].UAV());
- rt_di_shader->SetUnorderedAccessView("dispersion", rt_dispersion.UAV());
-
- rt_di_shader->SetShaderResourceView("position_map", position_map.SRV());
- rt_di_shader->SetShaderResourceView("depth_map", depth_map.SRV());
- rt_di_shader->SetShaderResourceView("motion_texture", motion_texture.SRV());
- rt_di_shader->SetUnorderedAccessView("bloom", rt_texture_curr[RT_TEXTURE_EMISSION].UAV());
- rt_di_shader->SetUnorderedAccessView("props", rt_texture_props.UAV());
+ //Set ray requests
rt_di_shader->SetShaderResourceView("ray0", rt_ray_sources0.SRV());
rt_di_shader->SetShaderResourceView("ray1", rt_ray_sources1.SRV());
rt_di_shader->SetShaderResourceView("rgbaNoise", rgba_noise_texture.SRV());
+ rt_di_shader->SetUnorderedAccessView("ray_inputs", input_rays.UAV());
- float3 dir;
- XMStoreFloat3(&dir, cam_entity.camera->xm_direction);
+ CameraEntity& cam_entity = cameras.GetData()[0];
rt_di_shader->SetFloat(TIME, time);
+ rt_di_shader->SetInt("enabled", rt_enabled & (rt_quality != eRtQuality::OFF ? 0xFF : 0x00));
+ rt_di_shader->SetInt("frame_count", frame_count);
+ rt_di_shader->SetInt("divider", RT_TEXTURE_RESOLUTION_DIVIDER);
rt_di_shader->SetFloat3(CAMERA_POSITION, cam_entity.camera->world_position);
- rt_di_shader->SetFloat3("cameraDirection", dir);
+
rt_di_shader->SetSamplerState(PCF_SAMPLER, dxcore->shadow_sampler);
rt_di_shader->SetSamplerState(BASIC_SAMPLER, dxcore->basic_sampler);
- rt_di_shader->SetShaderResourceViewArray("DiffuseTextures[0]", diffuseTextures, nobjects);
-
- PrepareLights(rt_di_shader);
rt_di_shader->CopyAllBufferData();
- dxcore->context->CSSetShaderResources(2, 1, bvh_buffer->SRV());
- dxcore->context->CSSetShaderResources(3, 1, tbvh_buffer.SRV());
- dxcore->context->CSSetShaderResources(4, 1, vertex_buffer->VertexSRV());
- dxcore->context->CSSetShaderResources(5, 1, vertex_buffer->IndexSRV());
rt_di_shader->SetShader();
- int32_t groupsX = (int32_t)(ceil((float)rt_texture_curr[RT_TEXTURE_REFLEX].Width() / (32.0f)));
- int32_t groupsY = (int32_t)(ceil((float)rt_texture_curr[RT_TEXTURE_REFLEX].Height() / (32.0f)));
- dxcore->context->Dispatch(groupsX, groupsY, 2);
-
- rt_di_shader->SetUnorderedAccessView("output0", nullptr);
- rt_di_shader->SetUnorderedAccessView("output1", nullptr);
- rt_di_shader->SetShaderResourceView("position_map", nullptr);
- rt_di_shader->SetShaderResourceView("motion_texture", nullptr);
+ int32_t groupsX = (int32_t)(ceil((float)rt_texture_di_curr[RT_TEXTURE_REFLEX].Width() / (32.0f)));
+ int32_t groupsY = (int32_t)(ceil((float)rt_texture_di_curr[RT_TEXTURE_REFLEX].Height() / (32.0f)));
+ dxcore->context->Dispatch(groupsX, groupsY, 1);
+
rt_di_shader->SetShaderResourceView("ray0", nullptr);
rt_di_shader->SetShaderResourceView("ray1", nullptr);
- rt_di_shader->SetUnorderedAccessView("bloom", nullptr);
- rt_di_shader->SetUnorderedAccessView("props", nullptr);
rt_di_shader->SetShaderResourceView("rgbaNoise", nullptr);
- rt_di_shader->SetUnorderedAccessView("dispersion", nullptr);
-
- UnprepareLights(rt_di_shader);
+ rt_di_shader->SetUnorderedAccessView("ray_inputs", nullptr);
rt_di_shader->CopyAllBufferData();
-#if 0
- //Smooth the dispersion textures
- groupsX = (int32_t)(ceil((float)rt_texture_curr[RT_TEXTURE_REFLEX].Width() / (32.0f)));
- groupsY = (int32_t)(ceil((float)rt_texture_curr[RT_TEXTURE_REFLEX].Height() / (32.0f)));
- rt_disp->SetShaderResourceView("input", rt_dispersion.SRV());
- rt_disp->SetUnorderedAccessView("output", texture_tmp.UAV());
- rt_disp->SetInt("type", 1);
- rt_disp->CopyAllBufferData();
- rt_disp->SetShader();
- dxcore->context->Dispatch(groupsX, groupsY, 1);
- rt_disp->SetShaderResourceView("input", nullptr);
- rt_disp->SetUnorderedAccessView("output", nullptr);
- rt_disp->CopyAllBufferData();
- rt_disp->SetShaderResourceView("input", texture_tmp.SRV());
- rt_disp->SetUnorderedAccessView("output", rt_dispersion.UAV());
- rt_disp->SetInt("type", 2);
- rt_disp->CopyAllBufferData();
- dxcore->context->Dispatch(groupsX, groupsY, 1);
- rt_disp->SetShaderResourceView("input", nullptr);
- rt_disp->SetUnorderedAccessView("output", nullptr);
- rt_disp->CopyAllBufferData();
-
- texture_tmp.Clear(zero);
- rt_disp->SetShaderResourceView("input", rt_dispersion.SRV());
- rt_disp->SetUnorderedAccessView("output", texture_tmp.UAV());
- rt_disp->SetInt("type", 3);
- rt_disp->CopyAllBufferData();
- rt_disp->SetShader();
+#if 1
+ //Resolve rays with screen space Ray Tracing
+ ray_reflex_screen_solver->SetInt("enabled", rt_enabled& (rt_quality != eRtQuality::OFF ? 0xFF : 0x00));
+ ray_reflex_screen_solver->SetInt("frame_count", frame_count);
+ ray_reflex_screen_solver->SetFloat(TIME, time);
+ ray_reflex_screen_solver->SetInt("kernel_size", RESTIR_KERNEL);
+ ray_reflex_screen_solver->SetInt("type", 1);
+ ray_reflex_screen_solver->SetFloat("hiz_ratio", HIZ_RATIO);
+ ray_reflex_screen_solver->SetInt("divider", RT_TEXTURE_RESOLUTION_DIVIDER);
+ ray_reflex_screen_solver->SetFloat3(CAMERA_POSITION, cam_entity.camera->world_position);
+ ray_reflex_screen_solver->SetMatrix4x4("view", cam_entity.camera->view);
+ ray_reflex_screen_solver->SetMatrix4x4("projection", cam_entity.camera->projection);
+ ray_reflex_screen_solver->SetMatrix4x4("inv_projection", cam_entity.camera->inverse_projection);
+
+ ray_reflex_screen_solver->SetShaderResourceView("ray0", rt_ray_sources0.SRV());
+ ray_reflex_screen_solver->SetShaderResourceView("ray1", rt_ray_sources1.SRV());
+ ray_reflex_screen_solver->SetUnorderedAccessView("ray_inputs", input_rays.UAV());
+ ray_reflex_screen_solver->SetUnorderedAccessView("output", rt_texture_di_curr[RT_TEXTURE_REFLEX].UAV());
+ ray_reflex_screen_solver->SetUnorderedAccessView("tiles_output", rt_textures_gi_tiles.UAV());
+
+ ray_reflex_screen_solver->SetShaderResourceView("colorTexture", post_process_pipeline->RenderResource());
+ ray_reflex_screen_solver->SetShaderResourceView("lightTexture", current_light_map->SRV());
+ ray_reflex_screen_solver->SetShaderResourceView("bloomTexture", bloom_map.SRV());
+
+ ray_reflex_screen_solver->SetShaderResourceViewArray("hiz_textures[0]", high_z_maps, HIZ_NTEXTURES);
+
+ ray_reflex_screen_solver->CopyAllBufferData();
+ ray_reflex_screen_solver->SetShader();
+
+ groupsX = (int32_t)(ceil((float)rt_texture_di_curr[RT_TEXTURE_REFLEX].Width() / (16.0f)));
+ groupsY = (int32_t)(ceil((float)rt_texture_di_curr[RT_TEXTURE_REFLEX].Height() / (16.0f)));
dxcore->context->Dispatch(groupsX, groupsY, 1);
- rt_disp->SetShaderResourceView("input", nullptr);
- rt_disp->SetUnorderedAccessView("output", nullptr);
- rt_disp->CopyAllBufferData();
-
- rt_disp->SetShaderResourceView("input", texture_tmp.SRV());
- rt_disp->SetUnorderedAccessView("output", rt_dispersion.UAV());
- rt_disp->SetInt("type", 4);
- rt_disp->CopyAllBufferData();
+
+ ray_reflex_screen_solver->SetShaderResourceView("ray0", nullptr);
+ ray_reflex_screen_solver->SetShaderResourceView("ray1", nullptr);
+ ray_reflex_screen_solver->SetUnorderedAccessView("ray_inputs", nullptr);
+ ray_reflex_screen_solver->SetUnorderedAccessView("output", nullptr);
+ ray_reflex_screen_solver->SetUnorderedAccessView("tiles_output", nullptr);
+
+ ray_reflex_screen_solver->SetShaderResourceView("colorTexture", nullptr);
+ ray_reflex_screen_solver->SetShaderResourceView("lightTexture", nullptr);
+ ray_reflex_screen_solver->SetShaderResourceView("bloomTexture", nullptr);
+
+ ray_reflex_screen_solver->SetShaderResourceViewArray("hiz_textures[0]", no_data, HIZ_NTEXTURES);
+
+ ray_reflex_screen_solver->CopyAllBufferData();
+#endif
+#if 1
+ // Resolve rays with world space Ray Tracing
+ {
+ //We need at this point the BVH structures to be available
+ std::lock_guard lock(rt_mutex);
+ tbvh_buffer.Refresh(tbvh.Root(), 0, tbvh.Size());
+ }
+ rt_texture_di_curr[RT_TEXTURE_REFRACT].Clear(zero);
+ ray_reflex_world_solver->SetInt("enabled", rt_enabled & (rt_quality != eRtQuality::OFF ? 0xFF : 0x00));
+ ray_reflex_world_solver->SetInt("frame_count", frame_count);
+ ray_reflex_world_solver->SetFloat(TIME, time);
+ ray_reflex_world_solver->SetInt("type", 1);
+ ray_reflex_world_solver->SetInt("kernel_size", RESTIR_KERNEL);
+ ray_reflex_world_solver->SetInt("nobjects", nobjects);
+ ray_reflex_world_solver->SetData("objectMaterials", objectMaterials, nobjects * sizeof(MaterialProps));
+ ray_reflex_world_solver->SetData("objectInfos", objects, nobjects * sizeof(ObjectInfo));
+ ray_reflex_world_solver->SetFloat3(CAMERA_POSITION, cam_entity.camera->world_position);
+
+ ray_reflex_world_solver->SetUnorderedAccessView("output0", rt_texture_di_curr[RT_TEXTURE_REFLEX].UAV());
+ ray_reflex_world_solver->SetUnorderedAccessView("output1", rt_texture_di_curr[RT_TEXTURE_REFRACT].UAV());
+ ray_reflex_world_solver->SetUnorderedAccessView("bloom", rt_texture_di_curr[RT_TEXTURE_EMISSION].UAV());
+ ray_reflex_world_solver->SetUnorderedAccessView("tiles_output", rt_textures_gi_tiles.UAV());
+ ray_reflex_world_solver->SetShaderResourceView("ray0", rt_ray_sources0.SRV());
+ ray_reflex_world_solver->SetShaderResourceView("ray1", rt_ray_sources1.SRV());
+ ray_reflex_world_solver->SetShaderResourceView("ray_inputs", input_rays.SRV());
+ ray_reflex_world_solver->SetShaderResourceViewArray("DiffuseTextures[0]", diffuseTextures, nobjects);
+ ray_reflex_world_solver->SetSamplerState(PCF_SAMPLER, dxcore->shadow_sampler);
+ ray_reflex_world_solver->SetSamplerState(BASIC_SAMPLER, dxcore->basic_sampler);
+
+ PrepareLights(ray_reflex_world_solver);
+
+ ray_reflex_world_solver->CopyAllBufferData();
+
+ dxcore->context->CSSetShaderResources(2, 1, bvh_buffer->SRV());
+ dxcore->context->CSSetShaderResources(3, 1, tbvh_buffer.SRV());
+ dxcore->context->CSSetShaderResources(4, 1, vertex_buffer->VertexSRV());
+ dxcore->context->CSSetShaderResources(5, 1, vertex_buffer->IndexSRV());
+ ray_reflex_world_solver->SetShader();
+
+ groupsX = (int32_t)(ceil((float)rt_texture_di_curr[RT_TEXTURE_REFLEX].Width() / (RESTIR_KERNEL)));
+ groupsY = (int32_t)(ceil((float)rt_texture_di_curr[RT_TEXTURE_REFLEX].Height() / (RESTIR_KERNEL)));
dxcore->context->Dispatch(groupsX, groupsY, 1);
- rt_disp->SetShaderResourceView("input", nullptr);
- rt_disp->SetUnorderedAccessView("output", nullptr);
- rt_disp->CopyAllBufferData();
+
+ ray_reflex_world_solver->SetUnorderedAccessView("output0", nullptr);
+ ray_reflex_world_solver->SetUnorderedAccessView("output1", nullptr);
+ ray_reflex_world_solver->SetShaderResourceView("ray0", nullptr);
+ ray_reflex_world_solver->SetShaderResourceView("ray1", nullptr);
+ ray_reflex_world_solver->SetUnorderedAccessView("bloom", nullptr);
+ ray_reflex_world_solver->SetUnorderedAccessView("tiles_output", nullptr);
+ ray_reflex_world_solver->SetShaderResourceView("ray_inputs", nullptr);
+ dxcore->context->CSSetShaderResources(2, 1, &nullsrc);
+ dxcore->context->CSSetShaderResources(3, 1, &nullsrc);
+ dxcore->context->CSSetShaderResources(4, 1, &nullsrc);
+ dxcore->context->CSSetShaderResources(5, 1, &nullsrc);
+
+ ray_reflex_world_solver->SetShaderResourceViewArray("DiffuseTextures[0]", no_data, nobjects);
+
+ UnprepareLights(ray_reflex_world_solver);
+ ray_reflex_world_solver->CopyAllBufferData();
#endif
+#if 1
//Denoiser
+ rt_di_denoiser->SetInt("kernel_size", RESTIR_KERNEL);
rt_di_denoiser->SetInt("debug", rt_debug);
rt_di_denoiser->SetShaderResourceView("positions", rt_ray_sources0.SRV());
rt_di_denoiser->SetShaderResourceView("normals", rt_ray_sources1.SRV());
rt_di_denoiser->SetShaderResourceView("motion_texture", motion_texture.SRV());
rt_di_denoiser->SetShaderResourceView("prev_position_map", prev_position_map.SRV());
- rt_di_denoiser->SetMatrix4x4(VIEW, cam_entity.camera->view);
- rt_di_denoiser->SetMatrix4x4(PROJECTION, cam_entity.camera->projection);
+ rt_di_denoiser->SetMatrix4x4("view_projection", cam_entity.camera->view_projection);
rt_di_denoiser->SetFloat3(CAMERA_POSITION, cam_entity.camera->world_position);
- rt_di_denoiser->SetShaderResourceView("dispersion", rt_dispersion.SRV());
+ rt_di_denoiser->SetShaderResourceView("tiles_output", rt_textures_gi_tiles.SRV());
static constexpr int textures[] = { RT_TEXTURE_REFLEX, RT_TEXTURE_REFRACT };
static constexpr int ntextures = sizeof(textures) / sizeof(int);
for (int i = 0; i < ntextures; ++i) {
int ntexture = textures[i];
- groupsX = (int32_t)(ceil((float)rt_texture_curr[ntexture].Width() / (32.0f)));
- groupsY = (int32_t)(ceil((float)rt_texture_curr[ntexture].Height() / (32.0f)));
+ groupsX = (int32_t)(ceil((float)rt_texture_di_curr[ntexture].Width() / (32.0f)));
+ groupsY = (int32_t)(ceil((float)rt_texture_di_curr[ntexture].Height() / (32.0f)));
- rt_di_denoiser->SetShaderResourceView("input", rt_texture_curr[ntexture].SRV());
+ rt_di_denoiser->SetShaderResourceView("input", rt_texture_di_curr[ntexture].SRV());
rt_di_denoiser->SetUnorderedAccessView("output", texture_tmp.UAV());
- rt_di_denoiser->SetShaderResourceView("prev_output", rt_texture_prev[ntexture].SRV());
+ rt_di_denoiser->SetShaderResourceView("prev_output", rt_texture_di_prev[ntexture].SRV());
rt_di_denoiser->SetInt("type", 1);
rt_di_denoiser->SetInt("light_type", i);
rt_di_denoiser->CopyAllBufferData();
rt_di_denoiser->SetShader();
- groupsX = (int32_t)(ceil((float)rt_texture_curr[ntexture].Width() / (32.0f)));
- groupsY = (int32_t)(ceil((float)rt_texture_curr[ntexture].Height() / (32.0f)));
dxcore->context->Dispatch(groupsX, groupsY, 1);
rt_di_denoiser->SetShaderResourceView("input", nullptr);
rt_di_denoiser->SetUnorderedAccessView("output", nullptr);
@@ -2009,7 +2303,7 @@ void RenderSystem::ProcessRT() {
//Denoiser
rt_di_denoiser->SetShaderResourceView("input", texture_tmp.SRV());
- rt_di_denoiser->SetUnorderedAccessView("output", rt_texture_curr[ntexture].UAV());
+ rt_di_denoiser->SetUnorderedAccessView("output", rt_texture_di_curr[ntexture].UAV());
rt_di_denoiser->SetInt("type", 2);
rt_di_denoiser->CopyAllBufferData();
dxcore->context->Dispatch(groupsX, groupsY, 1);
@@ -2025,17 +2319,19 @@ void RenderSystem::ProcessRT() {
rt_di_denoiser->SetShaderResourceView("motion_texture", nullptr);
rt_di_denoiser->SetShaderResourceView("prev_position_map", nullptr);
rt_di_denoiser->SetShaderResourceView("dispersion", nullptr);
- rt_di_denoiser->CopyAllBufferData();
+ rt_di_denoiser->SetShaderResourceView("tiles_output", nullptr);
+ rt_di_denoiser->CopyAllBufferData();
+#endif
#if 0
//Apply antialias
int ntexture = RT_TEXTURE_INDIRECT;
- groupsX = (int32_t)(ceil((float)rt_texture_curr[ntexture].Width() / (32.0f)));
- groupsY = (int32_t)(ceil((float)rt_texture_curr[ntexture].Height() / (32.0f)));
+ groupsX = (int32_t)(ceil((float)rt_texture_di_curr[ntexture].Width() / (32.0f)));
+ groupsY = (int32_t)(ceil((float)rt_texture_di_curr[ntexture].Height() / (32.0f)));
aa_shader->SetShaderResourceView("depthTexture", depth_map.SRV());
aa_shader->SetShaderResourceView("normalTexture", rt_ray_sources1.SRV());
- aa_shader->SetShaderResourceView("input", rt_texture_curr[ntexture].SRV());
+ aa_shader->SetShaderResourceView("input", rt_texture_di_curr[ntexture].SRV());
aa_shader->SetInt("enabled", true);
aa_shader->SetInt("size", 4);
aa_shader->SetUnorderedAccessView("output", texture_tmp.UAV());
@@ -2046,7 +2342,7 @@ void RenderSystem::ProcessRT() {
aa_shader->SetShaderResourceView("input", nullptr);
aa_shader->CopyAllBufferData();
aa_shader->SetShaderResourceView("input", texture_tmp.SRV());
- aa_shader->SetUnorderedAccessView("output", rt_texture_curr[ntexture].UAV());
+ aa_shader->SetUnorderedAccessView("output", rt_texture_di_curr[ntexture].UAV());
aa_shader->SetInt("size", 4);
aa_shader->CopyAllBufferData();
aa_shader->SetShader();
@@ -2605,6 +2901,7 @@ void RenderSystem::Draw() {
DrawScene(w, h, camera_position, view, projection, first_pass_texture.SRV(), second_pass_target, render_pass2_tree);
}
ProcessMotion();
+ ProcessHighZ();
ProcessRT();
ProcessGI();
PostProcessLight();
@@ -2696,10 +2993,16 @@ void RenderSystem::SetRayTracingQuality(eRtQuality quality) {
void RenderSystem::ResetRTBBuffers() {
for (int i = 0; i < RT_NTEXTURES; ++i) {
for (int x = 0; x < 2; ++x) {
- rt_textures[x][i].Clear(zero);
+ rt_textures_di[x][i].Clear(zero);
}
}
+ for (int x = 0; x < RT_GI_NTEXTURES; ++x) {
+ rt_textures_gi[x].Clear(zero);
+ }
+
+ rt_textures_gi_tiles.Clear(zero);
+
static const float nrays[4] = { RESTIR_PIXEL_RAYS, RESTIR_PIXEL_RAYS, RESTIR_PIXEL_RAYS, RESTIR_PIXEL_RAYS };
for (int i = 0; i < 2; ++i)
@@ -2707,6 +3010,7 @@ void RenderSystem::ResetRTBBuffers() {
light_map[i].Clear(zero);
restir_pdf[i].Clear(zero);
restir_w.Clear(nrays);
+ restir_pdf_mask.Clear(zero);
}
}
diff --git a/Engine/Engine/Systems/RenderSystem.h b/Engine/Engine/Systems/RenderSystem.h
index f880d34..e604d24 100644
--- a/Engine/Engine/Systems/RenderSystem.h
+++ b/Engine/Engine/Systems/RenderSystem.h
@@ -273,10 +273,13 @@ namespace HotBite {
//Motion blur
Core::SimpleComputeShader* motion_blur = nullptr;
-
+
+
+
//Ray tracing
eRtQuality rt_quality = eRtQuality::MID;
uint32_t RT_TEXTURE_RESOLUTION_DIVIDER = 1;
+ uint32_t GI_TEXTURE_RESOLUTION_DIVIDER = 4;
static constexpr uint32_t RT_REFLEX_ENABLE = 1;
static constexpr uint32_t RT_REFRACT_ENABLE = 2;
static constexpr uint32_t RT_INDIRECT_ENABLE = 4;
@@ -285,39 +288,50 @@ namespace HotBite {
Core::TBVH tbvh{ MAX_OBJECTS };
Core::SimpleComputeShader* rt_di_shader = nullptr;
Core::SimpleComputeShader* rt_di_denoiser = nullptr;
- Core::SimpleComputeShader* rt_disp = nullptr;
-
+
Core::SimpleComputeShader* gi_shader = nullptr;
Core::SimpleComputeShader* gi_average = nullptr;
Core::SimpleComputeShader* gi_weights = nullptr;
- //RT texture 1: Reflexed rays
- //RT texture 2: Refracted rays
- //RT texture 3: Indirect rays
+ Core::SimpleComputeShader* ray_gi_world_solver = nullptr;
+ Core::SimpleComputeShader* ray_gi_screen_solver = nullptr;
+ Core::SimpleComputeShader* ray_reflex_world_solver = nullptr;
+ Core::SimpleComputeShader* ray_reflex_screen_solver = nullptr;
+
static constexpr int RT_TEXTURE_REFLEX = 0;
static constexpr int RT_TEXTURE_REFRACT = 1;
- static constexpr int RT_TEXTURE_INDIRECT = 2;
- static constexpr int RT_TEXTURE_EMISSION = 3;
+ static constexpr int RT_TEXTURE_EMISSION = 2;
+
+ static constexpr int RT_NTEXTURES = 3;
+ Core::RenderTexture2D rt_textures_di[2][RT_NTEXTURES];
+
+ static constexpr int RT_GI_NTEXTURES = 5;
+ Core::RenderTexture2D rt_textures_gi[RT_GI_NTEXTURES];
+ Core::RenderTexture2D rt_textures_gi_tiles;
+ Core::RenderTexture2D rt_inputs;
- static constexpr int RT_NTEXTURES = 4;
- Core::RenderTexture2D rt_textures[2][RT_NTEXTURES];
Core::RenderTexture2D restir_pdf[2];
+ Core::RenderTexture2D restir_pdf_mask;
+
Core::RenderTexture2D restir_w;
Core::RenderTexture2D* restir_pdf_curr = nullptr;
Core::RenderTexture2D* restir_pdf_prev = nullptr;
- static constexpr uint32_t RESTIR_HALF_KERNEL = 5;
+ static constexpr uint32_t RESTIR_HALF_KERNEL = 4;
static constexpr uint32_t RESTIR_KERNEL = 2 * RESTIR_HALF_KERNEL + 1;
static constexpr uint32_t RESTIR_PIXEL_RAYS = 16;
static constexpr uint32_t RESTIR_TOTAL_RAYS = RESTIR_PIXEL_RAYS * RESTIR_KERNEL * RESTIR_KERNEL;
+ Core::RenderTexture2D* rt_texture_di_prev;
+ Core::RenderTexture2D* rt_texture_di_curr;
+ Core::RenderTexture2D* rt_texture_gi_prev;
+ Core::RenderTexture2D* rt_texture_gi_curr;
+ Core::RenderTexture2D* rt_texture_gi_tmp[2];
+ Core::RenderTexture2D* rt_texture_gi_trace = nullptr;
- Core::RenderTexture2D* rt_texture_prev;
- Core::RenderTexture2D* rt_texture_curr;
Core::RenderTexture2D rt_texture_props;
Core::RenderTexture2D rt_ray_sources0;
Core::RenderTexture2D rt_ray_sources1;
- Core::RenderTexture2D rt_dispersion;
Core::ExtBVHBuffer tbvh_buffer;
Core::BVHBuffer* bvh_buffer = nullptr;
ObjectInfo objects[MAX_OBJECTS]{};
@@ -330,6 +344,24 @@ namespace HotBite {
bool rt_prepare = false;
std::thread rt_thread;
+ struct RayData {
+ float2 dir0{ FLT_MAX, FLT_MAX };
+ float2 dir1{ FLT_MAX, FLT_MAX };
+ float2 dir2{ FLT_MAX, FLT_MAX };
+ float2 dir3{ FLT_MAX, FLT_MAX };
+ };
+
+ Core::RenderTexture2D input_rays;
+
+ //SSR
+ Core::SimpleComputeShader* high_z_shader = nullptr;
+ static constexpr uint32_t HIZ_RATIO = 5;
+ static constexpr uint32_t HIZ_DOWNSAMPLED_NTEXTURES = 3;
+ static constexpr uint32_t HIZ_NTEXTURES = HIZ_DOWNSAMPLED_NTEXTURES + 1;
+ Core::RenderTexture2D high_z_tmp_map;
+ Core::RenderTexture2D high_z_downsampled_map[HIZ_DOWNSAMPLED_NTEXTURES];
+ ID3D11ShaderResourceView* high_z_maps[HIZ_NTEXTURES]{};
+
//Copy texture shader
Core::SimpleComputeShader* copy_texture = nullptr;
@@ -396,6 +428,7 @@ namespace HotBite {
void ResetRTBBuffers();
void CopyTexture(const Core::RenderTexture2D& input, Core::RenderTexture2D& output);
void ProcessMotion();
+ void ProcessHighZ();
void PrepareRT();
void ProcessRT();
void ProcessGI();
diff --git a/Tests/DemoGame/DemoGame.cpp b/Tests/DemoGame/DemoGame.cpp
index dd2bfeb..ab50b22 100644
--- a/Tests/DemoGame/DemoGame.cpp
+++ b/Tests/DemoGame/DemoGame.cpp
@@ -87,7 +87,7 @@ class GameDemoApplication : public DXCore, public ECS::EventListener
AudioSystem::PlayId tone = AudioSystem::INVALID_PLAY_ID;
public:
- GameDemoApplication(HINSTANCE hInstance) :DXCore(hInstance, "HotBiteDemoGame", 1280, 720, true, false) {
+ GameDemoApplication(HINSTANCE hInstance) :DXCore(hInstance, "HotBiteDemoGame", 1920, 1080, true, false) {
root = "..\\..\\..\\Tests\\DemoGame\\";
//Initialize core DirectX
InitWindow();
@@ -279,6 +279,7 @@ class GameDemoApplication : public DXCore, public ECS::EventListener
};
set_terrain("Terrain*");
set_terrain("Bricks*");
+ set_terrain("floor*");
progress += 5.0f;
render->Update();
@@ -596,6 +597,7 @@ class GameDemoApplication : public DXCore, public ECS::EventListener
std::unordered_map last_ball_sound_ts;
//This method spawns a new fireball in the scene
void SpawnFireBall(int id) {
+ return;
ECS::Coordinator* c = world.GetCoordinator();
//NOTE: Always lock first renderer mutex before physics mutex to avoid interlock
shared_ptr rs = c->GetSystem();
diff --git a/Tests/DemoGame/GameCameraSystem.h b/Tests/DemoGame/GameCameraSystem.h
index 2123350..0995516 100644
--- a/Tests/DemoGame/GameCameraSystem.h
+++ b/Tests/DemoGame/GameCameraSystem.h
@@ -179,6 +179,7 @@ class GameCameraSystem : public ECS::System, public EventListener {
//Event CameraSystem::EVENT_ID_CAMERA_MOVED received every time the camera is moved,
//we check if the camera is clipping with the terrain and if so we correct the position
void CheckCameraPosition(ECS::Event& ev) {
+ return;
if (!is_checking_camera) {
this->is_checking_camera = true;
//Smooth correct position to avoid camera clipping with terrain
diff --git a/Tests/DemoGame/TerrainGS.hlsl b/Tests/DemoGame/TerrainGS.hlsl
index d13c7fb..39b882a 100644
--- a/Tests/DemoGame/TerrainGS.hlsl
+++ b/Tests/DemoGame/TerrainGS.hlsl
@@ -98,6 +98,15 @@ void CreateGrass(float3 pos, matrix worldViewProj, inout TriangleStream< GSOutpu
}
+float4 frustumPlanes[6] = {
+ float4(1, 0, 0, 1),
+ float4(-1, 0, 0, 1),
+ float4(0, 1, 0, 1),
+ float4(0, -1, 0, 1),
+ float4(0, 0, 1, 1),
+ float4(0, 0, -1, 1)
+};
+
[maxvertexcount(39)]
void main(
triangle TerrainDomainOutput input[3],
@@ -105,24 +114,58 @@ void main(
)
{
matrix worldViewProj = mul(view, projection);
-#if 0
+#if 1
bool process = false;
- uint i = 0;
+
float4 p[3];
+ float2 dimensions = { screenW , screenH };
+
+ uint i = 0;
for (i = 0; i < 3; i++) {
p[i] = mul(input[i].worldPos, worldViewProj);
}
+
+ bool behind = true;
for (i = 0; i < 3; i++) {
- float2 pos;
- pos = p[i].xy;
- pos.x /= p[i].w;
- pos.y /= -p[i].w;
- pos.x = (pos.x + 1.0f) * 0.5f;
- pos.y = (pos.y + 1.0f) * 0.5f;
- if (pos.x > -0.2f && pos.x < 1.2f && pos.y > -0.2f && pos.y < 1.2f) {
- process = true;
+ if (p[i].z >= 0.0f) {
+ behind = false;
break;
- }
+ }
+ }
+
+ if (!behind) {
+ for (i = 0; i < 3; i++) {
+ float2 pos;
+ pos = p[i].xy;
+ pos.xy /= p[i].w;
+ pos.y *= -1.0f;
+
+ pos.xy = (pos.xy + 1.0f) * 0.5f;
+ if (pos.x >= 0.0f && pos.x <= 1.0f && pos.y >= 0.0f && pos.y <= 1.0f) {
+ process = true;
+ break;
+ }
+ }
+ }
+
+ if (!process) {
+ float3 pp[3];
+ for (i = 0; i < 3; ++i) {
+ pp[i] = p[i].xyz / p[i].w;
+ }
+
+ float3 normal = cross(pp[1].xyz - pp[0].xyz, pp[2].xyz - pp[0].xyz);
+ float d = dot(normal, pp[0].xyz);
+ float3 frustumCenter = float3(0.0f, 0.0f, 0.0f);
+
+ for (int i = 0; i < 6; i++) {
+ frustumCenter += float3(frustumPlanes[i].x, frustumPlanes[i].y, frustumPlanes[i].z) * frustumPlanes[i].w;
+ }
+ frustumCenter /= 6.0f;
+
+ if (abs(dot(normal, frustumCenter) + d) < length(normal)) {
+ process = true;
+ }
}
#else
bool process = true;
@@ -132,6 +175,7 @@ void main(
p[i] = mul(input[i].worldPos, worldViewProj);
}
#endif
+
if (process) {
// Edges of the triangle : postion delta
diff --git a/Tests/DemoGame/assets/level.fbx b/Tests/DemoGame/assets/level.fbx
new file mode 100644
index 0000000..2c49379
Binary files /dev/null and b/Tests/DemoGame/assets/level.fbx differ
diff --git a/Tests/DemoGame/assets/materials/Background_Albedo.png b/Tests/DemoGame/assets/materials/Background_Albedo.png
new file mode 100644
index 0000000..c87da4f
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Background_Albedo.png differ
diff --git a/Tests/DemoGame/assets/materials/Background_Normal.png b/Tests/DemoGame/assets/materials/Background_Normal.png
new file mode 100644
index 0000000..a9be84c
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Background_Normal.png differ
diff --git a/Tests/DemoGame/assets/materials/Background_Roughness.png b/Tests/DemoGame/assets/materials/Background_Roughness.png
new file mode 100644
index 0000000..55e3232
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Background_Roughness.png differ
diff --git a/Tests/DemoGame/assets/materials/Bricks076C_1K_NormalGL.jpg b/Tests/DemoGame/assets/materials/Bricks076C_1K_NormalGL.jpg
new file mode 100644
index 0000000..a14d95d
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Bricks076C_1K_NormalGL.jpg differ
diff --git a/Tests/DemoGame/assets/materials/ChainTexture_Albedo.png b/Tests/DemoGame/assets/materials/ChainTexture_Albedo.png
new file mode 100644
index 0000000..59986b1
Binary files /dev/null and b/Tests/DemoGame/assets/materials/ChainTexture_Albedo.png differ
diff --git a/Tests/DemoGame/assets/materials/ChainTexture_Metallic.png b/Tests/DemoGame/assets/materials/ChainTexture_Metallic.png
new file mode 100644
index 0000000..01edb18
Binary files /dev/null and b/Tests/DemoGame/assets/materials/ChainTexture_Metallic.png differ
diff --git a/Tests/DemoGame/assets/materials/ChainTexture_Normal.png b/Tests/DemoGame/assets/materials/ChainTexture_Normal.png
new file mode 100644
index 0000000..8c8a6f8
Binary files /dev/null and b/Tests/DemoGame/assets/materials/ChainTexture_Normal.png differ
diff --git a/Tests/DemoGame/assets/materials/ChainTexture_Roughness.png b/Tests/DemoGame/assets/materials/ChainTexture_Roughness.png
new file mode 100644
index 0000000..2e5349d
Binary files /dev/null and b/Tests/DemoGame/assets/materials/ChainTexture_Roughness.png differ
diff --git a/Tests/DemoGame/assets/materials/Dielectric_metallic.png b/Tests/DemoGame/assets/materials/Dielectric_metallic.png
new file mode 100644
index 0000000..1a14068
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Dielectric_metallic.png differ
diff --git a/Tests/DemoGame/assets/materials/Lion_Albedo.png b/Tests/DemoGame/assets/materials/Lion_Albedo.png
new file mode 100644
index 0000000..856314b
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Lion_Albedo.png differ
diff --git a/Tests/DemoGame/assets/materials/Lion_Normal.png b/Tests/DemoGame/assets/materials/Lion_Normal.png
new file mode 100644
index 0000000..8f9f587
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Lion_Normal.png differ
diff --git a/Tests/DemoGame/assets/materials/Lion_Roughness.png b/Tests/DemoGame/assets/materials/Lion_Roughness.png
new file mode 100644
index 0000000..d37c9c9
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Lion_Roughness.png differ
diff --git a/Tests/DemoGame/assets/materials/Marble002_4K-JPG_Color.jpg b/Tests/DemoGame/assets/materials/Marble002_4K-JPG_Color.jpg
new file mode 100644
index 0000000..7724c30
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Marble002_4K-JPG_Color.jpg differ
diff --git a/Tests/DemoGame/assets/materials/Marble002_4K-JPG_Displacement.jpg b/Tests/DemoGame/assets/materials/Marble002_4K-JPG_Displacement.jpg
new file mode 100644
index 0000000..1edac04
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Marble002_4K-JPG_Displacement.jpg differ
diff --git a/Tests/DemoGame/assets/materials/Marble002_4K-JPG_NormalDX.jpg b/Tests/DemoGame/assets/materials/Marble002_4K-JPG_NormalDX.jpg
new file mode 100644
index 0000000..775f58d
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Marble002_4K-JPG_NormalDX.jpg differ
diff --git a/Tests/DemoGame/assets/materials/Marble002_4K-JPG_Roughness.jpg b/Tests/DemoGame/assets/materials/Marble002_4K-JPG_Roughness.jpg
new file mode 100644
index 0000000..3cf88ec
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Marble002_4K-JPG_Roughness.jpg differ
diff --git a/Tests/DemoGame/assets/materials/Metal062B_2K-PNG_Color.png b/Tests/DemoGame/assets/materials/Metal062B_2K-PNG_Color.png
new file mode 100644
index 0000000..4d3f152
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Metal062B_2K-PNG_Color.png differ
diff --git a/Tests/DemoGame/assets/materials/Metal062B_2K-PNG_Displacement.png b/Tests/DemoGame/assets/materials/Metal062B_2K-PNG_Displacement.png
new file mode 100644
index 0000000..6bce37b
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Metal062B_2K-PNG_Displacement.png differ
diff --git a/Tests/DemoGame/assets/materials/Metal062B_2K-PNG_NormalDX.png b/Tests/DemoGame/assets/materials/Metal062B_2K-PNG_NormalDX.png
new file mode 100644
index 0000000..0e1c765
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Metal062B_2K-PNG_NormalDX.png differ
diff --git a/Tests/DemoGame/assets/materials/Metal062B_2K-PNG_Roughness.png b/Tests/DemoGame/assets/materials/Metal062B_2K-PNG_Roughness.png
new file mode 100644
index 0000000..e0b66bf
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Metal062B_2K-PNG_Roughness.png differ
diff --git a/Tests/DemoGame/assets/materials/Metallic_metallic.png b/Tests/DemoGame/assets/materials/Metallic_metallic.png
new file mode 100644
index 0000000..68a2a3a
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Metallic_metallic.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza.fbx b/Tests/DemoGame/assets/materials/Sponza.fbx
new file mode 100644
index 0000000..dd13fc7
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza.fbx differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Arch_diffuse.png b/Tests/DemoGame/assets/materials/Sponza_Arch_diffuse.png
new file mode 100644
index 0000000..ca039b8
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Arch_diffuse.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Arch_normal.png b/Tests/DemoGame/assets/materials/Sponza_Arch_normal.png
new file mode 100644
index 0000000..c341663
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Arch_normal.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Arch_roughness.png b/Tests/DemoGame/assets/materials/Sponza_Arch_roughness.png
new file mode 100644
index 0000000..206c311
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Arch_roughness.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Bricks_a_Albedo.png b/Tests/DemoGame/assets/materials/Sponza_Bricks_a_Albedo.png
new file mode 100644
index 0000000..cb29c44
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Bricks_a_Albedo.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Bricks_a_Normal.png b/Tests/DemoGame/assets/materials/Sponza_Bricks_a_Normal.png
new file mode 100644
index 0000000..027b1d2
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Bricks_a_Normal.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Bricks_a_Roughness.png b/Tests/DemoGame/assets/materials/Sponza_Bricks_a_Roughness.png
new file mode 100644
index 0000000..cb68565
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Bricks_a_Roughness.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Ceiling_diffuse.png b/Tests/DemoGame/assets/materials/Sponza_Ceiling_diffuse.png
new file mode 100644
index 0000000..bac82fa
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Ceiling_diffuse.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Ceiling_normal.png b/Tests/DemoGame/assets/materials/Sponza_Ceiling_normal.png
new file mode 100644
index 0000000..459b7c4
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Ceiling_normal.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Ceiling_roughness.png b/Tests/DemoGame/assets/materials/Sponza_Ceiling_roughness.png
new file mode 100644
index 0000000..af12eac
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Ceiling_roughness.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Column_a_diffuse.png b/Tests/DemoGame/assets/materials/Sponza_Column_a_diffuse.png
new file mode 100644
index 0000000..00d633c
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Column_a_diffuse.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Column_a_normal.png b/Tests/DemoGame/assets/materials/Sponza_Column_a_normal.png
new file mode 100644
index 0000000..7ed36a4
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Column_a_normal.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Column_a_roughness.png b/Tests/DemoGame/assets/materials/Sponza_Column_a_roughness.png
new file mode 100644
index 0000000..4cc33d5
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Column_a_roughness.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Column_b_diffuse.png b/Tests/DemoGame/assets/materials/Sponza_Column_b_diffuse.png
new file mode 100644
index 0000000..8c2c3eb
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Column_b_diffuse.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Column_b_normal.png b/Tests/DemoGame/assets/materials/Sponza_Column_b_normal.png
new file mode 100644
index 0000000..028c728
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Column_b_normal.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Column_b_roughness.png b/Tests/DemoGame/assets/materials/Sponza_Column_b_roughness.png
new file mode 100644
index 0000000..ee586b2
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Column_b_roughness.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Column_c_diffuse.png b/Tests/DemoGame/assets/materials/Sponza_Column_c_diffuse.png
new file mode 100644
index 0000000..beb4383
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Column_c_diffuse.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Column_c_normal.png b/Tests/DemoGame/assets/materials/Sponza_Column_c_normal.png
new file mode 100644
index 0000000..7ce2b64
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Column_c_normal.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Column_c_roughness.png b/Tests/DemoGame/assets/materials/Sponza_Column_c_roughness.png
new file mode 100644
index 0000000..ce8affd
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Column_c_roughness.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Curtain_Blue_diffuse.png b/Tests/DemoGame/assets/materials/Sponza_Curtain_Blue_diffuse.png
new file mode 100644
index 0000000..7b7c9ca
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Curtain_Blue_diffuse.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Curtain_Blue_normal.png b/Tests/DemoGame/assets/materials/Sponza_Curtain_Blue_normal.png
new file mode 100644
index 0000000..1cce87b
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Curtain_Blue_normal.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Curtain_Green_diffuse.png b/Tests/DemoGame/assets/materials/Sponza_Curtain_Green_diffuse.png
new file mode 100644
index 0000000..df8feb6
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Curtain_Green_diffuse.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Curtain_Green_normal.png b/Tests/DemoGame/assets/materials/Sponza_Curtain_Green_normal.png
new file mode 100644
index 0000000..4f3b719
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Curtain_Green_normal.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Curtain_Red_diffuse.png b/Tests/DemoGame/assets/materials/Sponza_Curtain_Red_diffuse.png
new file mode 100644
index 0000000..8e840c9
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Curtain_Red_diffuse.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Curtain_Red_normal.png b/Tests/DemoGame/assets/materials/Sponza_Curtain_Red_normal.png
new file mode 100644
index 0000000..7d2522f
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Curtain_Red_normal.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Curtain_metallic.png b/Tests/DemoGame/assets/materials/Sponza_Curtain_metallic.png
new file mode 100644
index 0000000..f466bfd
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Curtain_metallic.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Curtain_roughness.png b/Tests/DemoGame/assets/materials/Sponza_Curtain_roughness.png
new file mode 100644
index 0000000..9454098
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Curtain_roughness.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Details_diffuse.png b/Tests/DemoGame/assets/materials/Sponza_Details_diffuse.png
new file mode 100644
index 0000000..711122d
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Details_diffuse.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Details_metallic.png b/Tests/DemoGame/assets/materials/Sponza_Details_metallic.png
new file mode 100644
index 0000000..b7ee51c
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Details_metallic.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Details_normal.png b/Tests/DemoGame/assets/materials/Sponza_Details_normal.png
new file mode 100644
index 0000000..271e1f5
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Details_normal.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Details_roughness.png b/Tests/DemoGame/assets/materials/Sponza_Details_roughness.png
new file mode 100644
index 0000000..6cb4a89
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Details_roughness.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Fabric_Blue_diffuse.png b/Tests/DemoGame/assets/materials/Sponza_Fabric_Blue_diffuse.png
new file mode 100644
index 0000000..199f5c0
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Fabric_Blue_diffuse.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Fabric_Blue_normal.png b/Tests/DemoGame/assets/materials/Sponza_Fabric_Blue_normal.png
new file mode 100644
index 0000000..dd793e7
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Fabric_Blue_normal.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Fabric_Green_diffuse.png b/Tests/DemoGame/assets/materials/Sponza_Fabric_Green_diffuse.png
new file mode 100644
index 0000000..9540ae4
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Fabric_Green_diffuse.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Fabric_Green_normal.png b/Tests/DemoGame/assets/materials/Sponza_Fabric_Green_normal.png
new file mode 100644
index 0000000..2416735
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Fabric_Green_normal.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Fabric_Red_diffuse.png b/Tests/DemoGame/assets/materials/Sponza_Fabric_Red_diffuse.png
new file mode 100644
index 0000000..76aa446
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Fabric_Red_diffuse.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Fabric_Red_normal.png b/Tests/DemoGame/assets/materials/Sponza_Fabric_Red_normal.png
new file mode 100644
index 0000000..492a4aa
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Fabric_Red_normal.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Fabric_metallic.png b/Tests/DemoGame/assets/materials/Sponza_Fabric_metallic.png
new file mode 100644
index 0000000..7677ed4
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Fabric_metallic.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Fabric_roughness.png b/Tests/DemoGame/assets/materials/Sponza_Fabric_roughness.png
new file mode 100644
index 0000000..ec2abcb
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Fabric_roughness.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_FlagPole_diffuse.png b/Tests/DemoGame/assets/materials/Sponza_FlagPole_diffuse.png
new file mode 100644
index 0000000..dd6fc4b
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_FlagPole_diffuse.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_FlagPole_normal.png b/Tests/DemoGame/assets/materials/Sponza_FlagPole_normal.png
new file mode 100644
index 0000000..21bb5bc
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_FlagPole_normal.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_FlagPole_roughness.png b/Tests/DemoGame/assets/materials/Sponza_FlagPole_roughness.png
new file mode 100644
index 0000000..d1bf2e8
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_FlagPole_roughness.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Floor_diffuse.png b/Tests/DemoGame/assets/materials/Sponza_Floor_diffuse.png
new file mode 100644
index 0000000..ee61f34
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Floor_diffuse.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Floor_normal.png b/Tests/DemoGame/assets/materials/Sponza_Floor_normal.png
new file mode 100644
index 0000000..c980963
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Floor_normal.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Floor_roughness.png b/Tests/DemoGame/assets/materials/Sponza_Floor_roughness.png
new file mode 100644
index 0000000..f62a596
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Floor_roughness.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Roof_diffuse.png b/Tests/DemoGame/assets/materials/Sponza_Roof_diffuse.png
new file mode 100644
index 0000000..eed06de
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Roof_diffuse.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Roof_normal.png b/Tests/DemoGame/assets/materials/Sponza_Roof_normal.png
new file mode 100644
index 0000000..b294452
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Roof_normal.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Roof_roughness.png b/Tests/DemoGame/assets/materials/Sponza_Roof_roughness.png
new file mode 100644
index 0000000..091f65f
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Roof_roughness.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Thorn_diffuse.png b/Tests/DemoGame/assets/materials/Sponza_Thorn_diffuse.png
new file mode 100644
index 0000000..584d546
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Thorn_diffuse.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Thorn_normal.png b/Tests/DemoGame/assets/materials/Sponza_Thorn_normal.png
new file mode 100644
index 0000000..1d9e723
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Thorn_normal.png differ
diff --git a/Tests/DemoGame/assets/materials/Sponza_Thorn_roughness.png b/Tests/DemoGame/assets/materials/Sponza_Thorn_roughness.png
new file mode 100644
index 0000000..1bf9129
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Sponza_Thorn_roughness.png differ
diff --git a/Tests/DemoGame/assets/materials/Tiles020_2K-JPG_Color.jpg b/Tests/DemoGame/assets/materials/Tiles020_2K-JPG_Color.jpg
new file mode 100644
index 0000000..61f8e88
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Tiles020_2K-JPG_Color.jpg differ
diff --git a/Tests/DemoGame/assets/materials/Tiles020_2K-JPG_Displacement.jpg b/Tests/DemoGame/assets/materials/Tiles020_2K-JPG_Displacement.jpg
new file mode 100644
index 0000000..6c767d2
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Tiles020_2K-JPG_Displacement.jpg differ
diff --git a/Tests/DemoGame/assets/materials/Tiles020_2K-JPG_NormalDX.jpg b/Tests/DemoGame/assets/materials/Tiles020_2K-JPG_NormalDX.jpg
new file mode 100644
index 0000000..7b8aa85
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Tiles020_2K-JPG_NormalDX.jpg differ
diff --git a/Tests/DemoGame/assets/materials/Tiles020_2K-JPG_Roughness.jpg b/Tests/DemoGame/assets/materials/Tiles020_2K-JPG_Roughness.jpg
new file mode 100644
index 0000000..ae4ba56
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Tiles020_2K-JPG_Roughness.jpg differ
diff --git a/Tests/DemoGame/assets/materials/VaseHanging_diffuse.png b/Tests/DemoGame/assets/materials/VaseHanging_diffuse.png
new file mode 100644
index 0000000..e91b94d
Binary files /dev/null and b/Tests/DemoGame/assets/materials/VaseHanging_diffuse.png differ
diff --git a/Tests/DemoGame/assets/materials/VaseHanging_normal.png b/Tests/DemoGame/assets/materials/VaseHanging_normal.png
new file mode 100644
index 0000000..0e6aa05
Binary files /dev/null and b/Tests/DemoGame/assets/materials/VaseHanging_normal.png differ
diff --git a/Tests/DemoGame/assets/materials/VaseHanging_roughness.png b/Tests/DemoGame/assets/materials/VaseHanging_roughness.png
new file mode 100644
index 0000000..6f0a326
Binary files /dev/null and b/Tests/DemoGame/assets/materials/VaseHanging_roughness.png differ
diff --git a/Tests/DemoGame/assets/materials/VasePlant_diffuse.png b/Tests/DemoGame/assets/materials/VasePlant_diffuse.png
new file mode 100644
index 0000000..6f8e00b
Binary files /dev/null and b/Tests/DemoGame/assets/materials/VasePlant_diffuse.png differ
diff --git a/Tests/DemoGame/assets/materials/VasePlant_normal.png b/Tests/DemoGame/assets/materials/VasePlant_normal.png
new file mode 100644
index 0000000..38dfedf
Binary files /dev/null and b/Tests/DemoGame/assets/materials/VasePlant_normal.png differ
diff --git a/Tests/DemoGame/assets/materials/VasePlant_roughness.png b/Tests/DemoGame/assets/materials/VasePlant_roughness.png
new file mode 100644
index 0000000..8abffaf
Binary files /dev/null and b/Tests/DemoGame/assets/materials/VasePlant_roughness.png differ
diff --git a/Tests/DemoGame/assets/materials/VaseRound_diffuse.png b/Tests/DemoGame/assets/materials/VaseRound_diffuse.png
new file mode 100644
index 0000000..064698c
Binary files /dev/null and b/Tests/DemoGame/assets/materials/VaseRound_diffuse.png differ
diff --git a/Tests/DemoGame/assets/materials/VaseRound_normal.png b/Tests/DemoGame/assets/materials/VaseRound_normal.png
new file mode 100644
index 0000000..b40f6c1
Binary files /dev/null and b/Tests/DemoGame/assets/materials/VaseRound_normal.png differ
diff --git a/Tests/DemoGame/assets/materials/VaseRound_roughness.png b/Tests/DemoGame/assets/materials/VaseRound_roughness.png
new file mode 100644
index 0000000..5890a11
Binary files /dev/null and b/Tests/DemoGame/assets/materials/VaseRound_roughness.png differ
diff --git a/Tests/DemoGame/assets/materials/Vase_diffuse.png b/Tests/DemoGame/assets/materials/Vase_diffuse.png
new file mode 100644
index 0000000..0a3d22f
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Vase_diffuse.png differ
diff --git a/Tests/DemoGame/assets/materials/Vase_normal.png b/Tests/DemoGame/assets/materials/Vase_normal.png
new file mode 100644
index 0000000..1e45da8
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Vase_normal.png differ
diff --git a/Tests/DemoGame/assets/materials/Vase_roughness.png b/Tests/DemoGame/assets/materials/Vase_roughness.png
new file mode 100644
index 0000000..fd3ce25
Binary files /dev/null and b/Tests/DemoGame/assets/materials/Vase_roughness.png differ
diff --git a/Tests/DemoGame/assets/materials/gi_flag.png b/Tests/DemoGame/assets/materials/gi_flag.png
new file mode 100644
index 0000000..0f9eebf
Binary files /dev/null and b/Tests/DemoGame/assets/materials/gi_flag.png differ
diff --git a/Tests/DemoGame/assets/materials/ground_0014_color_1k.jpg b/Tests/DemoGame/assets/materials/ground_0014_color_1k.jpg
new file mode 100644
index 0000000..a6daf01
Binary files /dev/null and b/Tests/DemoGame/assets/materials/ground_0014_color_1k.jpg differ
diff --git a/Tests/DemoGame/assets/materials/ground_0014_height_1k.png b/Tests/DemoGame/assets/materials/ground_0014_height_1k.png
new file mode 100644
index 0000000..84d0ea4
Binary files /dev/null and b/Tests/DemoGame/assets/materials/ground_0014_height_1k.png differ
diff --git a/Tests/DemoGame/assets/materials/ground_0014_normal_directx_1k.png b/Tests/DemoGame/assets/materials/ground_0014_normal_directx_1k.png
new file mode 100644
index 0000000..37b94aa
Binary files /dev/null and b/Tests/DemoGame/assets/materials/ground_0014_normal_directx_1k.png differ
diff --git a/Tests/DemoGame/assets/materials/herringbone-flooring_albedo.png b/Tests/DemoGame/assets/materials/herringbone-flooring_albedo.png
new file mode 100644
index 0000000..09c9fca
Binary files /dev/null and b/Tests/DemoGame/assets/materials/herringbone-flooring_albedo.png differ
diff --git a/Tests/DemoGame/assets/materials/herringbone-flooring_ao.png b/Tests/DemoGame/assets/materials/herringbone-flooring_ao.png
new file mode 100644
index 0000000..ba1d374
Binary files /dev/null and b/Tests/DemoGame/assets/materials/herringbone-flooring_ao.png differ
diff --git a/Tests/DemoGame/assets/materials/herringbone-flooring_height.png b/Tests/DemoGame/assets/materials/herringbone-flooring_height.png
new file mode 100644
index 0000000..7266deb
Binary files /dev/null and b/Tests/DemoGame/assets/materials/herringbone-flooring_height.png differ
diff --git a/Tests/DemoGame/assets/materials/herringbone-flooring_normal-ogl.png b/Tests/DemoGame/assets/materials/herringbone-flooring_normal-ogl.png
new file mode 100644
index 0000000..e02295f
Binary files /dev/null and b/Tests/DemoGame/assets/materials/herringbone-flooring_normal-ogl.png differ
diff --git a/Tests/DemoGame/assets/materials/metal_0029_ao_1k.jpg b/Tests/DemoGame/assets/materials/metal_0029_ao_1k.jpg
new file mode 100644
index 0000000..4fcb6ab
Binary files /dev/null and b/Tests/DemoGame/assets/materials/metal_0029_ao_1k.jpg differ
diff --git a/Tests/DemoGame/assets/materials/metal_0029_color_1k.jpg b/Tests/DemoGame/assets/materials/metal_0029_color_1k.jpg
new file mode 100644
index 0000000..52c054a
Binary files /dev/null and b/Tests/DemoGame/assets/materials/metal_0029_color_1k.jpg differ
diff --git a/Tests/DemoGame/assets/materials/metal_0029_metallic_1k.jpg b/Tests/DemoGame/assets/materials/metal_0029_metallic_1k.jpg
new file mode 100644
index 0000000..460c9f9
Binary files /dev/null and b/Tests/DemoGame/assets/materials/metal_0029_metallic_1k.jpg differ
diff --git a/Tests/DemoGame/assets/materials/metal_0029_normal_directx_1k.png b/Tests/DemoGame/assets/materials/metal_0029_normal_directx_1k.png
new file mode 100644
index 0000000..943068b
Binary files /dev/null and b/Tests/DemoGame/assets/materials/metal_0029_normal_directx_1k.png differ
diff --git a/Tests/DemoGame/assets/materials/metal_0029_roughness_1k.jpg b/Tests/DemoGame/assets/materials/metal_0029_roughness_1k.jpg
new file mode 100644
index 0000000..67faa74
Binary files /dev/null and b/Tests/DemoGame/assets/materials/metal_0029_roughness_1k.jpg differ
diff --git a/Tests/DemoGame/assets/materials/pitted-rusted-metal1_albedo.png b/Tests/DemoGame/assets/materials/pitted-rusted-metal1_albedo.png
new file mode 100644
index 0000000..5f806ab
Binary files /dev/null and b/Tests/DemoGame/assets/materials/pitted-rusted-metal1_albedo.png differ
diff --git a/Tests/DemoGame/assets/materials/pitted-rusted-metal1_normal-ogl.png b/Tests/DemoGame/assets/materials/pitted-rusted-metal1_normal-ogl.png
new file mode 100644
index 0000000..80c1c27
Binary files /dev/null and b/Tests/DemoGame/assets/materials/pitted-rusted-metal1_normal-ogl.png differ
diff --git a/Tests/DemoGame/assets/materials/rock_0006_ao_4k.jpg b/Tests/DemoGame/assets/materials/rock_0006_ao_4k.jpg
new file mode 100644
index 0000000..479f6bd
Binary files /dev/null and b/Tests/DemoGame/assets/materials/rock_0006_ao_4k.jpg differ
diff --git a/Tests/DemoGame/assets/materials/rock_0006_color_ice_4k.jpg b/Tests/DemoGame/assets/materials/rock_0006_color_ice_4k.jpg
new file mode 100644
index 0000000..7b6ff02
Binary files /dev/null and b/Tests/DemoGame/assets/materials/rock_0006_color_ice_4k.jpg differ
diff --git a/Tests/DemoGame/assets/materials/rock_0006_normal_2k.jpg b/Tests/DemoGame/assets/materials/rock_0006_normal_2k.jpg
new file mode 100644
index 0000000..0ee4bcb
Binary files /dev/null and b/Tests/DemoGame/assets/materials/rock_0006_normal_2k.jpg differ
diff --git a/Tests/DemoGame/assets/materials/rock_0006_roughness_4k.jpg b/Tests/DemoGame/assets/materials/rock_0006_roughness_4k.jpg
new file mode 100644
index 0000000..905ee9a
Binary files /dev/null and b/Tests/DemoGame/assets/materials/rock_0006_roughness_4k.jpg differ
diff --git a/Tests/DemoGame/assets/materials/rusty-metal_albedo.png b/Tests/DemoGame/assets/materials/rusty-metal_albedo.png
new file mode 100644
index 0000000..3e21f40
Binary files /dev/null and b/Tests/DemoGame/assets/materials/rusty-metal_albedo.png differ
diff --git a/Tests/DemoGame/assets/materials/rusty-metal_ao.png b/Tests/DemoGame/assets/materials/rusty-metal_ao.png
new file mode 100644
index 0000000..4fce9ee
Binary files /dev/null and b/Tests/DemoGame/assets/materials/rusty-metal_ao.png differ
diff --git a/Tests/DemoGame/assets/materials/rusty-metal_normal-ogl.png b/Tests/DemoGame/assets/materials/rusty-metal_normal-ogl.png
new file mode 100644
index 0000000..bc831da
Binary files /dev/null and b/Tests/DemoGame/assets/materials/rusty-metal_normal-ogl.png differ
diff --git a/Tests/DemoGame/assets/materials/speckled-rust_albedo.png b/Tests/DemoGame/assets/materials/speckled-rust_albedo.png
new file mode 100644
index 0000000..c45810e
Binary files /dev/null and b/Tests/DemoGame/assets/materials/speckled-rust_albedo.png differ
diff --git a/Tests/DemoGame/assets/materials/speckled-rust_normal-ogl.png b/Tests/DemoGame/assets/materials/speckled-rust_normal-ogl.png
new file mode 100644
index 0000000..e497fb4
Binary files /dev/null and b/Tests/DemoGame/assets/materials/speckled-rust_normal-ogl.png differ
diff --git a/Tests/DemoGame/assets/materials/speckled-rust_roughness.png b/Tests/DemoGame/assets/materials/speckled-rust_roughness.png
new file mode 100644
index 0000000..8424266
Binary files /dev/null and b/Tests/DemoGame/assets/materials/speckled-rust_roughness.png differ
diff --git a/Tests/DemoGame/assets/materials/spotted-rust_albedo.png b/Tests/DemoGame/assets/materials/spotted-rust_albedo.png
new file mode 100644
index 0000000..a397071
Binary files /dev/null and b/Tests/DemoGame/assets/materials/spotted-rust_albedo.png differ
diff --git a/Tests/DemoGame/assets/materials/spotted-rust_ao.png b/Tests/DemoGame/assets/materials/spotted-rust_ao.png
new file mode 100644
index 0000000..76bedc6
Binary files /dev/null and b/Tests/DemoGame/assets/materials/spotted-rust_ao.png differ
diff --git a/Tests/DemoGame/assets/materials/spotted-rust_normal-ogl.png b/Tests/DemoGame/assets/materials/spotted-rust_normal-ogl.png
new file mode 100644
index 0000000..a9194c5
Binary files /dev/null and b/Tests/DemoGame/assets/materials/spotted-rust_normal-ogl.png differ
diff --git a/Tests/DemoGame/demo_game_scene.json b/Tests/DemoGame/demo_game_scene.json
index 8ea035c..bf9ca80 100644
--- a/Tests/DemoGame/demo_game_scene.json
+++ b/Tests/DemoGame/demo_game_scene.json
@@ -2,7 +2,7 @@
"world": {
"path": "..\\..\\..\\Tests\\DemoGame\\",
"level": {
- "file": ".\\Assets\\particle_test.fbx",
+ "file": ".\\Assets\\level.fbx",
"triangulate": false
},
"audio": {
@@ -176,8 +176,8 @@
"ambient": {
"type": "ambient",
"name": "ambient",
- "color_down": "008008008",
- "color_up": "008008008"
+ "color_down": "000000000",
+ "color_up": "000000000"
}
},
"lights": [
diff --git a/Tests/DemoGame/demo_game_scene.mat b/Tests/DemoGame/demo_game_scene.mat
index 06b175f..593b723 100644
--- a/Tests/DemoGame/demo_game_scene.mat
+++ b/Tests/DemoGame/demo_game_scene.mat
@@ -203,8 +203,8 @@
"draw_ps": "LavaPS.cso",
"draw_vs": "MainRenderVS.cso",
"ds": "",
- "emission": 1.0,
- "emission_color": "#00000000",
+ "emission": 2.0,
+ "emission_color": "#FF573300",
"emission_textname": "",
"gs": "",
"high_textname": "",
@@ -440,7 +440,7 @@
"high_textname": "Bricks076C_1K_Displacement.jpg",
"hs": "",
"name": "Bricks",
- "normal_map_enabled": false,
+ "normal_map_enabled": true,
"normal_textname": "Bricks076C_1K_NormalDX.jpg",
"opacity": 1.0,
"opacity_textname": "",
@@ -450,12 +450,12 @@
"parallax_shadows": true,
"parallax_steps": 10.0,
"ps": "",
- "raytrace": false,
+ "raytrace": true,
"rt_reflex": 1.0,
"shadow_gs": "ShadowMapCubeGS.cso",
"shadow_vs": "ShadowVS.cso",
"spec_textname": "Bricks076C_1K_Roughness.jpg",
- "specular": 1.0,
+ "specular": 0.0,
"tess_factor": 4.0,
"tess_type": 0,
"vs": ""
@@ -539,6 +539,282 @@
"value": 1.0
}
]
+ },
+ {
+ "alpha_enabled": false,
+ "ambient_color": "#FFFFFFFF",
+ "ao_textname": "",
+ "arm_textname": "",
+ "blend_enabled": false,
+ "bloom_scale": 0.0,
+ "density": 1.0,
+ "depth_ps": "DepthPS.cso",
+ "depth_vs": "DepthVS.cso",
+ "diffuse_color": "#FFFFFFFF",
+ "diffuse_textname": "Sponza_Bricks_a_Albedo.png",
+ "displacement_scale": 0.0,
+ "draw_ds": "MainRenderDS.cso",
+ "draw_gs": "MainRenderGS.cso",
+ "draw_hs": "MainRenderHS.cso",
+ "draw_ps": "MainRenderPS.cso",
+ "draw_vs": "MainRenderVS.cso",
+ "ds": "",
+ "emission": 0.0,
+ "emission_color": "#00000000",
+ "emission_textname": "",
+ "gs": "",
+ "high_textname": "",
+ "hs": "",
+ "name": "sp_bricks",
+ "normal_map_enabled": false,
+ "normal_textname": "Sponza_Bricks_a_Normal.png",
+ "opacity": 1.0,
+ "opacity_textname": "",
+ "parallax_angle_steps": 5.0,
+ "parallax_scale": 0.0,
+ "parallax_shadow_scale": 0,
+ "parallax_shadows": false,
+ "parallax_steps": 4.0,
+ "ps": "",
+ "raytrace": true,
+ "rt_reflex": 1.0,
+ "shadow_gs": "ShadowMapCubeGS.cso",
+ "shadow_vs": "ShadowVS.cso",
+ "spec_textname": "Sponza_Bricks_a_Roughness.png",
+ "specular": 0.0,
+ "tess_factor": 32.0,
+ "tess_type": 0,
+ "vs": ""
+ },
+ {
+ "alpha_enabled": false,
+ "ambient_color": "#FFFFFFFF",
+ "ao_textname": "",
+ "arm_textname": "",
+ "blend_enabled": false,
+ "bloom_scale": 0.0,
+ "density": 1.0,
+ "depth_ps": "DepthPS.cso",
+ "depth_vs": "DepthVS.cso",
+ "diffuse_color": "#FFFFFFFF",
+ "diffuse_textname": "Sponza_Floor_diffuse.png",
+ "displacement_scale": 0.0,
+ "draw_ds": "MainRenderDS.cso",
+ "draw_gs": "MainRenderGS.cso",
+ "draw_hs": "MainRenderHS.cso",
+ "draw_ps": "MainRenderPS.cso",
+ "draw_vs": "MainRenderVS.cso",
+ "ds": "",
+ "emission": 0.0,
+ "emission_color": "#00000000",
+ "emission_textname": "",
+ "gs": "",
+ "high_textname": "",
+ "hs": "",
+ "name": "sp_floor",
+ "normal_map_enabled": false,
+ "normal_textname": "Sponza_Floor_normal.png",
+ "opacity": 1.0,
+ "opacity_textname": "",
+ "parallax_angle_steps": 5.0,
+ "parallax_scale": 0.0,
+ "parallax_shadow_scale": 0,
+ "parallax_shadows": false,
+ "parallax_steps": 4.0,
+ "ps": "",
+ "raytrace": true,
+ "rt_reflex": 1.0,
+ "shadow_gs": "ShadowMapCubeGS.cso",
+ "shadow_vs": "ShadowVS.cso",
+ "spec_textname": "Sponza_Floor_roughness.png",
+ "specular": 1.0,
+ "tess_factor": 32.0,
+ "tess_type": 0,
+ "vs": ""
+ },
+ {
+ "alpha_enabled": false,
+ "ambient_color": "#FFFFFFFF",
+ "ao_textname": "",
+ "arm_textname": "",
+ "blend_enabled": false,
+ "bloom_scale": 0.0,
+ "density": 1.0,
+ "depth_ps": "DepthPS.cso",
+ "depth_vs": "DepthVS.cso",
+ "diffuse_color": "#FFFFFFFF",
+ "diffuse_textname": "Sponza_Fabric_Red_diffuse.png",
+ "displacement_scale": 0.0,
+ "draw_ds": "MainRenderDS.cso",
+ "draw_gs": "MainRenderGS.cso",
+ "draw_hs": "MainRenderHS.cso",
+ "draw_ps": "MainRenderPS.cso",
+ "draw_vs": "MainRenderVS.cso",
+ "ds": "",
+ "emission": 0.0,
+ "emission_color": "#00000000",
+ "emission_textname": "",
+ "gs": "",
+ "high_textname": "",
+ "hs": "",
+ "name": "sp_fabric_red",
+ "normal_map_enabled": false,
+ "normal_textname": "Sponza_Fabric_Red_normal.png",
+ "opacity": 1.0,
+ "opacity_textname": "",
+ "parallax_angle_steps": 5.0,
+ "parallax_scale": 0.0,
+ "parallax_shadow_scale": 0,
+ "parallax_shadows": false,
+ "parallax_steps": 4.0,
+ "ps": "",
+ "raytrace": true,
+ "rt_reflex": 1.0,
+ "shadow_gs": "ShadowMapCubeGS.cso",
+ "shadow_vs": "ShadowVS.cso",
+ "spec_textname": "Sponza_Fabric_metallic.png",
+ "specular": 1.0,
+ "tess_factor": 32.0,
+ "tess_type": 0,
+ "vs": ""
+ },
+ {
+ "alpha_enabled": false,
+ "ambient_color": "#FFFFFFFF",
+ "ao_textname": "",
+ "arm_textname": "",
+ "blend_enabled": false,
+ "bloom_scale": 0.0,
+ "density": 1.0,
+ "depth_ps": "DepthPS.cso",
+ "depth_vs": "DepthVS.cso",
+ "diffuse_color": "#FFFFFFFF",
+ "diffuse_textname": "Sponza_Fabric_Blue_diffuse.png",
+ "displacement_scale": 0.0,
+ "draw_ds": "MainRenderDS.cso",
+ "draw_gs": "MainRenderGS.cso",
+ "draw_hs": "MainRenderHS.cso",
+ "draw_ps": "MainRenderPS.cso",
+ "draw_vs": "MainRenderVS.cso",
+ "ds": "",
+ "emission": 0.0,
+ "emission_color": "#00000000",
+ "emission_textname": "",
+ "gs": "",
+ "high_textname": "",
+ "hs": "",
+ "name": "sp_fabric_blue",
+ "normal_map_enabled": false,
+ "normal_textname": "Sponza_Fabric_Blue_normal.png",
+ "opacity": 1.0,
+ "opacity_textname": "",
+ "parallax_angle_steps": 5.0,
+ "parallax_scale": 0.0,
+ "parallax_shadow_scale": 0,
+ "parallax_shadows": false,
+ "parallax_steps": 4.0,
+ "ps": "",
+ "raytrace": true,
+ "rt_reflex": 1.0,
+ "shadow_gs": "ShadowMapCubeGS.cso",
+ "shadow_vs": "ShadowVS.cso",
+ "spec_textname": "Sponza_Fabric_metallic.png",
+ "specular": 1.0,
+ "tess_factor": 32.0,
+ "tess_type": 0,
+ "vs": ""
+ },
+ {
+ "alpha_enabled": false,
+ "ambient_color": "#FFFFFFFF",
+ "ao_textname": "",
+ "arm_textname": "",
+ "blend_enabled": false,
+ "bloom_scale": 0.0,
+ "density": 1.0,
+ "depth_ps": "DepthPS.cso",
+ "depth_vs": "DepthVS.cso",
+ "diffuse_color": "#FFFFFFFF",
+ "diffuse_textname": "Sponza_Fabric_Green_diffuse.png",
+ "displacement_scale": 0.0,
+ "draw_ds": "MainRenderDS.cso",
+ "draw_gs": "MainRenderGS.cso",
+ "draw_hs": "MainRenderHS.cso",
+ "draw_ps": "MainRenderPS.cso",
+ "draw_vs": "MainRenderVS.cso",
+ "ds": "",
+ "emission": 0.0,
+ "emission_color": "#00000000",
+ "emission_textname": "",
+ "gs": "",
+ "high_textname": "",
+ "hs": "",
+ "name": "sp_fabric_gree",
+ "normal_map_enabled": false,
+ "normal_textname": "Sponza_Fabric_Green_normal.png",
+ "opacity": 1.0,
+ "opacity_textname": "",
+ "parallax_angle_steps": 5.0,
+ "parallax_scale": 0.0,
+ "parallax_shadow_scale": 0,
+ "parallax_shadows": false,
+ "parallax_steps": 4.0,
+ "ps": "",
+ "raytrace": true,
+ "rt_reflex": 1.0,
+ "shadow_gs": "ShadowMapCubeGS.cso",
+ "shadow_vs": "ShadowVS.cso",
+ "spec_textname": "Sponza_Fabric_metallic.png",
+ "specular": 1.0,
+ "tess_factor": 32.0,
+ "tess_type": 0,
+ "vs": ""
+ },
+ {
+ "alpha_enabled": false,
+ "ambient_color": "#FFFFFFFF",
+ "ao_textname": "",
+ "arm_textname": "",
+ "blend_enabled": false,
+ "bloom_scale": 0.0,
+ "density": 1.0,
+ "depth_ps": "DepthPS.cso",
+ "depth_vs": "DepthVS.cso",
+ "diffuse_color": "#FFFFFFFF",
+ "diffuse_textname": "Sponza_Column_a_diffuse.png",
+ "displacement_scale": 0.0,
+ "draw_ds": "MainRenderDS.cso",
+ "draw_gs": "MainRenderGS.cso",
+ "draw_hs": "MainRenderHS.cso",
+ "draw_ps": "MainRenderPS.cso",
+ "draw_vs": "MainRenderVS.cso",
+ "ds": "",
+ "emission": 0.0,
+ "emission_color": "#00000000",
+ "emission_textname": "",
+ "gs": "",
+ "high_textname": "",
+ "hs": "",
+ "name": "sp_column_a",
+ "normal_map_enabled": false,
+ "normal_textname": "Sponza_Column_a_normal.png",
+ "opacity": 1.0,
+ "opacity_textname": "",
+ "parallax_angle_steps": 5.0,
+ "parallax_scale": 0.0,
+ "parallax_shadow_scale": 0,
+ "parallax_shadows": false,
+ "parallax_steps": 4.0,
+ "ps": "",
+ "raytrace": true,
+ "rt_reflex": 1.0,
+ "shadow_gs": "ShadowMapCubeGS.cso",
+ "shadow_vs": "ShadowVS.cso",
+ "spec_textname": "Sponza_Column_a_roughness.png",
+ "specular": 0.0,
+ "tess_factor": 32.0,
+ "tess_type": 0,
+ "vs": ""
}
],
"root": ".\\assets\\materials\\"
diff --git a/Tools/MaterialDesigner/Materials.h b/Tools/MaterialDesigner/Materials.h
index 80a321e..e68ed7f 100644
--- a/Tools/MaterialDesigner/Materials.h
+++ b/Tools/MaterialDesigner/Materials.h
@@ -181,6 +181,8 @@ class Material: public Element {
props["bloom_scale"] = std::make_shared>(0.0f);
props["normal_map_enabled"] = std::make_shared>(false);
props["alpha_enabled"] = std::make_shared>(false);
+ props["alpha_color"] = std::make_shared>("#00000000");
+ props["alpha_threshold"] = std::make_shared>(0.4f);
props["blend_enabled"] = std::make_shared>(false);
props["diffuse_textname"] = std::make_shared>("");
props["normal_textname"] = std::make_shared>("");
@@ -230,6 +232,8 @@ class Material: public Element {
props["bloom_scale"]->SetValue(js.value("bloom_scale", 0.0f));
props["normal_map_enabled"]->SetValue(js.value("normal_map_enabled", true));
props["alpha_enabled"]->SetValue(js.value("alpha_enabled", false));
+ props["alpha_color"]->SetValue(js.value("alpha_color", "#00000000"));
+ props["alpha_threshold"]->SetValue(js.value("alpha_threshold", 0.4f));
props["blend_enabled"]->SetValue(js.value("blend_enabled", false));
props["diffuse_textname"]->SetValue(js.value("diffuse_textname", ""));
props["normal_textname"]->SetValue(js.value("normal_textname", ""));
@@ -784,6 +788,35 @@ public ref class MaterialProp
}
}
+ [CategoryAttribute("Material")]
+ property Drawing::Color AlphaColor {
+ Drawing::Color get()
+ {
+ auto color = HotBite::Engine::Core::parseColorStringF4(material->props["alpha_color"]->GetValue());
+ return Drawing::Color::FromArgb((int)(color.w * 255.0f), (int)(color.x * 255.0f), (int)(color.y * 255.0f), (int)(color.z * 255.0f));
+ }
+
+ void set(Drawing::Color newValue)
+ {
+ char color[64];
+ snprintf(color, 64, "#%02X%02X%02X%02X", newValue.R, newValue.G, newValue.B, newValue.A);
+ return material->props["alpha_color"]->SetValue(color);
+ }
+ }
+
+ [CategoryAttribute("Material")]
+ property float AlphaThreshold {
+ float get()
+ {
+ return material->props["alpha_threshold"]->GetValue();
+ }
+
+ void set(float newValue)
+ {
+ return material->props["alpha_threshold"]->SetValue((float)newValue);
+ }
+ }
+
[CategoryAttribute("Material")]
property bool Blend {
bool get()
diff --git a/Tools/MaterialDesigner/material_scene.json b/Tools/MaterialDesigner/material_scene.json
index 4e75178..63ffa73 100644
--- a/Tools/MaterialDesigner/material_scene.json
+++ b/Tools/MaterialDesigner/material_scene.json
@@ -44,6 +44,9 @@
{
"name": "Floor",
"material": "MaterialDesignerFloor"
+ },{
+ "name": "Cube*",
+ "pass": 2
}
]
}