2022.3
This commit is contained in:
parent
49241c9f18
commit
2d2672829e
|
@ -1,4 +1,4 @@
|
|||
// Copyright (C) 2021, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#include "pch.h"
|
||||
|
||||
using namespace verus;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (C) 2021, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#pragma once
|
||||
|
||||
namespace verus
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (C) 2021, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
|
||||
// Copied from Lib.hlsl:
|
||||
#define VERUS_UBUFFER struct
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (C) 2021, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#include "pch.h"
|
||||
|
||||
using namespace verus;
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
// Copyright (C) 2021, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#include "pch.h"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (C) 2021, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#pragma once
|
||||
|
||||
#include <verus.h>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (C) 2021, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#include "pch.h"
|
||||
|
||||
using namespace verus;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (C) 2021, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#pragma once
|
||||
|
||||
namespace verus
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
R"(
|
||||
|
||||
// Copyright (C) 2021, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
|
||||
// Copied from Lib.hlsl:
|
||||
#define VERUS_UBUFFER struct
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (C) 2021, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#include "pch.h"
|
||||
|
||||
using namespace verus;
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
// Copyright (C) 2021, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#include "pch.h"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (C) 2021, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#pragma once
|
||||
|
||||
#include <verus.h>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (C) 2021, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
/*******************************************************************************
|
||||
*
|
||||
* PACK format with compression & encryption.
|
||||
|
|
|
@ -6,8 +6,9 @@ using namespace verus::CGI;
|
|||
|
||||
// DescriptorHeap:
|
||||
|
||||
void DescriptorHeap::Create(ID3D12Device* pDevice, D3D12_DESCRIPTOR_HEAP_TYPE type, UINT count, bool shaderVisible)
|
||||
void DescriptorHeap::Create(ID3D12Device* pDevice, D3D12_DESCRIPTOR_HEAP_TYPE type, int count, bool shaderVisible)
|
||||
{
|
||||
// Warning! On some hardware the maximum number of descriptor heaps is 4096!
|
||||
VERUS_CT_ASSERT(sizeof(*this) == 32);
|
||||
VERUS_RT_ASSERT(count > 0);
|
||||
HRESULT hr = 0;
|
||||
|
@ -22,12 +23,12 @@ void DescriptorHeap::Create(ID3D12Device* pDevice, D3D12_DESCRIPTOR_HEAP_TYPE ty
|
|||
_handleIncrementSize = pDevice->GetDescriptorHandleIncrementSize(desc.Type);
|
||||
}
|
||||
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE DescriptorHeap::AtCPU(INT index) const
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE DescriptorHeap::AtCPU(int index) const
|
||||
{
|
||||
return CD3DX12_CPU_DESCRIPTOR_HANDLE(_hCPUHandleForHeapStart, index, _handleIncrementSize);
|
||||
}
|
||||
|
||||
CD3DX12_GPU_DESCRIPTOR_HANDLE DescriptorHeap::AtGPU(INT index) const
|
||||
CD3DX12_GPU_DESCRIPTOR_HANDLE DescriptorHeap::AtGPU(int index) const
|
||||
{
|
||||
VERUS_RT_ASSERT(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV == _type || D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER == _type);
|
||||
return CD3DX12_GPU_DESCRIPTOR_HANDLE(_hGPUHandleForHeapStart, index, _handleIncrementSize);
|
||||
|
@ -35,7 +36,7 @@ CD3DX12_GPU_DESCRIPTOR_HANDLE DescriptorHeap::AtGPU(INT index) const
|
|||
|
||||
// DynamicDescriptorHeap:
|
||||
|
||||
void DynamicDescriptorHeap::Create(ID3D12Device* pDevice, D3D12_DESCRIPTOR_HEAP_TYPE type, UINT count, UINT staticCount, bool shaderVisible)
|
||||
void DynamicDescriptorHeap::Create(ID3D12Device* pDevice, D3D12_DESCRIPTOR_HEAP_TYPE type, int count, int staticCount, bool shaderVisible)
|
||||
{
|
||||
VERUS_CT_ASSERT(sizeof(*this) == 56);
|
||||
_capacity = count;
|
||||
|
@ -46,7 +47,6 @@ void DynamicDescriptorHeap::Create(ID3D12Device* pDevice, D3D12_DESCRIPTOR_HEAP_
|
|||
HandlePair DynamicDescriptorHeap::GetNextHandlePair(int count)
|
||||
{
|
||||
VERUS_QREF_RENDERER;
|
||||
VERUS_QREF_RENDERER_D3D12;
|
||||
|
||||
if (_currentFrame != renderer.GetFrameCount())
|
||||
{
|
||||
|
@ -56,7 +56,7 @@ HandlePair DynamicDescriptorHeap::GetNextHandlePair(int count)
|
|||
|
||||
if (_offset + count <= _capacity)
|
||||
{
|
||||
const INT index = _capacity * pRendererD3D12->GetRingBufferIndex() + _offset;
|
||||
const int index = _capacity * renderer->GetRingBufferIndex() + _offset;
|
||||
_offset += count;
|
||||
_peakLoad = Math::Max<UINT64>(_peakLoad, _offset);
|
||||
return HandlePair(AtCPU(index), AtGPU(index));
|
||||
|
@ -67,6 +67,6 @@ HandlePair DynamicDescriptorHeap::GetNextHandlePair(int count)
|
|||
|
||||
HandlePair DynamicDescriptorHeap::GetStaticHandlePair(int index)
|
||||
{
|
||||
const INT indexAt = _capacity * BaseRenderer::s_ringBufferSize + index;
|
||||
const int indexAt = _capacity * BaseRenderer::s_ringBufferSize + index;
|
||||
return HandlePair(AtCPU(indexAt), AtGPU(indexAt));
|
||||
}
|
||||
|
|
|
@ -18,10 +18,13 @@ namespace verus
|
|||
|
||||
ID3D12DescriptorHeap* GetD3DDescriptorHeap() const { return _pDescriptorHeap.Get(); }
|
||||
|
||||
void Create(ID3D12Device* pDevice, D3D12_DESCRIPTOR_HEAP_TYPE type, UINT count, bool shaderVisible = false);
|
||||
void Create(ID3D12Device* pDevice, D3D12_DESCRIPTOR_HEAP_TYPE type, int count, bool shaderVisible = false);
|
||||
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE AtCPU(INT index) const;
|
||||
CD3DX12_GPU_DESCRIPTOR_HANDLE AtGPU(INT index) const;
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE AtCPU(int index) const;
|
||||
CD3DX12_GPU_DESCRIPTOR_HANDLE AtGPU(int index) const;
|
||||
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE GetType() const { return _type; }
|
||||
UINT GetHandleIncrementSize() const { return _handleIncrementSize; }
|
||||
};
|
||||
VERUS_TYPEDEFS(DescriptorHeap);
|
||||
|
||||
|
@ -31,26 +34,27 @@ namespace verus
|
|||
CD3DX12_GPU_DESCRIPTOR_HANDLE _hGPU;
|
||||
|
||||
HandlePair(
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE hCPU = CD3DX12_CPU_DESCRIPTOR_HANDLE(),
|
||||
CD3DX12_GPU_DESCRIPTOR_HANDLE hGPU = CD3DX12_GPU_DESCRIPTOR_HANDLE()) : _hCPU(hCPU), _hGPU(hGPU) {}
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE hCPU = D3D12_DEFAULT,
|
||||
CD3DX12_GPU_DESCRIPTOR_HANDLE hGPU = D3D12_DEFAULT) : _hCPU(hCPU), _hGPU(hGPU) {}
|
||||
};
|
||||
VERUS_TYPEDEFS(HandlePair);
|
||||
|
||||
// This descriptor heap should be refilled every frame:
|
||||
class DynamicDescriptorHeap : public DescriptorHeap
|
||||
{
|
||||
UINT _capacity = 0;
|
||||
UINT _offset = 0;
|
||||
int _capacity = 0;
|
||||
int _offset = 0;
|
||||
UINT64 _currentFrame = UINT64_MAX;
|
||||
UINT64 _peakLoad = 0;
|
||||
|
||||
public:
|
||||
void Create(ID3D12Device* pDevice, D3D12_DESCRIPTOR_HEAP_TYPE type, UINT count, UINT staticCount = 0, bool shaderVisible = false);
|
||||
void Create(ID3D12Device* pDevice, D3D12_DESCRIPTOR_HEAP_TYPE type, int count, int staticCount = 0, bool shaderVisible = false);
|
||||
|
||||
HandlePair GetNextHandlePair(int count = 1);
|
||||
HandlePair GetStaticHandlePair(int index);
|
||||
|
||||
UINT GetCapacity() const { return _capacity; }
|
||||
UINT GetOffset() const { return _offset; }
|
||||
int GetCapacity() const { return _capacity; }
|
||||
int GetOffset() const { return _offset; }
|
||||
};
|
||||
VERUS_TYPEDEFS(DynamicDescriptorHeap);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,105 @@
|
|||
#include "pch.h"
|
||||
|
||||
using namespace verus;
|
||||
using namespace verus::CGI;
|
||||
|
||||
D3D12_COMPARISON_FUNC CGI::ToNativeCompareOp(CompareOp compareOp)
|
||||
{
|
||||
switch (compareOp)
|
||||
{
|
||||
case CompareOp::never: return D3D12_COMPARISON_FUNC_NEVER;
|
||||
case CompareOp::less: return D3D12_COMPARISON_FUNC_LESS;
|
||||
case CompareOp::equal: return D3D12_COMPARISON_FUNC_EQUAL;
|
||||
case CompareOp::lessOrEqual: return D3D12_COMPARISON_FUNC_LESS_EQUAL;
|
||||
case CompareOp::greater: return D3D12_COMPARISON_FUNC_GREATER;
|
||||
case CompareOp::notEqual: return D3D12_COMPARISON_FUNC_NOT_EQUAL;
|
||||
case CompareOp::greaterOrEqual: return D3D12_COMPARISON_FUNC_GREATER_EQUAL;
|
||||
case CompareOp::always: return D3D12_COMPARISON_FUNC_ALWAYS;
|
||||
default: throw VERUS_RECOVERABLE << "ToNativeCompareOp()";
|
||||
}
|
||||
}
|
||||
|
||||
UINT CGI::ToNativeCubeMapFace(CubeMapFace face)
|
||||
{
|
||||
switch (face)
|
||||
{
|
||||
case CubeMapFace::posX: return 0;
|
||||
case CubeMapFace::negX: return 1;
|
||||
case CubeMapFace::posY: return 2;
|
||||
case CubeMapFace::negY: return 3;
|
||||
case CubeMapFace::posZ: return 4;
|
||||
case CubeMapFace::negZ: return 5;
|
||||
default: throw VERUS_RECOVERABLE << "ToNativeCubeMapFace()";
|
||||
}
|
||||
}
|
||||
|
||||
D3D12_FILL_MODE CGI::ToNativePolygonMode(PolygonMode polygonMode)
|
||||
{
|
||||
switch (polygonMode)
|
||||
{
|
||||
case PolygonMode::fill: return D3D12_FILL_MODE_SOLID;
|
||||
case PolygonMode::line: return D3D12_FILL_MODE_WIREFRAME;
|
||||
default: throw VERUS_RECOVERABLE << "ToNativePolygonMode()";
|
||||
}
|
||||
}
|
||||
|
||||
D3D12_CULL_MODE CGI::ToNativeCullMode(CullMode cullMode)
|
||||
{
|
||||
switch (cullMode)
|
||||
{
|
||||
case CullMode::none: return D3D12_CULL_MODE_NONE;
|
||||
case CullMode::front: return D3D12_CULL_MODE_FRONT;
|
||||
case CullMode::back: return D3D12_CULL_MODE_BACK;
|
||||
default: throw VERUS_RECOVERABLE << "ToNativeCullMode()";
|
||||
}
|
||||
}
|
||||
|
||||
D3D_PRIMITIVE_TOPOLOGY CGI::ToNativePrimitiveTopology(PrimitiveTopology primitiveTopology)
|
||||
{
|
||||
switch (primitiveTopology)
|
||||
{
|
||||
case PrimitiveTopology::pointList: return D3D_PRIMITIVE_TOPOLOGY_POINTLIST;
|
||||
case PrimitiveTopology::lineList: return D3D_PRIMITIVE_TOPOLOGY_LINELIST;
|
||||
case PrimitiveTopology::lineStrip: return D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;
|
||||
case PrimitiveTopology::triangleList: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
|
||||
case PrimitiveTopology::triangleStrip: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
|
||||
case PrimitiveTopology::patchList3: return D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST;
|
||||
case PrimitiveTopology::patchList4: return D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST;
|
||||
default: throw VERUS_RECOVERABLE << "ToNativePrimitiveTopology()";
|
||||
}
|
||||
}
|
||||
|
||||
D3D12_PRIMITIVE_TOPOLOGY_TYPE CGI::ToNativePrimitiveTopologyType(PrimitiveTopology primitiveTopology)
|
||||
{
|
||||
switch (primitiveTopology)
|
||||
{
|
||||
case PrimitiveTopology::pointList: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT;
|
||||
case PrimitiveTopology::lineList: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE;
|
||||
case PrimitiveTopology::lineStrip: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE;
|
||||
case PrimitiveTopology::triangleList: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
|
||||
case PrimitiveTopology::triangleStrip: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
|
||||
case PrimitiveTopology::patchList3: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH;
|
||||
case PrimitiveTopology::patchList4: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH;
|
||||
default: throw VERUS_RECOVERABLE << "ToNativePrimitiveTopologyType()";
|
||||
}
|
||||
}
|
||||
|
||||
D3D12_RESOURCE_STATES CGI::ToNativeImageLayout(ImageLayout layout)
|
||||
{
|
||||
switch (layout)
|
||||
{
|
||||
case ImageLayout::undefined: return D3D12_RESOURCE_STATE_COMMON;
|
||||
case ImageLayout::general: return D3D12_RESOURCE_STATE_COMMON;
|
||||
case ImageLayout::colorAttachment: return D3D12_RESOURCE_STATE_RENDER_TARGET;
|
||||
case ImageLayout::depthStencilAttachment: return D3D12_RESOURCE_STATE_DEPTH_WRITE;
|
||||
case ImageLayout::depthStencilReadOnly: return D3D12_RESOURCE_STATE_DEPTH_READ | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
|
||||
case ImageLayout::xsReadOnly: return D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
|
||||
case ImageLayout::fsReadOnly: return D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
|
||||
case ImageLayout::transferSrc: return D3D12_RESOURCE_STATE_COPY_SOURCE;
|
||||
case ImageLayout::transferDst: return D3D12_RESOURCE_STATE_COPY_DEST;
|
||||
case ImageLayout::presentSrc: return D3D12_RESOURCE_STATE_PRESENT;
|
||||
default: throw VERUS_RECOVERABLE << "ToNativeImageLayout()";
|
||||
}
|
||||
}
|
||||
|
||||
DXGI_FORMAT CGI::ToNativeFormat(Format format, bool typeless)
|
||||
{
|
||||
|
@ -56,91 +154,6 @@ DXGI_FORMAT CGI::ToNativeSampledDepthFormat(Format format)
|
|||
};
|
||||
}
|
||||
|
||||
D3D12_CULL_MODE CGI::ToNativeCullMode(CullMode cullMode)
|
||||
{
|
||||
switch (cullMode)
|
||||
{
|
||||
case CullMode::none: return D3D12_CULL_MODE_NONE;
|
||||
case CullMode::front: return D3D12_CULL_MODE_FRONT;
|
||||
case CullMode::back: return D3D12_CULL_MODE_BACK;
|
||||
default: throw VERUS_RECOVERABLE << "ToNativeCullMode()";
|
||||
}
|
||||
}
|
||||
|
||||
D3D12_RESOURCE_STATES CGI::ToNativeImageLayout(ImageLayout layout)
|
||||
{
|
||||
switch (layout)
|
||||
{
|
||||
case ImageLayout::undefined: return D3D12_RESOURCE_STATE_COMMON;
|
||||
case ImageLayout::general: return D3D12_RESOURCE_STATE_COMMON;
|
||||
case ImageLayout::colorAttachment: return D3D12_RESOURCE_STATE_RENDER_TARGET;
|
||||
case ImageLayout::depthStencilAttachment: return D3D12_RESOURCE_STATE_DEPTH_WRITE;
|
||||
case ImageLayout::depthStencilReadOnly: return D3D12_RESOURCE_STATE_DEPTH_READ | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
|
||||
case ImageLayout::xsReadOnly: return D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
|
||||
case ImageLayout::fsReadOnly: return D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
|
||||
case ImageLayout::transferSrc: return D3D12_RESOURCE_STATE_COPY_SOURCE;
|
||||
case ImageLayout::transferDst: return D3D12_RESOURCE_STATE_COPY_DEST;
|
||||
case ImageLayout::presentSrc: return D3D12_RESOURCE_STATE_PRESENT;
|
||||
default: throw VERUS_RECOVERABLE << "ToNativeImageLayout()";
|
||||
}
|
||||
}
|
||||
|
||||
D3D12_FILL_MODE CGI::ToNativePolygonMode(PolygonMode polygonMode)
|
||||
{
|
||||
switch (polygonMode)
|
||||
{
|
||||
case PolygonMode::fill: return D3D12_FILL_MODE_SOLID;
|
||||
case PolygonMode::line: return D3D12_FILL_MODE_WIREFRAME;
|
||||
default: throw VERUS_RECOVERABLE << "ToNativePolygonMode()";
|
||||
}
|
||||
}
|
||||
|
||||
D3D_PRIMITIVE_TOPOLOGY CGI::ToNativePrimitiveTopology(PrimitiveTopology primitiveTopology)
|
||||
{
|
||||
switch (primitiveTopology)
|
||||
{
|
||||
case PrimitiveTopology::pointList: return D3D_PRIMITIVE_TOPOLOGY_POINTLIST;
|
||||
case PrimitiveTopology::lineList: return D3D_PRIMITIVE_TOPOLOGY_LINELIST;
|
||||
case PrimitiveTopology::lineStrip: return D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;
|
||||
case PrimitiveTopology::triangleList: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
|
||||
case PrimitiveTopology::triangleStrip: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
|
||||
case PrimitiveTopology::patchList3: return D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST;
|
||||
case PrimitiveTopology::patchList4: return D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST;
|
||||
default: throw VERUS_RECOVERABLE << "ToNativePrimitiveTopology()";
|
||||
}
|
||||
}
|
||||
|
||||
D3D12_PRIMITIVE_TOPOLOGY_TYPE CGI::ToNativePrimitiveTopologyType(PrimitiveTopology primitiveTopology)
|
||||
{
|
||||
switch (primitiveTopology)
|
||||
{
|
||||
case PrimitiveTopology::pointList: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT;
|
||||
case PrimitiveTopology::lineList: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE;
|
||||
case PrimitiveTopology::lineStrip: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE;
|
||||
case PrimitiveTopology::triangleList: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
|
||||
case PrimitiveTopology::triangleStrip: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
|
||||
case PrimitiveTopology::patchList3: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH;
|
||||
case PrimitiveTopology::patchList4: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH;
|
||||
default: throw VERUS_RECOVERABLE << "ToNativePrimitiveTopologyType()";
|
||||
}
|
||||
}
|
||||
|
||||
D3D12_COMPARISON_FUNC CGI::ToNativeCompareOp(CompareOp compareOp)
|
||||
{
|
||||
switch (compareOp)
|
||||
{
|
||||
case CompareOp::never: return D3D12_COMPARISON_FUNC_NEVER;
|
||||
case CompareOp::less: return D3D12_COMPARISON_FUNC_LESS;
|
||||
case CompareOp::equal: return D3D12_COMPARISON_FUNC_EQUAL;
|
||||
case CompareOp::lessOrEqual: return D3D12_COMPARISON_FUNC_LESS_EQUAL;
|
||||
case CompareOp::greater: return D3D12_COMPARISON_FUNC_GREATER;
|
||||
case CompareOp::notEqual: return D3D12_COMPARISON_FUNC_NOT_EQUAL;
|
||||
case CompareOp::greaterOrEqual: return D3D12_COMPARISON_FUNC_GREATER_EQUAL;
|
||||
case CompareOp::always: return D3D12_COMPARISON_FUNC_ALWAYS;
|
||||
default: throw VERUS_RECOVERABLE << "ToNativeCompareOp()";
|
||||
}
|
||||
}
|
||||
|
||||
CSZ CGI::ToNativeSemanticName(ViaUsage usage)
|
||||
{
|
||||
static const CSZ names[] =
|
||||
|
@ -230,17 +243,3 @@ DXGI_FORMAT CGI::ToNativeFormat(ViaUsage usage, ViaType type, int components)
|
|||
default: throw VERUS_RECOVERABLE << "ToNativeFormat(); ViaType=?";
|
||||
}
|
||||
}
|
||||
|
||||
UINT CGI::ToNativeCubeMapFace(CubeMapFace face)
|
||||
{
|
||||
switch (face)
|
||||
{
|
||||
case CubeMapFace::posX: return 0;
|
||||
case CubeMapFace::negX: return 1;
|
||||
case CubeMapFace::posY: return 2;
|
||||
case CubeMapFace::negY: return 3;
|
||||
case CubeMapFace::posZ: return 4;
|
||||
case CubeMapFace::negZ: return 5;
|
||||
default: throw VERUS_RECOVERABLE << "ToNativeCubeMapFace()";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,23 +5,23 @@ namespace verus
|
|||
{
|
||||
namespace CGI
|
||||
{
|
||||
DXGI_FORMAT ToNativeFormat(Format format, bool typeless);
|
||||
DXGI_FORMAT ToNativeSampledDepthFormat(Format format);
|
||||
D3D12_COMPARISON_FUNC ToNativeCompareOp(CompareOp compareOp);
|
||||
|
||||
D3D12_CULL_MODE ToNativeCullMode(CullMode cullMode);
|
||||
|
||||
D3D12_RESOURCE_STATES ToNativeImageLayout(ImageLayout layout);
|
||||
UINT ToNativeCubeMapFace(CubeMapFace face);
|
||||
|
||||
D3D12_FILL_MODE ToNativePolygonMode(PolygonMode polygonMode);
|
||||
|
||||
D3D12_CULL_MODE ToNativeCullMode(CullMode cullMode);
|
||||
|
||||
D3D_PRIMITIVE_TOPOLOGY ToNativePrimitiveTopology(PrimitiveTopology primitiveTopology);
|
||||
D3D12_PRIMITIVE_TOPOLOGY_TYPE ToNativePrimitiveTopologyType(PrimitiveTopology primitiveTopology);
|
||||
|
||||
D3D12_COMPARISON_FUNC ToNativeCompareOp(CompareOp compareOp);
|
||||
D3D12_RESOURCE_STATES ToNativeImageLayout(ImageLayout layout);
|
||||
|
||||
DXGI_FORMAT ToNativeFormat(Format format, bool typeless);
|
||||
DXGI_FORMAT ToNativeSampledDepthFormat(Format format);
|
||||
|
||||
CSZ ToNativeSemanticName(ViaUsage usage);
|
||||
DXGI_FORMAT ToNativeFormat(ViaUsage usage, ViaType type, int components);
|
||||
|
||||
UINT ToNativeCubeMapFace(CubeMapFace face);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ void PipelineD3D12::Init(RcPipelineDesc desc)
|
|||
gpsDesc.RasterizerState.DepthBias = static_cast<INT>(desc._rasterizationState._depthBiasConstantFactor);
|
||||
gpsDesc.RasterizerState.DepthBiasClamp = desc._rasterizationState._depthBiasClamp;
|
||||
gpsDesc.RasterizerState.SlopeScaledDepthBias = desc._rasterizationState._depthBiasSlopeFactor;
|
||||
gpsDesc.RasterizerState.DepthClipEnable = desc._rasterizationState._depthClampEnable;
|
||||
gpsDesc.RasterizerState.DepthClipEnable = TRUE;
|
||||
gpsDesc.RasterizerState.MultisampleEnable = FALSE;
|
||||
gpsDesc.RasterizerState.AntialiasedLineEnable = (desc._colorAttachBlendEqs[0] == VERUS_COLOR_BLEND_ALPHA) ? TRUE : FALSE;
|
||||
gpsDesc.RasterizerState.ForcedSampleCount = 0;
|
||||
|
@ -184,7 +184,7 @@ void PipelineD3D12::InitMeshShading(RcPipelineDesc desc)
|
|||
mspsDesc.RasterizerState.DepthBias = static_cast<INT>(desc._rasterizationState._depthBiasConstantFactor);
|
||||
mspsDesc.RasterizerState.DepthBiasClamp = desc._rasterizationState._depthBiasClamp;
|
||||
mspsDesc.RasterizerState.SlopeScaledDepthBias = desc._rasterizationState._depthBiasSlopeFactor;
|
||||
mspsDesc.RasterizerState.DepthClipEnable = desc._rasterizationState._depthClampEnable;
|
||||
mspsDesc.RasterizerState.DepthClipEnable = TRUE;
|
||||
mspsDesc.RasterizerState.MultisampleEnable = FALSE;
|
||||
mspsDesc.RasterizerState.AntialiasedLineEnable = (desc._colorAttachBlendEqs[0] == VERUS_COLOR_BLEND_ALPHA) ? TRUE : FALSE;
|
||||
mspsDesc.RasterizerState.ForcedSampleCount = 0;
|
||||
|
|
|
@ -140,7 +140,7 @@ void RendererD3D12::CreateSwapChainBuffersRTVs()
|
|||
HRESULT hr = 0;
|
||||
_vSwapChainBuffers.resize(_swapChainBufferCount);
|
||||
_dhSwapChainBuffersRTVs.Create(_pDevice.Get(), D3D12_DESCRIPTOR_HEAP_TYPE_RTV, _swapChainBufferCount);
|
||||
VERUS_U_FOR(i, _swapChainBufferCount)
|
||||
VERUS_FOR(i, _swapChainBufferCount)
|
||||
{
|
||||
ComPtr<ID3D12Resource> pBuffer;
|
||||
if (FAILED(hr = _pSwapChain->GetBuffer(i, IID_PPV_ARGS(&pBuffer))))
|
||||
|
@ -648,7 +648,7 @@ RPHandle RendererD3D12::CreateRenderPass(std::initializer_list<RP::Attachment> i
|
|||
renderPass._vAttachments.push_back(std::move(d3dAttach));
|
||||
}
|
||||
|
||||
auto GetAttachmentIndexByName = [&ilA](CSZ name) -> uint32_t
|
||||
auto GetAttachmentIndexByName = [&ilA](CSZ name) -> int
|
||||
{
|
||||
if (!name)
|
||||
return -1;
|
||||
|
|
|
@ -420,12 +420,22 @@ CSHandle ShaderD3D12::BindDescriptorSetTextures(int setNumber, std::initializer_
|
|||
_vComplexSets.resize(complexSetHandle + 1);
|
||||
}
|
||||
|
||||
bool toViewHeap = false;
|
||||
if (setNumber & ShaderD3D12::SET_MOD_TO_VIEW_HEAP)
|
||||
{
|
||||
setNumber &= ~ShaderD3D12::SET_MOD_TO_VIEW_HEAP;
|
||||
toViewHeap = true;
|
||||
}
|
||||
|
||||
auto& dsd = _vDescriptorSetDesc[setNumber];
|
||||
VERUS_RT_ASSERT(dsd._vSamplers.size() == il.size());
|
||||
|
||||
RComplexSet complexSet = _vComplexSets[complexSetHandle];
|
||||
complexSet._vTextures.reserve(il.size());
|
||||
complexSet._dhViews.Create(pRendererD3D12->GetD3DDevice(), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, Utils::Cast32(il.size()));
|
||||
if (toViewHeap)
|
||||
complexSet._hpBase = pRendererD3D12->GetViewHeap().GetNextHandlePair(1 + Utils::Cast32(il.size()));
|
||||
else
|
||||
complexSet._dhViews.Create(pRendererD3D12->GetD3DDevice(), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, Utils::Cast32(il.size()));
|
||||
if (!dsd._staticSamplersOnly)
|
||||
complexSet._dhSamplers.Create(pRendererD3D12->GetD3DDevice(), D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, Utils::Cast32(il.size()));
|
||||
int index = 0;
|
||||
|
@ -436,17 +446,37 @@ CSHandle ShaderD3D12::BindDescriptorSetTextures(int setNumber, std::initializer_
|
|||
auto& texD3D12 = static_cast<RTextureD3D12>(*x);
|
||||
if (Sampler::storage == dsd._vSamplers[index])
|
||||
{
|
||||
pRendererD3D12->GetD3DDevice()->CopyDescriptorsSimple(1,
|
||||
complexSet._dhViews.AtCPU(index),
|
||||
texD3D12.GetDescriptorHeapUAV().AtCPU(mip),
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
|
||||
if (toViewHeap)
|
||||
{
|
||||
pRendererD3D12->GetD3DDevice()->CopyDescriptorsSimple(1,
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE(complexSet._hpBase._hCPU, 1 + index, pRendererD3D12->GetViewHeap().GetHandleIncrementSize()),
|
||||
texD3D12.GetDescriptorHeapUAV().AtCPU(mip),
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
|
||||
}
|
||||
else
|
||||
{
|
||||
pRendererD3D12->GetD3DDevice()->CopyDescriptorsSimple(1,
|
||||
complexSet._dhViews.AtCPU(index),
|
||||
texD3D12.GetDescriptorHeapUAV().AtCPU(mip),
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pRendererD3D12->GetD3DDevice()->CopyDescriptorsSimple(1,
|
||||
complexSet._dhViews.AtCPU(index),
|
||||
texD3D12.GetDescriptorHeapSRV().AtCPU(mip),
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
|
||||
if (toViewHeap)
|
||||
{
|
||||
pRendererD3D12->GetD3DDevice()->CopyDescriptorsSimple(1,
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE(complexSet._hpBase._hCPU, 1 + index, pRendererD3D12->GetViewHeap().GetHandleIncrementSize()),
|
||||
texD3D12.GetDescriptorHeapSRV().AtCPU(mip),
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
|
||||
}
|
||||
else
|
||||
{
|
||||
pRendererD3D12->GetD3DDevice()->CopyDescriptorsSimple(1,
|
||||
complexSet._dhViews.AtCPU(index),
|
||||
texD3D12.GetDescriptorHeapSRV().AtCPU(mip),
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
|
||||
}
|
||||
if (Sampler::custom == dsd._vSamplers[index])
|
||||
{
|
||||
pRendererD3D12->GetD3DDevice()->CopyDescriptorsSimple(1,
|
||||
|
@ -540,7 +570,9 @@ CD3DX12_GPU_DESCRIPTOR_HANDLE ShaderD3D12::UpdateUniformBuffer(int setNumber, in
|
|||
auto& dsd = _vDescriptorSetDesc[setNumber];
|
||||
int at = 0;
|
||||
if (copyDescOnly)
|
||||
{
|
||||
at = dsd._capacity * pRendererD3D12->GetRingBufferIndex();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dsd._offset + dsd._alignedSize > dsd._capacityInBytes)
|
||||
|
@ -557,14 +589,26 @@ CD3DX12_GPU_DESCRIPTOR_HANDLE ShaderD3D12::UpdateUniformBuffer(int setNumber, in
|
|||
dsd._index++;
|
||||
}
|
||||
|
||||
auto hpBase = pRendererD3D12->GetViewHeap().GetNextHandlePair();
|
||||
bool hpBaseUsed = false;
|
||||
HandlePair hpBase;
|
||||
if (complexSetHandle >= 0)
|
||||
{
|
||||
const auto& complexSet = _vComplexSets[complexSetHandle];
|
||||
if (!complexSet._dhViews.GetD3DDescriptorHeap())
|
||||
{
|
||||
hpBase = complexSet._hpBase;
|
||||
hpBaseUsed = true;
|
||||
}
|
||||
}
|
||||
if (!hpBaseUsed)
|
||||
hpBase = pRendererD3D12->GetViewHeap().GetNextHandlePair();
|
||||
|
||||
// Copy CBV:
|
||||
pRendererD3D12->GetD3DDevice()->CopyDescriptorsSimple(1,
|
||||
hpBase._hCPU,
|
||||
dsd._dhDynamicOffsets.AtCPU(at),
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
|
||||
if (complexSetHandle >= 0)
|
||||
if (complexSetHandle >= 0 && !hpBaseUsed)
|
||||
{
|
||||
// Copy SRVs:
|
||||
const auto& complexSet = _vComplexSets[complexSetHandle];
|
||||
|
|
|
@ -29,6 +29,11 @@ namespace verus
|
|||
};
|
||||
VERUS_TYPEDEFS(Compiled);
|
||||
|
||||
enum SET_MOD
|
||||
{
|
||||
SET_MOD_TO_VIEW_HEAP = 0x10000
|
||||
};
|
||||
|
||||
private:
|
||||
typedef Map<String, Compiled> TMapCompiled;
|
||||
|
||||
|
@ -56,6 +61,7 @@ namespace verus
|
|||
Vector<TexturePtr> _vTextures;
|
||||
DescriptorHeap _dhViews;
|
||||
DescriptorHeap _dhSamplers;
|
||||
HandlePair _hpBase;
|
||||
};
|
||||
VERUS_TYPEDEFS(ComplexSet);
|
||||
|
||||
|
|
|
@ -390,7 +390,6 @@ void TextureD3D12::GenerateMips(PBaseCommandBuffer pCB)
|
|||
pCB->BindPipeline(renderer.GetPipelineGenerateMips(!!(_desc._flags & TextureDesc::Flags::exposureMips)));
|
||||
|
||||
shader->BeginBindDescriptors();
|
||||
const bool createComplexSets = _vCshGenerateMips.empty();
|
||||
int dispatchIndex = 0;
|
||||
for (int srcMip = 0; srcMip < maxMipLevel;)
|
||||
{
|
||||
|
@ -407,22 +406,15 @@ void TextureD3D12::GenerateMips(PBaseCommandBuffer pCB)
|
|||
ub._mipLevelCount = dispatchMipCount;
|
||||
ub._srcDimensionCase = ((srcHeight & 1) << 1) | (srcWidth & 1);
|
||||
ub._srgb = IsSRGBFormat(_desc._format);
|
||||
ub._texelSize.x = 1.f / dstWidth;
|
||||
ub._texelSize.y = 1.f / dstHeight;
|
||||
ub._dstTexelSize.x = 1.f / dstWidth;
|
||||
ub._dstTexelSize.y = 1.f / dstHeight;
|
||||
|
||||
if (createComplexSets)
|
||||
{
|
||||
int mips[5] = {}; // For input texture (always mip 0) and 4 UAV mips.
|
||||
VERUS_FOR(mip, dispatchMipCount)
|
||||
mips[mip + 1] = srcMip + mip;
|
||||
const CSHandle complexSetHandle = shader->BindDescriptorSetTextures(0, { tex, tex, tex, tex, tex }, mips);
|
||||
_vCshGenerateMips.push_back(complexSetHandle);
|
||||
pCB->BindDescriptors(shader, 0, complexSetHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
pCB->BindDescriptors(shader, 0, _vCshGenerateMips[dispatchIndex]);
|
||||
}
|
||||
int mips[5] = {}; // For input texture (always mip 0) and 4 UAV mips.
|
||||
VERUS_FOR(mip, dispatchMipCount)
|
||||
mips[mip + 1] = srcMip + mip;
|
||||
const CSHandle complexSetHandle = shader->BindDescriptorSetTextures(0 | ShaderD3D12::SET_MOD_TO_VIEW_HEAP, { tex, tex, tex, tex, tex }, mips);
|
||||
_vCshGenerateMips.push_back(complexSetHandle);
|
||||
pCB->BindDescriptors(shader, 0, complexSetHandle);
|
||||
|
||||
pCB->Dispatch(Math::DivideByMultiple(dstWidth, 8), Math::DivideByMultiple(dstHeight, 8));
|
||||
|
||||
|
@ -479,6 +471,7 @@ void TextureD3D12::GenerateMips(PBaseCommandBuffer pCB)
|
|||
if (_mainLayout != ImageLayout::xsReadOnly)
|
||||
pCB->PipelineImageMemoryBarrier(tex, ImageLayout::xsReadOnly, _mainLayout, Range(0, _desc._mipLevels));
|
||||
|
||||
ClearCshGenerateMips();
|
||||
Schedule(0);
|
||||
}
|
||||
|
||||
|
@ -495,6 +488,13 @@ Continue TextureD3D12::Scheduled_Update()
|
|||
}
|
||||
_vStagingBuffers.clear();
|
||||
|
||||
ClearCshGenerateMips();
|
||||
|
||||
return Continue::no;
|
||||
}
|
||||
|
||||
void TextureD3D12::ClearCshGenerateMips()
|
||||
{
|
||||
if (!_vCshGenerateMips.empty())
|
||||
{
|
||||
VERUS_QREF_RENDERER;
|
||||
|
@ -503,8 +503,6 @@ Continue TextureD3D12::Scheduled_Update()
|
|||
shader->FreeDescriptorSet(csh);
|
||||
_vCshGenerateMips.clear();
|
||||
}
|
||||
|
||||
return Continue::no;
|
||||
}
|
||||
|
||||
void TextureD3D12::CreateSampler()
|
||||
|
|
|
@ -42,6 +42,8 @@ namespace verus
|
|||
// D3D12
|
||||
//
|
||||
|
||||
void ClearCshGenerateMips();
|
||||
|
||||
void CreateSampler();
|
||||
|
||||
ID3D12Resource* GetD3DResource() const { return _resource._pResource.Get(); }
|
||||
|
|
|
@ -76,8 +76,8 @@ void CommandBufferVulkan::End()
|
|||
void CommandBufferVulkan::BeginRenderPass(RPHandle renderPassHandle, FBHandle framebufferHandle, std::initializer_list<Vector4> ilClearValues, bool setViewportAndScissor)
|
||||
{
|
||||
VERUS_QREF_RENDERER_VULKAN;
|
||||
VERUS_QREF_CONST_SETTINGS;
|
||||
RendererVulkan::RcFramebuffer framebuffer = pRendererVulkan->GetFramebuffer(framebufferHandle);
|
||||
// The application must ensure (using scissor if necessary) that all rendering is contained within the render area.
|
||||
VkRenderPassBeginInfo vkrpbi = {};
|
||||
vkrpbi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||
vkrpbi.renderPass = pRendererVulkan->GetRenderPass(renderPassHandle);
|
||||
|
@ -94,6 +94,7 @@ void CommandBufferVulkan::BeginRenderPass(RPHandle renderPassHandle, FBHandle fr
|
|||
}
|
||||
vkrpbi.clearValueCount = count;
|
||||
vkrpbi.pClearValues = clearValues;
|
||||
// There may be a performance cost for using a render area smaller than the framebuffer, unless it matches the render area granularity for the render pass.
|
||||
vkCmdBeginRenderPass(GetVkCommandBuffer(), &vkrpbi, VK_SUBPASS_CONTENTS_INLINE);
|
||||
if (setViewportAndScissor)
|
||||
{
|
||||
|
|
|
@ -3,6 +3,135 @@
|
|||
|
||||
using namespace verus;
|
||||
|
||||
VkCompareOp CGI::ToNativeCompareOp(CompareOp compareOp)
|
||||
{
|
||||
switch (compareOp)
|
||||
{
|
||||
case CompareOp::never: return VK_COMPARE_OP_NEVER;
|
||||
case CompareOp::less: return VK_COMPARE_OP_LESS;
|
||||
case CompareOp::equal: return VK_COMPARE_OP_EQUAL;
|
||||
case CompareOp::lessOrEqual: return VK_COMPARE_OP_LESS_OR_EQUAL;
|
||||
case CompareOp::greater: return VK_COMPARE_OP_GREATER;
|
||||
case CompareOp::notEqual: return VK_COMPARE_OP_NOT_EQUAL;
|
||||
case CompareOp::greaterOrEqual: return VK_COMPARE_OP_GREATER_OR_EQUAL;
|
||||
case CompareOp::always: return VK_COMPARE_OP_ALWAYS;
|
||||
default: throw VERUS_RECOVERABLE << "ToNativeCompareOp()";
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t CGI::ToNativeCubeMapFace(CubeMapFace face)
|
||||
{
|
||||
switch (face)
|
||||
{
|
||||
case CubeMapFace::posX: return 0;
|
||||
case CubeMapFace::negX: return 1;
|
||||
case CubeMapFace::posY: return 2;
|
||||
case CubeMapFace::negY: return 3;
|
||||
case CubeMapFace::posZ: return 4;
|
||||
case CubeMapFace::negZ: return 5;
|
||||
default: throw VERUS_RECOVERABLE << "ToNativeCubeMapFace()";
|
||||
}
|
||||
}
|
||||
|
||||
VkPolygonMode CGI::ToNativePolygonMode(PolygonMode polygonMode)
|
||||
{
|
||||
switch (polygonMode)
|
||||
{
|
||||
case PolygonMode::fill: return VK_POLYGON_MODE_FILL;
|
||||
case PolygonMode::line: return VK_POLYGON_MODE_LINE;
|
||||
default: throw VERUS_RECOVERABLE << "ToNativePolygonMode()";
|
||||
}
|
||||
}
|
||||
|
||||
VkCullModeFlagBits CGI::ToNativeCullMode(CullMode cullMode)
|
||||
{
|
||||
switch (cullMode)
|
||||
{
|
||||
case CullMode::none: return VK_CULL_MODE_NONE;
|
||||
case CullMode::front: return VK_CULL_MODE_FRONT_BIT;
|
||||
case CullMode::back: return VK_CULL_MODE_BACK_BIT;
|
||||
default: throw VERUS_RECOVERABLE << "ToNativeCullMode()";
|
||||
}
|
||||
}
|
||||
|
||||
VkPrimitiveTopology CGI::ToNativePrimitiveTopology(PrimitiveTopology primitiveTopology)
|
||||
{
|
||||
switch (primitiveTopology)
|
||||
{
|
||||
case PrimitiveTopology::pointList: return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
|
||||
case PrimitiveTopology::lineList: return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
|
||||
case PrimitiveTopology::lineStrip: return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
|
||||
case PrimitiveTopology::triangleList: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||
case PrimitiveTopology::triangleStrip: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
|
||||
case PrimitiveTopology::patchList3: return VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
|
||||
case PrimitiveTopology::patchList4: return VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
|
||||
default: throw VERUS_RECOVERABLE << "ToNativePrimitiveTopology()";
|
||||
}
|
||||
}
|
||||
|
||||
VkImageLayout CGI::ToNativeImageLayout(ImageLayout layout)
|
||||
{
|
||||
switch (layout)
|
||||
{
|
||||
case ImageLayout::undefined: return VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
case ImageLayout::general: return VK_IMAGE_LAYOUT_GENERAL;
|
||||
case ImageLayout::colorAttachment: return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
case ImageLayout::depthStencilAttachment: return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
case ImageLayout::depthStencilReadOnly: return VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
|
||||
case ImageLayout::xsReadOnly: return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
case ImageLayout::fsReadOnly: return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
case ImageLayout::transferSrc: return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||
case ImageLayout::transferDst: return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
case ImageLayout::presentSrc: return VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
default: throw VERUS_RECOVERABLE << "ToNativeImageLayout()";
|
||||
}
|
||||
}
|
||||
|
||||
VkShaderStageFlags CGI::ToNativeStageFlags(ShaderStageFlags stageFlags)
|
||||
{
|
||||
VkShaderStageFlags ret = 0;
|
||||
if (stageFlags & ShaderStageFlags::vs)
|
||||
ret |= VK_SHADER_STAGE_VERTEX_BIT;
|
||||
if (stageFlags & ShaderStageFlags::hs)
|
||||
ret |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
|
||||
if (stageFlags & ShaderStageFlags::ds)
|
||||
ret |= VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
|
||||
if (stageFlags & ShaderStageFlags::gs)
|
||||
ret |= VK_SHADER_STAGE_GEOMETRY_BIT;
|
||||
if (stageFlags & ShaderStageFlags::fs)
|
||||
ret |= VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
if (stageFlags & ShaderStageFlags::cs)
|
||||
ret |= VK_SHADER_STAGE_COMPUTE_BIT;
|
||||
if (stageFlags & ShaderStageFlags::rtrg)
|
||||
ret |= VK_SHADER_STAGE_RAYGEN_BIT_KHR;
|
||||
if (stageFlags & ShaderStageFlags::rtah)
|
||||
ret |= VK_SHADER_STAGE_ANY_HIT_BIT_KHR;
|
||||
if (stageFlags & ShaderStageFlags::rtch)
|
||||
ret |= VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
|
||||
if (stageFlags & ShaderStageFlags::rtm)
|
||||
ret |= VK_SHADER_STAGE_MISS_BIT_KHR;
|
||||
if (stageFlags & ShaderStageFlags::rti)
|
||||
ret |= VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
|
||||
if (stageFlags & ShaderStageFlags::rtc)
|
||||
ret |= VK_SHADER_STAGE_CALLABLE_BIT_KHR;
|
||||
return ret;
|
||||
}
|
||||
|
||||
VkSampleCountFlagBits CGI::ToNativeSampleCount(int sampleCount)
|
||||
{
|
||||
switch (sampleCount)
|
||||
{
|
||||
case 1: return VK_SAMPLE_COUNT_1_BIT;
|
||||
case 2: return VK_SAMPLE_COUNT_2_BIT;
|
||||
case 4: return VK_SAMPLE_COUNT_4_BIT;
|
||||
case 8: return VK_SAMPLE_COUNT_8_BIT;
|
||||
case 16: return VK_SAMPLE_COUNT_16_BIT;
|
||||
case 32: return VK_SAMPLE_COUNT_32_BIT;
|
||||
case 64: return VK_SAMPLE_COUNT_64_BIT;
|
||||
default: throw VERUS_RECOVERABLE << "ToNativeSampleCount()";
|
||||
}
|
||||
}
|
||||
|
||||
VkFormat CGI::ToNativeFormat(Format format)
|
||||
{
|
||||
switch (format)
|
||||
|
@ -43,121 +172,6 @@ VkFormat CGI::ToNativeFormat(Format format)
|
|||
}
|
||||
}
|
||||
|
||||
VkCullModeFlagBits CGI::ToNativeCullMode(CullMode cullMode)
|
||||
{
|
||||
switch (cullMode)
|
||||
{
|
||||
case CullMode::none: return VK_CULL_MODE_NONE;
|
||||
case CullMode::front: return VK_CULL_MODE_FRONT_BIT;
|
||||
case CullMode::back: return VK_CULL_MODE_BACK_BIT;
|
||||
default: throw VERUS_RECOVERABLE << "ToNativeCullMode()";
|
||||
}
|
||||
}
|
||||
|
||||
VkImageLayout CGI::ToNativeImageLayout(ImageLayout layout)
|
||||
{
|
||||
switch (layout)
|
||||
{
|
||||
case ImageLayout::undefined: return VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
case ImageLayout::general: return VK_IMAGE_LAYOUT_GENERAL;
|
||||
case ImageLayout::colorAttachment: return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
case ImageLayout::depthStencilAttachment: return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
case ImageLayout::depthStencilReadOnly: return VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
|
||||
case ImageLayout::xsReadOnly: return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
case ImageLayout::fsReadOnly: return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
case ImageLayout::transferSrc: return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||
case ImageLayout::transferDst: return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
case ImageLayout::presentSrc: return VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
default: throw VERUS_RECOVERABLE << "ToNativeImageLayout()";
|
||||
}
|
||||
}
|
||||
|
||||
VkPolygonMode CGI::ToNativePolygonMode(PolygonMode polygonMode)
|
||||
{
|
||||
switch (polygonMode)
|
||||
{
|
||||
case PolygonMode::fill: return VK_POLYGON_MODE_FILL;
|
||||
case PolygonMode::line: return VK_POLYGON_MODE_LINE;
|
||||
default: throw VERUS_RECOVERABLE << "ToNativePolygonMode()";
|
||||
}
|
||||
}
|
||||
|
||||
VkPrimitiveTopology CGI::ToNativePrimitiveTopology(PrimitiveTopology primitiveTopology)
|
||||
{
|
||||
switch (primitiveTopology)
|
||||
{
|
||||
case PrimitiveTopology::pointList: return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
|
||||
case PrimitiveTopology::lineList: return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
|
||||
case PrimitiveTopology::lineStrip: return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
|
||||
case PrimitiveTopology::triangleList: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||
case PrimitiveTopology::triangleStrip: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
|
||||
case PrimitiveTopology::patchList3: return VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
|
||||
case PrimitiveTopology::patchList4: return VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
|
||||
default: throw VERUS_RECOVERABLE << "ToNativePrimitiveTopology()";
|
||||
}
|
||||
}
|
||||
|
||||
VkSampleCountFlagBits CGI::ToNativeSampleCount(int sampleCount)
|
||||
{
|
||||
switch (sampleCount)
|
||||
{
|
||||
case 1: return VK_SAMPLE_COUNT_1_BIT;
|
||||
case 2: return VK_SAMPLE_COUNT_2_BIT;
|
||||
case 4: return VK_SAMPLE_COUNT_4_BIT;
|
||||
case 8: return VK_SAMPLE_COUNT_8_BIT;
|
||||
case 16: return VK_SAMPLE_COUNT_16_BIT;
|
||||
case 32: return VK_SAMPLE_COUNT_32_BIT;
|
||||
case 64: return VK_SAMPLE_COUNT_64_BIT;
|
||||
default: throw VERUS_RECOVERABLE << "ToNativeSampleCount()";
|
||||
}
|
||||
}
|
||||
|
||||
VkCompareOp CGI::ToNativeCompareOp(CompareOp compareOp)
|
||||
{
|
||||
switch (compareOp)
|
||||
{
|
||||
case CompareOp::never: return VK_COMPARE_OP_NEVER;
|
||||
case CompareOp::less: return VK_COMPARE_OP_LESS;
|
||||
case CompareOp::equal: return VK_COMPARE_OP_EQUAL;
|
||||
case CompareOp::lessOrEqual: return VK_COMPARE_OP_LESS_OR_EQUAL;
|
||||
case CompareOp::greater: return VK_COMPARE_OP_GREATER;
|
||||
case CompareOp::notEqual: return VK_COMPARE_OP_NOT_EQUAL;
|
||||
case CompareOp::greaterOrEqual: return VK_COMPARE_OP_GREATER_OR_EQUAL;
|
||||
case CompareOp::always: return VK_COMPARE_OP_ALWAYS;
|
||||
default: throw VERUS_RECOVERABLE << "ToNativeCompareOp()";
|
||||
}
|
||||
}
|
||||
|
||||
VkShaderStageFlags CGI::ToNativeStageFlags(ShaderStageFlags stageFlags)
|
||||
{
|
||||
VkShaderStageFlags ret = 0;
|
||||
if (stageFlags & ShaderStageFlags::vs)
|
||||
ret |= VK_SHADER_STAGE_VERTEX_BIT;
|
||||
if (stageFlags & ShaderStageFlags::hs)
|
||||
ret |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
|
||||
if (stageFlags & ShaderStageFlags::ds)
|
||||
ret |= VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
|
||||
if (stageFlags & ShaderStageFlags::gs)
|
||||
ret |= VK_SHADER_STAGE_GEOMETRY_BIT;
|
||||
if (stageFlags & ShaderStageFlags::fs)
|
||||
ret |= VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
if (stageFlags & ShaderStageFlags::cs)
|
||||
ret |= VK_SHADER_STAGE_COMPUTE_BIT;
|
||||
if (stageFlags & ShaderStageFlags::rtrg)
|
||||
ret |= VK_SHADER_STAGE_RAYGEN_BIT_KHR;
|
||||
if (stageFlags & ShaderStageFlags::rtah)
|
||||
ret |= VK_SHADER_STAGE_ANY_HIT_BIT_KHR;
|
||||
if (stageFlags & ShaderStageFlags::rtch)
|
||||
ret |= VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
|
||||
if (stageFlags & ShaderStageFlags::rtm)
|
||||
ret |= VK_SHADER_STAGE_MISS_BIT_KHR;
|
||||
if (stageFlags & ShaderStageFlags::rti)
|
||||
ret |= VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
|
||||
if (stageFlags & ShaderStageFlags::rtc)
|
||||
ret |= VK_SHADER_STAGE_CALLABLE_BIT_KHR;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int CGI::ToNativeLocation(ViaUsage usage, int usageIndex)
|
||||
{
|
||||
// See: https://www.opengl.org/sdk/docs/tutorials/ClockworkCoders/attributes.php
|
||||
|
@ -248,17 +262,3 @@ VkFormat CGI::ToNativeFormat(ViaUsage usage, ViaType type, int components)
|
|||
default: throw VERUS_RECOVERABLE << "ToNativeFormat(); ViaType=?";
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t CGI::ToNativeCubeMapFace(CubeMapFace face)
|
||||
{
|
||||
switch (face)
|
||||
{
|
||||
case CubeMapFace::posX: return 0;
|
||||
case CubeMapFace::negX: return 1;
|
||||
case CubeMapFace::posY: return 2;
|
||||
case CubeMapFace::negY: return 3;
|
||||
case CubeMapFace::posZ: return 4;
|
||||
case CubeMapFace::negZ: return 5;
|
||||
default: throw VERUS_RECOVERABLE << "ToNativeCubeMapFace()";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,25 +5,25 @@ namespace verus
|
|||
{
|
||||
namespace CGI
|
||||
{
|
||||
VkFormat ToNativeFormat(Format format);
|
||||
VkCompareOp ToNativeCompareOp(CompareOp compareOp);
|
||||
|
||||
VkCullModeFlagBits ToNativeCullMode(CullMode cullMode);
|
||||
|
||||
VkImageLayout ToNativeImageLayout(ImageLayout layout);
|
||||
uint32_t ToNativeCubeMapFace(CubeMapFace face);
|
||||
|
||||
VkPolygonMode ToNativePolygonMode(PolygonMode polygonMode);
|
||||
|
||||
VkCullModeFlagBits ToNativeCullMode(CullMode cullMode);
|
||||
|
||||
VkPrimitiveTopology ToNativePrimitiveTopology(PrimitiveTopology primitiveTopology);
|
||||
|
||||
VkSampleCountFlagBits ToNativeSampleCount(int sampleCount);
|
||||
|
||||
VkCompareOp ToNativeCompareOp(CompareOp compareOp);
|
||||
VkImageLayout ToNativeImageLayout(ImageLayout layout);
|
||||
|
||||
VkShaderStageFlags ToNativeStageFlags(ShaderStageFlags stageFlags);
|
||||
|
||||
VkSampleCountFlagBits ToNativeSampleCount(int sampleCount);
|
||||
|
||||
VkFormat ToNativeFormat(Format format);
|
||||
|
||||
int ToNativeLocation(ViaUsage usage, int usageIndex);
|
||||
VkFormat ToNativeFormat(ViaUsage usage, ViaType type, int components);
|
||||
|
||||
uint32_t ToNativeCubeMapFace(CubeMapFace face);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -96,7 +96,7 @@ void PipelineVulkan::Init(RcPipelineDesc desc)
|
|||
VkPipelineRasterizationStateCreateInfo rasterizationState = {};
|
||||
rasterizationState.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
||||
rasterizationState.pNext = &rasterizationLineState;
|
||||
rasterizationState.depthClampEnable = desc._rasterizationState._depthClampEnable;
|
||||
rasterizationState.depthClampEnable = VK_FALSE;
|
||||
rasterizationState.polygonMode = ToNativePolygonMode(desc._rasterizationState._polygonMode);
|
||||
rasterizationState.cullMode = ToNativeCullMode(desc._rasterizationState._cullMode);
|
||||
rasterizationState.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
|
||||
|
|
|
@ -532,16 +532,18 @@ void RendererVulkan::CreateSwapChain(VkSwapchainKHR oldSwapchain)
|
|||
if (VK_SUCCESS != (res = vkCreateSwapchainKHR(_device, &vksci, GetAllocator(), &_swapChain)))
|
||||
throw VERUS_RUNTIME_ERROR << "vkCreateSwapchainKHR(); res=" << res;
|
||||
|
||||
vkGetSwapchainImagesKHR(_device, _swapChain, &_swapChainBufferCount, nullptr);
|
||||
_vSwapChainImages.resize(_swapChainBufferCount);
|
||||
vkGetSwapchainImagesKHR(_device, _swapChain, &_swapChainBufferCount, _vSwapChainImages.data());
|
||||
uint32_t swapchainImageCount = _swapChainBufferCount;
|
||||
vkGetSwapchainImagesKHR(_device, _swapChain, &swapchainImageCount, nullptr);
|
||||
_vSwapChainImages.resize(swapchainImageCount);
|
||||
vkGetSwapchainImagesKHR(_device, _swapChain, &swapchainImageCount, _vSwapChainImages.data());
|
||||
_swapChainBufferCount = swapchainImageCount;
|
||||
}
|
||||
|
||||
void RendererVulkan::CreateImageViews()
|
||||
{
|
||||
VkResult res = VK_SUCCESS;
|
||||
_vSwapChainImageViews.resize(_swapChainBufferCount);
|
||||
VERUS_U_FOR(i, _swapChainBufferCount)
|
||||
VERUS_FOR(i, _swapChainBufferCount)
|
||||
{
|
||||
VkImageViewCreateInfo vkivci = {};
|
||||
vkivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
|
@ -583,7 +585,7 @@ void RendererVulkan::CreateSyncObjects()
|
|||
VkFenceCreateInfo vkfci = {};
|
||||
vkfci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||
vkfci.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
||||
VERUS_U_FOR(i, s_ringBufferSize)
|
||||
VERUS_FOR(i, s_ringBufferSize)
|
||||
{
|
||||
if (VK_SUCCESS != (res = vkCreateSemaphore(_device, &vksci, GetAllocator(), &_acquireNextImageSemaphores[i])))
|
||||
throw VERUS_RUNTIME_ERROR << "vkCreateSemaphore(); res=" << res;
|
||||
|
@ -821,8 +823,10 @@ void RendererVulkan::BeginFrame(bool present)
|
|||
throw VERUS_RUNTIME_ERROR << "vkResetFences(); res=" << res;
|
||||
if (present)
|
||||
{
|
||||
if (VK_SUCCESS != (res = vkAcquireNextImageKHR(_device, _swapChain, UINT64_MAX, _acquireNextImageSemaphores[_ringBufferIndex], VK_NULL_HANDLE, &_swapChainBufferIndex)))
|
||||
uint32_t imageIndex = _swapChainBufferIndex;
|
||||
if (VK_SUCCESS != (res = vkAcquireNextImageKHR(_device, _swapChain, UINT64_MAX, _acquireNextImageSemaphores[_ringBufferIndex], VK_NULL_HANDLE, &imageIndex)))
|
||||
throw VERUS_RUNTIME_ERROR << "vkAcquireNextImageKHR(); res=" << res;
|
||||
_swapChainBufferIndex = imageIndex;
|
||||
}
|
||||
|
||||
vmaSetCurrentFrameIndex(_vmaAllocator, static_cast<uint32_t>(renderer.GetFrameCount()));
|
||||
|
@ -878,6 +882,7 @@ void RendererVulkan::Present()
|
|||
|
||||
const VkSwapchainKHR swapChains[] = { _swapChain };
|
||||
|
||||
const uint32_t imageIndex = _swapChainBufferIndex;
|
||||
VkPresentInfoKHR vkpi = {};
|
||||
vkpi.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||
if (!_queueFamilyIndices.IsSameQueue())
|
||||
|
@ -887,7 +892,7 @@ void RendererVulkan::Present()
|
|||
}
|
||||
vkpi.swapchainCount = VERUS_COUNT_OF(swapChains);
|
||||
vkpi.pSwapchains = swapChains;
|
||||
vkpi.pImageIndices = &_swapChainBufferIndex;
|
||||
vkpi.pImageIndices = &imageIndex;
|
||||
if (VK_SUCCESS != (res = vkQueuePresentKHR(_presentQueue, &vkpi)))
|
||||
{
|
||||
if (res != VK_ERROR_OUT_OF_DATE_KHR)
|
||||
|
@ -1019,17 +1024,17 @@ RPHandle RendererVulkan::CreateRenderPass(std::initializer_list<RP::Attachment>
|
|||
|
||||
struct SubpassMetadata
|
||||
{
|
||||
int inputRefIndex = -1;
|
||||
int colorRefIndex = -1;
|
||||
int resolveRefIndex = -1;
|
||||
int depthStencilRefIndex = -1;
|
||||
int preserveIndex = -1;
|
||||
int inputRefsOffset = -1;
|
||||
int colorRefsOffset = -1;
|
||||
int resolveRefsOffset = -1;
|
||||
int depthStencilRefOffset = -1;
|
||||
int preserveOffset = -1;
|
||||
};
|
||||
|
||||
Vector<VkAttachmentReference> vAttachmentRef;
|
||||
vAttachmentRef.reserve(20);
|
||||
Vector<uint32_t> vAttachmentIndex;
|
||||
vAttachmentIndex.reserve(20);
|
||||
Vector<VkAttachmentReference> vAttachmentRefs;
|
||||
vAttachmentRefs.reserve(20);
|
||||
Vector<uint32_t> vAttachmentIndices;
|
||||
vAttachmentIndices.reserve(20);
|
||||
|
||||
Vector<SubpassMetadata> vSubpassMetadata;
|
||||
vSubpassMetadata.reserve(ilS.size());
|
||||
|
@ -1042,61 +1047,61 @@ RPHandle RendererVulkan::CreateRenderPass(std::initializer_list<RP::Attachment>
|
|||
vksd.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||
|
||||
vksd.inputAttachmentCount = Utils::Cast32(subpass._ilInput.size());
|
||||
subpassMetadata.inputRefIndex = Utils::Cast32(vAttachmentRef.size());
|
||||
subpassMetadata.inputRefsOffset = Utils::Cast32(vAttachmentRefs.size());
|
||||
for (const auto& input : subpass._ilInput)
|
||||
{
|
||||
VkAttachmentReference vkar = {};
|
||||
vkar.attachment = GetAttachmentIndexByName(input._name);
|
||||
vkar.layout = ToNativeImageLayout(input._layout);
|
||||
vAttachmentRef.push_back(vkar);
|
||||
vAttachmentRefs.push_back(vkar);
|
||||
}
|
||||
|
||||
vksd.colorAttachmentCount = Utils::Cast32(subpass._ilColor.size());
|
||||
subpassMetadata.colorRefIndex = Utils::Cast32(vAttachmentRef.size());
|
||||
subpassMetadata.colorRefsOffset = Utils::Cast32(vAttachmentRefs.size());
|
||||
for (const auto& color : subpass._ilColor)
|
||||
{
|
||||
VkAttachmentReference vkar = {};
|
||||
vkar.attachment = GetAttachmentIndexByName(color._name);
|
||||
vkar.layout = ToNativeImageLayout(color._layout);
|
||||
vAttachmentRef.push_back(vkar);
|
||||
vAttachmentRefs.push_back(vkar);
|
||||
}
|
||||
|
||||
if (subpass._depthStencil._name)
|
||||
{
|
||||
subpassMetadata.depthStencilRefIndex = Utils::Cast32(vAttachmentRef.size());
|
||||
subpassMetadata.depthStencilRefOffset = Utils::Cast32(vAttachmentRefs.size());
|
||||
VkAttachmentReference vkar = {};
|
||||
vkar.attachment = GetAttachmentIndexByName(subpass._depthStencil._name);
|
||||
vkar.layout = ToNativeImageLayout(subpass._depthStencil._layout);
|
||||
vAttachmentRef.push_back(vkar);
|
||||
vAttachmentRefs.push_back(vkar);
|
||||
}
|
||||
|
||||
vksd.preserveAttachmentCount = Utils::Cast32(subpass._ilPreserve.size());
|
||||
subpassMetadata.preserveIndex = Utils::Cast32(vAttachmentIndex.size());
|
||||
subpassMetadata.preserveOffset = Utils::Cast32(vAttachmentIndices.size());
|
||||
for (const auto& preserve : subpass._ilPreserve)
|
||||
{
|
||||
const uint32_t index = GetAttachmentIndexByName(preserve._name);
|
||||
vAttachmentIndex.push_back(index);
|
||||
vAttachmentIndices.push_back(index);
|
||||
}
|
||||
|
||||
vSubpassDesc.push_back(vksd);
|
||||
vSubpassMetadata.push_back(subpassMetadata);
|
||||
}
|
||||
|
||||
// vAttachmentRef is ready, convert indices to actual pointers:
|
||||
if (vAttachmentRef.empty())
|
||||
// vAttachmentRefs is ready, convert offsets to actual pointers:
|
||||
if (vAttachmentRefs.empty())
|
||||
throw VERUS_RECOVERABLE << "CreateRenderPass(); No attachment references";
|
||||
int index = 0;
|
||||
for (auto& sd : vSubpassDesc)
|
||||
{
|
||||
const SubpassMetadata& sm = vSubpassMetadata[index];
|
||||
if (sd.inputAttachmentCount)
|
||||
sd.pInputAttachments = &vAttachmentRef[sm.inputRefIndex];
|
||||
sd.pInputAttachments = &vAttachmentRefs[sm.inputRefsOffset];
|
||||
if (sd.colorAttachmentCount)
|
||||
sd.pColorAttachments = &vAttachmentRef[sm.colorRefIndex];
|
||||
if (sm.depthStencilRefIndex >= 0)
|
||||
sd.pDepthStencilAttachment = &vAttachmentRef[sm.depthStencilRefIndex];
|
||||
sd.pColorAttachments = &vAttachmentRefs[sm.colorRefsOffset];
|
||||
if (sm.depthStencilRefOffset >= 0)
|
||||
sd.pDepthStencilAttachment = &vAttachmentRefs[sm.depthStencilRefOffset];
|
||||
if (sd.preserveAttachmentCount)
|
||||
sd.pPreserveAttachments = &vAttachmentIndex[sm.preserveIndex];
|
||||
sd.pPreserveAttachments = &vAttachmentIndices[sm.preserveOffset];
|
||||
index++;
|
||||
}
|
||||
|
||||
|
|
|
@ -346,8 +346,8 @@ void TextureVulkan::GenerateMips(PBaseCommandBuffer pCB)
|
|||
ub._mipLevelCount = dispatchMipCount;
|
||||
ub._srcDimensionCase = ((srcHeight & 1) << 1) | (srcWidth & 1);
|
||||
ub._srgb = IsSRGBFormat(_desc._format);
|
||||
ub._texelSize.x = 1.f / dstWidth;
|
||||
ub._texelSize.y = 1.f / dstHeight;
|
||||
ub._dstTexelSize.x = 1.f / dstWidth;
|
||||
ub._dstTexelSize.y = 1.f / dstHeight;
|
||||
|
||||
if (createComplexSets)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (C) 2021, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#define VERUS_INCLUDE_COMPRESSONATOR
|
||||
#include <verus.h>
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
<ImportGroup Label="PropertySheets" />
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<IncludePath>C:\Compressonator_4.2.5185\include;C:\Home\Projects\Verus\verus\Verus\src;C:\Home\Middleware\AMD Tootle 2.3\include;C:\Home\Middleware\bullet3-2.89\src;C:\Home\Middleware\bullet3-2.89\Extras;C:\Home\Middleware\libogg-1.3.4\include;C:\Home\Middleware\libvorbis-1.3.7\include;C:\Home\Middleware\openal-soft-1.21.1-bin\include;C:\Home\Middleware\SDL2-2.0.16\include;C:\VulkanSDK\1.2.198.1\Include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>C:\Compressonator_4.2.5185\lib\VS2017\x64;C:\Home\Middleware\bullet3-2.89\bin;C:\Home\Middleware\AMD Tootle 2.3\lib;C:\Home\Middleware\libogg-1.3.4\lib;C:\Home\Middleware\libvorbis-1.3.7\lib2;C:\Home\Middleware\openal-soft-1.21.1-bin\libs\Win64;C:\Home\Middleware\SDL2-2.0.16\lib\x64;C:\VulkanSDK\1.2.198.1\Lib;$(LibraryPath)</LibraryPath>
|
||||
<IncludePath>C:\Compressonator_4.2.5185\include;C:\Home\Projects\Verus\verus\Verus\src;C:\Home\Middleware\AMD Tootle 2.3\include;C:\Home\Middleware\bullet3-2.89\src;C:\Home\Middleware\bullet3-2.89\Extras;C:\Home\Middleware\libogg-1.3.4\include;C:\Home\Middleware\libvorbis-1.3.7\include;C:\Home\Middleware\openal-soft-1.21.1-bin\include;C:\Home\Middleware\SDL2-2.0.16\include;C:\VulkanSDK\1.3.204.1\Include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>C:\Compressonator_4.2.5185\lib\VS2017\x64;C:\Home\Middleware\bullet3-2.89\bin;C:\Home\Middleware\AMD Tootle 2.3\lib;C:\Home\Middleware\libogg-1.3.4\lib;C:\Home\Middleware\libvorbis-1.3.7\lib2;C:\Home\Middleware\openal-soft-1.21.1-bin\libs\Win64;C:\Home\Middleware\SDL2-2.0.16\lib\x64;C:\VulkanSDK\1.3.204.1\Lib;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup />
|
||||
<ItemGroup />
|
||||
|
|
|
@ -814,7 +814,7 @@ void Skeleton::AdaptBindPoseOf(RcSkeleton that)
|
|||
continue;
|
||||
vd /= ld;
|
||||
vs /= ls;
|
||||
const Matrix3 matWorldR = Matrix3::MakeRotateTo(vd, vs);
|
||||
const Matrix3 matWorldR = Matrix3::MakeTrackTo(vd, vs);
|
||||
|
||||
const Point3 offset = pParentDst->_matFromBoneSpace * origin;
|
||||
const Transform3 matToBoneOrigin = Transform3::translation(-Vector3(offset));
|
||||
|
@ -836,7 +836,7 @@ void Skeleton::SimpleIK(CSZ boneDriven, CSZ boneDriver, RcVector3 dirDriverSpace
|
|||
}
|
||||
Vector3 dirDesired = dirDesiredMeshSpace;
|
||||
dirDesired.LimitDot(dirActual, limitDot);
|
||||
const Matrix3 matR = Matrix3::MakeRotateTo(
|
||||
const Matrix3 matR = Matrix3::MakeTrackTo(
|
||||
dirActual,
|
||||
VMath::normalizeApprox(VMath::lerp(alpha, dirActual, dirDesired)));
|
||||
const Matrix3 matDrivenFrom = pBoneDriven->_matFinal.getUpper3x3() * pBoneDriven->_matFromBoneSpace.getUpper3x3();
|
||||
|
@ -943,7 +943,7 @@ void Skeleton::ProcessKinectData(const BYTE* p, RMotion motion, int frame)
|
|||
const Vector3 kinePoseDir = VMath::normalize(bone._matExternal.getTranslation() - kinePosePos);
|
||||
|
||||
Matrix3 matR3;
|
||||
matR3.RotateTo(bindPoseDir, kinePoseDir);
|
||||
matR3.TrackTo(bindPoseDir, kinePoseDir);
|
||||
const Transform3 matR(matR3, Vector3(0));
|
||||
const Transform3 matT = Transform3::translation(kinePosePos - bindPosePos);
|
||||
const Transform3 matOffset = Transform3::translation(kinePosePos);
|
||||
|
|
|
@ -28,9 +28,9 @@ namespace verus
|
|||
protected:
|
||||
Vector<PScheduled> _vScheduled;
|
||||
BaseRendererDesc _desc;
|
||||
UINT32 _swapChainBufferCount = 0;
|
||||
UINT32 _swapChainBufferIndex = 0;
|
||||
UINT32 _ringBufferIndex = 0;
|
||||
int _swapChainBufferCount = 0;
|
||||
int _swapChainBufferIndex = 0;
|
||||
int _ringBufferIndex = 0;
|
||||
|
||||
BaseRenderer();
|
||||
virtual ~BaseRenderer();
|
||||
|
@ -43,9 +43,9 @@ namespace verus
|
|||
|
||||
void SetDesc(RBaseRendererDesc desc) { _desc = desc; }
|
||||
|
||||
UINT32 GetSwapChainBufferCount() const { return _swapChainBufferCount; }
|
||||
UINT32 GetSwapChainBufferIndex() const { return _swapChainBufferIndex; }
|
||||
UINT32 GetRingBufferIndex() const { return _ringBufferIndex; }
|
||||
int GetSwapChainBufferCount() const { return _swapChainBufferCount; }
|
||||
int GetSwapChainBufferIndex() const { return _swapChainBufferIndex; }
|
||||
int GetRingBufferIndex() const { return _ringBufferIndex; }
|
||||
|
||||
void Schedule(PScheduled p);
|
||||
void Unschedule(PScheduled p);
|
||||
|
|
|
@ -20,7 +20,9 @@ bool BaseTexture::IsSRGB() const
|
|||
return
|
||||
!Str::EndsWith(_C(_name), ".NM.dds") &&
|
||||
!Str::EndsWith(_C(_name), ".FX.dds") &&
|
||||
!Str::EndsWith(_C(_name), ".H.dds");
|
||||
!Str::EndsWith(_C(_name), ".H.dds") &&
|
||||
!Str::EndsWith(_C(_name), ".N.dds") &&
|
||||
!Str::EndsWith(_C(_name), ".X.dds");
|
||||
}
|
||||
|
||||
void BaseTexture::LoadDDS(CSZ url, int texturePart)
|
||||
|
|
|
@ -5,6 +5,37 @@ namespace verus
|
|||
{
|
||||
namespace CGI
|
||||
{
|
||||
enum class CompareOp : int
|
||||
{
|
||||
never,
|
||||
less, // <
|
||||
equal, // ==
|
||||
lessOrEqual, // <=
|
||||
greater, // >
|
||||
notEqual, // !=
|
||||
greaterOrEqual, // >=
|
||||
always
|
||||
};
|
||||
|
||||
enum class CubeMapFace : int
|
||||
{
|
||||
posX,
|
||||
negX,
|
||||
posY,
|
||||
negY,
|
||||
posZ,
|
||||
negZ,
|
||||
count,
|
||||
all,
|
||||
none = -1
|
||||
};
|
||||
|
||||
enum class PolygonMode : int
|
||||
{
|
||||
fill,
|
||||
line
|
||||
};
|
||||
|
||||
enum class CullMode : int
|
||||
{
|
||||
none,
|
||||
|
@ -12,6 +43,27 @@ namespace verus
|
|||
back
|
||||
};
|
||||
|
||||
struct PipelineRasterizationState
|
||||
{
|
||||
PolygonMode _polygonMode = PolygonMode::fill;
|
||||
CullMode _cullMode = CullMode::back;
|
||||
float _depthBiasConstantFactor = 0;
|
||||
float _depthBiasClamp = 0;
|
||||
float _depthBiasSlopeFactor = 0;
|
||||
bool _depthBiasEnable = false;
|
||||
};
|
||||
|
||||
enum class PrimitiveTopology : int
|
||||
{
|
||||
pointList,
|
||||
lineList,
|
||||
lineStrip,
|
||||
triangleList,
|
||||
triangleStrip,
|
||||
patchList3,
|
||||
patchList4
|
||||
};
|
||||
|
||||
enum class ImageLayout : int
|
||||
{
|
||||
undefined, // Does not support device access, the contents of the memory are not guaranteed to be preserved.
|
||||
|
@ -26,44 +78,25 @@ namespace verus
|
|||
presentSrc // Must only be used for presenting a presentable image for display.
|
||||
};
|
||||
|
||||
enum class PolygonMode : int
|
||||
enum class Sampler : int
|
||||
{
|
||||
fill,
|
||||
line
|
||||
};
|
||||
|
||||
enum class PrimitiveTopology : int
|
||||
{
|
||||
pointList,
|
||||
lineList,
|
||||
lineStrip,
|
||||
triangleList,
|
||||
triangleStrip,
|
||||
patchList3,
|
||||
patchList4
|
||||
};
|
||||
|
||||
struct PipelineRasterizationState
|
||||
{
|
||||
PolygonMode _polygonMode = PolygonMode::fill;
|
||||
CullMode _cullMode = CullMode::back;
|
||||
float _depthBiasConstantFactor = 0;
|
||||
float _depthBiasClamp = 0;
|
||||
float _depthBiasSlopeFactor = 0;
|
||||
bool _depthClampEnable = false;
|
||||
bool _depthBiasEnable = false;
|
||||
};
|
||||
|
||||
enum class CompareOp : int
|
||||
{
|
||||
never,
|
||||
less,
|
||||
equal,
|
||||
lessOrEqual,
|
||||
greater,
|
||||
notEqual,
|
||||
greaterOrEqual,
|
||||
always,
|
||||
custom, // Not immutable, not static sampler.
|
||||
input,
|
||||
storage, // Also known as UAV.
|
||||
lodBias,
|
||||
shadow,
|
||||
aniso, // Most common sampler for 3D.
|
||||
anisoClamp,
|
||||
anisoSharp, // For UI.
|
||||
linearMipL,
|
||||
nearestMipL,
|
||||
linearMipN,
|
||||
nearestMipN,
|
||||
linearClampMipL,
|
||||
nearestClampMipL,
|
||||
linearClampMipN,
|
||||
nearestClampMipN,
|
||||
count
|
||||
};
|
||||
|
||||
enum class ShaderStageFlags : UINT32
|
||||
|
@ -131,40 +164,6 @@ namespace verus
|
|||
};
|
||||
VERUS_TYPEDEFS(VertexInputAttrDesc);
|
||||
|
||||
enum class Sampler : int
|
||||
{
|
||||
custom, // Not immutable, not static sampler.
|
||||
input,
|
||||
storage, // Also known as UAV.
|
||||
lodBias,
|
||||
shadow,
|
||||
aniso, // Most common sampler for 3D.
|
||||
anisoClamp,
|
||||
anisoSharp, // For UI.
|
||||
linearMipL,
|
||||
nearestMipL,
|
||||
linearMipN,
|
||||
nearestMipN,
|
||||
linearClampMipL,
|
||||
nearestClampMipL,
|
||||
linearClampMipN,
|
||||
nearestClampMipN,
|
||||
count
|
||||
};
|
||||
|
||||
enum class CubeMapFace : int
|
||||
{
|
||||
posX,
|
||||
negX,
|
||||
posY,
|
||||
negY,
|
||||
posZ,
|
||||
negZ,
|
||||
count,
|
||||
all,
|
||||
none = -1
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class BaseHandle
|
||||
{
|
||||
|
|
|
@ -316,7 +316,7 @@ void Particles::Update()
|
|||
}
|
||||
|
||||
Matrix3 matAim3;
|
||||
matAim3.AimZ(normal, &up);
|
||||
matAim3.TrackToZ(normal, &up);
|
||||
Transform3 matAim(matAim3, Vector3(0));
|
||||
|
||||
VERUS_FOR(i, _capacity)
|
||||
|
@ -750,7 +750,7 @@ Transform3 Particles::GetBillboardMatrix(int index, float size, float spin, RcVe
|
|||
if (_decal)
|
||||
{
|
||||
Matrix3 matAim3;
|
||||
matAim3.AimZ(-normal2, &up2);
|
||||
matAim3.TrackToZ(-normal2, &up2);
|
||||
matAim = Transform3(matAim3, Vector3(0));
|
||||
}
|
||||
else
|
||||
|
@ -759,7 +759,7 @@ Transform3 Particles::GetBillboardMatrix(int index, float size, float spin, RcVe
|
|||
const Vector3 right = VMath::cross(up2, normal2);
|
||||
normal2 = VMath::normalizeApprox(VMath::cross(right, up2));
|
||||
Matrix3 matAim3;
|
||||
matAim3.AimZ(normal2, &up2);
|
||||
matAim3.TrackToZ(normal2, &up2);
|
||||
matAim = Transform3(matAim3, Vector3(0));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,11 +109,15 @@ void Ssr::OnSwapChainResized()
|
|||
|
||||
void Ssr::Generate()
|
||||
{
|
||||
VERUS_QREF_CONST_SETTINGS;
|
||||
VERUS_QREF_RENDERER;
|
||||
VERUS_QREF_SM;
|
||||
VERUS_QREF_SSAO;
|
||||
VERUS_QREF_ATMO;
|
||||
|
||||
if (!settings._postProcessSSR)
|
||||
return;
|
||||
|
||||
if (!_csh.IsSet())
|
||||
{
|
||||
if (atmo.GetCubeMapBaker().GetColorTexture())
|
||||
|
|
|
@ -281,7 +281,7 @@ float BaseCharacter::ComputeThirdPersonCamera(Scene::RCamera camera, Anim::RcOrb
|
|||
|
||||
// Consider orientation:
|
||||
Matrix3 matFromRaySpace;
|
||||
matFromRaySpace.AimZ(toEye);
|
||||
matFromRaySpace.TrackToZ(toEye);
|
||||
Matrix3 matToRaySpace = VMath::transpose(matFromRaySpace);
|
||||
toEye = (matFromRaySpace * orbit.GetMatrix() * matToRaySpace) * toEye;
|
||||
|
||||
|
|
|
@ -13,29 +13,29 @@ Timer::~Timer()
|
|||
|
||||
void Timer::Init()
|
||||
{
|
||||
const TTimePoint timeNow = std::chrono::high_resolution_clock::now();
|
||||
_tpInit = std::chrono::high_resolution_clock::now();
|
||||
for (auto& data : _data)
|
||||
{
|
||||
data._t = data._dt = 0;
|
||||
data._timePrev = timeNow;
|
||||
data._tpPrev = _tpInit;
|
||||
}
|
||||
}
|
||||
|
||||
void Timer::Update()
|
||||
{
|
||||
const TTimePoint timeNow = std::chrono::high_resolution_clock::now();
|
||||
const TTimePoint tpNow = std::chrono::high_resolution_clock::now();
|
||||
VERUS_FOR(i, +Type::count)
|
||||
{
|
||||
_data[i]._dtPrev = _data[i]._dt;
|
||||
|
||||
_data[i]._dt = std::chrono::duration_cast<std::chrono::duration<float>>(
|
||||
timeNow - _data[i]._timePrev).count() * GetGameSpeed(static_cast<Type>(i));
|
||||
tpNow - _data[i]._tpPrev).count() * GetGameSpeed(static_cast<Type>(i));
|
||||
if (_data[i]._dt > 0.25f) // Prevent long gaps.
|
||||
_data[i]._dt = 0.25f;
|
||||
|
||||
_data[i]._t += _data[i]._dt;
|
||||
_data[i]._timePrev2 = _data[i]._timePrev;
|
||||
_data[i]._timePrev = timeNow;
|
||||
_data[i]._tpPrev2 = _data[i]._tpPrev;
|
||||
_data[i]._tpPrev = tpNow;
|
||||
|
||||
_data[i]._dtInv = _data[i]._dt > 0.0001f ? 1 / _data[i]._dt : 10000;
|
||||
_data[i]._dtSq = _data[i]._dt * _data[i]._dt;
|
||||
|
@ -54,11 +54,17 @@ void Timer::Update()
|
|||
|
||||
bool Timer::IsEventEvery(int ms) const
|
||||
{
|
||||
auto a = std::chrono::duration_cast<std::chrono::milliseconds>(_data[+Type::game]._timePrev.time_since_epoch());
|
||||
auto b = std::chrono::duration_cast<std::chrono::milliseconds>(_data[+Type::game]._timePrev2.time_since_epoch());
|
||||
auto a = std::chrono::duration_cast<std::chrono::milliseconds>(_data[+Type::game]._tpPrev.time_since_epoch());
|
||||
auto b = std::chrono::duration_cast<std::chrono::milliseconds>(_data[+Type::game]._tpPrev2.time_since_epoch());
|
||||
return a.count() / ms != b.count() / ms;
|
||||
}
|
||||
|
||||
float Timer::GetTime() const
|
||||
{
|
||||
const TTimePoint tpNow = std::chrono::high_resolution_clock::now();
|
||||
return std::chrono::duration_cast<std::chrono::duration<float>>(tpNow - _tpInit).count();
|
||||
}
|
||||
|
||||
int Timer::InsertCountdown(float duration, int existingID)
|
||||
{
|
||||
const int count = Utils::Cast32(_vCountdowns.size());
|
||||
|
|
|
@ -25,8 +25,8 @@ namespace verus
|
|||
|
||||
struct Data
|
||||
{
|
||||
TTimePoint _timePrev;
|
||||
TTimePoint _timePrev2;
|
||||
TTimePoint _tpPrev;
|
||||
TTimePoint _tpPrev2;
|
||||
double _t = 0;
|
||||
float _dt = 0;
|
||||
float _dtInv = 0;
|
||||
|
@ -38,6 +38,7 @@ namespace verus
|
|||
bool _pause = false;
|
||||
};
|
||||
|
||||
TTimePoint _tpInit;
|
||||
Vector<Countdown> _vCountdowns;
|
||||
Data _data[static_cast<int>(Type::count)];
|
||||
|
||||
|
@ -50,7 +51,8 @@ namespace verus
|
|||
|
||||
bool IsEventEvery(int ms) const;
|
||||
|
||||
float GetTime(Type type = Type::game) const { return static_cast<float>(_data[+type]._t); }
|
||||
float GetTime() const;
|
||||
float GetAccumulatedTime(Type type = Type::game) const { return static_cast<float>(_data[+type]._t); }
|
||||
float GetDeltaTime(Type type = Type::game) const { return _data[+type]._dt; }
|
||||
float GetGameSpeed(Type type = Type::game) const { return _data[+type]._pause ? 0 : _data[+type]._gameSpeed; }
|
||||
void SetGameSpeed(float speed, Type type = Type::game) { _data[+type]._gameSpeed = speed; }
|
||||
|
@ -88,5 +90,5 @@ namespace verus
|
|||
VERUS_TYPEDEFS(PerfTimer);
|
||||
}
|
||||
|
||||
#define VERUS_PERF_BEGIN Utils::PerfTimer perfTimer; perfTimer.Begin();
|
||||
#define VERUS_PERF_END perfTimer.End(__FUNCTION__);
|
||||
#define VERUS_PERF_BEGIN Utils::PerfTimer perfTimer; perfTimer.Begin();
|
||||
#define VERUS_PERF_END perfTimer.End(__FUNCTION__);
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
||||
#pragma once
|
||||
|
||||
// Remember kids, unsigned integers are bad, mkay?
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
typedef int BOOL;
|
||||
|
|
|
@ -490,8 +490,8 @@ void Math::Test()
|
|||
{
|
||||
const Vector3 a(0, 0, 1), b(0, 0, -1), c(0, 1, 0);
|
||||
Matrix3 ab, ac;
|
||||
ab.RotateTo(a, b);
|
||||
ac.RotateTo(a, c);
|
||||
ab.TrackTo(a, b);
|
||||
ac.TrackTo(a, c);
|
||||
const Vector3 k = ab * a;
|
||||
const Vector3 l = ac * a;
|
||||
VERUS_RT_ASSERT(
|
||||
|
|
|
@ -38,56 +38,57 @@ bool Matrix3::IsOrthogonal(float e) const
|
|||
glm::epsilonEqual<float>(dotZX, 0, e);
|
||||
}
|
||||
|
||||
Matrix3 Matrix3::MakeAimZ(RcVector3 zAxis, PcVector3 pUp)
|
||||
Matrix3 Matrix3::MakeTrackToZ(RcVector3 zAxis, PcVector3 pUp)
|
||||
{
|
||||
if (zAxis.IsZero())
|
||||
return Matrix3::identity();
|
||||
const Vector3 zNorm = VMath::normalizeApprox(zAxis);
|
||||
if (zNorm.getY() > 0.999f)
|
||||
return Matrix3::rotationX(-VERUS_PI * 0.5f);
|
||||
if (zNorm.getY() < -0.999f)
|
||||
return Matrix3::rotationX(VERUS_PI * 0.5f);
|
||||
Vector3 up = pUp ? *pUp : Vector3(0, 1, 0);
|
||||
const float d = VMath::dot(zNorm, up);
|
||||
if (d + VERUS_FLOAT_THRESHOLD >= 1) // Same?
|
||||
{
|
||||
up = -zAxis.Perpendicular();
|
||||
}
|
||||
else if (d - VERUS_FLOAT_THRESHOLD < -1) // Opposite?
|
||||
{
|
||||
up = zAxis.Perpendicular();
|
||||
}
|
||||
return VMath::transpose(
|
||||
Matrix4::lookAt(Point3(0), Point3(-zAxis), pUp ? *pUp : Vector3(0, 1, 0)).getUpper3x3());
|
||||
Matrix4::lookAt(Point3(0), Point3(-zAxis), up).getUpper3x3());
|
||||
}
|
||||
|
||||
Matrix3 Matrix3::AimZ(RcVector3 zAxis, PcVector3 pUp)
|
||||
Matrix3 Matrix3::TrackToZ(RcVector3 zAxis, PcVector3 pUp)
|
||||
{
|
||||
*this = MakeAimZ(zAxis, pUp);
|
||||
*this = MakeTrackToZ(zAxis, pUp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Matrix3 Matrix3::MakeRotateTo(RcVector3 v0, RcVector3 v1)
|
||||
Matrix3 Matrix3::MakeTrackTo(RcVector3 vFrom, RcVector3 vTo)
|
||||
{
|
||||
const float e = 1e-6f;
|
||||
Quat q;
|
||||
const float d = VMath::dot(v0, v1);
|
||||
if (d >= 1 - e)
|
||||
const float d = VMath::dot(vFrom, vTo);
|
||||
if (d + VERUS_FLOAT_THRESHOLD >= 1) // Same?
|
||||
{
|
||||
return Matrix3::identity();
|
||||
}
|
||||
if (d < e - 1)
|
||||
else if (d - VERUS_FLOAT_THRESHOLD < -1) // Opposite?
|
||||
{
|
||||
Vector3 axis = VMath::cross(Vector3(1, 0, 0), v0);
|
||||
if (VMath::lengthSqr(axis) < e * e)
|
||||
axis = VMath::cross(Vector3(0, 1, 0), v0);
|
||||
axis = VMath::normalize(axis);
|
||||
q = Quat::rotation(VERUS_PI, axis);
|
||||
q = Quat::rotation(VERUS_PI, vFrom.Perpendicular());
|
||||
}
|
||||
else
|
||||
{
|
||||
const float s = sqrt((1 + d) * 2);
|
||||
const float invs = 1 / s;
|
||||
const Vector3 c = VMath::cross(v0, v1);
|
||||
const Vector3 c = VMath::cross(vFrom, vTo);
|
||||
q = Quat(c * invs, s * 0.5f);
|
||||
q = VMath::normalize(q);
|
||||
}
|
||||
return Matrix3(q);
|
||||
}
|
||||
|
||||
Matrix3 Matrix3::RotateTo(RcVector3 v0, RcVector3 v1)
|
||||
Matrix3 Matrix3::TrackTo(RcVector3 vFrom, RcVector3 vTo)
|
||||
{
|
||||
*this = MakeRotateTo(v0, v1);
|
||||
*this = MakeTrackTo(vFrom, vTo);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,10 +19,12 @@ namespace verus
|
|||
|
||||
bool IsOrthogonal(float e = VERUS_FLOAT_THRESHOLD) const;
|
||||
|
||||
static Matrix3 MakeAimZ(RcVector3 zAxis, PcVector3 pUp = nullptr);
|
||||
Matrix3 AimZ(RcVector3 zAxis, PcVector3 pUp = nullptr);
|
||||
static Matrix3 MakeRotateTo(RcVector3 v0, RcVector3 v1);
|
||||
Matrix3 RotateTo(RcVector3 v0, RcVector3 v1);
|
||||
// More stable than Quat::rotation(), tries to maintain the up vector:
|
||||
static Matrix3 MakeTrackToZ(RcVector3 zAxis, PcVector3 pUp = nullptr);
|
||||
Matrix3 TrackToZ(RcVector3 zAxis, PcVector3 pUp = nullptr);
|
||||
// More stable than Quat::rotation(), perpendicular vector is somewhat random:
|
||||
static Matrix3 MakeTrackTo(RcVector3 vFrom, RcVector3 vTo);
|
||||
Matrix3 TrackTo(RcVector3 vFrom, RcVector3 vTo);
|
||||
|
||||
static Matrix3 Lerp(const Matrix3& a, const Matrix3& b, float t);
|
||||
};
|
||||
|
|
|
@ -140,6 +140,14 @@ Vector3 Vector3::Reflect(RcVector3 normal, float bounce) const
|
|||
return (*this) - normal * ((1 + bounce) * VMath::dot(*this, normal));
|
||||
}
|
||||
|
||||
Vector3 Vector3::Perpendicular() const
|
||||
{
|
||||
Vector3 axis = VMath::cross(Vector3(1, 0, 0), (*this));
|
||||
if (VMath::lengthSqr(axis) < VERUS_FLOAT_THRESHOLD * VERUS_FLOAT_THRESHOLD)
|
||||
axis = VMath::cross(Vector3(0, 1, 0), (*this));
|
||||
return axis;
|
||||
}
|
||||
|
||||
// Vector4:
|
||||
|
||||
Vector4 Vector4::MakeFromPointer(const float* p)
|
||||
|
|
|
@ -58,6 +58,8 @@ namespace verus
|
|||
|
||||
void LimitDot(const Vector3& v, float d);
|
||||
Vector3 Reflect(const Vector3& normal, float bounce = 1) const;
|
||||
|
||||
Vector3 Perpendicular() const;
|
||||
};
|
||||
VERUS_TYPEDEFS(Vector3);
|
||||
|
||||
|
|
|
@ -285,7 +285,7 @@ void BaseMesh::LoadX3D3(RcBlob blob)
|
|||
sp >> index;
|
||||
pVB[i]._pos[3] = index;
|
||||
}
|
||||
_rigidSkeleton = true;
|
||||
_robotic = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -479,6 +479,13 @@ void BaseMesh::RecalculateTangentSpace()
|
|||
}
|
||||
}
|
||||
|
||||
int BaseMesh::GetPipelineIndex(bool instanced) const
|
||||
{
|
||||
if (_skeleton.IsInitialized())
|
||||
return _robotic ? 2 : 3;
|
||||
return instanced ? 1 : 0;
|
||||
}
|
||||
|
||||
btBvhTriangleMeshShape* BaseMesh::InitShape(RcTransform3 tr, CSZ url)
|
||||
{
|
||||
if (!_vertCount)
|
||||
|
|
|
@ -56,7 +56,7 @@ namespace verus
|
|||
float _tc0Deq[4];
|
||||
float _tc1Deq[4];
|
||||
bool _loadOnly = false;
|
||||
bool _rigidSkeleton = false;
|
||||
bool _robotic = false;
|
||||
bool _initShape = false;
|
||||
|
||||
public:
|
||||
|
@ -112,6 +112,7 @@ namespace verus
|
|||
// GPU:
|
||||
virtual void CreateDeviceBuffers() {}
|
||||
virtual void UpdateVertexBuffer(const void* p, int binding) {}
|
||||
int GetPipelineIndex(bool instanced = false) const;
|
||||
|
||||
// Physics:
|
||||
btBvhTriangleMeshShape* GetShape() const { return _pShape; }
|
||||
|
|
|
@ -6,6 +6,7 @@ using namespace verus::Scene;
|
|||
|
||||
LightMapBaker::LightMapBaker()
|
||||
{
|
||||
VERUS_ZERO_MEM(_queuedCount);
|
||||
}
|
||||
|
||||
LightMapBaker::~LightMapBaker()
|
||||
|
@ -17,11 +18,15 @@ void LightMapBaker::Init(RcDesc desc)
|
|||
{
|
||||
VERUS_INIT();
|
||||
VERUS_QREF_RENDERER;
|
||||
VERUS_QREF_TIMER;
|
||||
|
||||
_desc = desc;
|
||||
_pathname = desc._pathname;
|
||||
_desc._pathname = nullptr;
|
||||
|
||||
_stats = Stats();
|
||||
_stats._startTime = timer.GetTime();
|
||||
|
||||
_currentI = 0;
|
||||
_currentJ = 0;
|
||||
|
||||
|
@ -77,8 +82,8 @@ void LightMapBaker::Init(RcDesc desc)
|
|||
|
||||
_rph = renderer->CreateRenderPass(
|
||||
{
|
||||
CGI::RP::Attachment("Color", CGI::Format::unormR8).LoadOpClear().Layout(CGI::ImageLayout::fsReadOnly),
|
||||
CGI::RP::Attachment("Depth", CGI::Format::unormD16).LoadOpClear().Layout(CGI::ImageLayout::depthStencilAttachment),
|
||||
CGI::RP::Attachment("Color", CGI::Format::floatR32).LoadOpClear().Layout(CGI::ImageLayout::fsReadOnly),
|
||||
CGI::RP::Attachment("Depth", CGI::Format::unormD24uintS8).LoadOpClear().Layout(CGI::ImageLayout::depthStencilAttachment),
|
||||
},
|
||||
{
|
||||
CGI::RP::Subpass("Sp0").Color(
|
||||
|
@ -88,37 +93,95 @@ void LightMapBaker::Init(RcDesc desc)
|
|||
},
|
||||
{});
|
||||
|
||||
{
|
||||
CGI::PipelineDesc pipeDesc(renderer.GetGeoQuad(), renderer.GetShaderQuad(), "#HemicubeMask", _rph);
|
||||
pipeDesc._colorAttachBlendEqs[0] = VERUS_COLOR_BLEND_MUL;
|
||||
pipeDesc._topology = CGI::PrimitiveTopology::triangleStrip;
|
||||
pipeDesc.DisableDepthTest();
|
||||
_pipe[PIPE_HEMICUBE_MASK].Init(pipeDesc);
|
||||
}
|
||||
{
|
||||
CGI::PipelineDesc pipeDesc(renderer.GetGeoQuad(), renderer.GetShaderQuad(), "#", renderer.GetRenderPassHandle_AutoWithDepth());
|
||||
pipeDesc._topology = CGI::PrimitiveTopology::triangleStrip;
|
||||
pipeDesc.DisableDepthTest();
|
||||
_pipe[PIPE_QUAD].Init(pipeDesc);
|
||||
}
|
||||
|
||||
CGI::TextureDesc texDesc;
|
||||
texDesc._name = "LightMapBaker.ColorTex";
|
||||
texDesc._clearValue = Vector4::Replicate(1);
|
||||
texDesc._format = CGI::Format::unormR8;
|
||||
texDesc._width = _desc._texLumelSide;
|
||||
texDesc._height = _desc._texLumelSide;
|
||||
texDesc._mipLevels = 0;
|
||||
texDesc._flags = CGI::TextureDesc::Flags::colorAttachment | CGI::TextureDesc::Flags::generateMips;
|
||||
texDesc._readbackMip = -1;
|
||||
_tex[TEX_COLOR].Init(texDesc);
|
||||
texDesc.Reset();
|
||||
texDesc._name = "LightMapBaker.DepthTex";
|
||||
texDesc._clearValue = Vector4(1);
|
||||
texDesc._format = CGI::Format::unormD16;
|
||||
texDesc._format = CGI::Format::unormD24uintS8;
|
||||
texDesc._width = _desc._texLumelSide;
|
||||
texDesc._height = _desc._texLumelSide;
|
||||
_tex[TEX_DEPTH].Init(texDesc);
|
||||
texDesc.Reset();
|
||||
texDesc._name = "LightMapBaker.Dummy";
|
||||
texDesc._format = CGI::Format::unormR8G8B8A8;
|
||||
texDesc._width = 16;
|
||||
texDesc._height = 16;
|
||||
_tex[TEX_DUMMY].Init(texDesc);
|
||||
|
||||
_fbh = renderer->CreateFramebuffer(_rph,
|
||||
VERUS_FOR(ringBufferIndex, CGI::BaseRenderer::s_ringBufferSize)
|
||||
{
|
||||
VERUS_FOR(batchIndex, s_batchSize)
|
||||
{
|
||||
_tex[TEX_COLOR],
|
||||
_tex[TEX_DEPTH]
|
||||
},
|
||||
_desc._texLumelSide,
|
||||
_desc._texLumelSide);
|
||||
CGI::TextureDesc texDesc;
|
||||
texDesc._name = "LightMapBaker.ColorTex";
|
||||
texDesc._clearValue = Vector4::Replicate(1);
|
||||
texDesc._format = CGI::Format::floatR32;
|
||||
texDesc._width = _desc._texLumelSide;
|
||||
texDesc._height = _desc._texLumelSide;
|
||||
texDesc._mipLevels = 0;
|
||||
texDesc._flags = CGI::TextureDesc::Flags::colorAttachment | CGI::TextureDesc::Flags::generateMips;
|
||||
texDesc._readbackMip = -1;
|
||||
_texColor[ringBufferIndex][batchIndex].Init(texDesc);
|
||||
}
|
||||
_cshQuad[ringBufferIndex] = renderer.GetShaderQuad()->BindDescriptorSetTextures(1, { _texColor[ringBufferIndex][0] });
|
||||
}
|
||||
_cshHemicubeMask = renderer.GetShaderQuad()->BindDescriptorSetTextures(1, { _tex[TEX_DUMMY] });
|
||||
|
||||
VERUS_FOR(ringBufferIndex, CGI::BaseRenderer::s_ringBufferSize)
|
||||
{
|
||||
VERUS_FOR(batchIndex, s_batchSize)
|
||||
{
|
||||
CGI::TexturePtr tex = _texColor[ringBufferIndex][batchIndex];
|
||||
_fbh[ringBufferIndex][batchIndex] = renderer->CreateFramebuffer(_rph,
|
||||
{
|
||||
tex,
|
||||
_tex[TEX_DEPTH]
|
||||
},
|
||||
_desc._texLumelSide,
|
||||
_desc._texLumelSide);
|
||||
|
||||
// Define texture:
|
||||
renderer.GetCommandBuffer()->BeginRenderPass(_rph, _fbh[ringBufferIndex][batchIndex],
|
||||
{
|
||||
tex->GetClearValue(),
|
||||
_tex[TEX_DEPTH]->GetClearValue()
|
||||
});
|
||||
renderer.GetCommandBuffer()->EndRenderPass();
|
||||
tex->GenerateMips();
|
||||
}
|
||||
_vQueued[ringBufferIndex].resize(s_batchSize);
|
||||
}
|
||||
|
||||
_drawEmptyState = CGI::BaseRenderer::s_ringBufferSize + 1;
|
||||
}
|
||||
|
||||
void LightMapBaker::Done()
|
||||
{
|
||||
VERUS_QREF_RENDERER;
|
||||
renderer->DeleteFramebuffer(_fbh);
|
||||
if (renderer.GetShaderQuad())
|
||||
{
|
||||
VERUS_FOR(ringBufferIndex, CGI::BaseRenderer::s_ringBufferSize)
|
||||
renderer.GetShaderQuad()->FreeDescriptorSet(_cshQuad[ringBufferIndex]);
|
||||
renderer.GetShaderQuad()->FreeDescriptorSet(_cshHemicubeMask);
|
||||
}
|
||||
VERUS_FOR(ringBufferIndex, CGI::BaseRenderer::s_ringBufferSize)
|
||||
{
|
||||
VERUS_FOR(batchIndex, s_batchSize)
|
||||
renderer->DeleteFramebuffer(_fbh[ringBufferIndex][batchIndex]);
|
||||
}
|
||||
renderer->DeleteRenderPass(_rph);
|
||||
VERUS_DONE(LightMapBaker);
|
||||
}
|
||||
|
@ -127,42 +190,251 @@ void LightMapBaker::Update()
|
|||
{
|
||||
if (!IsInitialized() || !IsBaking())
|
||||
return;
|
||||
VERUS_FOR(rep, _repsPerUpdate)
|
||||
|
||||
if (_drawEmptyState)
|
||||
{
|
||||
if (_currentI == _desc._texHeight)
|
||||
if (CGI::BaseRenderer::s_ringBufferSize + 1 == _drawEmptyState)
|
||||
DrawEmpty();
|
||||
_drawEmptyState--;
|
||||
if (!_drawEmptyState)
|
||||
{
|
||||
Save();
|
||||
_desc._mode = Mode::idle;
|
||||
break;
|
||||
float value = 0;
|
||||
_texColor[0][0]->ReadbackSubresource(&value, false);
|
||||
_normalizationFactor = 1 / value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_currentUV = glm::vec2(
|
||||
(_currentJ + 0.5f) / _desc._texWidth,
|
||||
(_currentI + 0.5f) / _desc._texHeight);
|
||||
VERUS_QREF_RENDERER;
|
||||
|
||||
_quadtree.TraverseVisible(_currentUV);
|
||||
const int ringBufferIndex = renderer->GetRingBufferIndex();
|
||||
|
||||
auto NextLumel = [this]()
|
||||
{
|
||||
_currentJ++;
|
||||
if (_currentJ == _desc._texWidth)
|
||||
{
|
||||
_currentJ = 0;
|
||||
_currentI++;
|
||||
}
|
||||
};
|
||||
|
||||
int& queuedCount = _queuedCount[ringBufferIndex];
|
||||
if (queuedCount > 0) // Was there anything queued?
|
||||
{
|
||||
VERUS_FOR(i, queuedCount)
|
||||
{
|
||||
float value = 0;
|
||||
_texColor[ringBufferIndex][i]->ReadbackSubresource(&value, false);
|
||||
const BYTE value8 = Convert::UnormToUint8(Math::Clamp<float>(value * _normalizationFactor, 0, 1));
|
||||
|
||||
BYTE* pDst = reinterpret_cast<BYTE*>(_vQueued[ringBufferIndex][i]._pDst);
|
||||
VERUS_FOR(j, 3)
|
||||
pDst[j] = Math::Max(pDst[j], value8);
|
||||
pDst[3] = 0xFF;
|
||||
}
|
||||
}
|
||||
// Clear queued:
|
||||
memset(_vQueued[ringBufferIndex].data(), 0, sizeof(Queued) * s_batchSize);
|
||||
queuedCount = 0;
|
||||
|
||||
if (_currentI >= _desc._texHeight)
|
||||
{
|
||||
bool finish = true;
|
||||
VERUS_FOR(ringBufferIndex, CGI::BaseRenderer::s_ringBufferSize)
|
||||
{
|
||||
if (_queuedCount[ringBufferIndex])
|
||||
{
|
||||
finish = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (finish)
|
||||
{
|
||||
ComputeEdgePadding();
|
||||
Save();
|
||||
_desc._mode = Mode::idle;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
VERUS_FOR(rep, _repsPerUpdate)
|
||||
{
|
||||
// Fill queue:
|
||||
int& queuedCount = _queuedCount[ringBufferIndex];
|
||||
VERUS_RT_ASSERT(!queuedCount);
|
||||
while (queuedCount + s_maxLayers <= s_batchSize) // Enough space for this lumel?
|
||||
{
|
||||
_currentUV = glm::vec2(
|
||||
(_currentJ + 0.5f) / _desc._texWidth,
|
||||
(_currentI + 0.5f) / _desc._texHeight);
|
||||
|
||||
_currentLayer = 0;
|
||||
_quadtree.TraverseVisible(_currentUV);
|
||||
_stats._maxLayer = Math::Max<int>(_stats._maxLayer, _currentLayer);
|
||||
|
||||
NextLumel();
|
||||
if (_currentI >= _desc._texHeight)
|
||||
break; // No more lumels.
|
||||
}
|
||||
|
||||
// Draw queue:
|
||||
VERUS_FOR(i, queuedCount)
|
||||
{
|
||||
RQueued queued = _vQueued[ringBufferIndex][i];
|
||||
DrawLumel(queued._pos, queued._nrm, i);
|
||||
}
|
||||
}
|
||||
|
||||
const int progressPrev = static_cast<int>(_stats._progress * 100);
|
||||
_stats._progress = Math::Clamp<float>((_currentI * _desc._texWidth + _currentJ) * _invMapSize, 0, 1);
|
||||
const int progressNext = static_cast<int>(_stats._progress * 100);
|
||||
if (progressPrev != progressNext)
|
||||
{
|
||||
VERUS_QREF_TIMER;
|
||||
const float elapsedTime = timer.GetTime() - _stats._startTime;
|
||||
char buffer[80];
|
||||
sprintf_s(buffer, "Elapsed time: %.1fs, max layer: %d, progress: %.1f%%", elapsedTime, _stats._maxLayer, _stats._progress * 100);
|
||||
_stats._info = buffer;
|
||||
}
|
||||
_progress = Math::Clamp<float>((_currentI * _desc._texWidth + _currentJ) * _invMapSize, 0, 1);
|
||||
}
|
||||
|
||||
void LightMapBaker::DrawLumel(RcPoint3 eyePos, RcVector3 frontDir)
|
||||
void LightMapBaker::Draw()
|
||||
{
|
||||
if (!IsInitialized() || !IsBaking())
|
||||
return;
|
||||
|
||||
VERUS_QREF_RENDERER;
|
||||
|
||||
renderer.GetCommandBuffer()->BeginRenderPass(_rph, _fbh,
|
||||
const int ringBufferIndex = renderer->GetRingBufferIndex();
|
||||
auto cb = renderer.GetCommandBuffer();
|
||||
auto shader = renderer.GetShaderQuad();
|
||||
|
||||
cb->BindPipeline(_pipe[PIPE_QUAD]);
|
||||
shader->BeginBindDescriptors();
|
||||
cb->BindDescriptors(shader, 0);
|
||||
cb->BindDescriptors(shader, 1, _cshQuad[ringBufferIndex]);
|
||||
shader->EndBindDescriptors();
|
||||
renderer.DrawQuad(cb.Get());
|
||||
}
|
||||
|
||||
void LightMapBaker::DrawEmpty()
|
||||
{
|
||||
// Let's compute normalization factor by drawing an empty scene.
|
||||
VERUS_QREF_RENDERER;
|
||||
|
||||
auto cb = renderer.GetCommandBuffer();
|
||||
CGI::TexturePtr tex = _texColor[0][0];
|
||||
|
||||
cb->BeginRenderPass(_rph, _fbh[0][0],
|
||||
{
|
||||
_tex[TEX_COLOR]->GetClearValue(),
|
||||
tex->GetClearValue(),
|
||||
_tex[TEX_DEPTH]->GetClearValue()
|
||||
});
|
||||
|
||||
renderer.GetCommandBuffer()->EndRenderPass();
|
||||
DrawHemicubeMask();
|
||||
|
||||
cb->EndRenderPass();
|
||||
|
||||
tex->GenerateMips();
|
||||
tex->ReadbackSubresource(nullptr);
|
||||
}
|
||||
|
||||
void LightMapBaker::DrawHemicubeMask()
|
||||
{
|
||||
VERUS_QREF_RENDERER;
|
||||
|
||||
auto cb = renderer.GetCommandBuffer();
|
||||
auto shader = renderer.GetShaderQuad();
|
||||
|
||||
const float side = static_cast<float>(_desc._texLumelSide);
|
||||
cb->BindPipeline(_pipe[PIPE_HEMICUBE_MASK]);
|
||||
cb->SetViewport({ Vector4(0, 0, side, side) });
|
||||
shader->BeginBindDescriptors();
|
||||
cb->BindDescriptors(shader, 0);
|
||||
cb->BindDescriptors(shader, 1, _cshHemicubeMask);
|
||||
shader->EndBindDescriptors();
|
||||
renderer.DrawQuad(cb.Get());
|
||||
}
|
||||
|
||||
void LightMapBaker::DrawLumel(RcPoint3 pos, RcVector3 nrm, int batchIndex)
|
||||
{
|
||||
VERUS_QREF_RENDERER;
|
||||
VERUS_QREF_SM;
|
||||
|
||||
const int ringBufferIndex = renderer->GetRingBufferIndex();
|
||||
auto cb = renderer.GetCommandBuffer();
|
||||
auto shader = renderer.GetShaderQuad();
|
||||
CGI::TexturePtr tex = _texColor[ringBufferIndex][batchIndex];
|
||||
|
||||
cb->BeginRenderPass(_rph, _fbh[ringBufferIndex][batchIndex],
|
||||
{
|
||||
tex->GetClearValue(),
|
||||
_tex[TEX_DEPTH]->GetClearValue()
|
||||
});
|
||||
if (_pDelegate)
|
||||
{
|
||||
const glm::vec2 randVec = glm::circularRand(1.f);
|
||||
const Matrix3 m3 = Matrix3::MakeTrackTo(Vector3(0, 0, 1), nrm);
|
||||
const Vector3 perpVecA = m3 * Vector3(randVec.x, randVec.y, 0); // Up.
|
||||
const Vector3 perpVecB = VMath::cross(perpVecA, nrm); // Side.
|
||||
|
||||
DrawLumelDesc drawLumelDesc;
|
||||
drawLumelDesc._eyePos = pos;
|
||||
drawLumelDesc._frontDir = nrm;
|
||||
_pDelegate->LightMapBaker_Draw(CGI::CubeMapFace::none, drawLumelDesc);
|
||||
VERUS_FOR(i, 5)
|
||||
{
|
||||
const CGI::CubeMapFace cubeMapFace = static_cast<CGI::CubeMapFace>(i);
|
||||
|
||||
Camera cam;
|
||||
cam.MoveEyeTo(drawLumelDesc._eyePos);
|
||||
switch (cubeMapFace)
|
||||
{
|
||||
case CGI::CubeMapFace::posX:
|
||||
cam.MoveAtTo(drawLumelDesc._eyePos + perpVecB);
|
||||
cam.SetUpDirection(perpVecA);
|
||||
break;
|
||||
case CGI::CubeMapFace::negX:
|
||||
cam.MoveAtTo(drawLumelDesc._eyePos - perpVecB);
|
||||
cam.SetUpDirection(perpVecA);
|
||||
break;
|
||||
case CGI::CubeMapFace::posY:
|
||||
cam.MoveAtTo(drawLumelDesc._eyePos + perpVecA);
|
||||
cam.SetUpDirection(-nrm);
|
||||
break;
|
||||
case CGI::CubeMapFace::negY:
|
||||
cam.MoveAtTo(drawLumelDesc._eyePos - perpVecA);
|
||||
cam.SetUpDirection(nrm);
|
||||
break;
|
||||
case CGI::CubeMapFace::posZ:
|
||||
cam.MoveAtTo(drawLumelDesc._eyePos + nrm);
|
||||
cam.SetUpDirection(perpVecA);
|
||||
break;
|
||||
}
|
||||
cam.SetYFov(VERUS_PI * 0.5f);
|
||||
cam.SetAspectRatio(1);
|
||||
cam.SetZNear(0.00001f);
|
||||
cam.SetZFar(_desc._distance);
|
||||
cam.Update();
|
||||
PCamera pPrevCamera = sm.SetCamera(&cam);
|
||||
|
||||
drawLumelDesc._frontDir = cam.GetFrontDirection();
|
||||
_pDelegate->LightMapBaker_Draw(cubeMapFace, drawLumelDesc);
|
||||
|
||||
sm.SetCamera(pPrevCamera);
|
||||
}
|
||||
_pDelegate->LightMapBaker_Draw(CGI::CubeMapFace::negZ, drawLumelDesc);
|
||||
|
||||
DrawHemicubeMask();
|
||||
}
|
||||
cb->EndRenderPass();
|
||||
|
||||
tex->GenerateMips();
|
||||
tex->ReadbackSubresource(nullptr);
|
||||
}
|
||||
|
||||
Continue LightMapBaker::Quadtree_ProcessNode(void* pToken, void* pUser)
|
||||
|
@ -171,6 +443,7 @@ Continue LightMapBaker::Quadtree_ProcessNode(void* pToken, void* pUser)
|
|||
const int index = _currentI * _desc._texWidth + _currentJ;
|
||||
if (Math::IsPointInsideTriangle(face._v[0]._tc, face._v[1]._tc, face._v[2]._tc, _currentUV))
|
||||
{
|
||||
VERUS_QREF_RENDERER;
|
||||
switch (GetMode())
|
||||
{
|
||||
case Mode::faces:
|
||||
|
@ -180,15 +453,23 @@ Continue LightMapBaker::Quadtree_ProcessNode(void* pToken, void* pUser)
|
|||
break;
|
||||
case Mode::ambientOcclusion:
|
||||
{
|
||||
VERUS_RT_ASSERT(_currentLayer < s_maxLayers);
|
||||
|
||||
const Vector3 bc = Math::Barycentric(face._v[0]._tc, face._v[1]._tc, face._v[2]._tc, _currentUV);
|
||||
const glm::vec3 pos = Math::BarycentricInterpolation(face._v[0]._pos, face._v[1]._pos, face._v[2]._pos, bc);
|
||||
const glm::vec3 nrm = Math::BarycentricInterpolation(face._v[0]._nrm, face._v[1]._nrm, face._v[2]._nrm, bc);
|
||||
|
||||
const glm::vec4 nrm2 = glm::vec4(glm::normalize(nrm) * 0.5f + 0.5f, 1.f);
|
||||
const int ringBufferIndex = renderer->GetRingBufferIndex();
|
||||
int& queuedCount = _queuedCount[ringBufferIndex];
|
||||
RQueued queued = _vQueued[ringBufferIndex][queuedCount];
|
||||
queued._pos = pos;
|
||||
queued._nrm = glm::normalize(nrm);
|
||||
queued._pDst = &_vMap[index];
|
||||
|
||||
_vMap[index] = Convert::ColorFloatToInt32(&nrm2.x);
|
||||
_currentLayer++;
|
||||
queuedCount++;
|
||||
|
||||
DrawLumel(pos, nrm);
|
||||
return (_currentLayer >= s_maxLayers) ? Continue::no : Continue::yes;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -196,7 +477,98 @@ Continue LightMapBaker::Quadtree_ProcessNode(void* pToken, void* pUser)
|
|||
return Continue::yes;
|
||||
}
|
||||
|
||||
void LightMapBaker::ComputeEdgePadding(int radius)
|
||||
{
|
||||
const int radiusSq = radius * radius;
|
||||
VERUS_P_FOR(i, _desc._texHeight)
|
||||
{
|
||||
const int offset = i * _desc._texWidth;
|
||||
VERUS_FOR(j, _desc._texWidth)
|
||||
{
|
||||
BYTE* pOriginChannels = reinterpret_cast<BYTE*>(&_vMap[offset + j]);
|
||||
if (pOriginChannels[3])
|
||||
continue;
|
||||
|
||||
int minRadiusSq = INT_MAX;
|
||||
BYTE color[4] = {};
|
||||
for (int di = -radius; di <= radius; ++di)
|
||||
{
|
||||
const int ki = i + di;
|
||||
if (ki < 0 || ki >= _desc._texHeight)
|
||||
continue;
|
||||
for (int dj = -radius; dj <= radius; ++dj)
|
||||
{
|
||||
const int kj = j + dj;
|
||||
if (kj < 0 || kj >= _desc._texWidth)
|
||||
continue;
|
||||
if (!di && !dj)
|
||||
continue;
|
||||
const int lenSq = di * di + dj * dj;
|
||||
if (lenSq > radiusSq)
|
||||
continue;
|
||||
BYTE* pKernelChannels = reinterpret_cast<BYTE*>(&_vMap[ki * _desc._texWidth + kj]);
|
||||
if (!pKernelChannels[3])
|
||||
continue;
|
||||
if (lenSq < minRadiusSq)
|
||||
{
|
||||
minRadiusSq = lenSq;
|
||||
memcpy(color, pKernelChannels, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (minRadiusSq != INT_MAX)
|
||||
memcpy(pOriginChannels, color, 3);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void LightMapBaker::Save()
|
||||
{
|
||||
IO::FileSystem::SaveImage(_C(_pathname), _vMap.data(), _desc._texWidth, _desc._texHeight, IO::ImageFormat::extension);
|
||||
}
|
||||
|
||||
void LightMapBaker::BindPipeline(PIPE pipe, CGI::CommandBufferPtr cb)
|
||||
{
|
||||
VERUS_RT_ASSERT(pipe >= PIPE_MESH_SIMPLE_BAKE_AO && pipe <= PIPE_MESH_SIMPLE_BAKE_AO_SKINNED);
|
||||
|
||||
if (!_pipe[pipe])
|
||||
{
|
||||
static CSZ branches[] =
|
||||
{
|
||||
"#BakeAO",
|
||||
"#BakeAOInstanced",
|
||||
"#BakeAORobotic",
|
||||
"#BakeAOSkinned"
|
||||
};
|
||||
CGI::PipelineDesc pipeDesc(_desc._pMesh->GetGeometry(), Mesh::GetSimpleShader(), branches[pipe], _rph);
|
||||
pipeDesc._vertexInputBindingsFilter = _desc._pMesh->GetBindingsMask();
|
||||
_pipe[pipe].Init(pipeDesc);
|
||||
}
|
||||
|
||||
cb->BindPipeline(_pipe[pipe]);
|
||||
}
|
||||
|
||||
void LightMapBaker::SetViewportFor(CGI::CubeMapFace cubeMapFace, CGI::CommandBufferPtr cb)
|
||||
{
|
||||
const float sideDiv2 = static_cast<float>(_desc._texLumelSide >> 1);
|
||||
const float sideDiv4 = static_cast<float>(_desc._texLumelSide >> 2);
|
||||
switch (cubeMapFace)
|
||||
{
|
||||
case CGI::CubeMapFace::posX:
|
||||
cb->SetViewport({ Vector4(-sideDiv4, sideDiv4, sideDiv2, sideDiv2) });
|
||||
break;
|
||||
case CGI::CubeMapFace::negX:
|
||||
cb->SetViewport({ Vector4(sideDiv2 + sideDiv4, sideDiv4, sideDiv2, sideDiv2) });
|
||||
break;
|
||||
case CGI::CubeMapFace::posY:
|
||||
cb->SetViewport({ Vector4(sideDiv4, -sideDiv4, sideDiv2, sideDiv2) });
|
||||
break;
|
||||
case CGI::CubeMapFace::negY:
|
||||
cb->SetViewport({ Vector4(sideDiv4, sideDiv2 + sideDiv4, sideDiv2, sideDiv2) });
|
||||
break;
|
||||
case CGI::CubeMapFace::posZ:
|
||||
cb->SetViewport({ Vector4(sideDiv4, sideDiv4, sideDiv2, sideDiv2) });
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,25 @@ namespace verus
|
|||
{
|
||||
namespace Scene
|
||||
{
|
||||
struct DrawLumelDesc
|
||||
{
|
||||
Transform3 _matV;
|
||||
Point3 _eyePos;
|
||||
Vector3 _frontDir;
|
||||
};
|
||||
VERUS_TYPEDEFS(DrawLumelDesc);
|
||||
|
||||
struct LightMapBakerDelegate
|
||||
{
|
||||
virtual void LightMapBaker_Draw(CGI::CubeMapFace cubeMapFace, RcDrawLumelDesc drawLumelDesc) = 0;
|
||||
};
|
||||
VERUS_TYPEDEFS(LightMapBakerDelegate);
|
||||
|
||||
class LightMapBaker : public Singleton<LightMapBaker>, public Object, public Math::QuadtreeDelegate
|
||||
{
|
||||
static const int s_batchSize = 400;
|
||||
static const int s_maxLayers = 8;
|
||||
|
||||
struct Vertex
|
||||
{
|
||||
glm::vec3 _pos;
|
||||
|
@ -21,11 +38,30 @@ namespace verus
|
|||
};
|
||||
VERUS_TYPEDEFS(Face);
|
||||
|
||||
struct Queued
|
||||
{
|
||||
Point3 _pos;
|
||||
Vector3 _nrm;
|
||||
void* _pDst;
|
||||
};
|
||||
VERUS_TYPEDEFS(Queued);
|
||||
|
||||
public:
|
||||
enum PIPE
|
||||
{
|
||||
PIPE_MESH_SIMPLE_BAKE_AO,
|
||||
PIPE_MESH_SIMPLE_BAKE_AO_INSTANCED,
|
||||
PIPE_MESH_SIMPLE_BAKE_AO_ROBOTIC,
|
||||
PIPE_MESH_SIMPLE_BAKE_AO_SKINNED,
|
||||
PIPE_HEMICUBE_MASK,
|
||||
PIPE_QUAD,
|
||||
PIPE_COUNT
|
||||
};
|
||||
|
||||
enum TEX
|
||||
{
|
||||
TEX_COLOR,
|
||||
TEX_DEPTH,
|
||||
TEX_DUMMY,
|
||||
TEX_COUNT
|
||||
};
|
||||
|
||||
|
@ -36,34 +72,53 @@ namespace verus
|
|||
ambientOcclusion
|
||||
};
|
||||
|
||||
struct Stats
|
||||
{
|
||||
String _info;
|
||||
float _progress = 0;
|
||||
float _startTime = 0;
|
||||
int _maxLayer = 0;
|
||||
};
|
||||
VERUS_TYPEDEFS(Stats);
|
||||
|
||||
struct Desc
|
||||
{
|
||||
PcBaseMesh _pMesh = nullptr;
|
||||
CSZ _pathname = nullptr;
|
||||
Mode _mode = Mode::idle;
|
||||
int _texCoordIndex = 0;
|
||||
int _texWidth = 256;
|
||||
int _texHeight = 256;
|
||||
int _texLumelSide = 256;
|
||||
float _distance = 1;
|
||||
PcMesh _pMesh = nullptr;
|
||||
CSZ _pathname = nullptr;
|
||||
Mode _mode = Mode::idle;
|
||||
int _texCoordSet = 0;
|
||||
int _texWidth = 256;
|
||||
int _texHeight = 256;
|
||||
int _texLumelSide = 128;
|
||||
float _distance = 2;
|
||||
};
|
||||
VERUS_TYPEDEFS(Desc);
|
||||
|
||||
private:
|
||||
Math::Quadtree _quadtree;
|
||||
Vector<Face> _vFaces;
|
||||
Vector<UINT32> _vMap;
|
||||
String _pathname;
|
||||
Desc _desc;
|
||||
CGI::TexturePwns<TEX_COUNT> _tex;
|
||||
CGI::RPHandle _rph;
|
||||
CGI::FBHandle _fbh;
|
||||
int _repsPerUpdate = 1;
|
||||
int _currentI = 0;
|
||||
int _currentJ = 0;
|
||||
glm::vec2 _currentUV;
|
||||
float _progress = 0;
|
||||
float _invMapSize = 0;
|
||||
Math::Quadtree _quadtree;
|
||||
PLightMapBakerDelegate _pDelegate = nullptr;
|
||||
Vector<Face> _vFaces;
|
||||
Vector<UINT32> _vMap;
|
||||
Vector<Queued> _vQueued[CGI::BaseRenderer::s_ringBufferSize];
|
||||
String _pathname;
|
||||
Desc _desc;
|
||||
CGI::PipelinePwns<PIPE_COUNT> _pipe;
|
||||
CGI::TexturePwns<TEX_COUNT> _tex;
|
||||
CGI::TexturePwns<s_batchSize> _texColor[CGI::BaseRenderer::s_ringBufferSize];
|
||||
CGI::RPHandle _rph;
|
||||
CGI::FBHandle _fbh[CGI::BaseRenderer::s_ringBufferSize][s_batchSize];
|
||||
CGI::CSHandle _cshQuad[CGI::BaseRenderer::s_ringBufferSize];
|
||||
CGI::CSHandle _cshHemicubeMask;
|
||||
int _repsPerUpdate = 1;
|
||||
int _drawEmptyState = 0;
|
||||
int _queuedCount[CGI::BaseRenderer::s_ringBufferSize];
|
||||
int _currentLayer = 0;
|
||||
int _currentI = 0;
|
||||
int _currentJ = 0;
|
||||
glm::vec2 _currentUV;
|
||||
float _invMapSize = 0;
|
||||
float _normalizationFactor = 0;
|
||||
Stats _stats;
|
||||
|
||||
public:
|
||||
LightMapBaker();
|
||||
|
@ -73,8 +128,15 @@ namespace verus
|
|||
void Done();
|
||||
|
||||
void Update();
|
||||
void Draw();
|
||||
|
||||
void DrawLumel(RcPoint3 eyePos, RcVector3 frontDir);
|
||||
PLightMapBakerDelegate SetDelegate(PLightMapBakerDelegate p) { return Utils::Swap(_pDelegate, p); }
|
||||
|
||||
void DrawEmpty();
|
||||
void DrawHemicubeMask();
|
||||
void DrawLumel(RcPoint3 pos, RcVector3 nrm, int batchIndex);
|
||||
|
||||
RcDesc GetDesc() const { return _desc; }
|
||||
|
||||
bool IsBaking() const { return Mode::idle != _desc._mode; }
|
||||
Mode GetMode() const { return _desc._mode; }
|
||||
|
@ -82,9 +144,14 @@ namespace verus
|
|||
virtual Continue Quadtree_ProcessNode(void* pToken, void* pUser) override;
|
||||
|
||||
Str GetPathname() const { return _C(_pathname); }
|
||||
float GetProgress() const { return _progress; }
|
||||
RcStats GetStats() const { return _stats; }
|
||||
float GetProgress() const { return _stats._progress; }
|
||||
|
||||
void ComputeEdgePadding(int radius = 32);
|
||||
void Save();
|
||||
|
||||
void BindPipeline(PIPE pipe, CGI::CommandBufferPtr cb);
|
||||
void SetViewportFor(CGI::CubeMapFace cubeMapFace, CGI::CommandBufferPtr cb);
|
||||
};
|
||||
VERUS_TYPEDEFS(LightMapBaker);
|
||||
}
|
||||
|
|
|
@ -87,62 +87,88 @@ void Mesh::Done()
|
|||
VERUS_DONE(Mesh);
|
||||
}
|
||||
|
||||
void Mesh::Draw(RcDrawDesc dd, CGI::CommandBufferPtr cb)
|
||||
void Mesh::Draw(RcDrawDesc drawDesc, CGI::CommandBufferPtr cb)
|
||||
{
|
||||
auto shader = GetShader();
|
||||
|
||||
if (dd._pipe != PIPE_COUNT)
|
||||
BindPipeline(dd._pipe, cb);
|
||||
else
|
||||
BindPipeline(cb, dd._allowTess);
|
||||
if (drawDesc._bindPipeline)
|
||||
{
|
||||
if (drawDesc._pipe != PIPE_COUNT)
|
||||
BindPipeline(drawDesc._pipe, cb);
|
||||
else
|
||||
BindPipeline(cb, drawDesc._allowTess); // Auto.
|
||||
}
|
||||
BindGeo(cb);
|
||||
|
||||
// Set 0:
|
||||
UpdateUniformBufferPerFrame();
|
||||
if (drawDesc._pOverrideFogColor)
|
||||
s_ubSimplePerFrame._fogColor = drawDesc._pOverrideFogColor->GLM();
|
||||
cb->BindDescriptors(shader, 0);
|
||||
if (dd._bindMaterial)
|
||||
|
||||
// Set 1:
|
||||
if (drawDesc._bindMaterial)
|
||||
{
|
||||
// Material buffer should already be updated. For example call Material::UpdateMeshUniformBuffer.
|
||||
cb->BindDescriptors(shader, 1, dd._cshMaterial);
|
||||
cb->BindDescriptors(shader, 1, drawDesc._cshMaterial);
|
||||
}
|
||||
|
||||
// Set 2:
|
||||
UpdateUniformBufferPerMeshVS();
|
||||
cb->BindDescriptors(shader, 2);
|
||||
if (dd._bindSkeleton)
|
||||
|
||||
// Set 3:
|
||||
if (drawDesc._bindSkeleton)
|
||||
{
|
||||
UpdateUniformBufferSkeletonVS();
|
||||
cb->BindDescriptors(shader, 3);
|
||||
}
|
||||
UpdateUniformBufferPerObject(dd._matW, dd._userColor);
|
||||
|
||||
// Set 4:
|
||||
UpdateUniformBufferPerObject(drawDesc._matW, drawDesc._userColor);
|
||||
cb->BindDescriptors(shader, 4);
|
||||
|
||||
cb->DrawIndexed(GetIndexCount());
|
||||
}
|
||||
|
||||
void Mesh::DrawSimple(RcDrawDesc dd, CGI::CommandBufferPtr cb)
|
||||
void Mesh::DrawSimple(RcDrawDesc drawDesc, CGI::CommandBufferPtr cb)
|
||||
{
|
||||
DrawSimpleMode mode = DrawSimpleMode::envMap;
|
||||
if (dd._pipe >= PIPE_SIMPLE_PLANAR_REF && dd._pipe <= PIPE_SIMPLE_PLANAR_REF_SKINNED)
|
||||
if (drawDesc._pipe >= PIPE_SIMPLE_PLANAR_REF && drawDesc._pipe <= PIPE_SIMPLE_PLANAR_REF_SKINNED)
|
||||
mode = DrawSimpleMode::planarReflection;
|
||||
|
||||
auto shader = GetSimpleShader();
|
||||
|
||||
BindPipeline(dd._pipe, cb);
|
||||
if (drawDesc._bindPipeline)
|
||||
BindPipeline(drawDesc._pipe, cb);
|
||||
BindGeo(cb);
|
||||
|
||||
// Set 0:
|
||||
UpdateUniformBufferSimplePerFrame(mode);
|
||||
if (drawDesc._pOverrideFogColor)
|
||||
s_ubSimplePerFrame._fogColor = drawDesc._pOverrideFogColor->GLM();
|
||||
cb->BindDescriptors(shader, 0);
|
||||
if (dd._bindMaterial)
|
||||
|
||||
// Set 1:
|
||||
if (drawDesc._bindMaterial)
|
||||
{
|
||||
// Material buffer should already be updated. For example call Material::UpdateMeshUniformBuffer.
|
||||
cb->BindDescriptors(shader, 1, dd._cshMaterial);
|
||||
cb->BindDescriptors(shader, 1, drawDesc._cshMaterial);
|
||||
}
|
||||
|
||||
// Set 2:
|
||||
UpdateUniformBufferPerMeshVS();
|
||||
cb->BindDescriptors(shader, 2);
|
||||
if (dd._bindSkeleton)
|
||||
|
||||
// Set 3:
|
||||
if (drawDesc._bindSkeleton)
|
||||
{
|
||||
UpdateUniformBufferSimpleSkeletonVS();
|
||||
cb->BindDescriptors(shader, 3);
|
||||
}
|
||||
UpdateUniformBufferPerObject(dd._matW, dd._userColor);
|
||||
|
||||
// Set 4:
|
||||
UpdateUniformBufferPerObject(drawDesc._matW, drawDesc._userColor);
|
||||
cb->BindDescriptors(shader, 4);
|
||||
|
||||
cb->DrawIndexed(GetIndexCount());
|
||||
|
@ -161,15 +187,15 @@ void Mesh::BindPipeline(PIPE pipe, CGI::CommandBufferPtr cb)
|
|||
{
|
||||
case PIPE_TESS: pipe = PIPE_MAIN; break;
|
||||
case PIPE_TESS_INSTANCED: pipe = PIPE_INSTANCED; break;
|
||||
case PIPE_TESS_PLANT: pipe = PIPE_PLANT; break;
|
||||
case PIPE_TESS_ROBOTIC: pipe = PIPE_ROBOTIC; break;
|
||||
case PIPE_TESS_SKINNED: pipe = PIPE_SKINNED; break;
|
||||
case PIPE_TESS_PLANT: pipe = PIPE_PLANT; break;
|
||||
|
||||
case PIPE_DEPTH_TESS: pipe = PIPE_DEPTH; break;
|
||||
case PIPE_DEPTH_TESS_INSTANCED: pipe = PIPE_DEPTH_INSTANCED; break;
|
||||
case PIPE_DEPTH_TESS_PLANT: pipe = PIPE_DEPTH_PLANT; break;
|
||||
case PIPE_DEPTH_TESS_ROBOTIC: pipe = PIPE_DEPTH_ROBOTIC; break;
|
||||
case PIPE_DEPTH_TESS_SKINNED: pipe = PIPE_DEPTH_SKINNED; break;
|
||||
case PIPE_DEPTH_TESS_PLANT: pipe = PIPE_DEPTH_PLANT; break;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -179,27 +205,27 @@ void Mesh::BindPipeline(PIPE pipe, CGI::CommandBufferPtr cb)
|
|||
{
|
||||
"#",
|
||||
"#Instanced",
|
||||
"#Plant",
|
||||
"#Robotic",
|
||||
"#Skinned",
|
||||
"#Plant",
|
||||
|
||||
"#Tess",
|
||||
"#TessInstanced",
|
||||
"#TessPlant",
|
||||
"#TessRobotic",
|
||||
"#TessSkinned",
|
||||
"#TessPlant",
|
||||
|
||||
"#Depth",
|
||||
"#DepthInstanced",
|
||||
"#DepthPlant",
|
||||
"#DepthRobotic",
|
||||
"#DepthSkinned",
|
||||
"#DepthPlant",
|
||||
|
||||
"#DepthTess",
|
||||
"#DepthTessInstanced",
|
||||
"#DepthTessPlant",
|
||||
"#DepthTessRobotic",
|
||||
"#DepthTessSkinned",
|
||||
"#DepthTessPlant",
|
||||
|
||||
"#SolidColor",
|
||||
"#SolidColorInstanced",
|
||||
|
@ -265,18 +291,18 @@ void Mesh::BindPipeline(PIPE pipe, CGI::CommandBufferPtr cb)
|
|||
{
|
||||
case PIPE_MAIN:
|
||||
case PIPE_INSTANCED:
|
||||
case PIPE_PLANT:
|
||||
case PIPE_ROBOTIC:
|
||||
case PIPE_SKINNED:
|
||||
case PIPE_PLANT:
|
||||
{
|
||||
SetBlendEqsForDS();
|
||||
}
|
||||
break;
|
||||
case PIPE_TESS:
|
||||
case PIPE_TESS_INSTANCED:
|
||||
case PIPE_TESS_PLANT:
|
||||
case PIPE_TESS_ROBOTIC:
|
||||
case PIPE_TESS_SKINNED:
|
||||
case PIPE_TESS_PLANT:
|
||||
{
|
||||
SetBlendEqsForDS();
|
||||
if (settings._gpuTessellation)
|
||||
|
@ -285,9 +311,9 @@ void Mesh::BindPipeline(PIPE pipe, CGI::CommandBufferPtr cb)
|
|||
break;
|
||||
case PIPE_DEPTH:
|
||||
case PIPE_DEPTH_INSTANCED:
|
||||
case PIPE_DEPTH_PLANT:
|
||||
case PIPE_DEPTH_ROBOTIC:
|
||||
case PIPE_DEPTH_SKINNED:
|
||||
case PIPE_DEPTH_PLANT:
|
||||
{
|
||||
pipeDesc._colorAttachBlendEqs[0] = "";
|
||||
pipeDesc._renderPassHandle = atmo.GetShadowMapBaker().GetRenderPassHandle();
|
||||
|
@ -295,9 +321,9 @@ void Mesh::BindPipeline(PIPE pipe, CGI::CommandBufferPtr cb)
|
|||
break;
|
||||
case PIPE_DEPTH_TESS:
|
||||
case PIPE_DEPTH_TESS_INSTANCED:
|
||||
case PIPE_DEPTH_TESS_PLANT:
|
||||
case PIPE_DEPTH_TESS_ROBOTIC:
|
||||
case PIPE_DEPTH_TESS_SKINNED:
|
||||
case PIPE_DEPTH_TESS_PLANT:
|
||||
{
|
||||
pipeDesc._colorAttachBlendEqs[0] = "";
|
||||
pipeDesc._renderPassHandle = atmo.GetShadowMapBaker().GetRenderPassHandle();
|
||||
|
@ -332,40 +358,40 @@ void Mesh::BindPipeline(PIPE pipe, CGI::CommandBufferPtr cb)
|
|||
void Mesh::BindPipeline(CGI::CommandBufferPtr cb, bool allowTess)
|
||||
{
|
||||
VERUS_QREF_ATMO;
|
||||
if (_skeleton.IsInitialized())
|
||||
|
||||
static PIPE pipes[] =
|
||||
{
|
||||
if (atmo.GetShadowMapBaker().IsBaking())
|
||||
{
|
||||
if (allowTess)
|
||||
BindPipeline(PIPE_DEPTH_TESS_SKINNED, cb);
|
||||
else
|
||||
BindPipeline(PIPE_DEPTH_SKINNED, cb);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (allowTess)
|
||||
BindPipeline(PIPE_TESS_SKINNED, cb);
|
||||
else
|
||||
BindPipeline(PIPE_SKINNED, cb);
|
||||
}
|
||||
}
|
||||
PIPE_MAIN,
|
||||
PIPE_INSTANCED,
|
||||
PIPE_ROBOTIC,
|
||||
PIPE_SKINNED
|
||||
};
|
||||
static PIPE tessPipes[] =
|
||||
{
|
||||
PIPE_TESS,
|
||||
PIPE_TESS_INSTANCED,
|
||||
PIPE_TESS_ROBOTIC,
|
||||
PIPE_TESS_SKINNED
|
||||
};
|
||||
static PIPE depthPipes[] =
|
||||
{
|
||||
PIPE_DEPTH,
|
||||
PIPE_DEPTH_INSTANCED,
|
||||
PIPE_DEPTH_ROBOTIC,
|
||||
PIPE_DEPTH_SKINNED
|
||||
};
|
||||
static PIPE depthTessPipes[] =
|
||||
{
|
||||
PIPE_DEPTH_TESS,
|
||||
PIPE_DEPTH_TESS_INSTANCED,
|
||||
PIPE_DEPTH_TESS_ROBOTIC,
|
||||
PIPE_DEPTH_TESS_SKINNED
|
||||
};
|
||||
|
||||
if (atmo.GetShadowMapBaker().IsBaking())
|
||||
BindPipeline(allowTess ? depthTessPipes[GetPipelineIndex()] : depthPipes[GetPipelineIndex()], cb);
|
||||
else
|
||||
{
|
||||
if (atmo.GetShadowMapBaker().IsBaking())
|
||||
{
|
||||
if (allowTess)
|
||||
BindPipeline(PIPE_DEPTH_TESS, cb);
|
||||
else
|
||||
BindPipeline(PIPE_DEPTH, cb);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (allowTess)
|
||||
BindPipeline(PIPE_TESS, cb);
|
||||
else
|
||||
BindPipeline(PIPE_MAIN, cb);
|
||||
}
|
||||
}
|
||||
BindPipeline(allowTess ? tessPipes[GetPipelineIndex()] : pipes[GetPipelineIndex()], cb);
|
||||
}
|
||||
|
||||
void Mesh::BindPipelineInstanced(CGI::CommandBufferPtr cb, bool allowTess, bool plant)
|
||||
|
|
|
@ -22,27 +22,27 @@ namespace verus
|
|||
{
|
||||
PIPE_MAIN,
|
||||
PIPE_INSTANCED,
|
||||
PIPE_PLANT,
|
||||
PIPE_ROBOTIC,
|
||||
PIPE_SKINNED,
|
||||
PIPE_PLANT,
|
||||
|
||||
PIPE_TESS,
|
||||
PIPE_TESS_INSTANCED,
|
||||
PIPE_TESS_PLANT,
|
||||
PIPE_TESS_ROBOTIC,
|
||||
PIPE_TESS_SKINNED,
|
||||
PIPE_TESS_PLANT,
|
||||
|
||||
PIPE_DEPTH,
|
||||
PIPE_DEPTH_INSTANCED,
|
||||
PIPE_DEPTH_PLANT,
|
||||
PIPE_DEPTH_ROBOTIC,
|
||||
PIPE_DEPTH_SKINNED,
|
||||
PIPE_DEPTH_PLANT,
|
||||
|
||||
PIPE_DEPTH_TESS,
|
||||
PIPE_DEPTH_TESS_INSTANCED,
|
||||
PIPE_DEPTH_TESS_PLANT,
|
||||
PIPE_DEPTH_TESS_ROBOTIC,
|
||||
PIPE_DEPTH_TESS_SKINNED,
|
||||
PIPE_DEPTH_TESS_PLANT,
|
||||
|
||||
PIPE_WIREFRAME,
|
||||
PIPE_WIREFRAME_INSTANCED,
|
||||
|
@ -113,9 +113,11 @@ namespace verus
|
|||
Transform3 _matW = Transform3::identity();
|
||||
Vector4 _userColor = Vector4(0);
|
||||
CGI::CSHandle _cshMaterial;
|
||||
PcVector4 _pOverrideFogColor = nullptr;
|
||||
PIPE _pipe = PIPE_COUNT;
|
||||
bool _allowTess = true;
|
||||
bool _bindMaterial = true;
|
||||
bool _bindPipeline = true;
|
||||
bool _bindSkeleton = true;
|
||||
};
|
||||
VERUS_TYPEDEFS(DrawDesc);
|
||||
|
@ -129,8 +131,8 @@ namespace verus
|
|||
void Init(RcDesc desc = Desc());
|
||||
void Done();
|
||||
|
||||
void Draw(RcDrawDesc dd, CGI::CommandBufferPtr cb);
|
||||
void DrawSimple(RcDrawDesc dd, CGI::CommandBufferPtr cb);
|
||||
void Draw(RcDrawDesc drawDesc, CGI::CommandBufferPtr cb);
|
||||
void DrawSimple(RcDrawDesc drawDesc, CGI::CommandBufferPtr cb);
|
||||
|
||||
void BindPipeline(PIPE pipe, CGI::CommandBufferPtr cb);
|
||||
void BindPipeline(CGI::CommandBufferPtr cb, bool allowTess = true);
|
||||
|
@ -164,6 +166,8 @@ namespace verus
|
|||
int GetInstanceCount(bool fromFirstInstance = false) const { return fromFirstInstance ? _instanceCount - _firstInstance : _instanceCount; }
|
||||
int GetInstanceCapacity() const { return _instanceCapacity; }
|
||||
int GetFirstInstance() const { return _firstInstance; }
|
||||
|
||||
UINT32 GetBindingsMask() const { return _bindingsMask; }
|
||||
};
|
||||
VERUS_TYPEDEFS(Mesh);
|
||||
}
|
||||
|
|
|
@ -164,7 +164,7 @@ void Light::ConeFromPoint(RcPoint3 point, bool coneIn)
|
|||
|
||||
Transform3 Light::GetTransformNoScale() const
|
||||
{
|
||||
const Matrix3 matR = Matrix3::MakeAimZ(_data._dir);
|
||||
const Matrix3 matR = Matrix3::MakeTrackToZ(_data._dir);
|
||||
return Transform3(matR, Vector3(GetPosition()));
|
||||
}
|
||||
|
||||
|
@ -199,7 +199,7 @@ Vector3 Light::ComputeScale()
|
|||
|
||||
void Light::ComputeTransform()
|
||||
{
|
||||
const Matrix3 matR = Matrix3::MakeAimZ(_data._dir);
|
||||
const Matrix3 matR = Matrix3::MakeTrackToZ(_data._dir);
|
||||
const Transform3 tr = VMath::appendScale(Transform3(matR, Vector3(GetPosition())), ComputeScale());
|
||||
SceneNode::SetTransform(tr);
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ FSO mainFS(VSO si)
|
|||
const float sunStrength = g_ubBloomLightShaftsFS._maxDist_sunGloss_wideStrength_sunStrength.w;
|
||||
|
||||
const float2 ndcPos = ToNdcPos(si.tc0);
|
||||
const float rawDepth = g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.f).r;
|
||||
const float rawDepth = g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.0).r;
|
||||
const float3 posW = DS_GetPosition(rawDepth, g_ubBloomLightShaftsFS._matInvVP, ndcPos);
|
||||
|
||||
const float3 eyePos = g_ubBloomLightShaftsFS._eyePos.xyz;
|
||||
|
@ -67,8 +67,8 @@ FSO mainFS(VSO si)
|
|||
const float2 spec = pow(saturate(dot(g_ubBloomLightShaftsFS._dirToSun.xyz, pickingRayDir)), float2(7, sunGloss));
|
||||
const float strength = dot(spec, float2(wideStrength, sunStrength));
|
||||
|
||||
float3 lightShafts = 0.f;
|
||||
if (strength >= 0.0001f)
|
||||
float3 lightShafts = 0.0;
|
||||
if (strength >= 0.0001)
|
||||
{
|
||||
const float3 rand = Rand(si.pos.xy);
|
||||
|
||||
|
@ -84,7 +84,7 @@ FSO mainFS(VSO si)
|
|||
const float stride = maxDist / sampleCount;
|
||||
|
||||
float pickingRayLen = rand.y * stride;
|
||||
float acc = 0.f;
|
||||
float acc = 0.0;
|
||||
[unroll] for (int i = 0; i < sampleCount; ++i)
|
||||
{
|
||||
const float3 pos = eyePos + pickingRayDir * pickingRayLen;
|
||||
|
@ -104,7 +104,7 @@ FSO mainFS(VSO si)
|
|||
acc += shadowMask * step(pickingRayLen, depth);
|
||||
pickingRayLen += stride;
|
||||
}
|
||||
lightShafts = acc * (1.f / sampleCount) * g_ubBloomLightShaftsFS._sunColor.rgb * g_ubBloomFS._exposure.x * strength;
|
||||
lightShafts = acc * (1.0 / sampleCount) * g_ubBloomLightShaftsFS._sunColor.rgb * g_ubBloomFS._exposure.x * strength;
|
||||
}
|
||||
|
||||
so.color.rgb = lightShafts;
|
||||
|
@ -112,14 +112,14 @@ FSO mainFS(VSO si)
|
|||
const float colorScale = g_ubBloomFS._colorScale_colorBias.x;
|
||||
const float colorBias = g_ubBloomFS._colorScale_colorBias.y;
|
||||
|
||||
const float4 rawColor = g_texColor.SampleLevel(g_samColor, si.tc0, 0.f);
|
||||
const float4 rawColor = g_texColor.SampleLevel(g_samColor, si.tc0, 0.0);
|
||||
const float3 color = rawColor.rgb * g_ubBloomFS._exposure.x;
|
||||
const float3 bloom = saturate((color - colorBias) * colorScale);
|
||||
|
||||
so.color.rgb = bloom;
|
||||
#endif
|
||||
|
||||
so.color.a = 1.f;
|
||||
so.color.a = 1.0;
|
||||
|
||||
return so;
|
||||
}
|
||||
|
|
|
@ -37,8 +37,8 @@ struct FSO
|
|||
|
||||
float GlossBoost(float gloss)
|
||||
{
|
||||
const float x = 1.f - gloss;
|
||||
return 1.f - x * x;
|
||||
const float x = 1.0 - gloss;
|
||||
return 1.0 - x * x;
|
||||
}
|
||||
|
||||
#ifdef _VS
|
||||
|
@ -60,19 +60,19 @@ FSO mainFS(VSO si)
|
|||
FSO so;
|
||||
|
||||
#ifdef DEF_SSR
|
||||
const float alpha = g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.f).r;
|
||||
const float gloss = g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.f).a;
|
||||
const float alpha = g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.0).r;
|
||||
const float gloss = g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.0).a;
|
||||
|
||||
const float gloss64 = gloss * 64.f;
|
||||
const float eyeMask = saturate(1.f - gloss64);
|
||||
const float scaleByAlpha = 1.f - alpha;
|
||||
const float scaleByGloss = 1.f - GlossBoost(lerp(gloss, 0.75f, eyeMask));
|
||||
const float scale = max(0.001f, min(scaleByAlpha, scaleByGloss));
|
||||
const float gloss64 = gloss * 64.0;
|
||||
const float eyeMask = saturate(1.0 - gloss64);
|
||||
const float scaleByAlpha = 1.0 - alpha;
|
||||
const float scaleByGloss = 1.0 - GlossBoost(lerp(gloss, 0.75, eyeMask));
|
||||
const float scale = max(0.001, min(scaleByAlpha, scaleByGloss));
|
||||
|
||||
const int sampleCount = max(4, g_ubBlurFS._sampleCount * scale);
|
||||
const float radius = g_ubBlurFS._radius_invRadius_stride.x * scale;
|
||||
const float invRadius = 1.f / radius;
|
||||
const float stride = radius * 2.f / (sampleCount - 1);
|
||||
const float invRadius = 1.0 / radius;
|
||||
const float stride = radius * 2.0 / (sampleCount - 1);
|
||||
#else
|
||||
const int sampleCount = g_ubBlurFS._sampleCount;
|
||||
const float radius = g_ubBlurFS._radius_invRadius_stride.x;
|
||||
|
@ -80,22 +80,22 @@ FSO mainFS(VSO si)
|
|||
const float stride = g_ubBlurFS._radius_invRadius_stride.z;
|
||||
#endif
|
||||
|
||||
float4 acc = 0.f;
|
||||
float4 acc = 0.0;
|
||||
float2 offset_weightSum = float2(-radius, 0);
|
||||
for (int i = 0; i < sampleCount; ++i)
|
||||
{
|
||||
// Poor man's gaussian kernel:
|
||||
const float curve = smoothstep(1.f, 0.f, abs(offset_weightSum.x) * invRadius);
|
||||
const float curve = smoothstep(1.0, 0.0, abs(offset_weightSum.x) * invRadius);
|
||||
const float weight = curve * curve;
|
||||
#ifdef DEF_U
|
||||
const float2 tc = si.tc0 + float2(offset_weightSum.x, 0);
|
||||
#else
|
||||
const float2 tc = si.tc0 + float2(0, offset_weightSum.x);
|
||||
#endif
|
||||
acc += g_tex.SampleLevel(g_sam, tc, 0.f) * weight;
|
||||
acc += g_tex.SampleLevel(g_sam, tc, 0.0) * weight;
|
||||
offset_weightSum += float2(stride, weight);
|
||||
}
|
||||
acc *= 1.f / offset_weightSum.y;
|
||||
acc *= 1.0 / offset_weightSum.y;
|
||||
|
||||
so.color = acc;
|
||||
|
||||
|
@ -109,7 +109,7 @@ FSO mainFS(VSO si)
|
|||
|
||||
float DepthToCircleOfConfusion(float depth, float focusDist)
|
||||
{
|
||||
return abs((depth - focusDist * 2.f) / depth + 1.f);
|
||||
return abs((depth - focusDist * 2.0) / depth + 1.0);
|
||||
}
|
||||
|
||||
#ifdef _VS
|
||||
|
@ -133,47 +133,47 @@ FSO mainDofFS(VSO si)
|
|||
const float focusDist = g_ubExtraBlurFS._focusDist_blurStrength.x;
|
||||
const float blurStrength = g_ubExtraBlurFS._focusDist_blurStrength.y;
|
||||
|
||||
const float rawOriginDepth = g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.f).r;
|
||||
const float rawOriginDepth = g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.0).r;
|
||||
const float originDepth = ToLinearDepth(rawOriginDepth, g_ubExtraBlurFS._zNearFarEx);
|
||||
const float scale = DepthToCircleOfConfusion(originDepth, focusDist) * blurStrength;
|
||||
|
||||
const int sampleCount = clamp(g_ubBlurFS._sampleCount * scale, 3, 31);
|
||||
const float radius = g_ubBlurFS._radius_invRadius_stride.x * scale;
|
||||
const float invRadius = 1.f / radius;
|
||||
const float invRadius = 1.0 / radius;
|
||||
const float2 blurDir = g_ubExtraBlurFS._blurDir.xy;
|
||||
const float2 blurDir2 = g_ubExtraBlurFS._blurDir.zw * radius;
|
||||
|
||||
const float stride = radius * 2.f / (sampleCount - 1);
|
||||
const float stride = radius * 2.0 / (sampleCount - 1);
|
||||
const float2 stride2D = stride * blurDir;
|
||||
|
||||
float4 acc = 0.f;
|
||||
float4 acc = 0.0;
|
||||
float2 offset_weightSum = float2(-radius, 0);
|
||||
float2 tc = si.tc0 - blurDir * radius;
|
||||
for (int i = 0; i < sampleCount; ++i)
|
||||
{
|
||||
//const float origin = 1.f - abs(offset_weightSum.x) * invRadius; // Will generate buggy code in Vulkan!
|
||||
//const float origin = 1.0 - abs(offset_weightSum.x) * invRadius; // Will generate buggy code in Vulkan!
|
||||
const float origin = abs(offset_weightSum.x) * invRadius;
|
||||
|
||||
const float rawKernelDepth = g_texDepth.SampleLevel(g_samDepth, tc, 0.f).r;
|
||||
const float rawKernelDepth = g_texDepth.SampleLevel(g_samDepth, tc, 0.0).r;
|
||||
const float kernelDepth = ToLinearDepth(rawKernelDepth, g_ubExtraBlurFS._zNearFarEx);
|
||||
const float kernelDeeper = kernelDepth - originDepth;
|
||||
const float kernelScale = DepthToCircleOfConfusion(kernelDepth, focusDist) * blurStrength;
|
||||
// Blurry area should not sample sharp area unless it is closer to the camera.
|
||||
float weight = min(scale, min(2.f, max(kernelScale, kernelDeeper)));
|
||||
float weight = min(scale, min(2.0, max(kernelScale, kernelDeeper)));
|
||||
|
||||
#ifdef DEF_U // 1st pass - make a rhombus:
|
||||
weight *= 1.f - 0.5f * origin;
|
||||
const float4 colorA = g_tex.SampleLevel(g_sam, tc - blurDir2 + blurDir2 * origin, 0.f);
|
||||
const float4 colorB = g_tex.SampleLevel(g_sam, tc + blurDir2 - blurDir2 * origin, 0.f);
|
||||
acc += lerp(colorA, colorB, 0.5f) * weight;
|
||||
weight *= 1.0 - 0.5 * origin;
|
||||
const float4 colorA = g_tex.SampleLevel(g_sam, tc - blurDir2 + blurDir2 * origin, 0.0);
|
||||
const float4 colorB = g_tex.SampleLevel(g_sam, tc + blurDir2 - blurDir2 * origin, 0.0);
|
||||
acc += lerp(colorA, colorB, 0.5) * weight;
|
||||
#else // 2nd pass - blur the rhombus:
|
||||
acc += g_tex.SampleLevel(g_sam, tc, 0.f) * weight;
|
||||
acc += g_tex.SampleLevel(g_sam, tc, 0.0) * weight;
|
||||
#endif
|
||||
|
||||
offset_weightSum += float2(stride, weight);
|
||||
tc += stride2D;
|
||||
}
|
||||
acc *= 1.f / offset_weightSum.y;
|
||||
acc *= 1.0 / offset_weightSum.y;
|
||||
|
||||
so.color = acc;
|
||||
|
||||
|
@ -204,16 +204,16 @@ FSO mainSsaoFS(VSO si)
|
|||
FSO so;
|
||||
|
||||
// 4x4 box blur, using texture filtering.
|
||||
float4 acc = 0.f;
|
||||
float4 acc = 0.0;
|
||||
[unroll] for (int i = -1; i <= 1; i += 2)
|
||||
{
|
||||
#ifdef DEF_U
|
||||
acc += g_tex.SampleLevel(g_sam, si.tc0, 0.f, int2(i, 0));
|
||||
acc += g_tex.SampleLevel(g_sam, si.tc0, 0.0, int2(i, 0));
|
||||
#else // Sampling from sRGB, use alpha channel:
|
||||
acc += g_tex.SampleLevel(g_sam, si.tc0, 0.f, int2(0, i)).aaaa;
|
||||
acc += g_tex.SampleLevel(g_sam, si.tc0, 0.0, int2(0, i)).aaaa;
|
||||
#endif
|
||||
}
|
||||
acc *= 0.5f;
|
||||
acc *= 0.5;
|
||||
|
||||
so.color = acc;
|
||||
#ifndef DEF_V // Make sure to write R channel to alpha, destination is sRGB.
|
||||
|
@ -244,26 +244,26 @@ FSO mainAntiAliasingFS(VSO si)
|
|||
{
|
||||
FSO so;
|
||||
|
||||
const float4 rawGBuffer1 = g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.f);
|
||||
const float4 rawGBuffer1 = g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.0);
|
||||
const float3 normalWV = DS_GetNormal(rawGBuffer1);
|
||||
|
||||
// <DepthBased>
|
||||
float originDeeper;
|
||||
float depthBasedEdge;
|
||||
{
|
||||
const float rawOriginDepth = g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.f).r;
|
||||
const float rawOriginDepth = g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.0).r;
|
||||
const float originDepth = ToLinearDepth(rawOriginDepth, g_ubExtraBlurFS._zNearFarEx);
|
||||
const float4 rawKernelDepths = float4(
|
||||
g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.f, int2(-1, +0)).r, // L
|
||||
g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.f, int2(+0, -1)).r, // T
|
||||
g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.f, int2(+1, +0)).r, // R
|
||||
g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.f, int2(+0, +1)).r); // B
|
||||
g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.0, int2(-1, +0)).r, // L
|
||||
g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.0, int2(+0, -1)).r, // T
|
||||
g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.0, int2(+1, +0)).r, // R
|
||||
g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.0, int2(+0, +1)).r); // B
|
||||
const float4 kernelDepths = ToLinearDepth(rawKernelDepths, g_ubExtraBlurFS._zNearFarEx);
|
||||
const float minDepth = min(min(kernelDepths[0], kernelDepths[1]), min(kernelDepths[2], kernelDepths[3]));
|
||||
const float equalize = 1.f / originDepth;
|
||||
const float equalize = 1.0 / originDepth;
|
||||
originDeeper = saturate((originDepth - minDepth) * equalize);
|
||||
const float4 depthOffsets = abs((originDepth - kernelDepths) * equalize);
|
||||
depthBasedEdge = saturate(dot(depthOffsets, 1.f));
|
||||
depthBasedEdge = saturate(dot(depthOffsets, 1.0));
|
||||
}
|
||||
// </DepthBased>
|
||||
|
||||
|
@ -271,11 +271,11 @@ FSO mainAntiAliasingFS(VSO si)
|
|||
float normalBasedEdge;
|
||||
{
|
||||
const float4 rawNrmLT = float4(
|
||||
g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.f, int2(-1, +0)).rg,
|
||||
g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.f, int2(+0, -1)).rg);
|
||||
g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.0, int2(-1, +0)).rg,
|
||||
g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.0, int2(+0, -1)).rg);
|
||||
const float4 rawNrmRB = float4(
|
||||
g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.f, int2(+1, +0)).rg,
|
||||
g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.f, int2(+0, +1)).rg);
|
||||
g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.0, int2(+1, +0)).rg,
|
||||
g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.0, int2(+0, +1)).rg);
|
||||
const float4 diffA = rawNrmLT - rawNrmRB;
|
||||
const float4 diffB = rawNrmLT - rawNrmRB.zwxy;
|
||||
const float4 dots = float4(
|
||||
|
@ -284,7 +284,7 @@ FSO mainAntiAliasingFS(VSO si)
|
|||
dot(diffB.xy, diffB.xy),
|
||||
dot(diffB.zw, diffB.zw));
|
||||
const float maxDot = max(max(dots.x, dots.y), max(dots.z, dots.w));
|
||||
normalBasedEdge = saturate(maxDot * maxDot * 10.f);
|
||||
normalBasedEdge = saturate(maxDot * maxDot * 10.0);
|
||||
}
|
||||
// </NormalBased>
|
||||
|
||||
|
@ -294,21 +294,21 @@ FSO mainAntiAliasingFS(VSO si)
|
|||
const float omni = max(perp.z * perp.z * perp.z, originDeeper);
|
||||
const float2 dirs[4] =
|
||||
{
|
||||
lerp(perp.xy * +4.f, float2(-0.6f, -0.3f), omni),
|
||||
lerp(perp.xy * -2.f, float2(+0.3f, -0.6f), omni),
|
||||
lerp(perp.xy * -4.f, float2(-0.3f, +0.6f), omni),
|
||||
lerp(perp.xy * +2.f, float2(+0.6f, +0.3f), omni)
|
||||
lerp(perp.xy * +4.0, float2(-0.6, -0.3), omni),
|
||||
lerp(perp.xy * -2.0, float2(+0.3, -0.6), omni),
|
||||
lerp(perp.xy * -4.0, float2(-0.3, +0.6), omni),
|
||||
lerp(perp.xy * +2.0, float2(+0.6, +0.3), omni)
|
||||
};
|
||||
const float2 offsetScale = g_ubExtraBlurFS._textureSize.zw * max(normalBasedEdge, depthBasedEdge);
|
||||
const float3 kernelColors[4] =
|
||||
{
|
||||
g_tex.SampleLevel(g_sam, si.tc0 + dirs[0] * offsetScale, 0.f).rgb,
|
||||
g_tex.SampleLevel(g_sam, si.tc0 + dirs[1] * offsetScale, 0.f).rgb,
|
||||
g_tex.SampleLevel(g_sam, si.tc0 + dirs[2] * offsetScale, 0.f).rgb,
|
||||
g_tex.SampleLevel(g_sam, si.tc0 + dirs[3] * offsetScale, 0.f).rgb
|
||||
g_tex.SampleLevel(g_sam, si.tc0 + dirs[0] * offsetScale, 0.0).rgb,
|
||||
g_tex.SampleLevel(g_sam, si.tc0 + dirs[1] * offsetScale, 0.0).rgb,
|
||||
g_tex.SampleLevel(g_sam, si.tc0 + dirs[2] * offsetScale, 0.0).rgb,
|
||||
g_tex.SampleLevel(g_sam, si.tc0 + dirs[3] * offsetScale, 0.0).rgb
|
||||
};
|
||||
so.color.rgb = (kernelColors[0] + kernelColors[1] + kernelColors[2] + kernelColors[3]) * 0.25f;
|
||||
so.color.a = 1.f;
|
||||
so.color.rgb = (kernelColors[0] + kernelColors[1] + kernelColors[2] + kernelColors[3]) * 0.25;
|
||||
so.color.a = 1.0;
|
||||
|
||||
return so;
|
||||
}
|
||||
|
@ -333,7 +333,7 @@ FSO mainMotionFS(VSO si)
|
|||
FSO so;
|
||||
|
||||
const float3 rand = Rand(si.pos.xy);
|
||||
const float offsetScale = 0.45f + 0.05f * rand.x; // Blur 45% - 50% of frame time.
|
||||
const float offsetScale = 0.45 + 0.05 * rand.x; // Blur 45% - 50% of frame time.
|
||||
|
||||
#if _SHADER_QUALITY <= _Q_LOW
|
||||
const int sampleCount = 12;
|
||||
|
@ -345,11 +345,11 @@ FSO mainMotionFS(VSO si)
|
|||
const int sampleCount = 32;
|
||||
#endif
|
||||
|
||||
const float4 rawGBuffer1 = g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.f);
|
||||
const float4 rawGBuffer1 = g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.0);
|
||||
|
||||
const float rawOriginDepth = g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.f).r;
|
||||
const float rawOriginDepth = g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.0).r;
|
||||
const float originDepth = ToLinearDepth(rawOriginDepth, g_ubExtraBlurFS._zNearFarEx);
|
||||
const float equalize = 1.f / originDepth;
|
||||
const float equalize = 1.0 / originDepth;
|
||||
|
||||
float2 tcFrom;
|
||||
{
|
||||
|
@ -361,9 +361,9 @@ FSO mainMotionFS(VSO si)
|
|||
}
|
||||
|
||||
const float2 stride = (si.tc0 - tcFrom) * offsetScale / (sampleCount - 1);
|
||||
const float2 tcOrigin = lerp(tcFrom, si.tc0, 0.75f); // Start from this location up to offsetScale.
|
||||
const float2 tcOrigin = lerp(tcFrom, si.tc0, 0.75); // Start from this location up to offsetScale.
|
||||
|
||||
float4 acc = float4(g_tex.SampleLevel(g_sam, si.tc0, 0.f).rgb, 1); // Must have at least one sample.
|
||||
float4 acc = float4(g_tex.SampleLevel(g_sam, si.tc0, 0.0).rgb, 1); // Must have at least one sample.
|
||||
[unroll] for (int i = 0; i < sampleCount; ++i)
|
||||
{
|
||||
if (i == sampleCount / 2)
|
||||
|
@ -371,14 +371,14 @@ FSO mainMotionFS(VSO si)
|
|||
|
||||
const float2 kernelCoords = tcOrigin + stride * i;
|
||||
|
||||
const float rawKernelDepth = g_texDepth.SampleLevel(g_samDepth, kernelCoords, 0.f).r;
|
||||
const float rawKernelDepth = g_texDepth.SampleLevel(g_samDepth, kernelCoords, 0.0).r;
|
||||
const float kernelDepth = ToLinearDepth(rawKernelDepth, g_ubExtraBlurFS._zNearFarEx);
|
||||
const float kernelDeeper = kernelDepth - originDepth;
|
||||
const float allowed = saturate(1.f + kernelDeeper * equalize) * rawGBuffer1.a; // Closer points require extra care.
|
||||
const float weight = 1.f + saturate(kernelDeeper); // To fix the seam between foreground and background.
|
||||
const float allowed = saturate(1.0 + kernelDeeper * equalize) * rawGBuffer1.a; // Closer points require extra care.
|
||||
const float weight = 1.0 + saturate(kernelDeeper); // To fix the seam between foreground and background.
|
||||
|
||||
const float3 kernelColor = g_tex.SampleLevel(g_sam, kernelCoords, 0.f).rgb;
|
||||
acc += lerp(0.f, float4(kernelColor * weight, weight), allowed);
|
||||
const float3 kernelColor = g_tex.SampleLevel(g_sam, kernelCoords, 0.0).rgb;
|
||||
acc += lerp(0.0, float4(kernelColor * weight, weight), allowed);
|
||||
}
|
||||
acc /= acc.a;
|
||||
|
||||
|
|
|
@ -49,15 +49,15 @@ FSO mainFS(VSO si)
|
|||
const float noiseStrength = g_ubCinemaFS._brightness_noiseStrength.y;
|
||||
|
||||
const float3 rawFilmGrain = g_texFilmGrain.Sample(g_samFilmGrain, si.tcFilmGrain).rgb;
|
||||
const float3 filmGrain = lerp(1.f, 0.5f + rawFilmGrain.rgb, noiseStrength);
|
||||
const float3 filmGrain = lerp(1.0, 0.5 + rawFilmGrain.rgb, noiseStrength);
|
||||
|
||||
// Vignette:
|
||||
const float2 tcOffset = si.tc0 * 1.4f - 0.7f;
|
||||
const float2 tcOffset = si.tc0 * 1.4 - 0.7;
|
||||
const float lamp = saturate(dot(tcOffset, tcOffset));
|
||||
const float3 lampColor = lerp(1.f, float3(0.64f, 0.48f, 0.36f), lamp);
|
||||
const float3 lampColor = lerp(1.0, float3(0.64, 0.48, 0.36), lamp);
|
||||
|
||||
so.color.rgb = saturate(filmGrain * lampColor * brightness);
|
||||
so.color.a = saturate(dot(filmGrain, 1.f / 3.f) - 1.f);
|
||||
so.color.a = saturate(dot(filmGrain, 1.0 / 3.0) - 1.0);
|
||||
|
||||
return so;
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ VSO mainVS(VSI si)
|
|||
const float3 posUnit = mul(float3(0, 0, 1), matW33); // Need to know the scale.
|
||||
so.radius_radiusSq_invRadiusSq.y = dot(posUnit, posUnit);
|
||||
so.radius_radiusSq_invRadiusSq.x = sqrt(so.radius_radiusSq_invRadiusSq.y);
|
||||
so.radius_radiusSq_invRadiusSq.z = 1.f / so.radius_radiusSq_invRadiusSq.y;
|
||||
so.radius_radiusSq_invRadiusSq.z = 1.0 / so.radius_radiusSq_invRadiusSq.y;
|
||||
const float4 posOrigin = float4(0, 0, 0, 1);
|
||||
so.lightPosWV = mul(posOrigin, matWV).xyz;
|
||||
#endif
|
||||
|
@ -94,13 +94,13 @@ VSO mainVS(VSI si)
|
|||
#ifdef DEF_DIR
|
||||
const float3 posUnit = mul(float3(0, 0, 1), matWV33); // Assume no scale in matWV33.
|
||||
so.lightDirWV_invConeDelta = float4(posUnit, 1);
|
||||
#elif DEF_SPOT
|
||||
#elif defined(DEF_SPOT)
|
||||
so.lightDirWV_invConeDelta.xyz = normalize(mul(float3(0, 0, 1), matWV33));
|
||||
const float3 posCone = mul(float3(0, 1, 1), matW33);
|
||||
const float3 dirCone = normalize(posCone);
|
||||
const float3 dirUnit = normalize(posUnit);
|
||||
const float coneOut = dot(dirUnit, dirCone);
|
||||
const float invConeDelta = 1.f / (coneIn - coneOut);
|
||||
const float invConeDelta = 1.0 / (coneIn - coneOut);
|
||||
so.lightDirWV_invConeDelta.w = invConeDelta;
|
||||
so.color_coneOut.a = coneOut;
|
||||
#endif
|
||||
|
@ -134,7 +134,7 @@ DS_ACC_FSO mainFS(VSO si)
|
|||
// For Dir & Spot: light's direction & cone:
|
||||
#ifdef DEF_DIR
|
||||
const float3 lightDirWV = si.lightDirWV_invConeDelta.xyz;
|
||||
#elif DEF_SPOT
|
||||
#elif defined(DEF_SPOT)
|
||||
const float3 lightDirWV = si.lightDirWV_invConeDelta.xyz;
|
||||
const float invConeDelta = si.lightDirWV_invConeDelta.w;
|
||||
const float coneOut = si.color_coneOut.a;
|
||||
|
@ -144,8 +144,8 @@ DS_ACC_FSO mainFS(VSO si)
|
|||
const float depth = VK_SUBPASS_LOAD(g_texDepth, g_samDepth, tc0).r;
|
||||
const float3 posWV = DS_GetPosition(depth, g_ubPerFrame._matInvP, ndcPos.xy);
|
||||
|
||||
so.target0 = 0.f;
|
||||
so.target1 = 0.f;
|
||||
so.target0 = 0.0;
|
||||
so.target1 = 0.0;
|
||||
|
||||
#if defined(DEF_OMNI) || defined(DEF_SPOT)
|
||||
if (posWV.z <= lightPosWV.z + radius)
|
||||
|
@ -169,20 +169,20 @@ DS_ACC_FSO mainFS(VSO si)
|
|||
const float3 anisoWV = DS_GetAnisoSpec(rawGBuffer2);
|
||||
const float2 lamScaleBias = DS_GetLamScaleBias(rawGBuffer2);
|
||||
const float2 metalMask = DS_GetMetallicity(rawGBuffer2);
|
||||
const float gloss64 = rawGBuffer2.a * 64.f;
|
||||
const float gloss64 = rawGBuffer2.a * 64.0;
|
||||
|
||||
// Special:
|
||||
const float skinMask = emission.y;
|
||||
const float hairMask = metalMask.y;
|
||||
const float eyeMask = saturate(1.f - gloss64);
|
||||
const float eyeGloss = 48.f;
|
||||
const float2 lamScaleBiasWithHair = lerp(lamScaleBias, float2(1, 0.4f), hairMask);
|
||||
const float eyeMask = saturate(1.0 - gloss64);
|
||||
const float eyeGloss = 48.0;
|
||||
const float2 lamScaleBiasWithHair = lerp(lamScaleBias, float2(1, 0.4), hairMask);
|
||||
|
||||
const float gloss4K = lerp(gloss64 * gloss64, eyeGloss * eyeGloss, eyeMask);
|
||||
|
||||
#ifdef DEF_DIR
|
||||
const float3 dirToLightWV = -lightDirWV;
|
||||
const float lightFalloff = 1.f;
|
||||
const float lightFalloff = 1.0;
|
||||
#else
|
||||
const float3 toLightWV = lightPosWV - posWV;
|
||||
const float3 dirToLightWV = normalize(toLightWV);
|
||||
|
@ -192,22 +192,22 @@ DS_ACC_FSO mainFS(VSO si)
|
|||
#ifdef DEF_SPOT // Extra step for spot light:
|
||||
const float coneIntensity = ComputeSpotLightConeIntensity(dirToLightWV, lightDirWV, coneOut, invConeDelta);
|
||||
#else
|
||||
const float coneIntensity = 1.f;
|
||||
const float coneIntensity = 1.0;
|
||||
#endif
|
||||
|
||||
const float4 litRet = VerusLit(dirToLightWV, normalWV, dirToEyeWV,
|
||||
lerp(gloss4K * (2.f - lightFalloff), 12.f, hairMask),
|
||||
lerp(gloss4K * (2.0 - lightFalloff), 12.0, hairMask),
|
||||
lamScaleBiasWithHair,
|
||||
float4(anisoWV, hairMask));
|
||||
|
||||
// <Shadow>
|
||||
float shadowMask = 1.f;
|
||||
float shadowMask = 1.0;
|
||||
{
|
||||
#ifdef DEF_DIR
|
||||
const float lightPassOffset = saturate((lamScaleBiasWithHair.y - 0.5f) * 5.f) * 2.f;
|
||||
const float lightPassOffset = saturate((lamScaleBiasWithHair.y - 0.5) * 5.0) * 2.0;
|
||||
float4 shadowConfig = g_ubShadowFS._shadowConfig;
|
||||
const float lamBiasMask = saturate(lamScaleBiasWithHair.y * shadowConfig.y);
|
||||
shadowConfig.y = 1.f - lamBiasMask; // Keep penumbra blurry.
|
||||
shadowConfig.y = 1.0 - lamBiasMask; // Keep penumbra blurry.
|
||||
const float3 posForShadow = AdjustPosForShadow(posWV, normalWV, dirToLightWV, -posWV.z, lightPassOffset);
|
||||
shadowMask = ShadowMapCSM(
|
||||
g_texShadowCmp,
|
||||
|
@ -229,25 +229,25 @@ DS_ACC_FSO mainFS(VSO si)
|
|||
|
||||
const float lightFalloffWithCone = lightFalloff * coneIntensity;
|
||||
const float diffLightMask = lightFalloffWithCone * shadowMask;
|
||||
const float specLightMask = saturate(lightFalloffWithCone * 2.f) * shadowMask;
|
||||
const float specLightMask = saturate(lightFalloffWithCone * 2.0) * shadowMask;
|
||||
|
||||
// Subsurface scattering effect for front & back faces:
|
||||
const float3 frontSkinSSSColor = float3(1.6f, 1.2f, 0.3f);
|
||||
const float3 backSkinSSSColor = float3(1.6f, 0.8f, 0.5f);
|
||||
const float frontSkinSSSMask = 1.f - litRet.y;
|
||||
const float3 lightFaceColor = lightColor * lerp(1.f, frontSkinSSSColor, skinMask * frontSkinSSSMask * frontSkinSSSMask);
|
||||
const float3 frontSkinSSSColor = float3(1.6, 1.2, 0.3);
|
||||
const float3 backSkinSSSColor = float3(1.6, 0.8, 0.5);
|
||||
const float frontSkinSSSMask = 1.0 - litRet.y;
|
||||
const float3 lightFaceColor = lightColor * lerp(1.0, frontSkinSSSColor, skinMask * frontSkinSSSMask * frontSkinSSSMask);
|
||||
const float3 lightColorSSS = lerp(lightFaceColor, lightColor * backSkinSSSColor, skinMask * litRet.x);
|
||||
|
||||
const float3 metalColor = ToMetalColor(rawGBuffer0.rgb);
|
||||
const float3 specColor = saturate(lerp(1.f, metalColor, saturate(metalMask.x + (hairMask - eyeMask) * 0.4f)) + float3(-0.03f, 0.f, 0.05f) * skinMask);
|
||||
const float3 specColor = saturate(lerp(1.0, metalColor, saturate(metalMask.x + (hairMask - eyeMask) * 0.4)) + float3(-0.03, 0.0, 0.05) * skinMask);
|
||||
|
||||
const float3 maxDiff = lightColorSSS * diffLightMask;
|
||||
const float3 maxSpec = lightColorSSS * specLightMask * specColor * specMask;
|
||||
|
||||
so.target0.rgb = ToSafeHDR(maxDiff * litRet.y);
|
||||
so.target1.rgb = ToSafeHDR(maxSpec * litRet.z);
|
||||
so.target0.a = 1.f;
|
||||
so.target1.a = 1.f;
|
||||
so.target0.a = 1.0;
|
||||
so.target1.a = 1.0;
|
||||
}
|
||||
#if defined(DEF_OMNI) || defined(DEF_SPOT)
|
||||
else
|
||||
|
|
|
@ -73,10 +73,10 @@ VSO mainVS(VSI si)
|
|||
const float3 posUnit = mul(float3(0, 0, 1), matW33); // Need to know the scale.
|
||||
so.radius_radiusSq_invRadiusSq.y = dot(posUnit, posUnit);
|
||||
so.radius_radiusSq_invRadiusSq.x = sqrt(so.radius_radiusSq_invRadiusSq.y);
|
||||
so.radius_radiusSq_invRadiusSq.z = 1.f / so.radius_radiusSq_invRadiusSq.y;
|
||||
so.radius_radiusSq_invRadiusSq.z = 1.0 / so.radius_radiusSq_invRadiusSq.y;
|
||||
const float4 posOrigin = float4(0, 0, 0, 1);
|
||||
so.lightPosWV = mul(posOrigin, matWV).xyz;
|
||||
so.color_coneOut = float4(color, 1.f);
|
||||
so.color_coneOut = float4(color, 1.0);
|
||||
// </MoreAOParams>
|
||||
|
||||
return so;
|
||||
|
@ -88,7 +88,7 @@ FSO mainFS(VSO si)
|
|||
{
|
||||
FSO so;
|
||||
|
||||
so.color = 1.f;
|
||||
so.color = 1.0;
|
||||
|
||||
const float3 ndcPos = si.clipSpacePos.xyz / si.clipSpacePos.w;
|
||||
|
||||
|
@ -105,17 +105,17 @@ FSO mainFS(VSO si)
|
|||
|
||||
if (posWV.z <= lightPosWV.z + radius)
|
||||
{
|
||||
const float4 rawGBuffer1 = g_texGBuffer1.SampleLevel(g_samGBuffer1, tc0, 0.f);
|
||||
const float4 rawGBuffer1 = g_texGBuffer1.SampleLevel(g_samGBuffer1, tc0, 0.0);
|
||||
const float3 normalWV = DS_GetNormal(rawGBuffer1);
|
||||
|
||||
const float3 toLightWV = lightPosWV - posWV;
|
||||
const float3 dirToLightWV = normalize(toLightWV);
|
||||
const float distToLightSq = dot(toLightWV, toLightWV);
|
||||
const float lightFalloff = min(0.25f, ComputePointLightIntensity(distToLightSq, radiusSq, invRadiusSq));
|
||||
const float lightFalloff = min(0.25, ComputePointLightIntensity(distToLightSq, radiusSq, invRadiusSq));
|
||||
|
||||
const float nDotL = saturate(0.1f + dot(normalWV, dirToLightWV));
|
||||
const float nDotL = saturate(0.1 + dot(normalWV, dirToLightWV));
|
||||
|
||||
so.color = 1.f - nDotL * lightFalloff;
|
||||
so.color = 1.0 - nDotL * lightFalloff;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -43,18 +43,18 @@ DS_FSO mainFS(VSO si)
|
|||
{
|
||||
DS_FSO so;
|
||||
|
||||
const float4 rawGBuffer0 = g_texGBuffer0.SampleLevel(g_samGBuffer0, si.tc0, 0.f);
|
||||
const float4 rawGBuffer1 = g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.f);
|
||||
const float4 rawGBuffer2 = g_texGBuffer2.SampleLevel(g_samGBuffer2, si.tc0, 0.f);
|
||||
const float4 rawGBuffer0 = g_texGBuffer0.SampleLevel(g_samGBuffer0, si.tc0, 0.0);
|
||||
const float4 rawGBuffer1 = g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.0);
|
||||
const float4 rawGBuffer2 = g_texGBuffer2.SampleLevel(g_samGBuffer2, si.tc0, 0.0);
|
||||
|
||||
so.target0 = rawGBuffer0;
|
||||
so.target1 = rawGBuffer1;
|
||||
so.target2 = rawGBuffer2;
|
||||
|
||||
if (rawGBuffer1.a < 0.5f)
|
||||
if (rawGBuffer1.a < 0.5)
|
||||
{
|
||||
// Defringe:
|
||||
float minDist = 1000.f;
|
||||
float minDist = 1000.0;
|
||||
[unroll] for (int i = -7; i <= 7; ++i)
|
||||
{
|
||||
[unroll] for (int j = -7; j <= 7; ++j)
|
||||
|
@ -62,15 +62,15 @@ DS_FSO mainFS(VSO si)
|
|||
const float2 offset = float2(j, i);
|
||||
const float dist = dot(offset, offset);
|
||||
|
||||
const float4 rawKernel1 = g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.f, int2(j, i));
|
||||
const float4 rawKernel1 = g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.0, int2(j, i));
|
||||
const float kernelAlpha = rawKernel1.a;
|
||||
|
||||
if (kernelAlpha >= 0.5f && dist < minDist)
|
||||
if (kernelAlpha >= 0.5 && dist < minDist)
|
||||
{
|
||||
minDist = dist;
|
||||
|
||||
const float4 rawKernel0 = g_texGBuffer0.SampleLevel(g_samGBuffer0, si.tc0, 0.f, int2(j, i));
|
||||
const float4 rawKernel2 = g_texGBuffer2.SampleLevel(g_samGBuffer2, si.tc0, 0.f, int2(j, i));
|
||||
const float4 rawKernel0 = g_texGBuffer0.SampleLevel(g_samGBuffer0, si.tc0, 0.0, int2(j, i));
|
||||
const float4 rawKernel2 = g_texGBuffer2.SampleLevel(g_samGBuffer2, si.tc0, 0.0, int2(j, i));
|
||||
|
||||
so.target0 = rawKernel0;
|
||||
so.target1.rgb = rawKernel1.rgb;
|
||||
|
|
|
@ -70,14 +70,14 @@ FSO2 mainFS(VSO si)
|
|||
const float2 ndcPos = si.clipSpacePos.xy;
|
||||
|
||||
// <Sample>
|
||||
const float4 rawGBuffer0 = g_texGBuffer0.SampleLevel(g_samGBuffer0, si.tc0, 0.f);
|
||||
const float4 rawGBuffer1 = g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.f);
|
||||
const float4 rawGBuffer0 = g_texGBuffer0.SampleLevel(g_samGBuffer0, si.tc0, 0.0);
|
||||
const float4 rawGBuffer1 = g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.0);
|
||||
#ifdef DEF_AO
|
||||
const float4 rawGBuffer2 = g_texGBuffer2.SampleLevel(g_samGBuffer2, si.tc0, 0.f);
|
||||
const float4 rawGBuffer2 = g_texGBuffer2.SampleLevel(g_samGBuffer2, si.tc0, 0.0);
|
||||
#endif
|
||||
const float rawDepth = g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.f).r;
|
||||
const float4 rawAccDiff = g_texAccDiff.SampleLevel(g_samAccDiff, si.tc0, 0.f);
|
||||
const float4 rawAccSpec = g_texAccSpec.SampleLevel(g_samAccSpec, si.tc0, 0.f);
|
||||
const float rawDepth = g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.0).r;
|
||||
const float4 rawAccDiff = g_texAccDiff.SampleLevel(g_samAccDiff, si.tc0, 0.0);
|
||||
const float4 rawAccSpec = g_texAccSpec.SampleLevel(g_samAccSpec, si.tc0, 0.0);
|
||||
// </Sample>
|
||||
|
||||
// White color means 50% albedo, black is not really black:
|
||||
|
@ -88,18 +88,18 @@ FSO2 mainFS(VSO si)
|
|||
const float depth = ToLinearDepth(rawDepth, g_ubComposeFS._zNearFarEx);
|
||||
|
||||
#ifdef DEF_AO
|
||||
const float aoDiff = 0.5f + 0.5f * rawGBuffer2.r;
|
||||
const float aoDiff = 0.5 + 0.5 * rawGBuffer2.r;
|
||||
const float aoSpec = aoDiff;
|
||||
const float aoAmb = rawGBuffer2.r;
|
||||
#else
|
||||
const float aoDiff = 1.f;
|
||||
const float aoSpec = 1.f;
|
||||
const float aoAmb = 1.f;
|
||||
const float aoDiff = 1.0;
|
||||
const float aoSpec = 1.0;
|
||||
const float aoAmb = 1.0;
|
||||
#endif
|
||||
|
||||
const float3 normalW = mul(normalWV, (float3x3)g_ubComposeFS._matInvV);
|
||||
const float grayAmbient = Grayscale(ambientColor);
|
||||
const float3 finalAmbientColor = lerp(grayAmbient * 0.25f, ambientColor, normalW.y * 0.5f + 0.5f);
|
||||
const float3 finalAmbientColor = lerp(grayAmbient * 0.25, ambientColor, normalW.y * 0.5 + 0.5);
|
||||
|
||||
const float3 color = realAlbedo * (rawAccDiff.rgb * aoDiff + finalAmbientColor * aoAmb + emission.x) + rawAccSpec.rgb * aoSpec;
|
||||
|
||||
|
@ -107,17 +107,17 @@ FSO2 mainFS(VSO si)
|
|||
float3 underwaterColor;
|
||||
{
|
||||
const float diffuseMask = ToWaterDiffuseMask(posW.y);
|
||||
const float refractMask = saturate((diffuseMask - 0.5f) * 2.f);
|
||||
const float refractMask = saturate((diffuseMask - 0.5) * 2.0);
|
||||
const float3 waterDiffColorShallowAmbient = g_ubComposeFS._waterDiffColorShallow.rgb * ambientColor;
|
||||
const float3 waterDiffColorDeepAmbient = g_ubComposeFS._waterDiffColorDeep.rgb * ambientColor;
|
||||
const float deepAmbientColor = 0.5f + 0.5f * refractMask;
|
||||
const float deepAmbientColor = 0.5 + 0.5 * refractMask;
|
||||
const float3 planktonColor = lerp(
|
||||
waterDiffColorDeepAmbient * deepAmbientColor,
|
||||
waterDiffColorShallowAmbient,
|
||||
diffuseMask);
|
||||
underwaterColor = lerp(realAlbedo * planktonColor * 10.f, color, refractMask);
|
||||
underwaterColor = lerp(realAlbedo * planktonColor * 10.0, color, refractMask);
|
||||
const float fog = ComputeFog(depth, g_ubComposeFS._waterDiffColorShallow.a);
|
||||
underwaterColor = lerp(underwaterColor, planktonColor * 0.1f, fog * saturate(1.f - refractMask + g_ubComposeFS._waterDiffColorDeep.a));
|
||||
underwaterColor = lerp(underwaterColor, planktonColor * 0.1, fog * saturate(1.0 - refractMask + g_ubComposeFS._waterDiffColorDeep.a));
|
||||
}
|
||||
// </Underwater>
|
||||
|
||||
|
@ -131,11 +131,11 @@ FSO2 mainFS(VSO si)
|
|||
|
||||
so.target0.rgb = lerp(colorWithFog, realAlbedo, floor(rawDepth));
|
||||
so.target0.rgb = ToSafeHDR(so.target0.rgb);
|
||||
so.target0.a = 1.f;
|
||||
so.target0.a = 1.0;
|
||||
|
||||
// <BackgroundColor>
|
||||
const float2 normalWasSet = ceil(rawGBuffer1.rg);
|
||||
const float bg = 1.f - saturate(normalWasSet.r + normalWasSet.g);
|
||||
const float bg = 1.0 - saturate(normalWasSet.r + normalWasSet.g);
|
||||
so.target0.rgb = lerp(so.target0.rgb, g_ubComposeFS._backgroundColor.rgb, bg * g_ubComposeFS._backgroundColor.a);
|
||||
// </BackgroundColor>
|
||||
|
||||
|
@ -146,9 +146,9 @@ FSO2 mainFS(VSO si)
|
|||
const float3 posWV = mul(float4(posW, 1), g_ubComposeFS._matV);
|
||||
const float3 toPosDirWV = normalize(posWV);
|
||||
const float dp = -toPosDirWV.z;
|
||||
const float smoothSpec = pow(saturate(dp), 4096.f * lightGlossScale);
|
||||
const float spec = saturate((smoothSpec - 0.5f) * 3.f + 0.5f);
|
||||
so.target0 = max(so.target0, spec * 30000.f);
|
||||
const float smoothSpec = pow(saturate(dp), 4096.0 * lightGlossScale);
|
||||
const float spec = saturate((smoothSpec - 0.5) * 3.0 + 0.5);
|
||||
so.target0 = max(so.target0, spec * 30000.0);
|
||||
#endif
|
||||
|
||||
return so;
|
||||
|
@ -160,32 +160,32 @@ FSO mainFS(VSO si)
|
|||
FSO so;
|
||||
|
||||
// <Sample>
|
||||
const float4 rawGBuffer0 = g_texGBuffer0.SampleLevel(g_samGBuffer0, si.tc0, 0.f);
|
||||
const float4 rawGBuffer1 = g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.f);
|
||||
const float4 rawComposed = g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.f);
|
||||
const float4 rawGBuffer0 = g_texGBuffer0.SampleLevel(g_samGBuffer0, si.tc0, 0.0);
|
||||
const float4 rawGBuffer1 = g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.0);
|
||||
const float4 rawComposed = g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.0);
|
||||
#ifdef DEF_BLOOM
|
||||
const float4 rawAccDiff = g_texAccDiff.SampleLevel(g_samAccDiff, si.tc0, 0.f);
|
||||
const float4 rawAccDiff = g_texAccDiff.SampleLevel(g_samAccDiff, si.tc0, 0.0);
|
||||
#endif
|
||||
// </Sample>
|
||||
|
||||
const float gray = Grayscale(rawComposed.rgb);
|
||||
const float3 exposedComposed = Desaturate(rawComposed.rgb, saturate(1.f - gray * 0.03f)) * g_ubComposeFS._ambientColor_exposure.a;
|
||||
so.color.rgb = VerusToneMapping(exposedComposed, 0.5f);
|
||||
so.color.a = 1.f;
|
||||
const float3 exposedComposed = Desaturate(rawComposed.rgb, saturate(1.0 - gray * 0.03)) * g_ubComposeFS._ambientColor_exposure.a;
|
||||
so.color.rgb = VerusToneMapping(exposedComposed, 0.5);
|
||||
so.color.a = 1.0;
|
||||
|
||||
// SolidColor (using special value 1 for emission):
|
||||
so.color.rgb = lerp(so.color.rgb, rawGBuffer0.rgb, floor(rawGBuffer1.b));
|
||||
|
||||
#ifdef DEF_BLOOM
|
||||
const float3 bloom = rawAccDiff.rgb;
|
||||
so.color.rgb += bloom * (1.f - so.color.rgb);
|
||||
so.color.rgb += bloom * (1.0 - so.color.rgb);
|
||||
#endif
|
||||
|
||||
if (false)
|
||||
{
|
||||
const float gray = dot(rawComposed.rgb, 1.f / 3.f);
|
||||
so.color.r = saturate((gray - 5000.f) * 0.001f);
|
||||
so.color.gb *= 0.5f;
|
||||
const float gray = dot(rawComposed.rgb, 1.0 / 3.0);
|
||||
so.color.r = saturate((gray - 5000.0) * 0.001);
|
||||
so.color.gb *= 0.5;
|
||||
}
|
||||
|
||||
return so;
|
||||
|
|
|
@ -34,31 +34,31 @@ VSO mainVS(VSI si)
|
|||
{
|
||||
VSO so;
|
||||
|
||||
const float pointSpriteSize = si.tc0.x * (1.f / 500.f);
|
||||
const float angle = si.tc0.y * (1.f / 32767.f);
|
||||
const float pointSpriteSize = si.tc0.x * (1.0 / 500.0);
|
||||
const float angle = si.tc0.y * (1.0 / 32767.0);
|
||||
|
||||
const float3 toEye = g_ubForestVS._eyePos.xyz - si.pos.xyz;
|
||||
const float distToScreen = length(g_ubForestVS._eyePosScreen.xyz - si.pos.xyz);
|
||||
|
||||
const float nearAlpha = saturate((distToScreen - 60.f) * (1.f / 30.f)); // From 60m to 90m.
|
||||
const float farAlpha = 1.f - saturate((distToScreen - 900.f) * (1.f / 100.f)); // From 900m to 1000m.
|
||||
const float nearAlpha = saturate((distToScreen - 60.0) * (1.0 / 30.0)); // From 60m to 90m.
|
||||
const float farAlpha = 1.0 - saturate((distToScreen - 900.0) * (1.0 / 100.0)); // From 900m to 1000m.
|
||||
|
||||
so.pos = mul(si.pos, g_ubForestVS._matWVP);
|
||||
so.tc0 = 0.f;
|
||||
so.color.rgb = RandomColor(si.pos.xz, 0.3f, 0.2f);
|
||||
so.tc0 = 0.0;
|
||||
so.color.rgb = RandomColor(si.pos.xz, 0.3, 0.2);
|
||||
so.color.a = nearAlpha * farAlpha;
|
||||
so.psize.xy = pointSpriteSize * (g_ubForestVS._viewportSize.yx * g_ubForestVS._viewportSize.z) * g_ubForestVS._matP._m11;
|
||||
so.psize.xy *= ceil(so.color.a); // Hide if too close.
|
||||
so.psize.z = saturate(pointSpriteSize * 0.25f - 0.5f);
|
||||
so.psize.z = saturate(pointSpriteSize * 0.25 - 0.5);
|
||||
|
||||
float2 param0 = toEye.xy;
|
||||
float2 param1 = toEye.zz;
|
||||
param0.y = max(0.f, param0.y); // Only upper hemisphere.
|
||||
param0.y = max(0.0, param0.y); // Only upper hemisphere.
|
||||
param1.y = length(toEye.xz); // Distance in XZ-plane.
|
||||
so.angles.xy = (atan2(param0, param1) + _PI) * (0.5f / _PI); // atan2(x, z) and atan2(max(0.f, y), length(toEye.xz)). From 0 to 1.
|
||||
so.angles.y = (so.angles.y - 0.5f) * 4.f; // Choose this quadrant.
|
||||
so.angles.xy = (atan2(param0, param1) + _PI) * (0.5 / _PI); // atan2(x, z) and atan2(max(0.0, y), length(toEye.xz)). From 0 to 1.
|
||||
so.angles.y = (so.angles.y - 0.5) * 4.0; // Choose this quadrant.
|
||||
so.angles.xy = saturate(so.angles.xy);
|
||||
so.angles.x = frac(so.angles.x - angle + 0.5f); // Turn.
|
||||
so.angles.x = frac(so.angles.x - angle + 0.5); // Turn.
|
||||
|
||||
return so;
|
||||
}
|
||||
|
@ -83,21 +83,21 @@ void mainGS(point VSO si[1], inout TriangleStream<VSO> stream)
|
|||
|
||||
float2 ComputeTexCoords(float2 tc, float2 angles)
|
||||
{
|
||||
const float marginBias = 16.f / 512.f;
|
||||
const float marginScale = 1.f - marginBias * 2.f;
|
||||
const float marginBias = 16.0 / 512.0;
|
||||
const float marginScale = 1.0 - marginBias * 2.0;
|
||||
const float2 tcMargin = tc * marginScale + marginBias;
|
||||
|
||||
const float2 frameCount = float2(16, 16);
|
||||
const float2 frameScale = 1.f / frameCount;
|
||||
const float2 frameBias = floor(min(angles * frameCount + 0.5f, float2(256, frameCount.y - 0.5f)));
|
||||
const float2 frameScale = 1.0 / frameCount;
|
||||
const float2 frameBias = floor(min(angles * frameCount + 0.5, float2(256, frameCount.y - 0.5)));
|
||||
return (tcMargin + frameBias) * frameScale;
|
||||
}
|
||||
|
||||
float ComputeMask(float2 tc, float alpha)
|
||||
{
|
||||
const float2 tcCenter = tc - 0.5f;
|
||||
const float rad = saturate(dot(tcCenter, tcCenter) * 4.f);
|
||||
return saturate(rad + (alpha * 2.f - 1.f));
|
||||
const float2 tcCenter = tc - 0.5;
|
||||
const float rad = saturate(dot(tcCenter, tcCenter) * 4.0);
|
||||
return saturate(rad + (alpha * 2.0 - 1.0));
|
||||
}
|
||||
|
||||
#ifdef _FS
|
||||
|
@ -109,7 +109,7 @@ void mainFS(VSO si)
|
|||
|
||||
const float alpha = g_texGBuffer1.Sample(g_samGBuffer1, tc).a;
|
||||
|
||||
clip(alpha * mask - 0.53f);
|
||||
clip(alpha * mask - 0.53);
|
||||
}
|
||||
#else
|
||||
DS_FSO mainFS(VSO si)
|
||||
|
@ -128,10 +128,10 @@ DS_FSO mainFS(VSO si)
|
|||
so.target2 = rawGBuffer2;
|
||||
|
||||
so.target0.rgb *= si.color.rgb;
|
||||
const float lamBiasRatio = 1.f - ComputeMask(si.tc0, 0.5f);
|
||||
so.target2.g = lerp(so.target2.g, 0.25f, lamBiasRatio * lamBiasRatio * si.psize.z);
|
||||
const float lamBiasRatio = 1.0 - ComputeMask(si.tc0, 0.5);
|
||||
so.target2.g = lerp(so.target2.g, 0.25, lamBiasRatio * lamBiasRatio * si.psize.z);
|
||||
|
||||
clip(rawGBuffer1.a * mask - 0.53f);
|
||||
clip(rawGBuffer1.a * mask - 0.53);
|
||||
|
||||
return so;
|
||||
}
|
||||
|
|
|
@ -57,43 +57,43 @@ VSO mainVS(VSI si)
|
|||
float3 inPos;
|
||||
float3 pos;
|
||||
float2 center;
|
||||
float2 pointSpriteSize = 1.f;
|
||||
float2 pointSpriteSize = 1.0;
|
||||
float groundHeight;
|
||||
float3 normal;
|
||||
float2 tc0;
|
||||
bool bushMaskOK = true;
|
||||
{
|
||||
inPos = si.pos.xyz * (1.f / 1000.f);
|
||||
inPos = si.pos.xyz * (1.0 / 1000.0);
|
||||
pos = inPos + float3(si.patchPos.x, 0, si.patchPos.z);
|
||||
center = si.tc.zw * (1.f / 1000.f) + si.patchPos.xz;
|
||||
center = si.tc.zw * (1.0 / 1000.0) + si.patchPos.xz;
|
||||
#ifdef DEF_BILLBOARDS
|
||||
pointSpriteSize = inPos.y;
|
||||
pos = float3(center.x, 0.45f * pointSpriteSize.y, center.y);
|
||||
pos = float3(center.x, 0.45 * pointSpriteSize.y, center.y);
|
||||
#endif
|
||||
|
||||
const float distToEye = distance(pos + float3(0, si.patchPos.y * 0.01f, 0), g_ubGrassVS._posEye.xyz);
|
||||
const float geomipsLod = log2(clamp(distToEye * (2.f / 100.f), 1.f, 18.f));
|
||||
const float texelCenter = 0.5f * mapSideInv;
|
||||
const float distToEye = distance(pos + float3(0, si.patchPos.y * 0.01, 0), g_ubGrassVS._posEye.xyz);
|
||||
const float geomipsLod = log2(clamp(distToEye * (2.0 / 100.0), 1.0, 18.0));
|
||||
const float texelCenter = 0.5 * mapSideInv;
|
||||
const float mipTexelCenter = texelCenter * exp2(geomipsLod);
|
||||
const float2 tcMap = pos.xz * mapSideInv + 0.5f;
|
||||
const float2 tcUniform = center * mapSideInv + 0.5f;
|
||||
const float2 tcMap = pos.xz * mapSideInv + 0.5;
|
||||
const float2 tcUniform = center * mapSideInv + 0.5;
|
||||
groundHeight = UnpackTerrainHeight(g_texHeightVS.SampleLevel(g_samHeightVS, tcMap + mipTexelCenter, geomipsLod).r);
|
||||
pos.y += groundHeight;
|
||||
|
||||
const float4 rawNormal = g_texNormalVS.SampleLevel(g_samNormalVS, tcUniform + texelCenter, 0.f);
|
||||
normal = float3(rawNormal.x, 0, rawNormal.y) * 2.f - 1.f;
|
||||
const float4 rawNormal = g_texNormalVS.SampleLevel(g_samNormalVS, tcUniform + texelCenter, 0.0);
|
||||
normal = float3(rawNormal.x, 0, rawNormal.y) * 2.0 - 1.0;
|
||||
normal.y = ComputeNormalZ(normal.xz);
|
||||
|
||||
const float layer = g_texMLayerVS.SampleLevel(g_samMLayerVS, tcUniform, 0.f).r * 4.f;
|
||||
const float uShift = frac(layer) - (16.f / 256.f);
|
||||
const float vShift = floor(layer) * 0.25f;
|
||||
float vShiftAlt = 0.f;
|
||||
const float layer = g_texMLayerVS.SampleLevel(g_samMLayerVS, tcUniform, 0.0).r * 4.0;
|
||||
const float uShift = frac(layer) - (16.0 / 256.0);
|
||||
const float vShift = floor(layer) * 0.25;
|
||||
float vShiftAlt = 0.0;
|
||||
if (!(bushID & 0xF))
|
||||
vShiftAlt = 0.5f; // Every 16th bush uses alternative texture.
|
||||
tc0 = si.tc.xy * (1.f / 100.f) + float2(uShift, vShift + vShiftAlt);
|
||||
vShiftAlt = 0.5; // Every 16th bush uses alternative texture.
|
||||
tc0 = si.tc.xy * (1.0 / 100.0) + float2(uShift, vShift + vShiftAlt);
|
||||
|
||||
// Cull blank bushes:
|
||||
const int mainLayer = round(layer * 4.f);
|
||||
const int mainLayer = round(layer * 4.0);
|
||||
const int ibushMask = asint(bushMask);
|
||||
if (!((ibushMask >> mainLayer) & 0x1))
|
||||
{
|
||||
|
@ -103,20 +103,20 @@ VSO mainVS(VSI si)
|
|||
// </FromTextures>
|
||||
|
||||
// <Special>
|
||||
float phaseShift = 0.f;
|
||||
float2 windWarp = 0.f;
|
||||
float top = 0.f;
|
||||
float phaseShift = 0.0;
|
||||
float2 windWarp = 0.0;
|
||||
float top = 0.0;
|
||||
{
|
||||
#ifdef DEF_BILLBOARDS
|
||||
phaseShift = frac(si.pos.w * (1.f / 100.f));
|
||||
windWarp = 0.f;
|
||||
top = 0.28f;
|
||||
phaseShift = frac(si.pos.w * (1.0 / 100.0));
|
||||
windWarp = 0.0;
|
||||
top = 0.28;
|
||||
#else
|
||||
if (inPos.y >= 0.1f)
|
||||
if (inPos.y >= 0.1)
|
||||
{
|
||||
phaseShift = frac(si.pos.w * (1.f / 100.f));
|
||||
windWarp = warp.xz * (1.f + turbulence * sin((phase + phaseShift) * (_PI * 2.f)));
|
||||
top = 1.f;
|
||||
phaseShift = frac(si.pos.w * (1.0 / 100.0));
|
||||
windWarp = warp.xz * (1.0 + turbulence * sin((phase + phaseShift) * (_PI * 2.0)));
|
||||
top = 1.0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -126,17 +126,17 @@ VSO mainVS(VSI si)
|
|||
float3 posWarped = pos;
|
||||
{
|
||||
const float distToEye = -mul(float4(posWarped, 1), g_ubGrassVS._matWV).z;
|
||||
const float distant = saturate((distToEye - 50.f) * (1.f / 50.f)); // [50 to 100] -> [0 to 1].
|
||||
const float distExt = saturate((distToEye - 25.f) * (1.f / 25.f)); // [25 to 50] -> [0 to 1].
|
||||
const float distant = saturate((distToEye - 50.0) * (1.0 / 50.0)); // [50 to 100] -> [0 to 1].
|
||||
const float distExt = saturate((distToEye - 25.0) * (1.0 / 25.0)); // [25 to 50] -> [0 to 1].
|
||||
|
||||
const float cliff = dot(normal.xz, normal.xz);
|
||||
float hide = cliff + step(groundHeight, 1.f) + distant;
|
||||
float hide = cliff + step(groundHeight, 1.0) + distant;
|
||||
if (!bushMaskOK)
|
||||
hide = 1.f;
|
||||
hide = 1.0;
|
||||
posWarped.xz -= normal.xz;
|
||||
#ifdef DEF_BILLBOARDS
|
||||
const float distExtInv = 1.f - distExt;
|
||||
posWarped.xz += windWarp * 0.5f;
|
||||
const float distExtInv = 1.0 - distExt;
|
||||
posWarped.xz += windWarp * 0.5;
|
||||
hide += distExtInv * distExtInv;
|
||||
#else
|
||||
posWarped.xz += windWarp;
|
||||
|
@ -146,7 +146,7 @@ VSO mainVS(VSI si)
|
|||
hide = saturate(hide);
|
||||
|
||||
#ifdef DEF_BILLBOARDS
|
||||
pointSpriteSize = lerp(pointSpriteSize, float2(0.f, pointSpriteSize.y), hide);
|
||||
pointSpriteSize = lerp(pointSpriteSize, float2(0.0, pointSpriteSize.y), hide);
|
||||
#else
|
||||
posWarped = lerp(posWarped, float3(center.x, posWarped.y, center.y), hide); // Optimize by morphing to center point.
|
||||
#endif
|
||||
|
@ -159,13 +159,13 @@ VSO mainVS(VSI si)
|
|||
so.tcOffset_phaseShift = float3(0, 0, phaseShift);
|
||||
so.normal_top.xyz = mul(normal, (float3x3)g_ubGrassVS._matWV);
|
||||
so.normal_top.w = top;
|
||||
so.psize = 1.f;
|
||||
so.psize = 1.0;
|
||||
|
||||
#ifdef DEF_BILLBOARDS
|
||||
so.tcOffset_phaseShift.xy = tc0;
|
||||
so.psize = pointSpriteSize * (g_ubGrassVS._viewportSize.yx * g_ubGrassVS._viewportSize.z) * g_ubGrassVS._matP._m11;
|
||||
#else
|
||||
so.normal_top.xyz += float3(0, 0, top * top * 0.25f);
|
||||
so.normal_top.xyz += float3(0, 0, top * top * 0.25);
|
||||
#endif
|
||||
|
||||
return so;
|
||||
|
@ -196,17 +196,17 @@ DS_FSO mainFS(VSO si)
|
|||
|
||||
float2 tc = si.tc0;
|
||||
#ifdef DEF_BILLBOARDS
|
||||
tc = si.tc0 * 0.23f + si.tcOffset_phaseShift.xy;
|
||||
tc = si.tc0 * 0.23 + si.tcOffset_phaseShift.xy;
|
||||
#endif
|
||||
|
||||
const float4 rawAlbedo = g_texAlbedo.Sample(g_samAlbedo, tc);
|
||||
const float3 normal = normalize(si.normal_top.xyz);
|
||||
const float gray = Grayscale(rawAlbedo.rgb);
|
||||
const float mask = saturate((gray - 0.25f) * 2.f + 0.2f);
|
||||
const float mask = saturate((gray - 0.25) * 2.0 + 0.2);
|
||||
|
||||
const float top = si.normal_top.w;
|
||||
const float specMask = saturate(top * top * (mask + si.tcOffset_phaseShift.z * 0.1f));
|
||||
const float gloss = lerp(4.f, 12.f, specMask);
|
||||
const float specMask = saturate(top * top * (mask + si.tcOffset_phaseShift.z * 0.1));
|
||||
const float gloss = lerp(4.0, 12.0, specMask);
|
||||
|
||||
{
|
||||
DS_Reset(so);
|
||||
|
@ -215,15 +215,15 @@ DS_FSO mainFS(VSO si)
|
|||
DS_SetSpecMask(so, specMask);
|
||||
|
||||
DS_SetNormal(so, normal);
|
||||
DS_SetEmission(so, 0.f, 0.f);
|
||||
DS_SetMotionBlurMask(so, 1.f);
|
||||
DS_SetEmission(so, 0.0, 0.0);
|
||||
DS_SetMotionBlurMask(so, 1.0);
|
||||
|
||||
DS_SetLamScaleBias(so, float2(1.2f, -0.2f), 0.f);
|
||||
DS_SetMetallicity(so, 0.05f, 0.f);
|
||||
DS_SetLamScaleBias(so, float2(1.2, -0.2), 0.0);
|
||||
DS_SetMetallicity(so, 0.05, 0.0);
|
||||
DS_SetGloss(so, gloss);
|
||||
}
|
||||
|
||||
clip(rawAlbedo.a - 0.5f);
|
||||
clip(rawAlbedo.a - 0.5);
|
||||
|
||||
return so;
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ VSO mainVS(VSI si)
|
|||
const float3 inTan = si.tan.xyz;
|
||||
const float3 inBin = si.bin.xyz;
|
||||
|
||||
float addLamBias = 0.f;
|
||||
float addLamBias = 0.0;
|
||||
#if defined(DEF_SKINNED) || defined(DEF_ROBOTIC)
|
||||
const float4 warpMask = float4(
|
||||
1,
|
||||
|
@ -95,14 +95,14 @@ VSO mainVS(VSI si)
|
|||
#elif defined(DEF_PLANT)
|
||||
{
|
||||
const float3 normPos = NormalizePosition(si.pos.xyz);
|
||||
const float weightY = saturate(normPos.y * normPos.y - 0.01f);
|
||||
const float3 offsetXYZ = normPos - float3(0.5f, 0.8f, 0.5f);
|
||||
const float weightXZ = saturate((dot(offsetXYZ.xz, offsetXYZ.xz) - 0.01f) * 0.4f);
|
||||
const float weightY = saturate(normPos.y * normPos.y - 0.01);
|
||||
const float3 offsetXYZ = normPos - float3(0.5, 0.8, 0.5);
|
||||
const float weightXZ = saturate((dot(offsetXYZ.xz, offsetXYZ.xz) - 0.01) * 0.4);
|
||||
|
||||
const float phaseShiftY = frac(userColor.x + userColor.z);
|
||||
const float phaseShiftXZ = frac(phaseShiftY + inPos.x + inPos.z);
|
||||
const float2 bending = (float2(0.7f, 0.5f) + float2(0.3f, 0.5f) *
|
||||
sin((g_ubPerObject._userColor.rg + float2(phaseShiftY, phaseShiftXZ)) * (_PI * 2.f))) * float2(weightY, weightXZ);
|
||||
const float2 bending = (float2(0.7, 0.5) + float2(0.3, 0.5) *
|
||||
sin((g_ubPerObject._userColor.rg + float2(phaseShiftY, phaseShiftXZ)) * (_PI * 2.0))) * float2(weightY, weightXZ);
|
||||
|
||||
const float3x3 matW33 = (float3x3)matW;
|
||||
const float3x3 matBending = (float3x3)g_ubPerObject._matW;
|
||||
|
@ -121,7 +121,7 @@ VSO mainVS(VSI si)
|
|||
lerp(matW33[2], matNewW33[2], userColor.a),
|
||||
matW[3]);
|
||||
|
||||
const float weight = 1.f - saturate(dot(offsetXYZ, offsetXYZ));
|
||||
const float weight = 1.0 - saturate(dot(offsetXYZ, offsetXYZ));
|
||||
addLamBias = (-(weight * weight * weight)) * saturate(userColor.a);
|
||||
}
|
||||
const float3 pos = inPos;
|
||||
|
@ -137,13 +137,13 @@ VSO mainVS(VSI si)
|
|||
float3 binWV;
|
||||
{
|
||||
#ifdef DEF_SKINNED
|
||||
const float4 weights = si.bw * (1.f / 255.f);
|
||||
const float4 weights = si.bw * (1.0 / 255.0);
|
||||
const float4 indices = si.bi;
|
||||
|
||||
float3 posSkinned = 0.f;
|
||||
float3 nrmSkinned = 0.f;
|
||||
float3 tanSkinned = 0.f;
|
||||
float3 binSkinned = 0.f;
|
||||
float3 posSkinned = 0.0;
|
||||
float3 nrmSkinned = 0.0;
|
||||
float3 tanSkinned = 0.0;
|
||||
float3 binSkinned = 0.0;
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
|
@ -158,7 +158,7 @@ VSO mainVS(VSI si)
|
|||
nrmWV = mul(nrmSkinned, (float3x3)matWV);
|
||||
tanWV = mul(tanSkinned, (float3x3)matWV);
|
||||
binWV = mul(binSkinned, (float3x3)matWV);
|
||||
#elif DEF_ROBOTIC
|
||||
#elif defined(DEF_ROBOTIC)
|
||||
const int index = si.pos.w;
|
||||
|
||||
const mataff matBone = g_ubSkeletonVS._vMatBones[index];
|
||||
|
@ -190,7 +190,7 @@ VSO mainVS(VSI si)
|
|||
#if !defined(DEF_DEPTH)
|
||||
so.color0 = userColor;
|
||||
#ifdef DEF_PLANT
|
||||
so.color0.rgb = RandomColor(userColor.xz, 0.3f, 0.2f);
|
||||
so.color0.rgb = RandomColor(userColor.xz, 0.3, 0.2);
|
||||
so.color0.a = addLamBias;
|
||||
#endif
|
||||
#if !defined(DEF_DEPTH) && !defined(DEF_SOLID_COLOR)
|
||||
|
@ -214,7 +214,7 @@ PCFO PatchConstFunc(const OutputPatch<HSO, 3> outputPatch)
|
|||
}
|
||||
|
||||
[domain("tri")]
|
||||
[maxtessfactor(7.f)]
|
||||
[maxtessfactor(7.0)]
|
||||
[outputcontrolpoints(3)]
|
||||
[outputtopology("triangle_cw")]
|
||||
[partitioning(_PARTITION_METHOD)]
|
||||
|
@ -251,7 +251,7 @@ VSO mainDS(_IN_DS)
|
|||
|
||||
const float3 toEyeWV = g_ubPerFrame._eyePosWV_invTessDistSq.xyz - flatPosWV;
|
||||
const float distToEyeSq = dot(toEyeWV, toEyeWV);
|
||||
const float tessStrength = 1.f - saturate(distToEyeSq * g_ubPerFrame._eyePosWV_invTessDistSq.w * 1.1f - 0.1f);
|
||||
const float tessStrength = 1.0 - saturate(distToEyeSq * g_ubPerFrame._eyePosWV_invTessDistSq.w * 1.1 - 0.1);
|
||||
const float3 posWV = lerp(flatPosWV, smoothPosWV, tessStrength);
|
||||
so.pos = ApplyProjection(posWV, g_ubPerFrame._matP);
|
||||
_DS_COPY(tc0);
|
||||
|
@ -273,7 +273,7 @@ VSO mainDS(_IN_DS)
|
|||
void mainFS(VSO si)
|
||||
{
|
||||
const float rawAlbedo = g_texAlbedo.Sample(g_samAlbedo, si.tc0).a;
|
||||
clip(rawAlbedo - 1.f / 16.f);
|
||||
clip(rawAlbedo - 1.0 / 16.0);
|
||||
}
|
||||
#else
|
||||
DS_FSO mainFS(VSO si)
|
||||
|
@ -330,13 +330,13 @@ DS_FSO mainFS(VSO si)
|
|||
|
||||
// <Pick>
|
||||
const float2 alpha_spec = AlphaSwitch(rawAlbedo, tc0, mm_alphaSwitch);
|
||||
const float emitAlpha = PickAlpha(rawAlbedo.rgb, mm_emissionPick, 16.f);
|
||||
const float emitAlpha = PickAlpha(rawAlbedo.rgb, mm_emissionPick, 16.0);
|
||||
const float eyeAlpha = PickAlphaRound(mm_eyePick, tc0);
|
||||
const float glossAlpha = PickAlpha(rawAlbedo.rgb, mm_glossPick, 32.f);
|
||||
const float hairAlpha = round(PickAlpha(rawAlbedo.rgb, mm_hairPick, 16.f));
|
||||
const float metalAlpha = PickAlpha(rawAlbedo.rgb, mm_metalPick, 16.f);
|
||||
const float skinAlpha = PickAlpha(rawAlbedo.rgb, mm_skinPick, 16.f);
|
||||
const float userAlpha = PickAlpha(rawAlbedo.rgb, mm_userPick, 16.f);
|
||||
const float glossAlpha = PickAlpha(rawAlbedo.rgb, mm_glossPick, 32.0);
|
||||
const float hairAlpha = round(PickAlpha(rawAlbedo.rgb, mm_hairPick, 16.0));
|
||||
const float metalAlpha = PickAlpha(rawAlbedo.rgb, mm_metalPick, 16.0);
|
||||
const float skinAlpha = PickAlpha(rawAlbedo.rgb, mm_skinPick, 16.0);
|
||||
const float userAlpha = PickAlpha(rawAlbedo.rgb, mm_userPick, 16.0);
|
||||
// </Pick>
|
||||
|
||||
#ifdef DEF_PLANT
|
||||
|
@ -348,10 +348,10 @@ DS_FSO mainFS(VSO si)
|
|||
const float specMask = saturate(alpha_spec.y * mm_specScaleBias.x + mm_specScaleBias.y);
|
||||
|
||||
// <Gloss>
|
||||
float gloss = lerp(4.f, 16.f, alpha_spec.y) * mm_glossScaleBias.x + mm_glossScaleBias.y;
|
||||
float gloss = lerp(4.0, 16.0, alpha_spec.y) * mm_glossScaleBias.x + mm_glossScaleBias.y;
|
||||
gloss = lerp(gloss, mm_gloss, glossAlpha);
|
||||
gloss = lerp(gloss, 4.f + alpha_spec.y, skinAlpha);
|
||||
gloss = lerp(gloss, 0.f, eyeAlpha);
|
||||
gloss = lerp(gloss, 4.0 + alpha_spec.y, skinAlpha);
|
||||
gloss = lerp(gloss, 0.0, eyeAlpha);
|
||||
// </Gloss>
|
||||
|
||||
// <Normal>
|
||||
|
@ -375,7 +375,7 @@ DS_FSO mainFS(VSO si)
|
|||
// <Detail>
|
||||
{
|
||||
const float3 rawDetail = g_texDetail.Sample(g_samDetail, tc0 * mm_detailScale).rgb;
|
||||
rawAlbedo.rgb = rawAlbedo.rgb * lerp(0.5f, rawDetail, mm_detail) * 2.f;
|
||||
rawAlbedo.rgb = rawAlbedo.rgb * lerp(0.5, rawDetail, mm_detail) * 2.0;
|
||||
}
|
||||
// </Detail>
|
||||
|
||||
|
@ -383,14 +383,14 @@ DS_FSO mainFS(VSO si)
|
|||
float strass;
|
||||
{
|
||||
const float rawStrass = g_texStrass.Sample(g_samStrass, tc0 * mm_strassScale).r;
|
||||
strass = saturate(rawStrass * (0.6f + 1.4f * alpha_spec.y));
|
||||
strass = saturate(rawStrass * (0.6 + 1.4 * alpha_spec.y));
|
||||
}
|
||||
// </Strass>
|
||||
|
||||
// <LambertianScaleBias>
|
||||
float2 lamScaleBias = mm_lamScaleBias + float2(0, lightPassStrength * 8.f * mm_lightPass);
|
||||
lamScaleBias += float2(-0.1f, -0.3f) * alpha_spec.y + float2(0.1f, 0.2f); // We bring the noise!
|
||||
lamScaleBias = lerp(lamScaleBias, float2(1, 0.45f), skinAlpha);
|
||||
float2 lamScaleBias = mm_lamScaleBias + float2(0, lightPassStrength * 8.0 * mm_lightPass);
|
||||
lamScaleBias += float2(-0.1, -0.3) * alpha_spec.y + float2(0.1, 0.2); // We bring the noise!
|
||||
lamScaleBias = lerp(lamScaleBias, float2(1, 0.45), skinAlpha);
|
||||
#ifdef DEF_PLANT
|
||||
lamScaleBias.y += si.color0.a;
|
||||
#endif
|
||||
|
@ -398,17 +398,17 @@ DS_FSO mainFS(VSO si)
|
|||
|
||||
// <RimAlbedo>
|
||||
{
|
||||
const float3 newColor = saturate((rawAlbedo.rgb + gray) * 0.6f);
|
||||
const float mask = 1.f - abs(normalWV.z);
|
||||
rawAlbedo.rgb = lerp(rawAlbedo.rgb, newColor, mask * mask * (1.f - alpha_spec.y));
|
||||
const float3 newColor = saturate((rawAlbedo.rgb + gray) * 0.6);
|
||||
const float mask = 1.0 - abs(normalWV.z);
|
||||
rawAlbedo.rgb = lerp(rawAlbedo.rgb, newColor, mask * mask * (1.0 - alpha_spec.y));
|
||||
}
|
||||
// </RimAlbedo>
|
||||
|
||||
// <SpecFresnel>
|
||||
float specMaskWithFresnel;
|
||||
{
|
||||
const float fresnelMask = pow(saturate(1.f - normalWV.z), 5.f);
|
||||
const float maxSpecAdd = (1.f - specMask) * lerp(0.04f + 0.2f * specMask, 0.6f, metalAlpha);
|
||||
const float fresnelMask = pow(saturate(1.0 - normalWV.z), 5.0);
|
||||
const float maxSpecAdd = (1.0 - specMask) * lerp(0.04 + 0.2 * specMask, 0.6, metalAlpha);
|
||||
specMaskWithFresnel = FresnelSchlick(specMask, maxSpecAdd, fresnelMask);
|
||||
}
|
||||
// </SpecFresnel>
|
||||
|
@ -417,7 +417,7 @@ DS_FSO mainFS(VSO si)
|
|||
DS_Reset(so);
|
||||
|
||||
DS_SetAlbedo(so, lerp(rawAlbedo.rgb, hairAlbedo, hairAlpha));
|
||||
DS_SetSpecMask(so, lerp(max(strass, specMaskWithFresnel), 0.15f, eyeAlpha));
|
||||
DS_SetSpecMask(so, lerp(max(strass, specMaskWithFresnel), 0.15, eyeAlpha));
|
||||
|
||||
DS_SetNormal(so, normalWV + NormalDither(rand));
|
||||
DS_SetEmission(so, emitAlpha * mm_emission, skinAlpha);
|
||||
|
@ -425,10 +425,10 @@ DS_FSO mainFS(VSO si)
|
|||
|
||||
DS_SetLamScaleBias(so, lamScaleBias, float4(anisoWV, hairAlpha));
|
||||
DS_SetMetallicity(so, metalAlpha, hairAlpha);
|
||||
DS_SetGloss(so, gloss * lerp(toksvigFactor, 1.f, eyeAlpha));
|
||||
DS_SetGloss(so, gloss * lerp(toksvigFactor, 1.0, eyeAlpha));
|
||||
}
|
||||
|
||||
clip(alpha_spec.x - 0.5f);
|
||||
clip(alpha_spec.x - 0.5);
|
||||
#endif
|
||||
|
||||
return so;
|
||||
|
@ -438,27 +438,27 @@ DS_FSO mainFS(VSO si)
|
|||
|
||||
//@main:#
|
||||
//@main:#Instanced INSTANCED
|
||||
//@main:#Plant PLANT INSTANCED
|
||||
//@main:#Robotic ROBOTIC
|
||||
//@main:#Skinned SKINNED
|
||||
//@main:#Plant PLANT INSTANCED
|
||||
|
||||
//@main:#Tess TESS (VHDF)
|
||||
//@main:#TessInstanced TESS INSTANCED (VHDF)
|
||||
//@main:#TessPlant TESS PLANT INSTANCED (VHDF)
|
||||
//@main:#TessRobotic TESS ROBOTIC (VHDF)
|
||||
//@main:#TessSkinned TESS SKINNED (VHDF)
|
||||
//@main:#TessPlant TESS PLANT INSTANCED (VHDF)
|
||||
|
||||
//@main:#Depth DEPTH
|
||||
//@main:#DepthInstanced DEPTH INSTANCED
|
||||
//@main:#DepthPlant DEPTH PLANT INSTANCED
|
||||
//@main:#DepthRobotic DEPTH ROBOTIC
|
||||
//@main:#DepthSkinned DEPTH SKINNED
|
||||
//@main:#DepthPlant DEPTH PLANT INSTANCED
|
||||
|
||||
//@main:#DepthTess DEPTH TESS (VHDF)
|
||||
//@main:#DepthTessInstanced DEPTH TESS INSTANCED (VHDF)
|
||||
//@main:#DepthTessPlant DEPTH TESS PLANT INSTANCED (VHDF)
|
||||
//@main:#DepthTessRobotic DEPTH TESS ROBOTIC (VHDF)
|
||||
//@main:#DepthTessSkinned DEPTH TESS SKINNED (VHDF)
|
||||
//@main:#DepthTessPlant DEPTH TESS PLANT INSTANCED (VHDF)
|
||||
|
||||
//@main:#SolidColor SOLID_COLOR
|
||||
//@main:#SolidColorInstanced SOLID_COLOR INSTANCED
|
||||
|
|
|
@ -48,15 +48,15 @@ FSO mainFS(VSO si)
|
|||
{
|
||||
FSO so;
|
||||
|
||||
const float4 rawGBuffer0 = g_texGBuffer0.SampleLevel(g_samGBuffer0, si.tc0, 0.f);
|
||||
const float4 rawGBuffer2 = g_texGBuffer2.SampleLevel(g_samGBuffer2, si.tc0, 0.f);
|
||||
const float4 rawReflect = g_texReflect.SampleLevel(g_samReflect, si.tc0, 0.f);
|
||||
const float4 rawGBuffer0 = g_texGBuffer0.SampleLevel(g_samGBuffer0, si.tc0, 0.0);
|
||||
const float4 rawGBuffer2 = g_texGBuffer2.SampleLevel(g_samGBuffer2, si.tc0, 0.0);
|
||||
const float4 rawReflect = g_texReflect.SampleLevel(g_samReflect, si.tc0, 0.0);
|
||||
|
||||
const float specMask = rawGBuffer0.a;
|
||||
const float3 metalColor = ToMetalColor(rawGBuffer0.rgb);
|
||||
const float2 metalMask = DS_GetMetallicity(rawGBuffer2);
|
||||
so.color.rgb = rawReflect.rgb * lerp(1.f, metalColor, metalMask.x) * specMask;
|
||||
so.color.a = 1.f;
|
||||
so.color.rgb = rawReflect.rgb * lerp(1.0, metalColor, metalMask.x) * specMask;
|
||||
so.color.a = 1.0;
|
||||
|
||||
return so;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include "LibTessellation.hlsl"
|
||||
#include "DS_Terrain.inc.hlsl"
|
||||
|
||||
#define DETAIL_TC_SCALE 8.f
|
||||
#define DETAIL_TC_SCALE 8.0
|
||||
|
||||
ConstantBuffer<UB_TerrainVS> g_ubTerrainVS : register(b0, space0);
|
||||
ConstantBuffer<UB_TerrainFS> g_ubTerrainFS : register(b0, space1);
|
||||
|
@ -48,7 +48,7 @@ struct VSO
|
|||
#endif
|
||||
};
|
||||
|
||||
static const float g_layerScale = 1.f / 8.f;
|
||||
static const float g_layerScale = 1.0 / 8.0;
|
||||
|
||||
#ifdef _VS
|
||||
VSO mainVS(VSI si)
|
||||
|
@ -59,29 +59,29 @@ VSO mainVS(VSI si)
|
|||
const float mapSideInv = g_ubTerrainVS._eyePos_mapSideInv.w;
|
||||
|
||||
const float2 edgeCorrection = si.pos.yw;
|
||||
si.pos.yw = 0.f;
|
||||
si.pos.yw = 0.0;
|
||||
float3 pos = si.pos.xyz + si.posPatch.xyz;
|
||||
const float2 tcMap = pos.xz * mapSideInv + 0.5f; // Range [0, 1).
|
||||
const float2 posBlend = pos.xz + edgeCorrection * 0.5f;
|
||||
const float2 tcMap = pos.xz * mapSideInv + 0.5; // Range [0, 1).
|
||||
const float2 posBlend = pos.xz + edgeCorrection * 0.5;
|
||||
|
||||
// <HeightAndNormal>
|
||||
float3 inNrm;
|
||||
{
|
||||
const float approxHeight = UnpackTerrainHeight(g_texHeightVS.SampleLevel(g_samHeightVS, tcMap + (0.5f * mapSideInv) * 16.f, 4.f).r);
|
||||
const float approxHeight = UnpackTerrainHeight(g_texHeightVS.SampleLevel(g_samHeightVS, tcMap + (0.5 * mapSideInv) * 16.0, 4.0).r);
|
||||
pos.y = approxHeight;
|
||||
|
||||
const float distToEye = distance(pos, eyePos);
|
||||
const float geomipsLod = log2(clamp(distToEye * (2.f / 100.f), 1.f, 18.f));
|
||||
const float geomipsLod = log2(clamp(distToEye * (2.0 / 100.0), 1.0, 18.0));
|
||||
const float geomipsLodFrac = frac(geomipsLod);
|
||||
const float geomipsLodBase = floor(geomipsLod);
|
||||
const float geomipsLodNext = geomipsLodBase + 1.f;
|
||||
const float2 texelCenterAB = (0.5f * mapSideInv) * exp2(float2(geomipsLodBase, geomipsLodNext));
|
||||
const float geomipsLodNext = geomipsLodBase + 1.0;
|
||||
const float2 texelCenterAB = (0.5 * mapSideInv) * exp2(float2(geomipsLodBase, geomipsLodNext));
|
||||
const float yA = UnpackTerrainHeight(g_texHeightVS.SampleLevel(g_samHeightVS, tcMap + texelCenterAB.xx, geomipsLodBase).r);
|
||||
const float yB = UnpackTerrainHeight(g_texHeightVS.SampleLevel(g_samHeightVS, tcMap + texelCenterAB.yy, geomipsLodNext).r);
|
||||
pos.y = lerp(yA, yB, geomipsLodFrac);
|
||||
|
||||
const float4 rawNormal = g_texNormalVS.SampleLevel(g_samNormalVS, tcMap + texelCenterAB.xx, geomipsLodBase);
|
||||
inNrm = float3(rawNormal.x, 0, rawNormal.y) * 2.f - 1.f;
|
||||
inNrm = float3(rawNormal.x, 0, rawNormal.y) * 2.0 - 1.0;
|
||||
inNrm.y = ComputeNormalZ(inNrm.xz);
|
||||
}
|
||||
// </HeightAndNormal>
|
||||
|
@ -91,10 +91,10 @@ VSO mainVS(VSI si)
|
|||
#if !defined(DEF_DEPTH)
|
||||
so.layerForChannel = si.layerForChannel;
|
||||
#if !defined(DEF_DEPTH) && !defined(DEF_SOLID_COLOR)
|
||||
so.tcBlend.xy = posBlend * mapSideInv + 0.5f;
|
||||
so.tcBlend.xy = posBlend * mapSideInv + 0.5;
|
||||
so.tcBlend.z = pos.y;
|
||||
so.tcLayer_tcMap.xy = pos.xz * g_layerScale;
|
||||
so.tcLayer_tcMap.zw = (pos.xz + 0.5f) * mapSideInv + 0.5f; // Texel's center.
|
||||
so.tcLayer_tcMap.zw = (pos.xz + 0.5) * mapSideInv + 0.5; // Texel's center.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -113,7 +113,7 @@ PCFO PatchConstFunc(const OutputPatch<HSO, 3> outputPatch)
|
|||
}
|
||||
|
||||
[domain("tri")]
|
||||
[maxtessfactor(7.f)]
|
||||
[maxtessfactor(7.0)]
|
||||
[outputcontrolpoints(3)]
|
||||
[outputtopology("triangle_cw")]
|
||||
[partitioning(_PARTITION_METHOD)]
|
||||
|
@ -159,7 +159,7 @@ VSO mainDS(_IN_DS)
|
|||
|
||||
#ifndef DEF_DEPTH
|
||||
// Fade to non-tess mesh at 80 meters. LOD 1 starts at 100 meters.
|
||||
const float tessStrength = saturate((1.f - saturate(smoothPosWV.z / -80.f)) * 4.f);
|
||||
const float tessStrength = saturate((1.0 - saturate(smoothPosWV.z / -80.0)) * 4.0);
|
||||
const float3 posWV = lerp(flatPosWV, smoothPosWV, tessStrength);
|
||||
so.pos = ApplyProjection(posWV, g_ubTerrainVS._matP);
|
||||
#endif
|
||||
|
@ -183,13 +183,13 @@ DS_FSO mainFS(VSO si)
|
|||
const float2 tcMap = si.tcLayer_tcMap.zw;
|
||||
|
||||
const float4 rawBlend = g_texBlend.Sample(g_samBlend, si.tcBlend.xy);
|
||||
float4 weights = float4(rawBlend.rgb, 1.f - dot(rawBlend.rgb, float3(1, 1, 1)));
|
||||
float4 weights = float4(rawBlend.rgb, 1.0 - dot(rawBlend.rgb, float3(1, 1, 1)));
|
||||
|
||||
// <Basis>
|
||||
float3 basisTan, basisBin, basisNrm;
|
||||
{
|
||||
const float4 rawBasis = g_texNormal.Sample(g_samNormal, tcMap);
|
||||
const float4 basis = rawBasis * 2.f - 1.f;
|
||||
const float4 basis = rawBasis * 2.0 - 1.0;
|
||||
basisNrm = float3(basis.x, 0, basis.y);
|
||||
basisTan = float3(0, basis.z, basis.w);
|
||||
basisNrm.y = ComputeNormalZ(basisNrm.xz);
|
||||
|
@ -218,11 +218,11 @@ DS_FSO mainFS(VSO si)
|
|||
Grayscale(rawAlbedos[0].rgb),
|
||||
Grayscale(rawAlbedos[1].rgb),
|
||||
Grayscale(rawAlbedos[2].rgb),
|
||||
Grayscale(rawAlbedos[3].rgb)) - 0.25f) * 8.f + 0.25f);
|
||||
Grayscale(rawAlbedos[3].rgb)) - 0.25) * 8.0 + 0.25);
|
||||
weights = saturate(weights + weights * mask);
|
||||
const float weightsSum = dot(weights, 1.f);
|
||||
const float weightsSum = dot(weights, 1.0);
|
||||
weights /= weightsSum;
|
||||
float4 accAlbedo = 0.f;
|
||||
float4 accAlbedo = 0.0;
|
||||
accAlbedo += rawAlbedos[0] * weights.r;
|
||||
accAlbedo += rawAlbedos[1] * weights.g;
|
||||
accAlbedo += rawAlbedos[2] * weights.b;
|
||||
|
@ -251,26 +251,26 @@ DS_FSO mainFS(VSO si)
|
|||
{
|
||||
const float dryMask = saturate(si.tcBlend.z);
|
||||
const float dryMask3 = dryMask * dryMask * dryMask;
|
||||
const float wetMask = 1.f - dryMask;
|
||||
const float wetMask = 1.0 - dryMask;
|
||||
const float wetMask3 = wetMask * wetMask * wetMask;
|
||||
albedo.rgb *= dryMask3 * 0.5f + 0.5f;
|
||||
specMask = dryMask * saturate(specMask + wetMask3 * wetMask3 * 0.1f);
|
||||
waterGlossBoost = min(32.f, dryMask * wetMask3 * 100.f);
|
||||
albedo.rgb *= dryMask3 * 0.5 + 0.5;
|
||||
specMask = dryMask * saturate(specMask + wetMask3 * wetMask3 * 0.1);
|
||||
waterGlossBoost = min(32.0, dryMask * wetMask3 * 100.0);
|
||||
}
|
||||
// </Water>
|
||||
|
||||
const float gloss = lerp(3.3f, 15.f, specMask) + waterGlossBoost;
|
||||
const float gloss = lerp(3.3, 15.0, specMask) + waterGlossBoost;
|
||||
|
||||
// <Normal>
|
||||
float3 normalWV;
|
||||
float toksvigFactor;
|
||||
{
|
||||
float4 accNormal = 0.f;
|
||||
float4 accNormal = 0.0;
|
||||
accNormal += g_texLayersNM.Sample(g_samLayersNM, float3(tcLayer, layerForChannel.r)) * weights.r;
|
||||
accNormal += g_texLayersNM.Sample(g_samLayersNM, float3(tcLayer, layerForChannel.g)) * weights.g;
|
||||
accNormal += g_texLayersNM.Sample(g_samLayersNM, float3(tcLayer, layerForChannel.b)) * weights.b;
|
||||
accNormal += g_texLayersNM.Sample(g_samLayersNM, float3(tcLayer, layerForChannel.a)) * weights.a;
|
||||
accNormal = lerp(accNormal, float4(0, 0.5f, 0.5f, 0.5f), 0.5f);
|
||||
accNormal = lerp(accNormal, float4(0, 0.5, 0.5, 0.5), 0.5);
|
||||
const float4 normalAA = NormalMapAA(accNormal);
|
||||
normalWV = normalize(mul(normalAA.xyz, matFromTBN));
|
||||
toksvigFactor = ComputeToksvigFactor(normalAA.a, gloss);
|
||||
|
@ -280,15 +280,15 @@ DS_FSO mainFS(VSO si)
|
|||
// <Detail>
|
||||
{
|
||||
const float3 rawDetail = g_texDetail.Sample(g_samDetail, tcLayer * DETAIL_TC_SCALE).rgb;
|
||||
albedo.rgb = albedo.rgb * lerp(0.5f, rawDetail, detailStrength) * 2.f;
|
||||
albedo.rgb = albedo.rgb * lerp(0.5, rawDetail, detailStrength) * 2.0;
|
||||
}
|
||||
// </Detail>
|
||||
|
||||
// <SpecFresnel>
|
||||
float specMaskWithFresnel;
|
||||
{
|
||||
const float fresnelMask = pow(saturate(1.f - normalWV.z), 5.f);
|
||||
const float maxSpecAdd = (1.f - specMask) * (0.04f + 0.2f * specMask);
|
||||
const float fresnelMask = pow(saturate(1.0 - normalWV.z), 5.0);
|
||||
const float maxSpecAdd = (1.0 - specMask) * (0.04 + 0.2 * specMask);
|
||||
specMaskWithFresnel = FresnelSchlick(specMask, maxSpecAdd, fresnelMask);
|
||||
}
|
||||
// </SpecFresnel>
|
||||
|
@ -300,11 +300,11 @@ DS_FSO mainFS(VSO si)
|
|||
DS_SetSpecMask(so, specMaskWithFresnel);
|
||||
|
||||
DS_SetNormal(so, normalWV + NormalDither(rand));
|
||||
DS_SetEmission(so, 0.f, 0.f);
|
||||
DS_SetMotionBlurMask(so, 1.f);
|
||||
DS_SetEmission(so, 0.0, 0.0);
|
||||
DS_SetMotionBlurMask(so, 1.0);
|
||||
|
||||
DS_SetLamScaleBias(so, g_ubTerrainFS._lamScaleBias.xy, float4(0, 0, 1, 0));
|
||||
DS_SetMetallicity(so, 0.05f, 0.f);
|
||||
DS_SetMetallicity(so, 0.05, 0.0);
|
||||
DS_SetGloss(so, gloss * toksvigFactor);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -34,7 +34,7 @@ VSO mainVS(VSI si)
|
|||
VSO so;
|
||||
|
||||
so.pos = si.pos;
|
||||
so.tc0 = si.tc0.xy / 32767.f;
|
||||
so.tc0 = si.tc0.xy / 32767.0;
|
||||
so.color = ColorToLinear(si.color);
|
||||
|
||||
return so;
|
||||
|
|
|
@ -28,88 +28,82 @@ struct CSI
|
|||
#define DIM_CASE_WE_HO 2
|
||||
#define DIM_CASE_WO_HO 3
|
||||
|
||||
groupshared float gs_R[64];
|
||||
groupshared float gs_G[64];
|
||||
groupshared float gs_B[64];
|
||||
groupshared float gs_A[64];
|
||||
groupshared float gs_channelR[THREAD_GROUP_SIZE * THREAD_GROUP_SIZE];
|
||||
groupshared float gs_channelG[THREAD_GROUP_SIZE * THREAD_GROUP_SIZE];
|
||||
groupshared float gs_channelB[THREAD_GROUP_SIZE * THREAD_GROUP_SIZE];
|
||||
groupshared float gs_channelA[THREAD_GROUP_SIZE * THREAD_GROUP_SIZE];
|
||||
|
||||
void StoreColor(uint index, float4 color)
|
||||
{
|
||||
gs_R[index] = color.r;
|
||||
gs_G[index] = color.g;
|
||||
gs_B[index] = color.b;
|
||||
gs_A[index] = color.a;
|
||||
gs_channelR[index] = color.r;
|
||||
gs_channelG[index] = color.g;
|
||||
gs_channelB[index] = color.b;
|
||||
gs_channelA[index] = color.a;
|
||||
}
|
||||
|
||||
float4 LoadColor(uint index)
|
||||
{
|
||||
return float4(gs_R[index], gs_G[index], gs_B[index], gs_A[index]);
|
||||
return float4(gs_channelR[index], gs_channelG[index], gs_channelB[index], gs_channelA[index]);
|
||||
}
|
||||
|
||||
float4 PackColor(float4 x)
|
||||
{
|
||||
if (g_ub._srgb)
|
||||
{
|
||||
return ColorToSRGB(x);
|
||||
}
|
||||
else
|
||||
{
|
||||
return x;
|
||||
}
|
||||
return g_ub._srgb ? ColorToSRGB(x) : x;
|
||||
}
|
||||
|
||||
#ifdef _CS
|
||||
[numthreads(THREAD_GROUP_SIZE, THREAD_GROUP_SIZE, 1)]
|
||||
void mainCS(CSI si)
|
||||
{
|
||||
float4 srcColor1 = 0.f;
|
||||
float2 tc = 0.f;
|
||||
float4 srcColor1 = 0.0;
|
||||
float2 tc = 0.0;
|
||||
|
||||
switch (g_ub._srcDimensionCase)
|
||||
{
|
||||
case DIM_CASE_WE_HE:
|
||||
{
|
||||
tc = g_ub._texelSize * (si.dispatchThreadID.xy + 0.5f);
|
||||
tc = g_ub._dstTexelSize * (si.dispatchThreadID.xy + 0.5);
|
||||
|
||||
srcColor1 = g_texSrcMip.SampleLevel(g_samSrcMip, tc, g_ub._srcMipLevel);
|
||||
}
|
||||
break;
|
||||
case DIM_CASE_WO_HE:
|
||||
{
|
||||
tc = g_ub._texelSize * (si.dispatchThreadID.xy + float2(0.25f, 0.5f));
|
||||
const float2 offset = g_ub._texelSize * float2(0.5f, 0.f);
|
||||
tc = g_ub._dstTexelSize * (si.dispatchThreadID.xy + float2(0.25, 0.5));
|
||||
const float2 offset = g_ub._dstTexelSize * float2(0.5, 0.0);
|
||||
|
||||
srcColor1 = lerp(
|
||||
g_texSrcMip.SampleLevel(g_samSrcMip, tc, g_ub._srcMipLevel),
|
||||
g_texSrcMip.SampleLevel(g_samSrcMip, tc + offset, g_ub._srcMipLevel),
|
||||
0.5f);
|
||||
0.5);
|
||||
}
|
||||
break;
|
||||
case DIM_CASE_WE_HO:
|
||||
{
|
||||
tc = g_ub._texelSize * (si.dispatchThreadID.xy + float2(0.5f, 0.25f));
|
||||
const float2 offset = g_ub._texelSize * float2(0.f, 0.5f);
|
||||
tc = g_ub._dstTexelSize * (si.dispatchThreadID.xy + float2(0.5, 0.25));
|
||||
const float2 offset = g_ub._dstTexelSize * float2(0.0, 0.5);
|
||||
|
||||
srcColor1 = lerp(
|
||||
g_texSrcMip.SampleLevel(g_samSrcMip, tc, g_ub._srcMipLevel),
|
||||
g_texSrcMip.SampleLevel(g_samSrcMip, tc + offset, g_ub._srcMipLevel),
|
||||
0.5f);
|
||||
0.5);
|
||||
}
|
||||
break;
|
||||
case DIM_CASE_WO_HO:
|
||||
{
|
||||
tc = g_ub._texelSize * (si.dispatchThreadID.xy + float2(0.25f, 0.25f));
|
||||
const float2 offset = g_ub._texelSize * 0.5f;
|
||||
tc = g_ub._dstTexelSize * (si.dispatchThreadID.xy + 0.25);
|
||||
const float2 offset = g_ub._dstTexelSize * 0.5;
|
||||
|
||||
srcColor1 = lerp(
|
||||
lerp(
|
||||
g_texSrcMip.SampleLevel(g_samSrcMip, tc, g_ub._srcMipLevel),
|
||||
g_texSrcMip.SampleLevel(g_samSrcMip, tc + float2(offset.x, 0.f), g_ub._srcMipLevel),
|
||||
0.5f),
|
||||
lerp(g_texSrcMip.SampleLevel(g_samSrcMip, tc + float2(0.f, offset.y), g_ub._srcMipLevel),
|
||||
g_texSrcMip.SampleLevel(g_samSrcMip, tc + float2(offset.x, offset.y), g_ub._srcMipLevel),
|
||||
0.5f),
|
||||
0.5f);
|
||||
g_texSrcMip.SampleLevel(g_samSrcMip, tc + float2(offset.x, 0.0), g_ub._srcMipLevel),
|
||||
0.5),
|
||||
lerp(
|
||||
g_texSrcMip.SampleLevel(g_samSrcMip, tc + float2(0.0, offset.y), g_ub._srcMipLevel),
|
||||
g_texSrcMip.SampleLevel(g_samSrcMip, tc + offset, g_ub._srcMipLevel),
|
||||
0.5),
|
||||
0.5);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -117,32 +111,30 @@ void mainCS(CSI si)
|
|||
#ifdef DEF_EXPOSURE
|
||||
if (0 == g_ub._srcMipLevel)
|
||||
{
|
||||
const float2 delta = 0.5f - tc;
|
||||
const float2 centerWeighted = saturate((dot(delta, delta) - float2(0.1f, 0.01f)) * float2(4.f, 200.f));
|
||||
const float2 delta = 0.5 - tc;
|
||||
const float2 centerWeighted = saturate((dot(delta, delta) - float2(0.1, 0.01)) * float2(4.0, 200.0));
|
||||
const float gray = Grayscale(srcColor1.rgb);
|
||||
const float2 mask = saturate((float2(-1, 1) * gray + float2(0.1f, -0.99f)) * float2(10, 100));
|
||||
const float2 mask = saturate((float2(-1, 1) * gray + float2(0.1, -0.99)) * float2(10, 100));
|
||||
const float filter = max(mask.x, mask.y) * centerWeighted.y;
|
||||
const float alpha = max(centerWeighted.x, filter);
|
||||
srcColor1.rgb = lerp(srcColor1.rgb, 0.5f, alpha);
|
||||
srcColor1.a = 1.f - alpha;
|
||||
srcColor1.rgb = lerp(srcColor1.rgb, 0.5, alpha);
|
||||
srcColor1.a = 1.0 - alpha;
|
||||
}
|
||||
#endif
|
||||
|
||||
g_uavOutMip1[si.dispatchThreadID.xy] = PackColor(srcColor1);
|
||||
StoreColor(si.groupIndex, srcColor1);
|
||||
|
||||
if (1 == g_ub._mipLevelCount)
|
||||
return;
|
||||
|
||||
StoreColor(si.groupIndex, srcColor1);
|
||||
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
if ((si.groupIndex & 0x9) == 0) // 16 threads:
|
||||
if ((si.groupIndex & 0x9) == 0) // 16 threads (0, 2, 4, 6, 16, 18, 20, 22, etc.):
|
||||
{
|
||||
const float4 srcColor2 = LoadColor(si.groupIndex + 0x01); // {+0, +1}
|
||||
const float4 srcColor3 = LoadColor(si.groupIndex + 0x08); // {+1, +0}
|
||||
const float4 srcColor4 = LoadColor(si.groupIndex + 0x09); // {+1, +1}
|
||||
srcColor1 = 0.25f * (srcColor1 + srcColor2 + srcColor3 + srcColor4);
|
||||
srcColor1 = 0.25 * (srcColor1 + srcColor2 + srcColor3 + srcColor4);
|
||||
|
||||
g_uavOutMip2[si.dispatchThreadID.xy >> 1] = PackColor(srcColor1);
|
||||
StoreColor(si.groupIndex, srcColor1);
|
||||
|
@ -150,15 +142,14 @@ void mainCS(CSI si)
|
|||
|
||||
if (2 == g_ub._mipLevelCount)
|
||||
return;
|
||||
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
if ((si.groupIndex & 0x1B) == 0) // 4 threads:
|
||||
if ((si.groupIndex & 0x1B) == 0) // 4 threads (0, 4, 32, 36):
|
||||
{
|
||||
const float4 srcColor2 = LoadColor(si.groupIndex + 0x02); // {+0, +2}
|
||||
const float4 srcColor3 = LoadColor(si.groupIndex + 0x10); // {+2, +0}
|
||||
const float4 srcColor4 = LoadColor(si.groupIndex + 0x12); // {+2, +2}
|
||||
srcColor1 = 0.25f * (srcColor1 + srcColor2 + srcColor3 + srcColor4);
|
||||
srcColor1 = 0.25 * (srcColor1 + srcColor2 + srcColor3 + srcColor4);
|
||||
|
||||
g_uavOutMip3[si.dispatchThreadID.xy >> 2] = PackColor(srcColor1);
|
||||
StoreColor(si.groupIndex, srcColor1);
|
||||
|
@ -166,7 +157,6 @@ void mainCS(CSI si)
|
|||
|
||||
if (3 == g_ub._mipLevelCount)
|
||||
return;
|
||||
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
if (si.groupIndex == 0) // 1 thread:
|
||||
|
@ -174,7 +164,7 @@ void mainCS(CSI si)
|
|||
const float4 srcColor2 = LoadColor(si.groupIndex + 0x04); // {+0, +4}
|
||||
const float4 srcColor3 = LoadColor(si.groupIndex + 0x20); // {+4, +0}
|
||||
const float4 srcColor4 = LoadColor(si.groupIndex + 0x24); // {+4, +4}
|
||||
srcColor1 = 0.25f * (srcColor1 + srcColor2 + srcColor3 + srcColor4);
|
||||
srcColor1 = 0.25 * (srcColor1 + srcColor2 + srcColor3 + srcColor4);
|
||||
|
||||
g_uavOutMip4[si.dispatchThreadID.xy >> 3] = PackColor(srcColor1);
|
||||
}
|
||||
|
|
|
@ -6,5 +6,5 @@ VERUS_UBUFFER UB_GenerateMips
|
|||
int _mipLevelCount;
|
||||
int _srcDimensionCase;
|
||||
int _srgb;
|
||||
float2 _texelSize;
|
||||
float2 _dstTexelSize;
|
||||
};
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
# else
|
||||
# define VK_POINT_SIZE
|
||||
# endif
|
||||
# define VK_SET_POINT_SIZE so.psize = 1.f
|
||||
# define VK_SET_POINT_SIZE so.psize = 1.0
|
||||
#else
|
||||
# define VK_LOCATION(x)
|
||||
# define VK_LOCATION_POSITION
|
||||
|
@ -46,7 +46,7 @@
|
|||
# define VK_SUBPASS_INPUT(index, tex, sam, t, s, space)\
|
||||
Texture2D tex : register(t, space);\
|
||||
SamplerState sam : register(s, space)
|
||||
# define VK_SUBPASS_LOAD(tex, sam, tc) tex.SampleLevel(sam, tc, 0.f)
|
||||
# define VK_SUBPASS_LOAD(tex, sam, tc) tex.SampleLevel(sam, tc, 0.0)
|
||||
|
||||
# define VK_POINT_SIZE
|
||||
# define VK_SET_POINT_SIZE
|
||||
|
@ -66,9 +66,9 @@
|
|||
const float3x3 matFromTBN = float3x3(tan, bin, nrm);\
|
||||
const float3x3 matToTBN = transpose(matFromTBN);
|
||||
|
||||
#define _PI 3.141592654f
|
||||
#define _PI 3.141592654
|
||||
|
||||
#define _SINGULARITY_FIX 0.001f
|
||||
#define _SINGULARITY_FIX 0.001
|
||||
|
||||
#define _MAX_TERRAIN_LAYERS 32
|
||||
|
||||
|
@ -88,45 +88,45 @@ float2 ToNdcPos(float2 tc)
|
|||
|
||||
float2 ToTexCoords(float2 ndcPos)
|
||||
{
|
||||
return ndcPos * float2(0.5f, -0.5f) + 0.5f;
|
||||
return ndcPos * float2(0.5, -0.5) + 0.5;
|
||||
}
|
||||
|
||||
// Asymmetric abs():
|
||||
float2 AsymAbs(float2 x, float negScale = -1.f, float posScale = 1.f)
|
||||
float2 AsymAbs(float2 x, float negScale = -1.0, float posScale = 1.0)
|
||||
{
|
||||
return x * lerp(posScale, negScale, step(x, 0.f));
|
||||
return x * lerp(posScale, negScale, step(x, 0.0));
|
||||
}
|
||||
|
||||
float3 Rand(float2 uv)
|
||||
{
|
||||
return frac(sin(dot(uv, float2(12.9898f, 78.233f)) * float3(1, 2, 3)) * 43758.5453f);
|
||||
return frac(sin(dot(uv, float2(12.9898, 78.233)) * float3(1, 2, 3)) * 43758.5453);
|
||||
}
|
||||
|
||||
float4 Rand2(float2 pos)
|
||||
{
|
||||
const float4 primeA = float4(9.907f, 9.923f, 9.929f, 9.931f);
|
||||
const float4 primeB = float4(9.941f, 9.949f, 9.967f, 9.973f);
|
||||
const float4 primeA = float4(9.907, 9.923, 9.929, 9.931);
|
||||
const float4 primeB = float4(9.941, 9.949, 9.967, 9.973);
|
||||
return frac(primeA * pos.x + primeB * pos.y);
|
||||
}
|
||||
|
||||
float3 RandomColor(float2 pos, float randLum, float randRGB)
|
||||
{
|
||||
const float4 r = Rand2(pos);
|
||||
return (1.f - randLum - randRGB) + r.a * randLum + r.rgb * randRGB;
|
||||
return (1.0 - randLum - randRGB) + r.a * randLum + r.rgb * randRGB;
|
||||
}
|
||||
|
||||
float3 NormalDither(float3 rand)
|
||||
{
|
||||
const float2 rr = rand.xy * (1.f / 333.f) - (0.5f / 333.f);
|
||||
const float2 rr = rand.xy * (1.0 / 333.0) - (0.5 / 333.0);
|
||||
return float3(rr, 0);
|
||||
}
|
||||
|
||||
static const float2 _POINT_SPRITE_POS_OFFSETS[4] =
|
||||
{
|
||||
float2(-0.5f, 0.5f),
|
||||
float2(-0.5f, -0.5f),
|
||||
float2(0.5f, 0.5f),
|
||||
float2(0.5f, -0.5f)
|
||||
float2(-0.5, 0.5),
|
||||
float2(-0.5, -0.5),
|
||||
float2(0.5, 0.5),
|
||||
float2(0.5, -0.5)
|
||||
};
|
||||
|
||||
static const float2 _POINT_SPRITE_TEX_COORDS[4] =
|
||||
|
@ -141,12 +141,12 @@ static const float2 _POINT_SPRITE_TEX_COORDS[4] =
|
|||
|
||||
float3 ToRealAlbedo(float3 albedo)
|
||||
{
|
||||
return max(albedo.rgb * 0.5f, 0.0001f);
|
||||
return max(albedo.rgb * 0.5, 0.0001);
|
||||
}
|
||||
|
||||
float3 ToMetalColor(float3 albedo)
|
||||
{
|
||||
const float gray = dot(albedo, 1.f / 3.f);
|
||||
const float gray = dot(albedo, 1.0 / 3.0);
|
||||
return saturate(albedo / (gray + _SINGULARITY_FIX));
|
||||
}
|
||||
|
||||
|
@ -155,7 +155,7 @@ float3 ToSafeHDR(float3 hdr)
|
|||
{
|
||||
// Typical ambient is 4000.
|
||||
// Typical sunlight is 16000.
|
||||
return clamp(hdr, 0.f, 32000.f);
|
||||
return clamp(hdr, 0.0, 32000.0);
|
||||
}
|
||||
|
||||
// See: https://en.wikipedia.org/wiki/Schlick%27s_approximation
|
||||
|
@ -168,22 +168,80 @@ float FresnelSchlick(float minRef, float maxAdd, float power)
|
|||
|
||||
float UnpackTerrainHeight(float height)
|
||||
{
|
||||
return height * 0.01f;
|
||||
return height * 0.01;
|
||||
}
|
||||
|
||||
float ToLandMask(float height)
|
||||
{
|
||||
return saturate(height * 0.2f + 1.f); // [-5 to 0] -> [0 to 1]
|
||||
return saturate(height * 0.2 + 1.0); // [-5 to 0] -> [0 to 1]
|
||||
}
|
||||
|
||||
float ToWaterDiffuseMask(float height)
|
||||
{
|
||||
const float mask = saturate(height * 0.02f + 1.f); // [-50 to 0] -> [0 to 1]
|
||||
const float mask = saturate(height * 0.02 + 1.0); // [-50 to 0] -> [0 to 1]
|
||||
return mask * mask * mask;
|
||||
}
|
||||
|
||||
float3 ReflectionDimming(float3 hdr, float scale)
|
||||
{
|
||||
const float gray = dot(hdr, 1.f / 3.f);
|
||||
return lerp(hdr * scale, hdr, saturate(gray * (1.f / 65536.f)));
|
||||
const float gray = dot(hdr, 1.0 / 3.0);
|
||||
return lerp(hdr * scale, hdr, saturate(gray * (1.0 / 65536.0)));
|
||||
}
|
||||
|
||||
// Also known as The Multiplier Map, for hemicube's shape compensation.
|
||||
float ComputeHemicubeMask(float2 tc)
|
||||
{
|
||||
// Hint. Compare two pixels when looking at them from the focal point of hemicube:
|
||||
// one is in the middle of hemicube's face and the other one is at the corner.
|
||||
// What will be the ratio of their areas (solid angles)?
|
||||
const float2 atc = abs(tc * 2.0 - 1.0);
|
||||
if (atc.y < 0.5)
|
||||
{
|
||||
if (atc.x < 0.5)
|
||||
{
|
||||
const float3 faceNrm = float3(0, 0, 1);
|
||||
const float3 v = float3(atc.x * 2.0, atc.y * 2.0, 1);
|
||||
const float len = length(v);
|
||||
const float3 vn = v / len;
|
||||
|
||||
const float cosLaw = vn.z;
|
||||
const float distFactor = 1.0 / (len * len);
|
||||
const float faceFactor = dot(vn, faceNrm);
|
||||
|
||||
return cosLaw * distFactor * faceFactor;
|
||||
}
|
||||
else
|
||||
{
|
||||
const float3 faceNrm = float3(1, 0, 0);
|
||||
const float3 v = float3(1, atc.y * 2.0, 2.0 - 2.0 * atc.x);
|
||||
const float len = length(v);
|
||||
const float3 vn = v / len;
|
||||
|
||||
const float cosLaw = vn.z;
|
||||
const float distFactor = 1.0 / (len * len);
|
||||
const float faceFactor = dot(vn, faceNrm);
|
||||
|
||||
return cosLaw * distFactor * faceFactor;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (atc.x < 0.5)
|
||||
{
|
||||
const float3 faceNrm = float3(0, 1, 0);
|
||||
const float3 v = float3(atc.x * 2.0, 1, 2.0 - 2.0 * atc.y);
|
||||
const float len = length(v);
|
||||
const float3 vn = v / len;
|
||||
|
||||
const float cosLaw = vn.z;
|
||||
const float distFactor = 1.0 / (len * len);
|
||||
const float faceFactor = dot(vn, faceNrm);
|
||||
|
||||
return cosLaw * distFactor * faceFactor;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,41 +3,41 @@
|
|||
// See: https://en.wikipedia.org/wiki/Grayscale
|
||||
float Grayscale(float3 color)
|
||||
{
|
||||
return dot(color, float3(0.2126f, 0.7152f, 0.0722f));
|
||||
return dot(color, float3(0.2126, 0.7152, 0.0722));
|
||||
}
|
||||
|
||||
float3 Desaturate(float3 color, float alpha, float lum = 1.f)
|
||||
float3 Desaturate(float3 color, float alpha, float lum = 1.0)
|
||||
{
|
||||
const float gray = Grayscale(color) * lum;
|
||||
return lerp(color, gray, alpha);
|
||||
}
|
||||
|
||||
// See: http://www.chilliant.com/rgb2hsv.html
|
||||
// See: https://www.chilliant.com/rgb2hsv.html
|
||||
float3 ConvertRGBtoHCV(float3 color)
|
||||
{
|
||||
const float4 p = (color.g < color.b) ? float4(color.bg, -1.f, 2.f / 3.f) : float4(color.gb, 0.f, -1.f / 3.f);
|
||||
const float4 p = (color.g < color.b) ? float4(color.bg, -1.0, 2.0 / 3.0) : float4(color.gb, 0.0, -1.0 / 3.0);
|
||||
const float4 q = (color.r < p.x) ? float4(p.xyw, color.r) : float4(color.r, p.yzx);
|
||||
const float c = q.x - min(q.w, q.y);
|
||||
const float h = abs((q.w - q.y) / (6.f * c + _SINGULARITY_FIX) + q.z);
|
||||
const float h = abs((q.w - q.y) / (6.0 * c + _SINGULARITY_FIX) + q.z);
|
||||
return float3(h, c, q.x);
|
||||
}
|
||||
|
||||
float Contrast(float gray, float contrast)
|
||||
{
|
||||
return saturate(((gray - 0.5f) * contrast) + 0.5f);
|
||||
return saturate(((gray - 0.5) * contrast) + 0.5);
|
||||
}
|
||||
|
||||
float3 Overlay(float3 colorA, float3 colorB)
|
||||
{
|
||||
const float3 x = step(0.5f, colorA);
|
||||
return lerp(colorA * colorB * 2.f, 1.f - (2.f * (1.f - colorA) * (1.f - colorB)), x);
|
||||
const float3 x = step(0.5, colorA);
|
||||
return lerp(colorA * colorB * 2.0, 1.0 - (2.0 * (1.0 - colorA) * (1.0 - colorB)), x);
|
||||
}
|
||||
|
||||
// <AlbedoPick>
|
||||
float PickAlpha(float3 albedo, float4 pick, float sharp)
|
||||
{
|
||||
const float3 d = albedo - pick.rgb;
|
||||
return saturate(1.f - dot(d, d) * sharp) * pick.a;
|
||||
return saturate(1.0 - dot(d, d) * sharp) * pick.a;
|
||||
}
|
||||
|
||||
float PickAlphaRound(float4 pick, float2 tc)
|
||||
|
@ -53,47 +53,47 @@ float2 AlphaSwitch(float4 albedo, float2 tc, float2 alphaSwitch)
|
|||
if (all(frac(tc) >= alphaSwitch))
|
||||
return float2(albedo.a, Grayscale(albedo.rgb)); // 8-bit alpha.
|
||||
else
|
||||
return saturate(float2(albedo.a * 8.f, (albedo.a - 0.15f) / 0.85f)); // 5-bit alpha.
|
||||
return saturate(float2(albedo.a * 8.0, (albedo.a - 0.15) / 0.85)); // 5-bit alpha.
|
||||
}
|
||||
|
||||
// See: http://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html
|
||||
float4 ColorToLinear(float4 x)
|
||||
{
|
||||
const float3 rgb = x.rgb < 0.04045f ? x.rgb * (1.f / 12.92f) : pow(abs(x.rgb + 0.055f) / 1.055f, 2.4f);
|
||||
const float3 rgb = x.rgb < 0.04045 ? x.rgb * (1.0 / 12.92) : pow(abs(x.rgb + 0.055) / 1.055, 2.4);
|
||||
return float4(rgb, x.a);
|
||||
}
|
||||
float4 ColorToSRGB(float4 x)
|
||||
{
|
||||
const float3 rgb = x.rgb < 0.0031308f ? 12.92f * x.rgb : 1.055f * pow(abs(x.rgb), 1.f / 2.4f) - 0.055f;
|
||||
const float3 rgb = x.rgb < 0.0031308 ? 12.92 * x.rgb : 1.055 * pow(abs(x.rgb), 1.0 / 2.4) - 0.055;
|
||||
return float4(rgb, x.a);
|
||||
}
|
||||
|
||||
float3 ToneMappingReinhard(float3 x)
|
||||
{
|
||||
return x / (1.f + x);
|
||||
return x / (1.0 + x);
|
||||
}
|
||||
|
||||
float3 ToneMappingInvReinhard(float3 x)
|
||||
{
|
||||
return -x / (x - 1.f);
|
||||
return -x / (x - 1.0);
|
||||
}
|
||||
|
||||
// See: https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/
|
||||
float3 ToneMappingACES(float3 x)
|
||||
{
|
||||
const float a = 2.51f;
|
||||
const float b = 0.03f;
|
||||
const float c = 2.43f;
|
||||
const float d = 0.59f;
|
||||
const float e = 0.14f;
|
||||
const float a = 2.51;
|
||||
const float b = 0.03;
|
||||
const float c = 2.43;
|
||||
const float d = 0.59;
|
||||
const float e = 0.14;
|
||||
return saturate((x * (a * x + b)) / (x * (c * x + d) + e));
|
||||
}
|
||||
|
||||
float3 VerusToneMapping(float3 hdr, float filmicLook = 1.f)
|
||||
float3 VerusToneMapping(float3 hdr, float filmicLook = 1.0)
|
||||
{
|
||||
const float maxValue = max(max(hdr.r, hdr.g), hdr.b);
|
||||
const float desatMask = saturate(maxValue * 0.15f);
|
||||
const float desatMask = saturate(maxValue * 0.15);
|
||||
hdr = lerp(hdr, maxValue, desatMask * desatMask); // Color crosstalk.
|
||||
const float3 ldr = lerp(1.f - exp(-hdr), ToneMappingACES(hdr), filmicLook);
|
||||
return saturate(ldr * 1.2f - 0.002f); // Add some clipping.
|
||||
const float3 ldr = lerp(1.0 - exp(-hdr), ToneMappingACES(hdr), filmicLook);
|
||||
return saturate(ldr * 1.2 - 0.002); // Add some clipping.
|
||||
}
|
||||
|
|
|
@ -16,38 +16,38 @@ struct DS_ACC_FSO
|
|||
// See: http://aras-p.info/texts/CompactNormalStorage.html#method04spheremap
|
||||
float2 EncodeNormal(float3 n)
|
||||
{
|
||||
const float rf = rsqrt(abs(8.f * n.z + 8.f));
|
||||
return n.xy * rf + 0.5f;
|
||||
const float rf = rsqrt(abs(8.0 * n.z + 8.0));
|
||||
return n.xy * rf + 0.5;
|
||||
}
|
||||
|
||||
float3 DecodeNormal(float2 enc)
|
||||
{
|
||||
const float2 fenc = enc * 4.f - 2.f;
|
||||
const float2 fenc = enc * 4.0 - 2.0;
|
||||
const float f = dot(fenc, fenc);
|
||||
const float2 f2 = 1.f - f * float2(0.25f, 0.5f);
|
||||
const float2 f2 = 1.0 - f * float2(0.25, 0.5);
|
||||
const float g = sqrt(abs(f2.x));
|
||||
return float3(fenc * g, f2.y);
|
||||
}
|
||||
|
||||
void DS_Reset(out DS_FSO so)
|
||||
{
|
||||
so.target0 = 0.f;
|
||||
so.target1 = 0.f;
|
||||
so.target2 = 0.f;
|
||||
so.target0 = 0.0;
|
||||
so.target1 = 0.0;
|
||||
so.target2 = 0.0;
|
||||
}
|
||||
|
||||
void DS_SolidColor(out DS_FSO so, float3 color)
|
||||
{
|
||||
so.target0 = float4(color, 0.f);
|
||||
so.target1 = float4(EncodeNormal(float3(0, 0, 1)), 0.25f, 0);
|
||||
so.target2 = float4(1.f / 8.f, 0.5f, 0.5f, 0);
|
||||
so.target0 = float4(color, 0.0);
|
||||
so.target1 = float4(EncodeNormal(float3(0, 0, 1)), 0.25, 0);
|
||||
so.target2 = float4(1.0 / 8.0, 0.5, 0.5, 0);
|
||||
}
|
||||
|
||||
void DS_Test(out DS_FSO so, float3 normal, float specMask, float gloss)
|
||||
{
|
||||
so.target0 = float4(0.5f, 0.5f, 0.5f, specMask);
|
||||
so.target1 = float4(EncodeNormal(normal), 0.25f, 0.5f);
|
||||
so.target2 = float4(1.f / 8.f, 0.5f, 0.5f, gloss * (1.f / 64.f));
|
||||
so.target0 = float4(0.5, 0.5, 0.5, specMask);
|
||||
so.target1 = float4(EncodeNormal(normal), 0.25, 0.5);
|
||||
so.target2 = float4(1.0 / 8.0, 0.5, 0.5, gloss * (1.0 / 64.0));
|
||||
}
|
||||
|
||||
void DS_SetAlbedo(inout DS_FSO so, float3 albedo)
|
||||
|
@ -72,15 +72,15 @@ void DS_SetNormal(inout DS_FSO so, float3 normal)
|
|||
|
||||
float2 DS_GetEmission(float4 gbuffer)
|
||||
{
|
||||
const float2 em_skin = saturate((gbuffer.b - 0.25f) * float2(1.f / 0.75f, -1.f / 0.25f));
|
||||
const float em = exp2(em_skin.x * 15.f) - 1.f;
|
||||
const float2 em_skin = saturate((gbuffer.b - 0.25) * float2(1.0 / 0.75, -1.0 / 0.25));
|
||||
const float em = exp2(em_skin.x * 15.0) - 1.0;
|
||||
return float2(em, em_skin.y);
|
||||
}
|
||||
|
||||
void DS_SetEmission(inout DS_FSO so, float emission, float skinMask)
|
||||
{
|
||||
const float em = saturate(log2(1.f + emission) * (1.f / 15.f));
|
||||
so.target1.b = (3.f * em - skinMask) * 0.25f + 0.25f;
|
||||
const float em = saturate(log2(1.0 + emission) * (1.0 / 15.0));
|
||||
so.target1.b = (3.0 * em - skinMask) * 0.25 + 0.25;
|
||||
}
|
||||
|
||||
void DS_SetMotionBlurMask(inout DS_FSO so, float motionBlurMask)
|
||||
|
@ -95,25 +95,25 @@ float2 DS_GetLamScaleBias(float4 gbuffer)
|
|||
|
||||
void DS_SetLamScaleBias(inout DS_FSO so, float2 lamScaleBias, float4 aniso)
|
||||
{
|
||||
so.target2.rg = lerp(lamScaleBias * float2(1.f / 8.f, 0.25f) + float2(0, 0.5f), EncodeNormal(aniso.xyz), aniso.w);
|
||||
so.target2.rg = lerp(lamScaleBias * float2(1.0 / 8.0, 0.25) + float2(0, 0.5), EncodeNormal(aniso.xyz), aniso.w);
|
||||
}
|
||||
|
||||
float2 DS_GetMetallicity(float4 gbuffer)
|
||||
{
|
||||
const float x2 = gbuffer.b * 2.02f;
|
||||
const float x2 = gbuffer.b * 2.02;
|
||||
return float2(
|
||||
saturate(x2 - 1.02f),
|
||||
saturate(1.f - x2));
|
||||
saturate(x2 - 1.02),
|
||||
saturate(1.0 - x2));
|
||||
}
|
||||
|
||||
void DS_SetMetallicity(inout DS_FSO so, float metalMask, float hairMask)
|
||||
{
|
||||
so.target2.b = (metalMask - hairMask) * 0.5f + 0.5f;
|
||||
so.target2.b = (metalMask - hairMask) * 0.5 + 0.5;
|
||||
}
|
||||
|
||||
void DS_SetGloss(inout DS_FSO so, float gloss)
|
||||
{
|
||||
so.target2.a = gloss * (1.f / 64.f);
|
||||
so.target2.a = gloss * (1.0 / 64.0);
|
||||
}
|
||||
|
||||
float3 DS_GetPosition(float4 gbuffer, matrix matInvProj, float2 ndcPos)
|
||||
|
|
|
@ -16,26 +16,26 @@ float4 ToLinearDepth(float4 dz, float4 zNearFarEx)
|
|||
return zNearFarEx.w / (dz - zNearFarEx.z);
|
||||
}
|
||||
|
||||
float ComputeFog(float depth, float density, float height = 0.f)
|
||||
float ComputeFog(float depth, float density, float height = 0.0)
|
||||
{
|
||||
const float strength = 1.f - saturate(height * 0.003f);
|
||||
const float power = depth * lerp(0.f, density, strength * strength);
|
||||
const float fog = 1.f / exp(power * power);
|
||||
return 1.f - saturate(fog);
|
||||
const float strength = 1.0 - saturate(height * 0.003);
|
||||
const float power = depth * lerp(0.0, density, strength * strength);
|
||||
const float fog = 1.0 / exp(power * power);
|
||||
return 1.0 - saturate(fog);
|
||||
}
|
||||
|
||||
float3 AdjustPosForShadow(float3 pos, float3 normal, float3 dirToLight, float depth, float offset = 0.f)
|
||||
float3 AdjustPosForShadow(float3 pos, float3 normal, float3 dirToLight, float depth, float offset = 0.0)
|
||||
{
|
||||
const float scale = depth - 5.f;
|
||||
const float scale = depth - 5.0;
|
||||
return pos +
|
||||
normal * 0.015f * max(1.f, scale * 0.2f) +
|
||||
dirToLight * max(0.f, scale * 0.002f + offset);
|
||||
normal * 0.015 * max(1.0, scale * 0.2) +
|
||||
dirToLight * max(0.0, scale * 0.002 + offset);
|
||||
}
|
||||
|
||||
float ComputePenumbraContrast(float deltaScale, float strength, float dzFrag, float dzBlockers)
|
||||
{
|
||||
const float delta = saturate(dzFrag - dzBlockers);
|
||||
return 1.f + max(0.f, 3.f - delta * deltaScale) * strength;
|
||||
return 1.0 + max(0.0, 3.0 - delta * deltaScale) * strength;
|
||||
}
|
||||
|
||||
float PCF(
|
||||
|
@ -51,7 +51,7 @@ float PCF(
|
|||
return texCmp.SampleCmpLevelZero(samCmp, tc.xy, dzFrag).r;
|
||||
#elif _SHADOW_QUALITY <= _Q_HIGH
|
||||
// High quality, use 5x5 PCF:
|
||||
float sum = 0.f;
|
||||
float sum = 0.0;
|
||||
[unroll] for (int y = -2; y <= 2; y += 2)
|
||||
{
|
||||
[unroll] for (int x = -2; x <= 2; x += 2)
|
||||
|
@ -62,11 +62,11 @@ float PCF(
|
|||
sum += texCmp.SampleCmpLevelZero(samCmp, tc.xy, dzFrag, offset).r;
|
||||
}
|
||||
}
|
||||
sum *= (1.f / 9.f); // 3x3
|
||||
if (sum * (1.f - sum) != 0.f)
|
||||
sum *= (1.0 / 9.0); // 3x3
|
||||
if (sum * (1.0 - sum) != 0.0)
|
||||
{
|
||||
float2 dzBlockers_blockerCount = 0.f;
|
||||
sum = 0.f;
|
||||
float2 dzBlockers_blockerCount = 0.0;
|
||||
sum = 0.0;
|
||||
[unroll] for (int y = -2; y <= 2; ++y)
|
||||
{
|
||||
[unroll] for (int x = -2; x <= 2; ++x)
|
||||
|
@ -79,12 +79,12 @@ float PCF(
|
|||
dzBlockers_blockerCount += float2(dzBlocker, 1);
|
||||
}
|
||||
}
|
||||
const float ret = sum *= (1.f / 21.f); // 5x5 - 4
|
||||
if (dzBlockers_blockerCount.y > 0.f)
|
||||
const float ret = sum *= (1.0 / 21.0); // 5x5 - 4
|
||||
if (dzBlockers_blockerCount.y > 0.0)
|
||||
{
|
||||
const float dzBlockers = dzBlockers_blockerCount.x / dzBlockers_blockerCount.y;
|
||||
const float contrast = ComputePenumbraContrast(config.x, config.y, dzFrag, dzBlockers);
|
||||
return saturate((ret - 0.5f) * contrast + 0.5f);
|
||||
return saturate((ret - 0.5) * contrast + 0.5);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -97,7 +97,7 @@ float PCF(
|
|||
}
|
||||
#else
|
||||
// Ultra quality, use 7x7 PCF:
|
||||
float sum = 0.f;
|
||||
float sum = 0.0;
|
||||
[unroll] for (int y = -3; y <= 3; y += 2)
|
||||
{
|
||||
[unroll] for (int x = -3; x <= 3; x += 2)
|
||||
|
@ -108,11 +108,11 @@ float PCF(
|
|||
sum += texCmp.SampleCmpLevelZero(samCmp, tc.xy, dzFrag, offset).r;
|
||||
}
|
||||
}
|
||||
sum *= (1.f / 16.f); // 4x4
|
||||
if (sum * (1.f - sum) != 0.f)
|
||||
sum *= (1.0 / 16.0); // 4x4
|
||||
if (sum * (1.0 - sum) != 0.0)
|
||||
{
|
||||
float2 dzBlockers_blockerCount = 0.f;
|
||||
sum = 0.f;
|
||||
float2 dzBlockers_blockerCount = 0.0;
|
||||
sum = 0.0;
|
||||
[unroll] for (int y = -3; y <= 3; ++y)
|
||||
{
|
||||
[unroll] for (int x = -3; x <= 3; ++x)
|
||||
|
@ -125,12 +125,12 @@ float PCF(
|
|||
dzBlockers_blockerCount += float2(dzBlocker, 1);
|
||||
}
|
||||
}
|
||||
const float ret = sum *= (1.f / 45.f); // 7x7 - 4
|
||||
if (dzBlockers_blockerCount.y > 0.f)
|
||||
const float ret = sum *= (1.0 / 45.0); // 7x7 - 4
|
||||
if (dzBlockers_blockerCount.y > 0.0)
|
||||
{
|
||||
const float dzBlockers = dzBlockers_blockerCount.x / dzBlockers_blockerCount.y;
|
||||
const float contrast = ComputePenumbraContrast(config.x, config.y, dzFrag, dzBlockers);
|
||||
return saturate((ret - 0.5f) * contrast + 0.5f);
|
||||
return saturate((ret - 0.5) * contrast + 0.5);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -161,8 +161,8 @@ float ShadowMap(
|
|||
float4 config)
|
||||
{
|
||||
const float ret = PCF(texCmp, samCmp, tex, sam, tc, config);
|
||||
const float2 center = tc.xy * 2.f - 1.f;
|
||||
return max(ret, saturate(dot(center, center) * (9.f / 4.f) - 1.f));
|
||||
const float2 center = tc.xy * 2.0 - 1.0;
|
||||
return max(ret, saturate(dot(center, center) * (9.0 / 4.0) - 1.0));
|
||||
}
|
||||
|
||||
float SimpleShadowMap(
|
||||
|
@ -171,14 +171,14 @@ float SimpleShadowMap(
|
|||
float3 tc)
|
||||
{
|
||||
const float ret = SimplePCF(texCmp, samCmp, tc);
|
||||
const float2 center = tc.xy * 2.f - 1.f;
|
||||
return max(ret, saturate(dot(center, center) * (9.f / 4.f) - 1.f));
|
||||
const float2 center = tc.xy * 2.0 - 1.0;
|
||||
return max(ret, saturate(dot(center, center) * (9.0 / 4.0) - 1.0));
|
||||
}
|
||||
|
||||
bool IsClippedCSM(float4 clipSpacePos)
|
||||
{
|
||||
const float4 absPos = abs(clipSpacePos);
|
||||
return all(absPos.xyz <= absPos.w * float3(1.01f, 1.01f, 1.f));
|
||||
return all(absPos.xyz <= absPos.w * float3(1.01, 1.01, 1.0));
|
||||
}
|
||||
|
||||
float ShadowMapCSM(
|
||||
|
@ -197,51 +197,51 @@ float ShadowMapCSM(
|
|||
float4 config)
|
||||
{
|
||||
#if _SHADOW_QUALITY >= _Q_HIGH
|
||||
float ret = 1.f;
|
||||
float contrast = 1.f;
|
||||
float ret = 1.0;
|
||||
float contrast = 1.0;
|
||||
const float contrastScale = config.w;
|
||||
const float4 clipSpacePos = mul(float4(inPos, 1.f), matScreen);
|
||||
const float4 clipSpacePos = mul(float4(inPos, 1.0), matScreen);
|
||||
const float depth = clipSpacePos.w;
|
||||
|
||||
if (IsClippedCSM(clipSpacePos))
|
||||
{
|
||||
if (depth >= csmSplitRanges.x)
|
||||
{
|
||||
const float fadeStart = (csmSplitRanges.x + csmSplitRanges.w) * 0.5f;
|
||||
const float fadeStart = (csmSplitRanges.x + csmSplitRanges.w) * 0.5;
|
||||
const float fade = saturate((depth - fadeStart) / (csmSplitRanges.w - fadeStart));
|
||||
|
||||
contrast = contrastScale * contrastScale * contrastScale;
|
||||
const float3 tc = mul(float4(biasedPos, 1.f), mat0).xyz;
|
||||
const float3 tc = mul(float4(biasedPos, 1.0), mat0).xyz;
|
||||
ret = max(PCF(texCmp, samCmp, tex, sam, tc, config), fade);
|
||||
}
|
||||
else if (depth >= csmSplitRanges.y)
|
||||
{
|
||||
contrast = contrastScale * contrastScale;
|
||||
const float3 tc = mul(float4(biasedPos, 1.f), mat1).xyz;
|
||||
const float3 tc = mul(float4(biasedPos, 1.0), mat1).xyz;
|
||||
ret = PCF(texCmp, samCmp, tex, sam, tc, config);
|
||||
}
|
||||
else if (depth >= csmSplitRanges.z)
|
||||
{
|
||||
contrast = contrastScale;
|
||||
const float3 tc = mul(float4(biasedPos, 1.f), mat2).xyz;
|
||||
const float3 tc = mul(float4(biasedPos, 1.0), mat2).xyz;
|
||||
ret = PCF(texCmp, samCmp, tex, sam, tc, config);
|
||||
}
|
||||
else
|
||||
{
|
||||
const float3 tc = mul(float4(biasedPos, 1.f), mat3).xyz;
|
||||
const float3 tc = mul(float4(biasedPos, 1.0), mat3).xyz;
|
||||
ret = PCF(texCmp, samCmp, tex, sam, tc, config);
|
||||
}
|
||||
|
||||
return saturate((ret - 0.5f) * contrast + 0.5f);
|
||||
return saturate((ret - 0.5) * contrast + 0.5);
|
||||
}
|
||||
else
|
||||
return 1.f;
|
||||
return 1.0;
|
||||
#else
|
||||
const float3 tc = mul(float4(biasedPos, 1.f), mat0).xyz;
|
||||
if (all(tc.xy >= 0.f) && all(tc.xy < 1.f))
|
||||
const float3 tc = mul(float4(biasedPos, 1.0), mat0).xyz;
|
||||
if (all(tc.xy >= 0.0) && all(tc.xy < 1.0))
|
||||
return ShadowMap(texCmp, samCmp, tex, sam, tc, config);
|
||||
else
|
||||
return 1.f;
|
||||
return 1.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -260,50 +260,50 @@ float SimpleShadowMapCSM(
|
|||
bool clipping = true)
|
||||
{
|
||||
#if _SHADOW_QUALITY >= _Q_HIGH
|
||||
float ret = 1.f;
|
||||
float contrast = 1.f;
|
||||
float ret = 1.0;
|
||||
float contrast = 1.0;
|
||||
const float contrastScale = config.w;
|
||||
const float4 clipSpacePos = mul(float4(inPos, 1.f), matScreen);
|
||||
const float4 clipSpacePos = mul(float4(inPos, 1.0), matScreen);
|
||||
const float depth = clipSpacePos.w;
|
||||
|
||||
if (!clipping || IsClippedCSM(clipSpacePos))
|
||||
{
|
||||
if (depth >= csmSplitRanges.x)
|
||||
{
|
||||
const float fadeStart = (csmSplitRanges.x + csmSplitRanges.w) * 0.5f;
|
||||
const float fadeStart = (csmSplitRanges.x + csmSplitRanges.w) * 0.5;
|
||||
const float fade = saturate((depth - fadeStart) / (csmSplitRanges.w - fadeStart));
|
||||
|
||||
contrast = contrastScale * contrastScale * contrastScale;
|
||||
const float3 tc = mul(float4(biasedPos, 1.f), mat0).xyz;
|
||||
const float3 tc = mul(float4(biasedPos, 1.0), mat0).xyz;
|
||||
ret = max(SimplePCF(texCmp, samCmp, tc), fade);
|
||||
}
|
||||
else if (depth >= csmSplitRanges.y)
|
||||
{
|
||||
contrast = contrastScale * contrastScale;
|
||||
const float3 tc = mul(float4(biasedPos, 1.f), mat1).xyz;
|
||||
const float3 tc = mul(float4(biasedPos, 1.0), mat1).xyz;
|
||||
ret = SimplePCF(texCmp, samCmp, tc);
|
||||
}
|
||||
else if (depth >= csmSplitRanges.z)
|
||||
{
|
||||
contrast = contrastScale;
|
||||
const float3 tc = mul(float4(biasedPos, 1.f), mat2).xyz;
|
||||
const float3 tc = mul(float4(biasedPos, 1.0), mat2).xyz;
|
||||
ret = SimplePCF(texCmp, samCmp, tc);
|
||||
}
|
||||
else
|
||||
{
|
||||
const float3 tc = mul(float4(biasedPos, 1.f), mat3).xyz;
|
||||
const float3 tc = mul(float4(biasedPos, 1.0), mat3).xyz;
|
||||
ret = SimplePCF(texCmp, samCmp, tc);
|
||||
}
|
||||
|
||||
return saturate((ret - 0.5f) * contrast + 0.5f);
|
||||
return saturate((ret - 0.5) * contrast + 0.5);
|
||||
}
|
||||
else
|
||||
return 1.f;
|
||||
return 1.0;
|
||||
#else
|
||||
const float3 tc = mul(float4(biasedPos, 1.f), mat0).xyz;
|
||||
if (all(tc.xy >= 0.f) && all(tc.xy < 1.f))
|
||||
const float3 tc = mul(float4(biasedPos, 1.0), mat0).xyz;
|
||||
if (all(tc.xy >= 0.0) && all(tc.xy < 1.0))
|
||||
return SimpleShadowMap(texCmp, samCmp, tc);
|
||||
else
|
||||
return 1.f;
|
||||
return 1.0;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -2,16 +2,56 @@
|
|||
|
||||
float SinAcos(float x)
|
||||
{
|
||||
return sqrt(saturate(1.f - x * x));
|
||||
return sqrt(saturate(1.0 - x * x));
|
||||
}
|
||||
|
||||
float EnergyNorm(float gloss)
|
||||
{
|
||||
return (gloss + 8.f) * (1.f / (8.f * _PI));
|
||||
return (gloss + 8.0) * (1.0 / (8.0 * _PI));
|
||||
}
|
||||
|
||||
// Aka D:
|
||||
float MicrofacetDistribution(float alphaRoughnessSq, float nDotH)
|
||||
{
|
||||
const float f = (nDotH * nDotH) * (alphaRoughnessSq - 1.0) + 1.0;
|
||||
return alphaRoughnessSq / (f * f);
|
||||
}
|
||||
|
||||
// Aka V:
|
||||
float MaskingShadowingFunction(float alphaRoughnessSq, float nDotL, float nDotV)
|
||||
{
|
||||
const float2 nDotL_nDotV = float2(nDotL, nDotV);
|
||||
const float2 nDotLSq_nDotVSq = nDotL_nDotV * nDotL_nDotV;
|
||||
const float2 ggxl_ggxv = nDotL_nDotV.yx * sqrt(alphaRoughnessSq + (1.0 - alphaRoughnessSq) * nDotLSq_nDotVSq);
|
||||
const float ggx = ggxl_ggxv.x + ggxl_ggxv.y;
|
||||
if (ggx > 0.0)
|
||||
return 0.5 / ggx;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
void VerusLit2(float3 normal, float3 dirToLight, float3 dirToEye, float metallic, float roughness, float3 albedo, out float3 diff, out float3 spec)
|
||||
{
|
||||
const float alphaRoughness = roughness * roughness;
|
||||
const float alphaRoughnessSq = alphaRoughness * alphaRoughness;
|
||||
const float3 hv = normalize(dirToLight + dirToEye);
|
||||
const float nDotL = saturate(dot(normal, dirToLight));
|
||||
const float nDotV = saturate(dot(normal, dirToEye));
|
||||
const float nDotH = saturate(dot(normal, hv));
|
||||
const float vDotH = saturate(dot(dirToEye, hv));
|
||||
|
||||
const float3 diffuse = albedo * (1.0 - metallic);
|
||||
|
||||
const float3 f0 = lerp(0.04, albedo, metallic);
|
||||
const float3 f = f0 + (1.0 - f0) * pow(saturate(1.0 - vDotH), 5.0);
|
||||
|
||||
diff = nDotL * (1 - f) * diffuse;
|
||||
spec = nDotL * f * MicrofacetDistribution(alphaRoughnessSq, nDotH) * MaskingShadowingFunction(alphaRoughnessSq, nDotL, nDotV);
|
||||
|
||||
diff = diff + spec;
|
||||
}
|
||||
|
||||
float4 VerusLit(float3 dirToLight, float3 normal, float3 dirToEye, float gloss,
|
||||
float2 lamScaleBias, float4 aniso = 0.f, float eyeFresnel = 0.f)
|
||||
float2 lamScaleBias, float4 aniso = 0.0, float eyeFresnel = 0.0)
|
||||
{
|
||||
float4 ret = float4(1, 0, 0, 1);
|
||||
const float3 hv = normalize(dirToEye + dirToLight);
|
||||
|
@ -21,14 +61,14 @@ float4 VerusLit(float3 dirToLight, float3 normal, float3 dirToEye, float gloss,
|
|||
const float nDotH = dot(normal, hv);
|
||||
const float aDotH = SinAcos(dot(aniso.xyz, hv));
|
||||
|
||||
const float4 spec = pow(saturate(float4(nDotH, aDotH, 1.f - nDotL, 1.f - nDotE)), float4(gloss, gloss * 8.f, 5, 5));
|
||||
const float4 spec = pow(saturate(float4(nDotH, aDotH, 1.0 - nDotL, 1.0 - nDotE)), float4(gloss, gloss * 8.0, 5, 5));
|
||||
|
||||
const float maxSpec = max(spec.x, spec.y * aniso.w);
|
||||
const float specContrast = 1.f + gloss * (0.5f / 4096.f);
|
||||
const float specContrast = 1.0 + gloss * (0.5 / 4096.0);
|
||||
|
||||
ret.x = saturate(nDotLRaw * -4.f); // For subsurface scattering effect.
|
||||
ret.x = saturate(nDotLRaw * -4.0); // For subsurface scattering effect.
|
||||
ret.y = saturate(nDotL);
|
||||
ret.z = saturate(nDotL * 8.f) * saturate((maxSpec - 0.5f) * specContrast + 0.5f) * EnergyNorm(gloss);
|
||||
ret.z = saturate(nDotL * 8.0) * saturate((maxSpec - 0.5) * specContrast + 0.5) * EnergyNorm(gloss);
|
||||
ret.w = lerp(spec.z, spec.w, eyeFresnel); // For fresnel effect.
|
||||
|
||||
return ret;
|
||||
|
@ -36,9 +76,9 @@ float4 VerusLit(float3 dirToLight, float3 normal, float3 dirToEye, float gloss,
|
|||
|
||||
float ComputePointLightIntensity(float distSq, float radiusSq, float invRadiusSq)
|
||||
{
|
||||
const float scaleFivePercent = 19.f * invRadiusSq;
|
||||
const float invSquareLaw = 1.f / max(0.1f, distSq * scaleFivePercent);
|
||||
const float x = max(0.f, radiusSq - distSq); // Zero at radius.
|
||||
const float scaleFivePercent = 19.0 * invRadiusSq;
|
||||
const float invSquareLaw = 1.0 / max(0.1, distSq * scaleFivePercent);
|
||||
const float x = max(0.0, radiusSq - distSq); // Zero at radius.
|
||||
const float limit = x * x * invRadiusSq * invRadiusSq;
|
||||
return min(invSquareLaw, limit);
|
||||
}
|
||||
|
|
|
@ -2,20 +2,20 @@
|
|||
|
||||
float ComputeNormalZ(float2 v)
|
||||
{
|
||||
return sqrt(saturate(1.f - dot(v.xy, v.xy)));
|
||||
return sqrt(saturate(1.0 - dot(v.xy, v.xy)));
|
||||
}
|
||||
|
||||
float4 NormalMapAA(float4 rawNormal)
|
||||
{
|
||||
float3 normal = rawNormal.agb * -2.f + 1.f; // Dmitry's reverse!
|
||||
float3 normal = rawNormal.agb * -2.0 + 1.0; // Dmitry's reverse!
|
||||
normal.z = ComputeNormalZ(normal.xy);
|
||||
const float len = rawNormal.b + 0.5f;
|
||||
const float len = rawNormal.b + 0.5;
|
||||
return float4(normal, len * len);
|
||||
}
|
||||
|
||||
float ComputeToksvigFactor(float len, float gloss)
|
||||
{
|
||||
return len / lerp(gloss + _SINGULARITY_FIX, 1.f, len);
|
||||
return len / lerp(gloss + _SINGULARITY_FIX, 1.0, len);
|
||||
}
|
||||
|
||||
float3 ComputeNormals(Texture2D tex, SamplerState sam, float2 tc, float damp, int scale = 1)
|
||||
|
@ -29,10 +29,10 @@ float3 ComputeNormals(Texture2D tex, SamplerState sam, float2 tc, float damp, in
|
|||
const float r = damp * tex.Sample(sam, tc, int2(+scale, 0)).r;
|
||||
const float br = damp * tex.Sample(sam, tc, int2(+scale, +scale)).r;
|
||||
|
||||
const float dX = (-47.f * tl - 162.f * l - 47.f * bl) + (47.f * tr + 162.f * r + 47.f * br); // Left + Right.
|
||||
const float dY = (-47.f * tl - 162.f * t - 47.f * tr) + (47.f * bl + 162.f * b + 47.f * br); // Top + Bottom.
|
||||
const float dX = (-47.0 * tl - 162.0 * l - 47.0 * bl) + (47.0 * tr + 162.0 * r + 47.0 * br); // Left + Right.
|
||||
const float dY = (-47.0 * tl - 162.0 * t - 47.0 * tr) + (47.0 * bl + 162.0 * b + 47.0 * br); // Top + Bottom.
|
||||
|
||||
const float3 normal = normalize(float3(dX, dY, 1));
|
||||
|
||||
return normal * 0.5f + 0.5f;
|
||||
return normal * 0.5 + 0.5;
|
||||
}
|
||||
|
|
|
@ -35,16 +35,16 @@ struct PCFO
|
|||
so.posWV[2] = ComputeBezierPoint(inputPatch[nextID].pos.xyz, inputPatch[thisID].pos.xyz, inputPatch[nextID].nrmWV.xyz); \
|
||||
so.clipped = ComputeClipping(matP, so.posWV[0], so.posWV[1], so.posWV[2]); \
|
||||
so.oppositeEdgeTessFactor = ComputeEdgeTessFactor(matP, inputPatch[thisID].pos.xyz, inputPatch[nextID].pos.xyz, viewportSize.xy); \
|
||||
const float3 normal = (inputPatch[thisID].nrmWV.xyz + inputPatch[nextID].nrmWV.xyz) * 0.5f; \
|
||||
so.oppositeEdgeTessFactor = (normal.z < -0.75f) ? 0.f : max(1.f, so.oppositeEdgeTessFactor * (1.f - abs(normal.z * 0.75f)));
|
||||
const float3 normal = (inputPatch[thisID].nrmWV.xyz + inputPatch[nextID].nrmWV.xyz) * 0.5; \
|
||||
so.oppositeEdgeTessFactor = (normal.z < -0.75) ? 0.0 : max(1.0, so.oppositeEdgeTessFactor * (1.0 - abs(normal.z * 0.75)));
|
||||
|
||||
#define _HS_PNAEN_BODY(nrmWV, matP, viewportSize) \
|
||||
const uint thisID = id; \
|
||||
const uint nextID = (thisID < 2) ? thisID + 1 : 0; \
|
||||
const uint thisEX = 3 + 2 * id; \
|
||||
const uint nextEX = thisEX + 1; \
|
||||
const float kA = max(_SINGULARITY_FIX, 1.f - dot(inputPatch[thisID].nrmWV.xyz, inputPatch[thisEX].nrmWV.xyz)); \
|
||||
const float kB = max(_SINGULARITY_FIX, 1.f - dot(inputPatch[nextID].nrmWV.xyz, inputPatch[nextEX].nrmWV.xyz)); \
|
||||
const float kA = max(_SINGULARITY_FIX, 1.0 - dot(inputPatch[thisID].nrmWV.xyz, inputPatch[thisEX].nrmWV.xyz)); \
|
||||
const float kB = max(_SINGULARITY_FIX, 1.0 - dot(inputPatch[nextID].nrmWV.xyz, inputPatch[nextEX].nrmWV.xyz)); \
|
||||
const float sum = kA + kB; \
|
||||
const float ratio = kB / sum; \
|
||||
float3 myCP, exCP; \
|
||||
|
@ -57,8 +57,8 @@ struct PCFO
|
|||
so.posWV[2] = lerp(myCP, exCP, ratio); \
|
||||
so.clipped = ComputeClipping(matP, so.posWV[0], so.posWV[1], so.posWV[2]); \
|
||||
so.oppositeEdgeTessFactor = ComputeEdgeTessFactor(matP, inputPatch[thisID].pos.xyz, inputPatch[nextID].pos.xyz, viewportSize.xy); \
|
||||
const float3 normal = (inputPatch[thisID].nrmWV.xyz + inputPatch[thisEX].nrmWV.xyz + inputPatch[nextID].nrmWV.xyz + inputPatch[nextEX].nrmWV.xyz) * 0.25f; \
|
||||
so.oppositeEdgeTessFactor = (normal.z < -0.75f) ? 0.f : max(1.f, so.oppositeEdgeTessFactor * (1.f - abs(normal.z * 0.75f)));
|
||||
const float3 normal = (inputPatch[thisID].nrmWV.xyz + inputPatch[thisEX].nrmWV.xyz + inputPatch[nextID].nrmWV.xyz + inputPatch[nextEX].nrmWV.xyz) * 0.25; \
|
||||
so.oppositeEdgeTessFactor = (normal.z < -0.75) ? 0.0 : max(1.0, so.oppositeEdgeTessFactor * (1.0 - abs(normal.z * 0.75)));
|
||||
|
||||
// Patch Constant Function, here central bezier control point is calculated:
|
||||
#define _HS_PCF_BODY(matP) \
|
||||
|
@ -75,11 +75,11 @@ struct PCFO
|
|||
const float3 b003 = outputPatch[2].posWV[0]; \
|
||||
const float3 b102 = outputPatch[2].posWV[1]; \
|
||||
const float3 b201 = outputPatch[2].posWV[2]; \
|
||||
const float3 e = (b210 + b120 + b021 + b012 + b102 + b201) * (1.f / 6.f); \
|
||||
const float3 v = (b003 + b030 + b300) * (1.f / 3.f); \
|
||||
so.b111 = e + (e - v) * 0.5f; \
|
||||
const float3 e = (b210 + b120 + b021 + b012 + b102 + b201) * (1.0 / 6.0); \
|
||||
const float3 v = (b003 + b030 + b300) * (1.0 / 3.0); \
|
||||
so.b111 = e + (e - v) * 0.5; \
|
||||
const float b111Clipped = IsClipped(ApplyProjection(so.b111, matP)); \
|
||||
if (outputPatch[0].clipped && outputPatch[1].clipped && outputPatch[2].clipped && b111Clipped) { so.tessFactors[0] = 0.f; }
|
||||
if (outputPatch[0].clipped && outputPatch[1].clipped && outputPatch[2].clipped && b111Clipped) { so.tessFactors[0] = 0.0; }
|
||||
|
||||
#define _DS_INIT_FLAT_POS \
|
||||
const float3 flatPosWV = \
|
||||
|
@ -90,7 +90,7 @@ struct PCFO
|
|||
#define _DS_INIT_SMOOTH_POS \
|
||||
const float3 uvw = domainLocation; \
|
||||
const float3 uvwSq = uvw * uvw; \
|
||||
const float3 uvwSq3 = uvwSq * 3.f; \
|
||||
const float3 uvwSq3 = uvwSq * 3.0; \
|
||||
const float3 smoothPosWV = \
|
||||
outputPatch[0].posWV[0] * uvwSq.x * uvw.x + \
|
||||
outputPatch[1].posWV[0] * uvwSq.y * uvw.y + \
|
||||
|
@ -101,13 +101,13 @@ struct PCFO
|
|||
outputPatch[1].posWV[2] * uvwSq3.z * uvw.y + \
|
||||
outputPatch[2].posWV[1] * uvwSq3.z * uvw.x + \
|
||||
outputPatch[2].posWV[2] * uvwSq3.x * uvw.z + \
|
||||
si.b111 * uvw.x * uvw.y * uvw.z * 6.f
|
||||
si.b111 * uvw.x * uvw.y * uvw.z * 6.0
|
||||
|
||||
float3 ComputeBezierPoint(float3 posA, float3 posB, float3 nrmA)
|
||||
{
|
||||
// Project a 1/3 midpoint on the plane, which is defined by the nearest vertex and it's normal.
|
||||
const float extrudeLen = dot(posB - posA, nrmA);
|
||||
return (2.f * posA + posB - extrudeLen * nrmA) * (1.f / 3.f);
|
||||
return (2.0 * posA + posB - extrudeLen * nrmA) * (1.0 / 3.0);
|
||||
}
|
||||
|
||||
// Optimized version of the projection transform:
|
||||
|
@ -126,13 +126,13 @@ float2 ProjectAndScale(float3 posWV, matrix matP, float2 viewportSize)
|
|||
{
|
||||
const float4 clipSpacePos = ApplyProjection(posWV, matP);
|
||||
const float2 ndcPos = clipSpacePos.xy / clipSpacePos.w;
|
||||
return ndcPos * viewportSize * (32.f / 1080.f);
|
||||
return ndcPos * viewportSize * (32.0 / 1080.0);
|
||||
}
|
||||
|
||||
float IsClipped(float4 clipSpacePos)
|
||||
{
|
||||
const float4 absPos = abs(clipSpacePos);
|
||||
return all(absPos.xyz <= absPos.w * 2.f) ? 0.f : 1.f; // Safe area, because patch can have all points outside, but still be visible.
|
||||
return all(absPos.xyz <= absPos.w * 2.0) ? 0.0 : 1.0; // Safe area, because patch can have all points outside, but still be visible.
|
||||
}
|
||||
|
||||
float ComputeClipping(matrix matP, float3 posA, float3 posB, float3 posC)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
float3 DequantizeUsingDeq3D(float3 v, float3 scale, float3 bias) { return v * scale + bias; }
|
||||
float2 DequantizeUsingDeq2D(float2 v, float2 scale, float2 bias) { return v * scale + bias; }
|
||||
|
||||
float3 NormalizePosition(float3 v) { return v * (1.f / 65535.f) + 0.5f; }
|
||||
float3 NormalizePosition(float3 v) { return v * (1.0 / 65535.0) + 0.5; }
|
||||
|
||||
mataff GetInstMatrix(float4 part0, float4 part1, float4 part2)
|
||||
{
|
||||
|
@ -16,7 +16,7 @@ mataff GetInstMatrix(float4 part0, float4 part1, float4 part2)
|
|||
float3 Warp(float3 pos, float4 center_radInv, float3 offset)
|
||||
{
|
||||
const float3 d = pos - center_radInv.xyz;
|
||||
const float scale = saturate(1.f - dot(d, d) * center_radInv.w);
|
||||
const float scale = saturate(1.0 - dot(d, d) * center_radInv.w);
|
||||
return offset * scale;
|
||||
}
|
||||
|
||||
|
@ -33,5 +33,5 @@ float3 ApplyWarp(float3 pos, float4 zones[32], float4 mask)
|
|||
|
||||
float4 GetWarpScale()
|
||||
{
|
||||
return float4(1, 1.f / 32767.f, 1, 1);
|
||||
return float4(1, 1.0 / 32767.0, 1, 1);
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ FSO mainFS(VSO si)
|
|||
const float4 rawColor = g_tex.Sample(g_sam, si.tc0);
|
||||
|
||||
so.color = rawColor * si.color0;
|
||||
so.color.a *= 1.f - si.additive;
|
||||
so.color.a *= 1.0 - si.additive;
|
||||
|
||||
return so;
|
||||
}
|
||||
|
|
|
@ -43,10 +43,16 @@ FSO mainFS(VSO si)
|
|||
{
|
||||
FSO so;
|
||||
|
||||
so.color = g_tex.SampleLevel(g_sam, si.tc0, 0.f);
|
||||
#ifdef DEF_HEMICUBE_MASK
|
||||
const float weight = ComputeHemicubeMask(si.tc0);
|
||||
so.color = weight;
|
||||
#else
|
||||
so.color = g_tex.SampleLevel(g_sam, si.tc0, 0.0);
|
||||
#endif
|
||||
|
||||
return so;
|
||||
}
|
||||
#endif
|
||||
|
||||
//@main:#
|
||||
//@main:#HemicubeMask HEMICUBE_MASK
|
||||
|
|
|
@ -49,20 +49,20 @@ VSO mainVS(VSI si)
|
|||
const float3 eyePos = g_ubSimpleForestVS._eyePos_clipDistanceOffset.xyz;
|
||||
const float clipDistanceOffset = g_ubSimpleForestVS._eyePos_clipDistanceOffset.w;
|
||||
|
||||
const float pointSpriteSize = si.tc0.x * (1.f / 500.f);
|
||||
const float angle = si.tc0.y * (1.f / 32767.f);
|
||||
const float pointSpriteSize = si.tc0.x * (1.0 / 500.0);
|
||||
const float angle = si.tc0.y * (1.0 / 32767.0);
|
||||
|
||||
const float3 toEye = eyePos - si.pos.xyz;
|
||||
const float distToScreen = length(g_ubSimpleForestVS._eyePosScreen.xyz - si.pos.xyz);
|
||||
|
||||
const float nearAlpha = saturate((distToScreen - 6.f) * (1.f / 3.f)); // From 6m to 9m.
|
||||
const float farAlpha = 1.f - saturate((distToScreen - 900.f) * (1.f / 100.f)); // From 900m to 1000m.
|
||||
const float nearAlpha = saturate((distToScreen - 6.0) * (1.0 / 3.0)); // From 6m to 9m.
|
||||
const float farAlpha = 1.0 - saturate((distToScreen - 900.0) * (1.0 / 100.0)); // From 900m to 1000m.
|
||||
|
||||
so.pos = mul(si.pos, g_ubSimpleForestVS._matWVP);
|
||||
so.tc0 = 0.f;
|
||||
so.tc0 = 0.0;
|
||||
so.dirToEye = toEye;
|
||||
so.posW_depth = float4(si.pos.xyz, so.pos.z);
|
||||
so.color.rgb = RandomColor(si.pos.xz, 0.3f, 0.2f);
|
||||
so.color.rgb = RandomColor(si.pos.xz, 0.3, 0.2);
|
||||
so.color.a = nearAlpha * farAlpha;
|
||||
so.psize = (pointSpriteSize * (g_ubSimpleForestVS._viewportSize.yx * g_ubSimpleForestVS._viewportSize.z)).xyxy;
|
||||
so.psize.xy *= g_ubSimpleForestVS._pointSpriteScale.xy * g_ubSimpleForestVS._matP._m11;
|
||||
|
@ -70,12 +70,12 @@ VSO mainVS(VSI si)
|
|||
|
||||
float2 param0 = toEye.xy;
|
||||
float2 param1 = toEye.zz;
|
||||
param0.y = max(0.f, param0.y); // Only upper hemisphere.
|
||||
param0.y = max(0.0, param0.y); // Only upper hemisphere.
|
||||
param1.y = length(toEye.xz); // Distance in XZ-plane.
|
||||
so.angles.xy = (atan2(param0, param1) + _PI) * (0.5f / _PI); // atan2(x, z) and atan2(max(0.f, y), length(toEye.xz)). From 0 to 1.
|
||||
so.angles.y = (so.angles.y - 0.5f) * 4.f; // Choose this quadrant.
|
||||
so.angles.xy = (atan2(param0, param1) + _PI) * (0.5 / _PI); // atan2(x, z) and atan2(max(0.0, y), length(toEye.xz)). From 0 to 1.
|
||||
so.angles.y = (so.angles.y - 0.5) * 4.0; // Choose this quadrant.
|
||||
so.angles.xy = saturate(so.angles.xy);
|
||||
so.angles.x = frac(so.angles.x - angle + 0.5f); // Turn.
|
||||
so.angles.x = frac(so.angles.x - angle + 0.5); // Turn.
|
||||
|
||||
return so;
|
||||
}
|
||||
|
@ -103,21 +103,21 @@ void mainGS(point VSO si[1], inout TriangleStream<VSO> stream)
|
|||
|
||||
float2 ComputeTexCoords(float2 tc, float2 angles)
|
||||
{
|
||||
const float marginBias = 16.f / 512.f;
|
||||
const float marginScale = 1.f - marginBias * 2.f;
|
||||
const float marginBias = 16.0 / 512.0;
|
||||
const float marginScale = 1.0 - marginBias * 2.0;
|
||||
const float2 tcMargin = tc * marginScale + marginBias;
|
||||
|
||||
const float2 frameCount = float2(16, 16);
|
||||
const float2 frameScale = 1.f / frameCount;
|
||||
const float2 frameBias = floor(min(angles * frameCount + 0.5f, float2(256, frameCount.y - 0.5f)));
|
||||
const float2 frameScale = 1.0 / frameCount;
|
||||
const float2 frameBias = floor(min(angles * frameCount + 0.5, float2(256, frameCount.y - 0.5)));
|
||||
return (tcMargin + frameBias) * frameScale;
|
||||
}
|
||||
|
||||
float ComputeMask(float2 tc, float alpha)
|
||||
{
|
||||
const float2 tcCenter = tc - 0.5f;
|
||||
const float rad = saturate(dot(tcCenter, tcCenter) * 4.f);
|
||||
return saturate(rad + (alpha * 2.f - 1.f));
|
||||
const float2 tcCenter = tc - 0.5;
|
||||
const float rad = saturate(dot(tcCenter, tcCenter) * 4.0);
|
||||
return saturate(rad + (alpha * 2.0 - 1.0));
|
||||
}
|
||||
|
||||
#ifdef _FS
|
||||
|
@ -146,7 +146,7 @@ FSO mainFS(VSO si)
|
|||
|
||||
// GBuffer2:
|
||||
const float2 lamScaleBias = DS_GetLamScaleBias(rawGBuffer2);
|
||||
const float gloss64 = rawGBuffer2.a * 64.f;
|
||||
const float gloss64 = rawGBuffer2.a * 64.0;
|
||||
const float gloss4K = gloss64 * gloss64;
|
||||
|
||||
// <Shadow>
|
||||
|
@ -154,7 +154,7 @@ FSO mainFS(VSO si)
|
|||
{
|
||||
float4 shadowConfig = g_ubSimpleForestFS._shadowConfig;
|
||||
const float lamBiasMask = saturate(lamScaleBias.y * shadowConfig.y);
|
||||
shadowConfig.y = 1.f - lamBiasMask; // Keep penumbra blurry.
|
||||
shadowConfig.y = 1.0 - lamBiasMask; // Keep penumbra blurry.
|
||||
const float3 posForShadow = AdjustPosForShadow(si.posW_depth.xyz, normal, g_ubSimpleForestFS._dirToSun.xyz, depth);
|
||||
shadowMask = SimpleShadowMapCSM(
|
||||
g_texShadowCmp,
|
||||
|
@ -180,14 +180,14 @@ FSO mainFS(VSO si)
|
|||
const float3 specColor = litRet.z * g_ubSimpleForestFS._sunColor.rgb * shadowMask * specMask;
|
||||
|
||||
so.color.rgb = realAlbedo * diffColor + specColor;
|
||||
so.color.a = 1.f;
|
||||
so.color.a = 1.0;
|
||||
|
||||
const float fog = ComputeFog(depth, g_ubSimpleForestFS._fogColor.a, si.posW_depth.y);
|
||||
so.color.rgb = lerp(so.color.rgb, g_ubSimpleForestFS._fogColor.rgb, fog);
|
||||
|
||||
so.color.rgb = ToSafeHDR(so.color.rgb);
|
||||
|
||||
clip(alpha * mask * step(0.f, si.clipDistance) - 0.53f);
|
||||
clip(alpha * mask * step(0.0, si.clipDistance) - 0.53);
|
||||
|
||||
return so;
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ struct VSO
|
|||
float4 color0 : COLOR0;
|
||||
float2 tc0 : TEXCOORD0;
|
||||
float4 posW_depth : TEXCOORD1;
|
||||
#if !defined(DEF_TEXTURE)
|
||||
#if !defined(DEF_TEXTURE) && !defined(DEF_BAKE_AO)
|
||||
float3 nrmW : TEXCOORD2;
|
||||
float3 dirToEye : TEXCOORD3;
|
||||
#endif
|
||||
|
@ -81,12 +81,12 @@ VSO mainVS(VSI si)
|
|||
float3 posW;
|
||||
float3 nrmW;
|
||||
{
|
||||
#ifdef DEF_SKINNED
|
||||
const float4 weights = si.bw * (1.f / 255.f);
|
||||
#if defined(DEF_SKINNED)
|
||||
const float4 weights = si.bw * (1.0 / 255.0);
|
||||
const float4 indices = si.bi;
|
||||
|
||||
float3 posSkinned = 0.f;
|
||||
float3 nrmSkinned = 0.f;
|
||||
float3 posSkinned = 0.0;
|
||||
float3 nrmSkinned = 0.0;
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
|
@ -97,7 +97,7 @@ VSO mainVS(VSI si)
|
|||
|
||||
posW = mul(float4(posSkinned, 1), matW).xyz;
|
||||
nrmW = mul(nrmSkinned, (float3x3)matW);
|
||||
#elif DEF_ROBOTIC
|
||||
#elif defined(DEF_ROBOTIC)
|
||||
const int index = si.pos.w;
|
||||
|
||||
const mataff matBone = g_ubSimpleSkeletonVS._vMatBones[index];
|
||||
|
@ -117,7 +117,7 @@ VSO mainVS(VSI si)
|
|||
so.posW_depth = float4(posW, so.pos.z);
|
||||
so.color0 = userColor;
|
||||
so.tc0 = inTc0;
|
||||
#if !defined(DEF_TEXTURE)
|
||||
#if !defined(DEF_TEXTURE) && !defined(DEF_BAKE_AO)
|
||||
so.nrmW = nrmW;
|
||||
so.dirToEye = eyePos - posW;
|
||||
#endif
|
||||
|
@ -132,11 +132,36 @@ FSO mainFS(VSO si)
|
|||
{
|
||||
FSO so;
|
||||
|
||||
#ifdef DEF_TEXTURE
|
||||
#if defined(DEF_TEXTURE)
|
||||
const float4 rawAlbedo = g_texAlbedo.Sample(g_samAlbedo, si.tc0);
|
||||
so.color.rgb = rawAlbedo.rgb * si.color0.rgb;
|
||||
so.color.rgb = ToSafeHDR(so.color.rgb);
|
||||
so.color.a = 1.f;
|
||||
so.color.a = 1.0;
|
||||
#elif defined(DEF_BAKE_AO)
|
||||
// <Material>
|
||||
const float2 mm_alphaSwitch = g_ubSimplePerMaterialFS._alphaSwitch_anisoSpecDir.xy;
|
||||
const float4 mm_tc0ScaleBias = g_ubSimplePerMaterialFS._tc0ScaleBias;
|
||||
// </Material>
|
||||
|
||||
const float2 tc0 = si.tc0 * mm_tc0ScaleBias.xy + mm_tc0ScaleBias.zw;
|
||||
|
||||
// <Albedo>
|
||||
const float4 rawAlbedo = g_texAlbedo.Sample(g_samAlbedo, tc0);
|
||||
// </Albedo>
|
||||
|
||||
// <Pick>
|
||||
const float2 alpha_spec = AlphaSwitch(rawAlbedo, tc0, mm_alphaSwitch);
|
||||
// </Pick>
|
||||
|
||||
so.color.rgb = rawAlbedo.rgb * si.color0.rgb;
|
||||
|
||||
const float fogFactor = saturate(si.posW_depth.w * g_ubSimplePerFrame._fogColor.a);
|
||||
so.color.rgb = lerp(so.color.rgb, g_ubSimplePerFrame._fogColor.rgb, fogFactor);
|
||||
|
||||
so.color.rgb = ToSafeHDR(so.color.rgb);
|
||||
so.color.a = 1.0;
|
||||
|
||||
clip(alpha_spec.x - 0.5);
|
||||
#else
|
||||
// <Material>
|
||||
const float2 mm_alphaSwitch = g_ubSimplePerMaterialFS._alphaSwitch_anisoSpecDir.xy;
|
||||
|
@ -171,12 +196,12 @@ FSO mainFS(VSO si)
|
|||
|
||||
// <Pick>
|
||||
const float2 alpha_spec = AlphaSwitch(rawAlbedo, tc0, mm_alphaSwitch);
|
||||
const float emitAlpha = PickAlpha(rawAlbedo.rgb, mm_emissionPick, 16.f);
|
||||
const float emitAlpha = PickAlpha(rawAlbedo.rgb, mm_emissionPick, 16.0);
|
||||
const float eyeAlpha = PickAlphaRound(mm_eyePick, tc0);
|
||||
const float glossAlpha = PickAlpha(rawAlbedo.rgb, mm_glossPick, 32.f);
|
||||
const float hairAlpha = round(PickAlpha(rawAlbedo.rgb, mm_hairPick, 16.f));
|
||||
const float skinAlpha = PickAlpha(rawAlbedo.rgb, mm_skinPick, 16.f);
|
||||
const float userAlpha = PickAlpha(rawAlbedo.rgb, mm_userPick, 16.f);
|
||||
const float glossAlpha = PickAlpha(rawAlbedo.rgb, mm_glossPick, 32.0);
|
||||
const float hairAlpha = round(PickAlpha(rawAlbedo.rgb, mm_hairPick, 16.0));
|
||||
const float skinAlpha = PickAlpha(rawAlbedo.rgb, mm_skinPick, 16.0);
|
||||
const float userAlpha = PickAlpha(rawAlbedo.rgb, mm_userPick, 16.0);
|
||||
// </Pick>
|
||||
|
||||
rawAlbedo.rgb = lerp(rawAlbedo.rgb, Overlay(gray, si.color0.rgb), userAlpha * si.color0.a);
|
||||
|
@ -185,15 +210,15 @@ FSO mainFS(VSO si)
|
|||
const float specMask = saturate(alpha_spec.y * mm_specScaleBias.x + mm_specScaleBias.y);
|
||||
|
||||
// <Gloss>
|
||||
float gloss = lerp(4.f, 16.f, alpha_spec.y) * mm_glossScaleBias.x + mm_glossScaleBias.y;
|
||||
float gloss = lerp(4.0, 16.0, alpha_spec.y) * mm_glossScaleBias.x + mm_glossScaleBias.y;
|
||||
gloss = lerp(gloss, mm_gloss, glossAlpha);
|
||||
gloss = lerp(gloss, 4.f + alpha_spec.y, skinAlpha);
|
||||
gloss = lerp(gloss, 0.f, eyeAlpha);
|
||||
gloss = lerp(gloss, 4.0 + alpha_spec.y, skinAlpha);
|
||||
gloss = lerp(gloss, 0.0, eyeAlpha);
|
||||
const float gloss4K = gloss * gloss;
|
||||
// </Gloss>
|
||||
|
||||
// <LambertianScaleBias>
|
||||
const float2 lamScaleBias = lerp(mm_lamScaleBias, float2(1, 0.45f), skinAlpha);
|
||||
const float2 lamScaleBias = lerp(mm_lamScaleBias, float2(1, 0.45), skinAlpha);
|
||||
// </LambertianScaleBias>
|
||||
|
||||
const float3 normal = normalize(si.nrmW);
|
||||
|
@ -205,7 +230,7 @@ FSO mainFS(VSO si)
|
|||
{
|
||||
float4 shadowConfig = g_ubSimplePerFrame._shadowConfig;
|
||||
const float lamBiasMask = saturate(lamScaleBias.y * shadowConfig.y);
|
||||
shadowConfig.y = 1.f - lamBiasMask; // Keep penumbra blurry.
|
||||
shadowConfig.y = 1.0 - lamBiasMask; // Keep penumbra blurry.
|
||||
const float3 posForShadow = AdjustPosForShadow(si.posW_depth.xyz, normal, g_ubSimplePerFrame._dirToSun.xyz, depth);
|
||||
shadowMask = SimpleShadowMapCSM(
|
||||
g_texShadowCmp,
|
||||
|
@ -232,14 +257,14 @@ FSO mainFS(VSO si)
|
|||
const float emission = emitAlpha * mm_emission;
|
||||
|
||||
so.color.rgb = realAlbedo * (diffColor + emission) + specColor;
|
||||
so.color.a = 1.f;
|
||||
so.color.a = 1.0;
|
||||
|
||||
const float fog = ComputeFog(depth, g_ubSimplePerFrame._fogColor.a, si.posW_depth.y);
|
||||
so.color.rgb = lerp(so.color.rgb, g_ubSimplePerFrame._fogColor.rgb, fog);
|
||||
const float fogFactor = ComputeFog(depth, g_ubSimplePerFrame._fogColor.a, si.posW_depth.y);
|
||||
so.color.rgb = lerp(so.color.rgb, g_ubSimplePerFrame._fogColor.rgb, fogFactor);
|
||||
|
||||
so.color.rgb = ToSafeHDR(so.color.rgb);
|
||||
|
||||
clip(alpha_spec.x - 0.5f);
|
||||
clip(alpha_spec.x - 0.5);
|
||||
#endif
|
||||
|
||||
return so;
|
||||
|
@ -255,3 +280,8 @@ FSO mainFS(VSO si)
|
|||
//@main:#TextureInstanced TEXTURE INSTANCED
|
||||
//@main:#TextureRobotic TEXTURE ROBOTIC
|
||||
//@main:#TextureSkinned TEXTURE SKINNED
|
||||
|
||||
//@main:#BakeAO BAKE_AO
|
||||
//@main:#BakeAOInstanced BAKE_AO INSTANCED
|
||||
//@main:#BakeAORobotic BAKE_AO ROBOTIC
|
||||
//@main:#BakeAOSkinned BAKE_AO SKINNED
|
||||
|
|
|
@ -47,7 +47,7 @@ struct FSO
|
|||
float4 color : SV_Target0;
|
||||
};
|
||||
|
||||
static const float g_layerScale = 1.f / 8.f;
|
||||
static const float g_layerScale = 1.0 / 8.0;
|
||||
|
||||
#ifdef _VS
|
||||
VSO mainVS(VSI si)
|
||||
|
@ -59,29 +59,29 @@ VSO mainVS(VSI si)
|
|||
const float clipDistanceOffset = g_ubSimpleTerrainVS._mapSideInv_clipDistanceOffset.y;
|
||||
|
||||
const float2 edgeCorrection = si.pos.yw;
|
||||
si.pos.yw = 0.f;
|
||||
si.pos.yw = 0.0;
|
||||
float3 pos = si.pos.xyz + si.posPatch.xyz;
|
||||
const float2 tcMap = pos.xz * mapSideInv + 0.5f; // Range [0, 1).
|
||||
const float2 posBlend = pos.xz + edgeCorrection * 0.5f;
|
||||
const float2 tcMap = pos.xz * mapSideInv + 0.5; // Range [0, 1).
|
||||
const float2 posBlend = pos.xz + edgeCorrection * 0.5;
|
||||
|
||||
// <HeightAndNormal>
|
||||
float3 inNrm;
|
||||
{
|
||||
const float approxHeight = UnpackTerrainHeight(g_texHeightVS.SampleLevel(g_samHeightVS, tcMap + (0.5f * mapSideInv) * 16.f, 4.f).r);
|
||||
const float approxHeight = UnpackTerrainHeight(g_texHeightVS.SampleLevel(g_samHeightVS, tcMap + (0.5 * mapSideInv) * 16.0, 4.0).r);
|
||||
pos.y = approxHeight;
|
||||
|
||||
const float distToEye = distance(pos, eyePos);
|
||||
const float geomipsLod = log2(clamp(distToEye * (2.f / 100.f), 1.f, 18.f));
|
||||
const float geomipsLod = log2(clamp(distToEye * (2.0 / 100.0), 1.0, 18.0));
|
||||
const float geomipsLodFrac = frac(geomipsLod);
|
||||
const float geomipsLodBase = floor(geomipsLod);
|
||||
const float geomipsLodNext = geomipsLodBase + 1.f;
|
||||
const float2 texelCenterAB = (0.5f * mapSideInv) * exp2(float2(geomipsLodBase, geomipsLodNext));
|
||||
const float geomipsLodNext = geomipsLodBase + 1.0;
|
||||
const float2 texelCenterAB = (0.5 * mapSideInv) * exp2(float2(geomipsLodBase, geomipsLodNext));
|
||||
const float yA = UnpackTerrainHeight(g_texHeightVS.SampleLevel(g_samHeightVS, tcMap + texelCenterAB.xx, geomipsLodBase).r);
|
||||
const float yB = UnpackTerrainHeight(g_texHeightVS.SampleLevel(g_samHeightVS, tcMap + texelCenterAB.yy, geomipsLodNext).r);
|
||||
pos.y = lerp(yA, yB, geomipsLodFrac);
|
||||
|
||||
const float4 rawNormal = g_texNormalVS.SampleLevel(g_samNormalVS, tcMap + texelCenterAB.xx, geomipsLodBase);
|
||||
inNrm = float3(rawNormal.x, 0, rawNormal.y) * 2.f - 1.f;
|
||||
inNrm = float3(rawNormal.x, 0, rawNormal.y) * 2.0 - 1.0;
|
||||
inNrm.y = ComputeNormalZ(inNrm.xz);
|
||||
}
|
||||
// </HeightAndNormal>
|
||||
|
@ -90,9 +90,9 @@ VSO mainVS(VSI si)
|
|||
so.posW_depth = float4(pos, so.pos.z);
|
||||
so.nrmW = mul(inNrm, (float3x3)g_ubSimpleTerrainVS._matW);
|
||||
so.layerForChannel = si.layerForChannel;
|
||||
so.tcBlend = posBlend * mapSideInv + 0.5f;
|
||||
so.tcBlend = posBlend * mapSideInv + 0.5;
|
||||
so.tcLayer_tcMap.xy = pos.xz * g_layerScale;
|
||||
so.tcLayer_tcMap.zw = (pos.xz + 0.5f) * mapSideInv + 0.5f; // Texel's center.
|
||||
so.tcLayer_tcMap.zw = (pos.xz + 0.5) * mapSideInv + 0.5; // Texel's center.
|
||||
so.dirToEye = eyePos - pos;
|
||||
so.clipDistance = pos.y + clipDistanceOffset;
|
||||
|
||||
|
@ -109,7 +109,7 @@ FSO mainFS(VSO si)
|
|||
const float2 tcLayer = si.tcLayer_tcMap.xy;
|
||||
|
||||
const float4 rawBlend = g_texBlend.Sample(g_samBlend, si.tcBlend);
|
||||
float4 weights = float4(rawBlend.rgb, 1.f - dot(rawBlend.rgb, float3(1, 1, 1)));
|
||||
float4 weights = float4(rawBlend.rgb, 1.0 - dot(rawBlend.rgb, float3(1, 1, 1)));
|
||||
|
||||
// <Albedo>
|
||||
float4 albedo;
|
||||
|
@ -122,7 +122,7 @@ FSO mainFS(VSO si)
|
|||
g_texLayers.Sample(g_samLayers, float3(tcLayer, layerForChannel.b)),
|
||||
g_texLayers.Sample(g_samLayers, float3(tcLayer, layerForChannel.a))
|
||||
};
|
||||
float4 accAlbedo = 0.f;
|
||||
float4 accAlbedo = 0.0;
|
||||
accAlbedo += rawAlbedos[0] * weights.r;
|
||||
accAlbedo += rawAlbedos[1] * weights.g;
|
||||
accAlbedo += rawAlbedos[2] * weights.b;
|
||||
|
@ -145,15 +145,15 @@ FSO mainFS(VSO si)
|
|||
{
|
||||
const float dryMask = saturate(si.posW_depth.y);
|
||||
const float dryMask3 = dryMask * dryMask * dryMask;
|
||||
const float wetMask = 1.f - dryMask;
|
||||
const float wetMask = 1.0 - dryMask;
|
||||
const float wetMask3 = wetMask * wetMask * wetMask;
|
||||
realAlbedo *= dryMask3 * 0.5f + 0.5f;
|
||||
specMask = dryMask * saturate(specMask + wetMask3 * wetMask3 * 0.1f);
|
||||
waterGlossBoost = min(32.f, dryMask * wetMask3 * 100.f);
|
||||
realAlbedo *= dryMask3 * 0.5 + 0.5;
|
||||
specMask = dryMask * saturate(specMask + wetMask3 * wetMask3 * 0.1);
|
||||
waterGlossBoost = min(32.0, dryMask * wetMask3 * 100.0);
|
||||
}
|
||||
// </Water>
|
||||
|
||||
const float gloss64 = lerp(3.3f, 15.f, specMask) + waterGlossBoost;
|
||||
const float gloss64 = lerp(3.3, 15.0, specMask) + waterGlossBoost;
|
||||
const float gloss4K = gloss64 * gloss64;
|
||||
|
||||
const float3 normal = normalize(si.nrmW);
|
||||
|
@ -165,7 +165,7 @@ FSO mainFS(VSO si)
|
|||
{
|
||||
float4 shadowConfig = g_ubSimpleTerrainFS._shadowConfig;
|
||||
const float lamBiasMask = saturate(g_ubSimpleTerrainFS._lamScaleBias.y * shadowConfig.y);
|
||||
shadowConfig.y = 1.f - lamBiasMask; // Keep penumbra blurry.
|
||||
shadowConfig.y = 1.0 - lamBiasMask; // Keep penumbra blurry.
|
||||
const float3 posForShadow = AdjustPosForShadow(si.posW_depth.xyz, normal, g_ubSimpleTerrainFS._dirToSun.xyz, depth);
|
||||
shadowMask = SimpleShadowMapCSM(
|
||||
g_texShadowCmp,
|
||||
|
@ -191,7 +191,7 @@ FSO mainFS(VSO si)
|
|||
const float3 specColor = litRet.z * g_ubSimpleTerrainFS._sunColor.rgb * shadowMask * specMask;
|
||||
|
||||
so.color.rgb = realAlbedo * diffColor + specColor;
|
||||
so.color.a = 1.f;
|
||||
so.color.a = 1.0;
|
||||
|
||||
const float fog = ComputeFog(depth, g_ubSimpleTerrainFS._fogColor.a, si.posW_depth.y);
|
||||
so.color.rgb = lerp(so.color.rgb, g_ubSimpleTerrainFS._fogColor.rgb, fog);
|
||||
|
|
|
@ -65,12 +65,12 @@ VSO mainVS(VSI si)
|
|||
const float3 inPos = DequantizeUsingDeq3D(si.pos.xyz, g_ubPerMeshVS._posDeqScale.xyz, g_ubPerMeshVS._posDeqBias.xyz);
|
||||
|
||||
so.pos = mul(float4(inPos, 1), g_ubPerObject._matWVP).xyww; // Peg the depth. (c) ATI
|
||||
so.color0 = pow(saturate(dot(normalize(inPos * float3(1, 0.25f, 1)), g_ubPerFrame._dirToSun.xyz)), 4.f);
|
||||
so.tc0 = float2(g_ubPerFrame._time_cloudiness.x, 0.5f - inPos.y);
|
||||
so.tcStars = inPos.xz * 16.f; // Stars.
|
||||
so.color0 = pow(saturate(dot(normalize(inPos * float3(1, 0.25, 1)), g_ubPerFrame._dirToSun.xyz)), 4.0);
|
||||
so.tc0 = float2(g_ubPerFrame._time_cloudiness.x, 0.5 - inPos.y);
|
||||
so.tcStars = inPos.xz * 16.0; // Stars.
|
||||
#ifdef DEF_CLOUDS
|
||||
so.tcPhaseA = inPos.xz * (4.f - 4.f * inPos.y) + g_ubPerFrame._phaseAB.xy;
|
||||
so.tcPhaseB = inPos.xz * (2.f - 2.f * inPos.y) + g_ubPerFrame._phaseAB.zw;
|
||||
so.tcPhaseA = inPos.xz * (4.0 - 4.0 * inPos.y) + g_ubPerFrame._phaseAB.xy;
|
||||
so.tcPhaseB = inPos.xz * (2.0 - 2.0 * inPos.y) + g_ubPerFrame._phaseAB.zw;
|
||||
#endif
|
||||
|
||||
return so;
|
||||
|
@ -98,62 +98,62 @@ FSO mainFS(VSO si)
|
|||
const float time = g_ubPerFrame._time_cloudiness.x;
|
||||
const float cloudiness = g_ubPerFrame._time_cloudiness.y;
|
||||
|
||||
const float dayRatio = (1.f - abs(0.5f - time) * 1.9f);
|
||||
const float dayRatio = (1.0 - abs(0.5 - time) * 1.9);
|
||||
const float sunAlpha = g_ubPerFrame._sunColor.a;
|
||||
const float sunBoost = si.color0.r * sunAlpha;
|
||||
|
||||
#ifdef DEF_CLOUDS
|
||||
const float3 rawSky = g_texSky.Sample(g_samSky, float2(time, 0.3f)).rgb;
|
||||
const float3 rawRim = g_texSky.Sample(g_samSky, float2(time, 0.4f)).rgb;
|
||||
const float3 rawSky = g_texSky.Sample(g_samSky, float2(time, 0.3)).rgb;
|
||||
const float3 rawRim = g_texSky.Sample(g_samSky, float2(time, 0.4)).rgb;
|
||||
const float colorA = g_texClouds.Sample(g_samClouds, si.tcPhaseA).r;
|
||||
const float colorB = g_texClouds.Sample(g_samClouds, si.tcPhaseB).r;
|
||||
const float4 normalA = g_texCloudsNM.Sample(g_samCloudsNM, si.tcPhaseA);
|
||||
const float4 normalB = g_texCloudsNM.Sample(g_samCloudsNM, si.tcPhaseB);
|
||||
|
||||
const float noon = saturate(g_ubPerFrame._dirToSun.y);
|
||||
const float noonHalf = noon * 0.5f;
|
||||
const float avgColor = (colorA + colorB) * 0.5f;
|
||||
const float negative = 1.f - avgColor;
|
||||
const float3 cloudColor = saturate(Desaturate(rawSky, 0.4f + noonHalf) + 0.4f * noon); // White, bright clouds at noon.
|
||||
const float3 rimColor = saturate(rawRim * 2.f);
|
||||
const float noonHalf = noon * 0.5;
|
||||
const float avgColor = (colorA + colorB) * 0.5;
|
||||
const float negative = 1.0 - avgColor;
|
||||
const float3 cloudColor = saturate(Desaturate(rawSky, 0.4 + noonHalf) + 0.4 * noon); // White, bright clouds at noon.
|
||||
const float3 rimColor = saturate(rawRim * 2.0);
|
||||
|
||||
float3 normal = 1.f - (normalA.agb + normalB.agb);
|
||||
float3 normal = 1.0 - (normalA.agb + normalB.agb);
|
||||
normal.b = ComputeNormalZ(normal.rg);
|
||||
normal.xyz = normal.xzy; // From normal-map space to world.
|
||||
|
||||
const float clearSky = 1.f - cloudiness;
|
||||
const float clearSkySoft = 0.6f + 0.4f * clearSky;
|
||||
const float alpha = saturate((avgColor - clearSky) * 3.f);
|
||||
const float clearSky = 1.0 - cloudiness;
|
||||
const float clearSkySoft = 0.6 + 0.4 * clearSky;
|
||||
const float alpha = saturate((avgColor - clearSky) * 3.0);
|
||||
|
||||
const float directLight = saturate(dot(normal, g_ubPerFrame._dirToSun.xyz)) * sunAlpha;
|
||||
const float edgeMask = saturate((0.9f - alpha) * 2.f);
|
||||
const float glowAmbient = edgeMask * 0.1f + noonHalf * 0.25f + sunBoost * dayRatio;
|
||||
const float edgeMask = saturate((0.9 - alpha) * 2.0);
|
||||
const float glowAmbient = edgeMask * 0.1 + noonHalf * 0.25 + sunBoost * dayRatio;
|
||||
const float glow = saturate(lerp(directLight * directLight, edgeMask, noonHalf) + glowAmbient);
|
||||
const float diff = saturate((0.6f + 0.4f * (max(directLight, negative) + sunBoost)) * dayRatio * clearSkySoft);
|
||||
const float diff = saturate((0.6 + 0.4 * (max(directLight, negative) + sunBoost)) * dayRatio * clearSkySoft);
|
||||
|
||||
const float3 finalColor = saturate(diff * cloudColor + glow * rimColor * clearSkySoft * 0.25f);
|
||||
const float3 finalColor = saturate(diff * cloudColor + glow * rimColor * clearSkySoft * 0.25);
|
||||
|
||||
const float hdrScale = Grayscale(g_ubPerFrame._ambientColor.xyz) * (10.f - 6.f * cloudiness);
|
||||
const float hdrScale = Grayscale(g_ubPerFrame._ambientColor.xyz) * (10.0 - 6.0 * cloudiness);
|
||||
so.color.rgb = finalColor * hdrScale;
|
||||
so.color.a = alpha;
|
||||
|
||||
// <Fog>
|
||||
{
|
||||
const float cloudScale = cloudiness * cloudiness;
|
||||
const float fogBias = 0.01f + 0.49f * cloudScale;
|
||||
const float fogContrast = 1.f + 2.f * cloudScale;
|
||||
const float fog = saturate((si.tc0.y - 0.5f + fogBias) * (fogContrast / fogBias));
|
||||
const float fogBias = 0.01 + 0.49 * cloudScale;
|
||||
const float fogContrast = 1.0 + 2.0 * cloudScale;
|
||||
const float fog = saturate((si.tc0.y - 0.5 + fogBias) * (fogContrast / fogBias));
|
||||
so.color.rgb = lerp(so.color.rgb, g_ubPerFrame._fogColor.rgb, fog);
|
||||
so.color.a = max(so.color.a, fog);
|
||||
}
|
||||
// </Fog>
|
||||
#else
|
||||
const float4 rawSky = g_texSky.Sample(g_samSky, si.tc0);
|
||||
const float3 skyColor = rawSky.rgb + rand * lerp(0.001f, 0.01f, rawSky.rgb); // Dithering.
|
||||
const float3 skyColor = rawSky.rgb + rand * lerp(0.001, 0.01, rawSky.rgb); // Dithering.
|
||||
const float4 rawStars = g_texStars.Sample(g_samStars, si.tcStars);
|
||||
|
||||
const float hdrScale = Grayscale(g_ubPerFrame._ambientColor.xyz) * (4.f + 3.f * sunBoost);
|
||||
so.color = float4(skyColor.rgb * hdrScale + rawStars.rgb * 50.f, 1);
|
||||
const float hdrScale = Grayscale(g_ubPerFrame._ambientColor.xyz) * (4.0 + 3.0 * sunBoost);
|
||||
so.color = float4(skyColor.rgb * hdrScale + rawStars.rgb * 50.0, 1);
|
||||
#endif
|
||||
|
||||
so.color.rgb = ToSafeHDR(so.color.rgb);
|
||||
|
@ -168,14 +168,14 @@ FSO mainSkyBodyFS(VSO_SKY_BODY si)
|
|||
so.color = g_texClouds.Sample(g_samClouds, si.tc0);
|
||||
const float mask = abs(si.height);
|
||||
#ifdef DEF_SUN
|
||||
so.color.rgb *= lerp(float3(1.f, 0.2f, 0.001f), 1.f, mask);
|
||||
so.color.rgb *= (60.f * 1000.f) + (100.f * 1000.f) * mask;
|
||||
so.color.rgb *= lerp(float3(1.0, 0.2, 0.001), 1.0, mask);
|
||||
so.color.rgb *= (60.0 * 1000.0) + (100.0 * 1000.0) * mask;
|
||||
so.color.rgb = ToSafeHDR(so.color.rgb);
|
||||
#endif
|
||||
#ifdef DEF_MOON
|
||||
const float hdrScale = Grayscale(g_ubPerFrame._ambientColor.xyz) * 12.f;
|
||||
so.color.rgb *= lerp(float3(1.f, 0.9f, 0.8f), 1.f, mask);
|
||||
so.color.rgb *= max(100.f, hdrScale);
|
||||
const float hdrScale = Grayscale(g_ubPerFrame._ambientColor.xyz) * 12.0;
|
||||
so.color.rgb *= lerp(float3(1.0, 0.9, 0.8), 1.0, mask);
|
||||
so.color.rgb *= max(100.0, hdrScale);
|
||||
so.color.a *= mask;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ Texture2D g_texDepth : register(t3, space1);
|
|||
SamplerState g_samDepth : register(s3, space1);
|
||||
|
||||
// Normalized diagonal 1/sqrt(1+1+1):
|
||||
static const float g_s = 0.57735f;
|
||||
static const float g_s = 0.57735;
|
||||
static const float3 g_rays[8] =
|
||||
{
|
||||
float3(+g_s, +g_s, +g_s),
|
||||
|
@ -70,35 +70,35 @@ FSO mainFS(VSO si)
|
|||
const float weightScale = g_ubSsaoFS._smallRad_largeRad_weightScale_weightBias.z;
|
||||
const float weightBias = g_ubSsaoFS._smallRad_largeRad_weightScale_weightBias.w;
|
||||
|
||||
const float3 randNormalWV = g_texRandNormals.SampleLevel(g_samRandNormals, si.tcNorm, 0.f).xyz * 2.f - 1.f;
|
||||
const float3 randNormalWV = g_texRandNormals.SampleLevel(g_samRandNormals, si.tcNorm, 0.0).xyz * 2.0 - 1.0;
|
||||
|
||||
const float4 rawGBuffer1 = g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.f);
|
||||
const float4 rawGBuffer1 = g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.0);
|
||||
const float3 normalWV = DS_GetNormal(rawGBuffer1);
|
||||
|
||||
const float rawDepth = g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.f).r;
|
||||
const float rawDepth = g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.0).r;
|
||||
const float originDepth = ToLinearDepth(rawDepth, g_ubSsaoFS._zNearFarEx);
|
||||
|
||||
const float perspectScale = 1.f / originDepth;
|
||||
const float perspectScale = 1.0 / originDepth;
|
||||
const float4 scale = float4(smallRad, smallRad, largeRad, largeRad) * perspectScale * g_ubSsaoFS._camScale.xyxy;
|
||||
|
||||
float2 acc = _SINGULARITY_FIX;
|
||||
[unroll] for (uint i = 0; i < 8; i++)
|
||||
{
|
||||
const float3 randRayWV = reflect(g_rays[i], randNormalWV);
|
||||
const float3 hemiRayWV = randRayWV + normalWV * saturate(-dot(normalWV, randRayWV)) * 2.f;
|
||||
const float3 hemiRayWV = randRayWV + normalWV * saturate(-dot(normalWV, randRayWV)) * 2.0;
|
||||
const float nDotR = saturate(dot(normalWV, hemiRayWV));
|
||||
|
||||
const float3 smallRay = hemiRayWV * float3(scale.xy, smallRad);
|
||||
const float3 largeRay = hemiRayWV * float3(scale.zw, largeRad);
|
||||
|
||||
const float2 rawKernelDepths = float2(
|
||||
g_texDepth.SampleLevel(g_samDepth, si.tc0 + smallRay.xy, 0.f).r,
|
||||
g_texDepth.SampleLevel(g_samDepth, si.tc0 + largeRay.xy, 0.f).r);
|
||||
g_texDepth.SampleLevel(g_samDepth, si.tc0 + smallRay.xy, 0.0).r,
|
||||
g_texDepth.SampleLevel(g_samDepth, si.tc0 + largeRay.xy, 0.0).r);
|
||||
const float2 kernelDepths = ToLinearDepth(rawKernelDepths, g_ubSsaoFS._zNearFarEx);
|
||||
|
||||
const float2 kernelDeeper = kernelDepths - originDepth;
|
||||
const float2 rayCloser = kernelDeeper + float2(smallRay.z, largeRay.z);
|
||||
const float2 visible = step(0.f, rayCloser);
|
||||
const float2 visible = step(0.0, rayCloser);
|
||||
const float weight = saturate(weightBias + weightScale * rayCloser.y) * nDotR;
|
||||
|
||||
acc += float2(min(visible.x, visible.y) * weight, weight);
|
||||
|
|
|
@ -19,10 +19,10 @@ SamplerState g_samEnv : register(s4, space1);
|
|||
|
||||
static const float3 g_tetrahedron[4] =
|
||||
{
|
||||
float3(-1.f, -1.f, -1.f),
|
||||
float3(+1.f, +1.f, -1.f),
|
||||
float3(-1.f, +1.f, +1.f),
|
||||
float3(+1.f, -1.f, +1.f)
|
||||
float3(-1.0, -1.0, -1.0),
|
||||
float3(+1.0, +1.0, -1.0),
|
||||
float3(-1.0, +1.0, +1.0),
|
||||
float3(+1.0, -1.0, +1.0)
|
||||
};
|
||||
|
||||
struct VSI
|
||||
|
@ -44,14 +44,14 @@ struct FSO
|
|||
|
||||
float SoftBorderMask(float2 tc)
|
||||
{
|
||||
const float2 mask = saturate((1.f - abs(0.5f - tc)) * 10.f - 5.f);
|
||||
const float2 mask = saturate((1.0 - abs(0.5 - tc)) * 10.0 - 5.0);
|
||||
return mask.x * mask.y;
|
||||
}
|
||||
|
||||
float AlphaBoost(float alpha)
|
||||
{
|
||||
const float x = 1.f - alpha;
|
||||
return 1.f - x * x;
|
||||
const float x = 1.0 - alpha;
|
||||
return 1.0 - x * x;
|
||||
}
|
||||
|
||||
#ifdef _VS
|
||||
|
@ -81,11 +81,11 @@ FSO mainFS(VSO si)
|
|||
|
||||
// Position:
|
||||
const float2 ndcPos = ToNdcPos(si.tc0);
|
||||
const float rawDepth = g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.f).r;
|
||||
const float rawDepth = g_texDepth.SampleLevel(g_samDepth, si.tc0, 0.0).r;
|
||||
const float3 posWV = DS_GetPosition(rawDepth, g_ubSsrFS._matInvP, ndcPos);
|
||||
|
||||
// Normal:
|
||||
const float4 rawGBuffer1 = g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.f);
|
||||
const float4 rawGBuffer1 = g_texGBuffer1.SampleLevel(g_samGBuffer1, si.tc0, 0.0);
|
||||
const float3 normalWV = DS_GetNormal(rawGBuffer1);
|
||||
|
||||
// Ray from eye:
|
||||
|
@ -95,29 +95,29 @@ FSO mainFS(VSO si)
|
|||
// Reflected ray:
|
||||
const float3 reflectedDir = reflect(rayFromEye, normalWV);
|
||||
const float complement = saturate(dot(-rayFromEye, normalWV));
|
||||
const float fresnel = 1.f - complement * complement;
|
||||
const float fresnel = 1.0 - complement * complement;
|
||||
|
||||
// Environment map:
|
||||
const float3 reflectedDirW = mul(reflectedDir, (float3x3)g_ubSsrFS._matInvV);
|
||||
float3 envColor = 0.f;
|
||||
float3 envColor = 0.0;
|
||||
#if _SHADER_QUALITY <= _Q_MEDIUM
|
||||
envColor = g_texEnv.SampleLevel(g_samEnv, reflectedDirW, 0.f).rgb * fresnel;
|
||||
envColor = g_texEnv.SampleLevel(g_samEnv, reflectedDirW, 0.0).rgb * fresnel;
|
||||
#else
|
||||
[unroll] for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
const float3 dir = reflectedDirW + g_tetrahedron[i] * 0.003f;
|
||||
envColor += g_texEnv.SampleLevel(g_samEnv, dir, 0.f).rgb;
|
||||
const float3 dir = reflectedDirW + g_tetrahedron[i] * 0.003;
|
||||
envColor += g_texEnv.SampleLevel(g_samEnv, dir, 0.0).rgb;
|
||||
}
|
||||
envColor *= 0.25f * fresnel;
|
||||
envColor *= 0.25 * fresnel;
|
||||
#endif
|
||||
|
||||
float4 color = float4(envColor, 0.f);
|
||||
float4 color = float4(envColor, 0.0);
|
||||
|
||||
#ifdef DEF_SSR
|
||||
const float originDepth = ToLinearDepth(rawDepth, g_ubSsrFS._zNearFarEx);
|
||||
const float equalize = equalizeDist / originDepth;
|
||||
|
||||
const float invRadius = 1.f / radius;
|
||||
const float invRadius = 1.0 / radius;
|
||||
#if _SHADER_QUALITY <= _Q_LOW
|
||||
const int maxSampleCount = 6;
|
||||
#elif _SHADER_QUALITY <= _Q_MEDIUM
|
||||
|
@ -138,23 +138,23 @@ FSO mainFS(VSO si)
|
|||
{
|
||||
float4 tcRaySample = mul(float4(kernelPosWV, 1), g_ubSsrFS._matPTex);
|
||||
tcRaySample /= tcRaySample.w;
|
||||
const float rawKernelDepth = g_texDepth.SampleLevel(g_samDepth, tcRaySample.xy, 0.f).r;
|
||||
const float rawKernelDepth = g_texDepth.SampleLevel(g_samDepth, tcRaySample.xy, 0.0).r;
|
||||
|
||||
const float2 rayDepth_texDepth = ToLinearDepth(float2(tcRaySample.z, rawKernelDepth), g_ubSsrFS._zNearFarEx);
|
||||
const float rayDeeper = rayDepth_texDepth.x - rayDepth_texDepth.y;
|
||||
|
||||
if (rayDeeper > 0.f && rayDeeper < thickness) // Ray deeper, but not too deep?
|
||||
if (rayDeeper > 0.0 && rayDeeper < thickness) // Ray deeper, but not too deep?
|
||||
{
|
||||
const float ratio = prevRayDeeper / (prevRayDeeper + rayDeeper);
|
||||
const float2 tcFinal = lerp(prevTcRaySample, tcRaySample.xy, ratio);
|
||||
|
||||
const float tcMask = SoftBorderMask(tcFinal);
|
||||
|
||||
const float distMask = 1.f - ((j + ratio) * stride * invRadius);
|
||||
const float distMask = 1.0 - ((j + ratio) * stride * invRadius);
|
||||
|
||||
const float alpha = tcMask * AlphaBoost(distMask) * fresnel;
|
||||
|
||||
color.rgb = lerp(envColor, g_texColor.SampleLevel(g_samColor, tcFinal, 0.f).rgb, alpha);
|
||||
color.rgb = lerp(envColor, g_texColor.SampleLevel(g_samColor, tcFinal, 0.0).rgb, alpha);
|
||||
color.a = alpha;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -52,16 +52,16 @@ struct FSO
|
|||
float4 color : SV_Target0;
|
||||
};
|
||||
|
||||
static const float g_waterPatchTexelCenter = 0.5f / 1024.f;
|
||||
static const float g_beachTexelCenter = 0.5f / 16.f;
|
||||
static const float g_beachMip = 6.f;
|
||||
static const float g_beachHeightScale = 3.f;
|
||||
static const float g_adjustHeightBy = 0.7f;
|
||||
static const float g_foamScale = 8.f;
|
||||
static const float g_shadeScale = 1.f / 32.f;
|
||||
static const float g_wavesZoneMaskCenter = -10.f;
|
||||
static const float g_wavesZoneMaskContrast = 0.12f;
|
||||
static const float g_wavesMaskScaleBias = 20.f;
|
||||
static const float g_waterPatchTexelCenter = 0.5 / 1024.0;
|
||||
static const float g_beachTexelCenter = 0.5 / 16.0;
|
||||
static const float g_beachMip = 6.0;
|
||||
static const float g_beachHeightScale = 3.0;
|
||||
static const float g_adjustHeightBy = 0.7;
|
||||
static const float g_foamScale = 8.0;
|
||||
static const float g_shadeScale = 1.0 / 32.0;
|
||||
static const float g_wavesZoneMaskCenter = -10.0;
|
||||
static const float g_wavesZoneMaskContrast = 0.12;
|
||||
static const float g_wavesMaskScaleBias = 20.0;
|
||||
|
||||
float2 GetWaterHeightAt(
|
||||
Texture2D texTerrainHeightmap, SamplerState samTerrainHeightmap,
|
||||
|
@ -70,19 +70,19 @@ float2 GetWaterHeightAt(
|
|||
float distToEye, float distToMipScale, float landDistToMipScale)
|
||||
{
|
||||
const float2 tc = pos * waterScale;
|
||||
const float2 tcLand = pos * mapSideInv + 0.5f;
|
||||
const float2 tcLand = pos * mapSideInv + 0.5;
|
||||
|
||||
float landHeight;
|
||||
{
|
||||
const float mip = log2(max(1.f, distToEye * landDistToMipScale));
|
||||
const float texelCenter = 0.5f * mapSideInv * exp2(mip);
|
||||
const float mip = log2(max(1.0, distToEye * landDistToMipScale));
|
||||
const float texelCenter = 0.5 * mapSideInv * exp2(mip);
|
||||
landHeight = UnpackTerrainHeight(texTerrainHeightmap.SampleLevel(samTerrainHeightmap, tcLand + texelCenter, mip).r);
|
||||
}
|
||||
const float landMask = ToLandMask(landHeight);
|
||||
|
||||
float seaWaterHeight;
|
||||
{
|
||||
const float mip = log2(max(1.f, distToEye * distToMipScale));
|
||||
const float mip = log2(max(1.0, distToEye * distToMipScale));
|
||||
const float texelCenter = g_waterPatchTexelCenter * exp2(mip);
|
||||
seaWaterHeight = texGenHeightmap.SampleLevel(samGenHeightmap, tc + texelCenter, mip).r;
|
||||
}
|
||||
|
@ -124,20 +124,20 @@ VSO mainVS(VSI si)
|
|||
// <Waves>
|
||||
float wave;
|
||||
{
|
||||
const float phaseShift = saturate(g_texFoamVS.SampleLevel(g_samFoamVS, tc0 * g_shadeScale, 4.f).r * 2.f);
|
||||
const float wavesZoneMask = saturate(1.f - g_wavesZoneMaskContrast * abs(height_landHeight.y - g_wavesZoneMaskCenter));
|
||||
const float2 wavesMaskCenter = frac(wavePhase + phaseShift + float2(0.f, 0.5f)) * g_wavesMaskScaleBias - g_wavesMaskScaleBias;
|
||||
const float2 absDeltaAsym = AsymAbs(height_landHeight.y - wavesMaskCenter, -1.f, 3.f);
|
||||
const float wavesMask = smoothstep(0.f, 1.f, saturate(1.f - 0.15f * min(absDeltaAsym.x, absDeltaAsym.y)));
|
||||
const float phaseShift = saturate(g_texFoamVS.SampleLevel(g_samFoamVS, tc0 * g_shadeScale, 4.0).r * 2.0);
|
||||
const float wavesZoneMask = saturate(1.0 - g_wavesZoneMaskContrast * abs(height_landHeight.y - g_wavesZoneMaskCenter));
|
||||
const float2 wavesMaskCenter = frac(wavePhase + phaseShift + float2(0.0, 0.5)) * g_wavesMaskScaleBias - g_wavesMaskScaleBias;
|
||||
const float2 absDeltaAsym = AsymAbs(height_landHeight.y - wavesMaskCenter, -1.0, 3.0);
|
||||
const float wavesMask = smoothstep(0.0, 1.0, saturate(1.0 - 0.15 * min(absDeltaAsym.x, absDeltaAsym.y)));
|
||||
wave = wavesMask * wavesZoneMask;
|
||||
}
|
||||
// </Waves>
|
||||
|
||||
posW.y = height_landHeight.x + wave * 2.f * saturate(1.f / (distToEye * 0.01f));
|
||||
posW.y = height_landHeight.x + wave * 2.0 * saturate(1.0 / (distToEye * 0.01));
|
||||
|
||||
so.pos = mul(float4(posW, 1), g_ubWaterVS._matVP);
|
||||
so.tc0 = tc0;
|
||||
so.tcLand_height.xy = (posW.xz + 0.5f) * mapSideInv + 0.5f;
|
||||
so.tcLand_height.xy = (posW.xz + 0.5) * mapSideInv + 0.5;
|
||||
so.tcLand_height.z = height_landHeight.x;
|
||||
so.tcScreen = mul(float4(posW, 1), g_ubWaterVS._matScreen);
|
||||
so.dirToEye_depth.xyz = dirToEye;
|
||||
|
@ -161,7 +161,7 @@ FSO mainFS(VSO si)
|
|||
const float3 dirToEye = normalize(si.dirToEye_depth.xyz);
|
||||
const float depth = si.dirToEye_depth.w;
|
||||
|
||||
const float4 tcScreenInv = 1.f / si.tcScreen;
|
||||
const float4 tcScreenInv = 1.0 / si.tcScreen;
|
||||
const float perspectScale = tcScreenInv.z;
|
||||
const float2 tcScreen = si.tcScreen.xy * tcScreenInv.w;
|
||||
|
||||
|
@ -174,25 +174,25 @@ FSO mainFS(VSO si)
|
|||
beachWaterHeight = g_texGenHeightmap.SampleLevel(g_samGenHeightmap, si.tc0 + g_beachTexelCenter, g_beachMip).r * g_beachHeightScale + g_adjustHeightBy;
|
||||
landHeight = UnpackTerrainHeight(g_texTerrainHeightmap.Sample(g_samTerrainHeightmap, si.tcLand_height.xy).r);
|
||||
landMask = ToLandMask(landHeight - beachWaterHeight);
|
||||
landMaskStatic = lerp(saturate((ToLandMask(landHeight) - 0.8f) * 5.f), landMask, 0.1f);
|
||||
landMaskStatic = lerp(saturate((ToLandMask(landHeight) - 0.8) * 5.0), landMask, 0.1);
|
||||
}
|
||||
const float alpha = saturate((1.f - landMask) * 20.f);
|
||||
const float alpha = saturate((1.0 - landMask) * 20.0);
|
||||
// </Land>
|
||||
|
||||
// <Waves>
|
||||
float wave;
|
||||
float fresnelDimmer; // A trick to make waves look more 3D.
|
||||
{
|
||||
const float phaseShift = saturate(g_texFoam.SampleLevel(g_samFoam, si.tc0 * g_shadeScale, 4.f).r * 2.f);
|
||||
const float wavesZoneMask = saturate(1.f - g_wavesZoneMaskContrast * abs(landHeight - g_wavesZoneMaskCenter));
|
||||
const float2 wavesMaskCenter = frac(wavePhase + phaseShift + float2(0.f, 0.5f)) * g_wavesMaskScaleBias - g_wavesMaskScaleBias;
|
||||
const float phaseShift = saturate(g_texFoam.SampleLevel(g_samFoam, si.tc0 * g_shadeScale, 4.0).r * 2.0);
|
||||
const float wavesZoneMask = saturate(1.0 - g_wavesZoneMaskContrast * abs(landHeight - g_wavesZoneMaskCenter));
|
||||
const float2 wavesMaskCenter = frac(wavePhase + phaseShift + float2(0.0, 0.5)) * g_wavesMaskScaleBias - g_wavesMaskScaleBias;
|
||||
const float2 delta = landHeight - wavesMaskCenter;
|
||||
const float2 absDelta = abs(delta);
|
||||
const float2 absDeltaAsym = AsymAbs(delta, -1.f, 3.5f);
|
||||
const float wavesMask = saturate(1.f - 0.5f * min(absDeltaAsym.x, absDeltaAsym.y));
|
||||
const float2 absDeltaAsym = AsymAbs(delta, -1.0, 3.5);
|
||||
const float wavesMask = saturate(1.0 - 0.5 * min(absDeltaAsym.x, absDeltaAsym.y));
|
||||
wave = wavesMask * wavesZoneMask;
|
||||
const float biggerWavesMask = saturate(1.f - 0.5f * min(absDelta.x, absDelta.y));
|
||||
fresnelDimmer = saturate(1.f - biggerWavesMask * wavesZoneMask * 1.5f);
|
||||
const float biggerWavesMask = saturate(1.0 - 0.5 * min(absDelta.x, absDelta.y));
|
||||
fresnelDimmer = saturate(1.0 - biggerWavesMask * wavesZoneMask * 1.5);
|
||||
}
|
||||
// </Waves>
|
||||
|
||||
|
@ -200,7 +200,7 @@ FSO mainFS(VSO si)
|
|||
float3 normal;
|
||||
{
|
||||
const float3 rawNormal = g_texGenNormals.Sample(g_samGenNormals, si.tc0).rgb;
|
||||
const float3 normalWithLand = lerp(rawNormal, float3(0.5f, 0.5f, 1), saturate(landMask * 0.8f + wave));
|
||||
const float3 normalWithLand = lerp(rawNormal, float3(0.5, 0.5, 1), saturate(landMask * 0.8 + wave));
|
||||
normal = normalize(normalWithLand.xzy * float3(-2, 2, -2) + float3(1, -1, 1));
|
||||
}
|
||||
// </Normal>
|
||||
|
@ -208,35 +208,35 @@ FSO mainFS(VSO si)
|
|||
// <Reflection>
|
||||
float3 reflectColor;
|
||||
{
|
||||
const float fudgeFactor = 32.f;
|
||||
const float fudgeFactor = 32.0;
|
||||
const float3 flatReflect = reflect(-dirToEye, float3(0, 1, 0));
|
||||
const float3 bumpReflect = reflect(-dirToEye, normal);
|
||||
const float3 delta = bumpReflect - flatReflect;
|
||||
const float2 viewSpaceOffsetPerMeter = mul(float4(delta, 0), g_ubWaterFS._matV).xy;
|
||||
const float2 offset = viewSpaceOffsetPerMeter * saturate(perspectScale) * camScale * fudgeFactor;
|
||||
reflectColor = g_texReflection.Sample(g_samReflection, tcScreen + max(offset, float2(-1, 0))).rgb;
|
||||
reflectColor = ReflectionDimming(reflectColor, 0.8f);
|
||||
reflectColor = ReflectionDimming(reflectColor, 0.8);
|
||||
}
|
||||
// </Reflection>
|
||||
|
||||
// <Refraction>
|
||||
float3 refractColor;
|
||||
{
|
||||
const float fudgeFactor = (0.1f + 0.9f * abs(dirToEye.y) * abs(dirToEye.y)) * 2.5f;
|
||||
const float fudgeFactor = (0.1 + 0.9 * abs(dirToEye.y) * abs(dirToEye.y)) * 2.5;
|
||||
const float waterDepth = -landHeight;
|
||||
const float2 tcScreen2 = tcScreen * 2.f - 1.f;
|
||||
const float2 tcScreen2 = tcScreen * 2.0 - 1.0;
|
||||
const float mask = saturate(dot(tcScreen2, tcScreen2));
|
||||
const float3 bumpRefract = refract(-dirToEye, normal, 1.f / 1.33f);
|
||||
const float3 bumpRefract = refract(-dirToEye, normal, 1.0 / 1.33);
|
||||
const float3 delta = bumpRefract + dirToEye;
|
||||
const float2 viewSpaceOffsetPerMeter = mul(float4(delta, 0), g_ubWaterFS._matV).xy * (1.f - mask);
|
||||
const float2 viewSpaceOffsetPerMeter = mul(float4(delta, 0), g_ubWaterFS._matV).xy * (1.0 - mask);
|
||||
const float2 offset = viewSpaceOffsetPerMeter * waterDepth * saturate(perspectScale) * camScale * fudgeFactor;
|
||||
const float2 tcRefractR = tcScreen + offset * 0.9f;
|
||||
const float2 tcRefractG = tcScreen + offset * 1.f;
|
||||
const float2 tcRefractB = tcScreen + offset * 1.1f;
|
||||
const float2 tcRefractR = tcScreen + offset * 0.9;
|
||||
const float2 tcRefractG = tcScreen + offset * 1.0;
|
||||
const float2 tcRefractB = tcScreen + offset * 1.1;
|
||||
refractColor = float3(
|
||||
g_texRefraction.SampleLevel(g_samRefraction, tcRefractR, 0.f).r,
|
||||
g_texRefraction.SampleLevel(g_samRefraction, tcRefractG, 0.f).g,
|
||||
g_texRefraction.SampleLevel(g_samRefraction, tcRefractB, 0.f).b);
|
||||
g_texRefraction.SampleLevel(g_samRefraction, tcRefractR, 0.0).r,
|
||||
g_texRefraction.SampleLevel(g_samRefraction, tcRefractG, 0.0).g,
|
||||
g_texRefraction.SampleLevel(g_samRefraction, tcRefractB, 0.0).b);
|
||||
}
|
||||
// </Refraction>
|
||||
|
||||
|
@ -247,24 +247,24 @@ FSO mainFS(VSO si)
|
|||
float foamHeightAlpha;
|
||||
{
|
||||
const float2 tcFoam = si.tc0 * g_foamScale;
|
||||
const float2 tcFoamA = tcFoam + phase + float2(0.5f, 0.f);
|
||||
const float2 tcFoamA = tcFoam + phase + float2(0.5, 0.0);
|
||||
const float2 tcFoamB = tcFoam - phase;
|
||||
const float3 foamColorA = g_texFoam.Sample(g_samFoam, tcFoamA).rgb;
|
||||
const float3 foamColorB = g_texFoam.Sample(g_samFoam, tcFoamB).rgb;
|
||||
foamColor.rgb = lerp(foamColorA, foamColorB, 0.5f);
|
||||
foamColor.a = saturate(foamColor.b * 2.f);
|
||||
foamColor.rgb = lerp(foamColorA, foamColorB, 0.5);
|
||||
foamColor.a = saturate(foamColor.b * 2.0);
|
||||
|
||||
const float a = saturate(height - 0.1f);
|
||||
const float a = saturate(height - 0.1);
|
||||
const float a2 = a * a;
|
||||
const float a4 = a2 * a2;
|
||||
foamHeightAlpha = saturate(a4 * a4 + wave * 0.75f);
|
||||
foamHeightAlpha = saturate(a4 * a4 + wave * 0.75);
|
||||
|
||||
const float complement = 1.f - shade;
|
||||
const float mask = saturate((landMask - 0.9f) * 10.f * (1.f - shade * 3.f)) * complement * complement;
|
||||
const float superfoam = saturate(mask * (1.f - mask) * 3.f);
|
||||
foamColor = lerp(foamColor, 1.f, max(superfoam * superfoam, saturate(wave * 0.75f)));
|
||||
const float complement = 1.0 - shade;
|
||||
const float mask = saturate((landMask - 0.9) * 10.0 * (1.0 - shade * 3.0)) * complement * complement;
|
||||
const float superfoam = saturate(mask * (1.0 - mask) * 3.0);
|
||||
foamColor = lerp(foamColor, 1.0, max(superfoam * superfoam, saturate(wave * 0.75)));
|
||||
}
|
||||
const float foamAlpha = 0.002f + 0.998f * saturate(landMaskStatic + foamHeightAlpha) * foamColor.a;
|
||||
const float foamAlpha = 0.002 + 0.998 * saturate(landMaskStatic + foamHeightAlpha) * foamColor.a;
|
||||
// </Foam>
|
||||
|
||||
// <Plankton>
|
||||
|
@ -273,22 +273,22 @@ FSO mainFS(VSO si)
|
|||
{
|
||||
const float diffuseMask = ToWaterDiffuseMask(landHeight);
|
||||
planktonColor = lerp(g_ubWaterFS._diffuseColorDeep.rgb, g_ubWaterFS._diffuseColorShallow.rgb, diffuseMask);
|
||||
planktonColor *= 0.1f + 0.2f * saturate(shade - wave);
|
||||
refractMask = saturate((diffuseMask - 0.75f) * 4.f);
|
||||
planktonColor *= 0.1 + 0.2 * saturate(shade - wave);
|
||||
refractMask = saturate((diffuseMask - 0.75) * 4.0);
|
||||
}
|
||||
// </Plankton>
|
||||
|
||||
const float spec = lerp(1.f, 0.1f, foamAlpha);
|
||||
const float gloss = lerp(1200.f, 4.f, foamAlpha);
|
||||
const float spec = lerp(1.0, 0.1, foamAlpha);
|
||||
const float gloss = lerp(1200.0, 4.0, foamAlpha);
|
||||
|
||||
const float2 lamScaleBias = float2(1, 0.2f);
|
||||
const float2 lamScaleBias = float2(1, 0.2);
|
||||
|
||||
// <Shadow>
|
||||
float shadowMask;
|
||||
{
|
||||
float4 shadowConfig = g_ubWaterFS._shadowConfig;
|
||||
const float lamBiasMask = saturate(lamScaleBias.y * shadowConfig.y);
|
||||
shadowConfig.y = 1.f - lamBiasMask; // Keep penumbra blurry.
|
||||
shadowConfig.y = 1.0 - lamBiasMask; // Keep penumbra blurry.
|
||||
const float3 posForShadow = AdjustPosForShadow(si.posW, normal, g_ubWaterFS._dirToSun.xyz, depth);
|
||||
shadowMask = ShadowMapCSM(
|
||||
g_texShadowCmp,
|
||||
|
@ -311,9 +311,9 @@ FSO mainFS(VSO si)
|
|||
gloss,
|
||||
lamScaleBias,
|
||||
float4(0, 0, 1, 0),
|
||||
1.f);
|
||||
1.0);
|
||||
|
||||
const float fresnelTerm = FresnelSchlick(0.03f, 0.6f * fresnelDimmer, litRet.w);
|
||||
const float fresnelTerm = FresnelSchlick(0.03, 0.6 * fresnelDimmer, litRet.w);
|
||||
|
||||
const float3 diff = litRet.y * g_ubWaterFS._sunColor.rgb * shadowMask + g_ubWaterFS._ambientColor.rgb;
|
||||
const float3 diffColorFoam = foamColor.rgb * diff;
|
||||
|
@ -323,10 +323,10 @@ FSO mainFS(VSO si)
|
|||
|
||||
const float fog = ComputeFog(depth, g_ubWaterFS._fogColor.a);
|
||||
|
||||
so.color.rgb = lerp(diffColor * (1.f - fresnelTerm) + specColor, g_ubWaterFS._fogColor.rgb, fog);
|
||||
so.color.rgb = lerp(diffColor * (1.0 - fresnelTerm) + specColor, g_ubWaterFS._fogColor.rgb, fog);
|
||||
so.color.a = alpha;
|
||||
|
||||
clip(so.color.a - 0.01f);
|
||||
clip(so.color.a - 0.01);
|
||||
|
||||
return so;
|
||||
}
|
||||
|
|
|
@ -66,16 +66,16 @@ FSO mainGenHeightmapFS(VSO si)
|
|||
float2(-1, +0),
|
||||
float2(+0, -1)
|
||||
};
|
||||
const float4 offsets = float4(0, 0.3f, 0.5f, 0.7f);
|
||||
float accHeight = 0.f;
|
||||
const float4 offsets = float4(0, 0.3, 0.5, 0.7);
|
||||
float accHeight = 0.0;
|
||||
[unroll] for (uint i = 0; i < 4; ++i)
|
||||
{
|
||||
float height = g_texSourceHeightmap.SampleLevel(g_samSourceHeightmap, (si.tc0 + offsets[i]) * (i / 2 + 1) + g_ubGenHeightmapFS._phase.x * dirs[i], 0.f).r - 0.5f;
|
||||
float height = g_texSourceHeightmap.SampleLevel(g_samSourceHeightmap, (si.tc0 + offsets[i]) * (i / 2 + 1) + g_ubGenHeightmapFS._phase.x * dirs[i], 0.0).r - 0.5;
|
||||
height *= amplitudes[i]; // Must be local float4 to work in D3D12!
|
||||
accHeight += height;
|
||||
}
|
||||
const float splash = max(0.f, accHeight);
|
||||
so.color = accHeight * 2.f + splash * splash * splash * 16.f;
|
||||
const float splash = max(0.0, accHeight);
|
||||
so.color = accHeight * 2.0 + splash * splash * splash * 16.0;
|
||||
|
||||
return so;
|
||||
}
|
||||
|
@ -86,9 +86,9 @@ FSO mainGenNormalsFS(VSO si)
|
|||
{
|
||||
FSO so;
|
||||
|
||||
const float damp = (1.f / 512.f / 2.f) * g_ubGenNormalsFS._waterScale.x * g_ubGenNormalsFS._textureSize.x;
|
||||
const float damp = (1.0 / 512.0 / 2.0) * g_ubGenNormalsFS._waterScale.x * g_ubGenNormalsFS._textureSize.x;
|
||||
so.color.rgb = ComputeNormals(g_texGenHeightmap, g_samGenHeightmap, si.tc0, damp, 2);
|
||||
so.color.a = 1.f;
|
||||
so.color.a = 1.0;
|
||||
|
||||
return so;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue