Skip to content

Commit

Permalink
Cook-Torrance split-sum BRDF lookup texture
Browse files Browse the repository at this point in the history
  • Loading branch information
Benualdo committed Nov 3, 2024
1 parent 8bd4481 commit a980ac5
Show file tree
Hide file tree
Showing 21 changed files with 119 additions and 52 deletions.
Binary file added data/Engine/BRDF/CookTorrance.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions data/Scenes/Aiguelongue.scene
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,7 @@
<Property type="String" name="m_resourcePath" flags="NotVisible" value="data/Textures/EnvMaps/Default.psd"/>
</Object>
</Property>
<Property type="Float" name="m_environmentAmbientIntensity" flags="HasRange" value="0.25"/>
<Property type="Float" name="m_environmentAmbientIntensity" flags="HasRange" value="0.15000001"/>
</Object>
</Property>
<Property type="ObjectPtrVector" name="m_children" flags="NotVisible">
Expand Down Expand Up @@ -655,8 +655,8 @@
<Property type="Uint2" name="m_shadowSize" x="50" y="50"/>
<Property type="Uint2" name="m_shadowResolution" x="4096" y="4096"/>
<Property type="Float" name="m_shadowIntensity" flags="HasRange" value="1"/>
<Property type="Float4" name="m_color" flags="" x="0.94999999" y="0.94999999" z="0.89999998" w="0.412"/>
<Property type="Float" name="m_intensity" flags="HasRange" value="0.85000002"/>
<Property type="Float4" name="m_color" flags="" x="1" y="1" z="1" w="1"/>
<Property type="Float" name="m_intensity" flags="HasRange" value="1"/>
</Object>
</Property>
</Object>
Expand Down
13 changes: 12 additions & 1 deletion data/Shaders/background/background.hlsl
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
#include "system/semantics.hlsli"
#include "system/table.hlsli"
#include "system/view.hlsli"
#include "system/bindless.hlsli"
#include "system/samplers.hlsli"
#include "system/environment.hlsli"
#include "background.hlsli"

struct VS_Output_Quad
Expand Down Expand Up @@ -26,7 +31,13 @@ PS_Output_Quad PS_Gradient(VS_Output_Quad _input)
{
PS_Output_Quad output;
float2 uv = _input.uv;
output.color0 = rootConstants.color;

//output.color0 = rootConstants.color;

ViewConstants viewConstants;
viewConstants.Load(getBuffer(RESERVEDSLOT_BUFSRV_VIEWCONSTANTS));
output.color0 = float4(getEnvironmentBackgroundColor(uv, viewConstants), 1);

return output;
}

Expand Down
13 changes: 9 additions & 4 deletions data/Shaders/lighting/deferredLighting.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "system/view.hlsli"
#include "system/lighting.hlsli"
#include "system/msaa.hlsli"
#include "system/environment.hlsli"

struct DepthStencilSample
{
Expand Down Expand Up @@ -45,11 +46,10 @@ struct GBufferSample

float3 shadeSample(GBufferSample _gbuffer, DepthStencilSample _depthStencil, float2 _uv, ViewConstants _viewConstants)
{
#if SAMPLE_COUNT > 1
if (_depthStencil.depth >= 1.0f)
{
float3 envColor = _viewConstants.getEnvironmentColor();
return envColor;
}
return getEnvironmentBackgroundColor(_uv, _viewConstants);
#endif

float3 worldPos = _viewConstants.getWorldPos(_uv, _depthStencil.depth);
float3 camPos = _viewConstants.getCameraPos();
Expand Down Expand Up @@ -157,6 +157,11 @@ void CS_DeferredLighting(int2 dispatchThreadID : SV_DispatchThreadID)
// Deferred shading result
float3 color[SAMPLE_COUNT];

#if SAMPLE_COUNT == 1
if (depthStencilSamples[0].depth >= 1.0f)
return;
#endif

// Shade sample 0
color[0] = shadeSample(gbufferSamples[0], depthStencilSamples[0], uv, viewConstants);

Expand Down
7 changes: 5 additions & 2 deletions data/Shaders/system/bindless.hlsli
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#pragma once
#ifndef _BINDLESS__HLSLI_
#define _BINDLESS__HLSLI_

#ifdef __cplusplus
#error bindless.hlsli should not be included from C++
Expand Down Expand Up @@ -71,4 +72,6 @@ DECL_DESCRIPTOR_RANGE_RO(RaytracingAccelerationStructure, g_TLASTable, BINDLESS_
//
//RaytracingAccelerationStructure getTLAS(uint _handle) { return g_TLASTable[_handle - BINDLESS_TLAS_START]; }

#endif // __cplusplus
#endif // __cplusplus

#endif // _BINDLESS__HLSLI_
5 changes: 4 additions & 1 deletion data/Shaders/system/displaymodes.hlsli
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#pragma once
#ifndef _DISPLAY_MODES__HLSLI_
#define _DISPLAY_MODES__HLSLI_

#include "types.hlsli"

Expand Down Expand Up @@ -61,3 +62,5 @@ vg_enum(DisplayFlags, uint,
AlbedoMap = 0x00000001,
NormalMap = 0x00000002
);

#endif
26 changes: 26 additions & 0 deletions data/Shaders/system/environment.hlsli
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef _ENVIRONMENT__HLSLI_
#define _ENVIRONMENT__HLSLI_

float3 getEnvironmentBackgroundColor(float2 _uv, ViewConstants _viewConstants)
{
//uint ambientCubemapTexHandle = _viewConstants.getEnvironmentTextureHandle();
//
//if (ReservedSlot::InvalidTextureCube != (ReservedSlot)ambientCubemapTexHandle)
//{
// float4 clipPos = float4(_uv*2-1, 1,1);
// float4 viewPos = mul(clipPos, _viewConstants.getProjInv());
// viewPos.xz *= -1;
// float4 worldPos = mul(viewPos, _viewConstants.getViewInv());
// worldPos.xyz *= -1;
//
// TextureCube cubemap = getTextureCube(ambientCubemapTexHandle);
// return cubemap.Sample(linearClamp, normalize(worldPos));
//}
//else
{
float3 envColor = _viewConstants.getEnvironmentColor();
return envColor;
}
}

#endif // _ENVIRONMENT__HLSLI_
33 changes: 18 additions & 15 deletions data/Shaders/system/lighting.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,13 @@ float gaSchlickGGX(float cosLi, float cosLo, float roughness)
//--------------------------------------------------------------------------------------
float3 fresnelSchlick(float3 F0, float cosTheta)
{
return F0 + (1.0f - F0) * pow(1.0f - cosTheta, 4.0f);
return F0 + (1.0f - F0) * pow(1.0f - cosTheta, 5.0f);
}

//--------------------------------------------------------------------------------------
float3 fresnelSchlickRoughness(float3 F0, float cosTheta, float roughness)
{
return F0 + (max(float3(1.0 - roughness, 1.0 - roughness, 1.0 - roughness), F0) - F0) * pow(1.0 - cosTheta, 5.0);
}

//--------------------------------------------------------------------------------------
Expand All @@ -75,7 +81,7 @@ struct LightingResult
float3 Lh = normalize(Li + Lo);

// Calculate angles between surface normal and various light vectors.
float cosLi = _cosLi; //max(0.0f, dot(_worldNormal, Li));
float cosLi = _cosLi;
float cosLh = max(0.0f, dot(_worldNormal, Lh));

// Calculate Fresnel term for direct lighting.
Expand All @@ -95,7 +101,7 @@ struct LightingResult
// Lambert diffuse BRDF.
// We don't scale by 1/PI for lighting & material units to be more convenient.
// See: https://seblagarde.wordpress.com/2012/01/08/pi-or-not-to-pi-in-game-lighting-equation/
float3 diffuseBRDF = kd;// * _albedo;
float3 diffuseBRDF = kd;

// Cook-Torrance specular microfacet BRDF.
float3 specularBRDF = (F * D * G) / max(Epsilon, 4.0 * cosLi * cosLo);
Expand Down Expand Up @@ -192,21 +198,15 @@ LightingResult computeDirectLighting(ViewConstants _viewConstants, float3 _eyePo
cubemap.GetDimensions(0, width, height, mipLevels);

// environment diffuse

// Calculate Fresnel term for ambient lighting.
// Since we use pre-filtered cubemap(s) and irradiance is coming from many directions
// use cosLo instead of angle with light's half-vector (cosLh above).
// See: https://seblagarde.wordpress.com/2011/08/17/hello-world/
float3 F = fresnelSchlick(F0, cosLo);

// Get diffuse contribution factor (as with direct lighting).
float3 kd = lerp(1.0 - F, 0.0, metalness);
float diffuseEnvMip = mipLevels-1;
output.envDiffuse = kd * cubemap.SampleLevel(linearClamp, normalize(_worldNormal.rgb), diffuseEnvMip).rgb * ambientIntensity;

output.envDiffuse = kd * cubemap.SampleLevel(linearClamp, normalize(_worldNormal.rgb), mipLevels-1).rgb * ambientIntensity;

// environment specular
float mipLevel = roughness * (mipLevels - 1);
output.envSpecular = F * cubemap.SampleLevel(linearClamp, Lr, mipLevel).rgb * ambientIntensity;
// environment specular using split-sum approximation factors for Cook-Torrance specular BRDF.
float2 specularBRDF = getTexture2D((uint)ReservedSlot::CookTorranceBRDF).Sample(linearClamp, float2(cosLo, roughness)).rg;
float specularEnvMip = roughness * (mipLevels - 1);
output.envSpecular = (F0 * specularBRDF.x + specularBRDF.y) * cubemap.SampleLevel(linearClamp, Lr, specularEnvMip).rgb * ambientIntensity;
}
else
{
Expand All @@ -217,6 +217,9 @@ LightingResult computeDirectLighting(ViewConstants _viewConstants, float3 _eyePo
output.envSpecular = _viewConstants.getEnvironmentColor() * ambientIntensity;
}

output.envDiffuse *= occlusion;
output.envSpecular *= occlusion;

for(uint i=0; i < lightsHeader.getDirectionalCount(); ++i)
{
DirectionalLightConstants directional = lights.Load<DirectionalLightConstants>(offset);
Expand Down
1 change: 1 addition & 0 deletions data/Shaders/system/table.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@

vg_enum_class(ReservedSlot, uint,
// Texture
CookTorranceBRDF = BINDLESS_TEXTURE_INVALID - 6,
ImGuiFontTexSrv = BINDLESS_TEXTURE_INVALID - 5,
DefaultPBRTexSrv = BINDLESS_TEXTURE_INVALID - 4,
DefaultNormalTexSrv = BINDLESS_TEXTURE_INVALID - 3,
Expand Down
7 changes: 5 additions & 2 deletions data/Shaders/system/view.hlsli
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#pragma once
#ifndef _VIEW__HLSLI_
#define _VIEW__HLSLI_

#include "types.hlsli"
#include "packing.hlsli"
Expand Down Expand Up @@ -114,4 +115,6 @@ struct ViewConstants

void setEnvironmentTextureHandle(uint _value) { m_textures.x = packUint16low(m_textures.x, _value); }
uint getEnvironmentTextureHandle() { return unpackUint16low(m_textures.x); }
};
};

#endif // _VIEW__HLSLI_
Binary file modified data/Textures/EnvMaps/Default.psd
Binary file not shown.
2 changes: 1 addition & 1 deletion src/engine/Resource/Texture/TextureResourceMeta.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace vg::engine
registerPropertyEnum(TextureResourceMeta, gfx::TextureImporterType, m_importSettings.m_importerType, "Type");
registerPropertyEnum(TextureResourceMeta, gfx::TextureImporterFormat, m_importSettings.m_importerFormat, "Format");
registerProperty(TextureResourceMeta, m_importSettings.m_sRGB, "sRGB");
registerPropertyEnum(TextureResourceMeta, gfx::MipLevelCount, m_importSettings.m_mipLevelCount, "Mipmaps");
registerPropertyEnum(TextureResourceMeta, gfx::TextureImporterMipLevelCount, m_importSettings.m_mipLevelCount, "Mipmaps");
registerPropertyEnum(TextureResourceMeta, gfx::Downscale, m_importSettings.m_downscale, "Downscale");

return true;
Expand Down
37 changes: 21 additions & 16 deletions src/gfx/Device/Device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "gfx/Profiler/Profiler.h"
#include "gfx/Importer/TextureImporter.h"
#include "gfx/RingBuffer/Upload/UploadBuffer.h"
#include "gfx/Importer/TextureImporterSettings.h"

#if !VG_ENABLE_INLINE
#include "Device.inl"
Expand Down Expand Up @@ -443,22 +444,26 @@ namespace vg::gfx
}

//--------------------------------------------------------------------------------------
//Texture * Device::createTexture(const core::string & _path, ReservedSlot _reservedSlot)
//{
// TextureDesc texDesc;
// core::vector<u8> texData;
//
// if (m_textureImporter->importTextureData(_path, texDesc, texData))
// {
// Texture * tex = createTexture(texDesc, _path, texData.data(), _reservedSlot);
// return tex;
// }
// else
// {
// VG_ERROR("[Device] Failed to create texture from \"%s\"", _path.c_str());
// }
// return nullptr;
//}
Texture * Device::createTexture(const core::string & _path, ReservedSlot _reservedSlot)
{
TextureDesc texDesc;
core::vector<u8> texData;

TextureImporterSettings settings;
settings.m_mipLevelCount = (TextureImporterMipLevelCount)1;
settings.m_sRGB = false;

if (m_textureImporter->importTextureData(_path, texDesc, texData, &settings))
{
Texture * tex = createTexture(texDesc, _path, texData.data(), _reservedSlot);
return tex;
}
else
{
VG_ERROR("[Device] Failed to create texture from \"%s\"", _path.c_str());
}
return nullptr;
}

//--------------------------------------------------------------------------------------
Buffer * Device::createBuffer(const BufferDesc & _bufDesc, const core::string & _name, const void * _initData, ReservedSlot _reservedSlot)
Expand Down
2 changes: 1 addition & 1 deletion src/gfx/Device/Device.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ namespace vg::gfx
void endFrame ();

Texture * createTexture (const TextureDesc & _texDesc, const core::string & _name, const void * _initData = nullptr, ReservedSlot _reservedSlot = ReservedSlot::None);
//Texture * createTexture (const core::string & _path, ReservedSlot _reservedSlot = ReservedSlot::None);
Texture * createTexture (const core::string & _path, ReservedSlot _reservedSlot = ReservedSlot::None);
Buffer * createBuffer (const BufferDesc & _bufDesc, const core::string & _name, const void * _initData = nullptr, ReservedSlot _reservedSlot = ReservedSlot::None);

RootSignatureHandle addRootSignature (const RootSignatureDesc & _desc);
Expand Down
6 changes: 3 additions & 3 deletions src/gfx/Importer/TextureImporter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ namespace vg::gfx
}

// recompute mipmap count
if (_importSettings && MipLevelCount::Automatic != _importSettings->m_mipLevelCount)
if (_importSettings && TextureImporterMipLevelCount::Automatic != _importSettings->m_mipLevelCount)
{
const uint maxMipCount = computeMaxMipmapCount(type, width, height, slices);
mipmapCount = min((uint)_importSettings->m_mipLevelCount, maxMipCount);
Expand All @@ -86,7 +86,7 @@ namespace vg::gfx
sRGB = false;
}

if (nullptr == _importSettings || MipLevelCount::Automatic == _importSettings->m_mipLevelCount)
if (nullptr == _importSettings || TextureImporterMipLevelCount::Automatic == _importSettings->m_mipLevelCount)
{
const uint maxMipCount = computeMaxMipmapCount(type, width, height, slices);
mipmapCount = maxMipCount;
Expand All @@ -103,7 +103,7 @@ namespace vg::gfx

sRGB = _importSettings->m_sRGB;

if (MipLevelCount::Automatic != _importSettings->m_mipLevelCount)
if (TextureImporterMipLevelCount::Automatic != _importSettings->m_mipLevelCount)
{
const uint maxMipCount = computeMaxMipmapCount(type, width, height, slices);
mipmapCount = min((uint)_importSettings->m_mipLevelCount, maxMipCount);
Expand Down
4 changes: 2 additions & 2 deletions src/gfx/Importer/TextureImporterSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace vg::gfx
RGBA8 = 1
);

vg_enum_class(MipLevelCount, core::u8,
vg_enum_class(TextureImporterMipLevelCount, core::u8,
Automatic = 0,

MipLevelCount_1 = 1,
Expand Down Expand Up @@ -51,7 +51,7 @@ namespace vg::gfx
TextureImporterType m_importerType = TextureImporterType::Automatic;
TextureImporterFormat m_importerFormat = TextureImporterFormat::Automatic;
bool m_sRGB = true;
MipLevelCount m_mipLevelCount = MipLevelCount::Automatic;
TextureImporterMipLevelCount m_mipLevelCount = TextureImporterMipLevelCount::Automatic;
Downscale m_downscale = Downscale::None;
};
}
1 change: 1 addition & 0 deletions src/gfx/Shader/ShaderManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ namespace vg::gfx

// TODO: read dir to root folders names used #include ?
m_shaderRootFolders.push_back("system");
m_shaderRootFolders.push_back("background");
m_shaderRootFolders.push_back("extern");

m_shaderCompiler = new ShaderCompiler();
Expand Down
2 changes: 1 addition & 1 deletion src/gfx/Shader/dxc/ShaderCompiler_dxc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class CustomIncludeHandler : public IDxcIncludeHandler
{
const string shaderIncludeFolder = rootFolders[i];

auto lastShaderFolder = tolower(path).rfind(shaderIncludeFolder);
auto lastShaderFolder = tolower(path).rfind(shaderIncludeFolder+"/");
if (string::npos != lastShaderFolder)
{
lastShaderFolder += shaderIncludeFolder.length() + 1;
Expand Down
3 changes: 3 additions & 0 deletions src/renderer/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ namespace vg::renderer

VG_SAFE_RELEASE(gameViewport);
}

m_cookTorranceBRDF = m_device.createTexture("data/Engine/BRDF/CookTorrance.png", ReservedSlot::CookTorranceBRDF);
}

//--------------------------------------------------------------------------------------
Expand All @@ -256,6 +258,7 @@ namespace vg::renderer
//--------------------------------------------------------------------------------------
void Renderer::deinit()
{
VG_SAFE_RELEASE(m_cookTorranceBRDF);
VG_SAFE_DELETE(m_sharedCullingJobOutput);
VG_SAFE_RELEASE(m_hdrOutput);

Expand Down
2 changes: 2 additions & 0 deletions src/renderer/Renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@ namespace vg::renderer

// TODO : remove
core::vector<View *> m_views[core::enumCount<gfx::ViewTarget>()];

gfx::Texture * m_cookTorranceBRDF = nullptr;
};
}

Expand Down
1 change: 1 addition & 0 deletions vgframework.sln
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "system", "system", "{34ABDE
data\Shaders\system\depthbias.hlsli = data\Shaders\system\depthbias.hlsli
data\Shaders\system\depthstencil.hlsli = data\Shaders\system\depthstencil.hlsli
data\Shaders\system\displaymodes.hlsli = data\Shaders\system\displaymodes.hlsli
data\Shaders\system\environment.hlsli = data\Shaders\system\environment.hlsli
data\Shaders\system\gamma.hlsli = data\Shaders\system\gamma.hlsli
data\Shaders\system\instancedata.hlsli = data\Shaders\system\instancedata.hlsli
data\Shaders\system\lighting.hlsli = data\Shaders\system\lighting.hlsli
Expand Down

0 comments on commit a980ac5

Please sign in to comment.