Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions editor/StartWindow/StartWindowViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,13 @@ private void LaunchProject(string projectPath, Window parentWindow) {
"--build .toast/cmake_cache --config Release --parallel"));
#endif

var vm = new LoaderViewModel(tasks) {
OnComplete = async () => {
await Dispatcher.UIThread.InvokeAsync(() => { }, DispatcherPriority.Render);
_ = new ToastEngine(projectPath);
}
};
tasks.Add(LoaderTask.Do("Start engine", async log => {
log("Compiling changed shaders");
await Dispatcher.UIThread.InvokeAsync(() => { }, DispatcherPriority.Render);
_ = new ToastEngine(projectPath);
}));

var vm = new LoaderViewModel(tasks);

var desktop = (IClassicDesktopStyleApplicationLifetime)Application.Current!.ApplicationLifetime!;
desktop.MainWindow = new SplashLoaderWindow(vm);
Expand Down
10 changes: 8 additions & 2 deletions editor/Workspace/MainWindowViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1103,6 +1103,8 @@ private async Task CompileGameRelease() {

Directory.CreateDirectory(outputDir);

Log.InvalidateBacktraceCache();

async Task CopyDlls(Action<string> log) {
var libExt = OperatingSystem.IsWindows() ? ".dll" : ".so";
var exeExt = OperatingSystem.IsWindows() ? ".exe" : "";
Expand Down Expand Up @@ -1157,7 +1159,11 @@ async Task CopyBakedLighting(Action<string> log) {

async Task BakeAndPack(Action<string> log, string dbName, string dbSourceDir, string manifestJsonPath) {
var stageDir = Path.Combine(stageRoot, dbName);
if (Directory.Exists(stageDir)) Directory.Delete(stageDir, true);
if (Directory.Exists(stageDir)) {
foreach (var f in Directory.EnumerateFiles(stageDir, "*", SearchOption.AllDirectories))
File.SetAttributes(f, FileAttributes.Normal);
Directory.Delete(stageDir, true);
}
Directory.CreateDirectory(stageDir);

// Copy all source files into staging
Expand All @@ -1168,7 +1174,7 @@ await Task.Run(() => {
var dest = Path.Combine(stageDir, rel);
Directory.CreateDirectory(Path.GetDirectoryName(dest)!);
File.Copy(srcFile, dest, true);
File.SetAttributes(dest, File.GetAttributes(dest) & ~FileAttributes.ReadOnly);
File.SetAttributes(dest, File.GetAttributes(dest) & ~FileAttributes.ReadOnly);
}
});

Expand Down
9 changes: 7 additions & 2 deletions engine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -106,16 +106,20 @@ target_link_libraries(toast_engine
unofficial::VulkanMemoryAllocator-Hpp::VulkanMemoryAllocator-Hpp
slang::gfx slang::slang protobuf::libprotobuf tinysplinecxx::tinysplinecxx
LZ4::lz4
imgui::imgui
$<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:imgui::imgui>
RmlUi::RmlUi
cpptrace::cpptrace
$<$<CONFIG:Debug>:${EXTERNAL_LIBS_DEBUG}>
$<$<NOT:$<CONFIG:Debug>>:${EXTERNAL_LIBS_RELEASE}>
${LUA_LIBRARIES}
PUBLIC
Tracy::TracyClient glm::glm nlohmann_json::nlohmann_json GPUOpen::VulkanMemoryAllocator
$<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:Tracy::TracyClient> glm::glm nlohmann_json::nlohmann_json GPUOpen::VulkanMemoryAllocator
)

# Release links without Tracy
get_target_property(_tracy_headers Tracy::TracyClient INTERFACE_INCLUDE_DIRECTORIES)
target_include_directories(toast_engine PUBLIC ${_tracy_headers})

foreach (config IN ITEMS Debug Release RelWithDebInfo MinSizeRel)
string(TOUPPER "${config}" config_upper)
set_target_properties(toast_engine PROPERTIES
Expand Down Expand Up @@ -161,6 +165,7 @@ target_compile_definitions(toast_engine PUBLIC
$<$<AND:$<CONFIG:Debug>,$<BOOL:${TOAST_SYNC_VALIDATION}>>:TOAST_SYNC_VALIDATION>
$<$<OR:$<CONFIG:Release>,$<CONFIG:MinSizeRel>>:NDEBUG>
$<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:TRACY_ENABLE>
$<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:TOAST_DEV_TOOLS>
$<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:TOAST_BREAK_ON_ERROR>
$<$<CONFIG:RelWithDebInfo>:TOAST_LUA_OWNERSHIP_CHECKS>
GLM_FORCE_INTRINSICS
Expand Down
44 changes: 26 additions & 18 deletions engine/assets/shaders/exposure.slang
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ static const float kLowPercentile = 0.1;
static const float kHighPercentile = 0.9;

groupshared uint sBins[kBins];
groupshared float2 sSums[kBins];

float luminance(float3 color)
{
Expand Down Expand Up @@ -70,34 +71,41 @@ void histogramMain(uint3 id : SV_DispatchThreadID, uint index : SV_GroupIndex)
[numthreads(256, 1, 1)]
void adaptMain(uint index : SV_GroupIndex)
{
sBins[index] = gHistogram[index];
const uint count = gHistogram[index];
sBins[index] = count;
GroupMemoryBarrierWithGroupSync();

if (index != 0u)
for (uint offset = 1u; offset < kBins; offset <<= 1u)
{
return;
const uint below = index >= offset ? sBins[index - offset] : 0u;
GroupMemoryBarrierWithGroupSync();
sBins[index] += below;
GroupMemoryBarrierWithGroupSync();
}

float total = 0.0;
for (uint i = 0u; i < kBins; ++i)
const float total = float(sBins[kBins - 1u]);
const float seen = float(sBins[index] - count);
const float low = total * kLowPercentile;
const float high = total * kHighPercentile;
const float inside = max(min(seen + float(count), high) - max(seen, low), 0.0);
sSums[index] = float2(inside * (gParams.minLog + (float(index) + 0.5) / float(kBins) * gParams.logRange), inside);
GroupMemoryBarrierWithGroupSync();

for (uint stride = kBins / 2u; stride > 0u; stride >>= 1u)
{
total += float(sBins[i]);
if (index < stride)
{
sSums[index] += sSums[index + stride];
}
GroupMemoryBarrierWithGroupSync();
}

float low = total * kLowPercentile;
float high = total * kHighPercentile;
float seen = 0.0;
float weighted = 0.0;
float counted = 0.0;
for (uint i = 0u; i < kBins; ++i)
if (index != 0u)
{
float count = float(sBins[i]);
float inside = max(min(seen + count, high) - max(seen, low), 0.0);
weighted += inside * (gParams.minLog + (float(i) + 0.5) / float(kBins) * gParams.logRange);
counted += inside;
seen += count;
return;
}

const float weighted = sSums[0].x;
const float counted = sSums[0].y;
float target = counted > 0.0 ? weighted / counted : gParams.minLog + 0.5 * gParams.logRange;
float previous = gExposure[0];
float speed = target > previous ? gParams.speedUp : gParams.speedDown;
Expand Down
18 changes: 18 additions & 0 deletions engine/assets/shaders/fullscreen.slang
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,21 @@ public FullscreenVSOutput fullscreenTriangle(uint vertexId)
output.position = float4(output.uv * 2.0 - 1.0, 0.0, 1.0);
return output;
}

public float4 uiToDisplay(float4 premultiplied, float hdrPaperWhiteScale)
{
if (hdrPaperWhiteScale <= 0.0)
{
return premultiplied;
}

const float alpha = premultiplied.a;
const float3 encoded = alpha > 1e-5 ? premultiplied.rgb / alpha : float3(0.0, 0.0, 0.0);
const float3 low = encoded / 12.92;
const float3 high = pow((encoded + 0.055) / 1.055, float3(2.4, 2.4, 2.4));
const float3 linearColor = float3(
encoded.x <= 0.04045 ? low.x : high.x,
encoded.y <= 0.04045 ? low.y : high.y,
encoded.z <= 0.04045 ? low.z : high.z);
return float4(linearColor * hdrPaperWhiteScale * alpha, alpha);
}
27 changes: 27 additions & 0 deletions engine/assets/shaders/ggx_sampling.slang
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,33 @@ float3 sampleVisibleNormal(float3 view, float alpha, float2 u)
return normalize(float3(alpha * h.x, alpha * h.y, max(h.z, 0.0)));
}

/// Any 4x4 texel window holds every stratum once
static const uint kLobeStrata = 16u;
static const uint kLobeBayer[16] = {0u, 8u, 2u, 10u, 12u, 4u, 14u, 6u, 3u, 11u, 1u, 9u, 15u, 7u, 13u, 5u};

uint lobeStratumIndex(int2 cell)
{
return kLobeBayer[(uint(cell.y) & 3u) * 4u + (uint(cell.x) & 3u)];
}

/// Hammersley point of a stratum
float2 lobeStratumSample(uint index)
{
const uint reversed = ((index & 1u) << 3) | ((index & 2u) << 1) | ((index & 4u) >> 1) | ((index & 8u) >> 3);
return (float2(float(index), float(reversed)) + 0.5) / float(kLobeStrata);
}

float2 lobeStratum(int2 texel)
{
return lobeStratumSample(lobeStratumIndex(texel));
}

/// Every stratum of the 4x4 tile weighs the same over the 5x5 tent
float lobeStratumWeight(int2 offset)
{
return (abs(offset.x) == 2 ? 0.5 : 1.0) * (abs(offset.y) == 2 ? 0.5 : 1.0);
}

/// Of a direction sampled through sampleVisibleNormal
float visibleNormalPdf(float NdotV, float NdotH, float alpha)
{
Expand Down
11 changes: 7 additions & 4 deletions engine/assets/shaders/gi_rays.slang
Original file line number Diff line number Diff line change
Expand Up @@ -512,14 +512,17 @@ void shadeMain(uint3 id : SV_DispatchThreadID)
const float3 normal = sceneHitNormal(hit, ray.direction);
// Salted so the light pick is independent of the seeding draw of traceMain
uint random = giHash(ray.random ^ 0x68bc21ebu);
const float3 radiance = giClampRay(frame, giOffscreenRadiance(frame, hit, position, normal, ray.pixel, random));

const uint top = frame.frame.y - 1u;
const bool primaryHit = !pixelRay || hit.t <= giIntervalEnd(frame, ray.lod, top);
giSplitRay(frame, ray.deposit, ray.lod, ray.origin, ray.direction, primaryHit, hit.t, radiance);
const float3 radiance = giOffscreenRadiance(frame, hit, position, normal, ray.pixel, random);

// Reread so the frame is not live across the traces
const GiFrame after = gFrame[0];
const float3 clamped = giClampRay(after, radiance);
giSplitRay(after, ray.deposit, ray.lod, ray.origin, ray.direction, primaryHit, hit.t, clamped);
if (ray.overlapDeposit != kGiEmpty)
{
giSplitRay(frame, ray.overlapDeposit, ray.lod + 1u, ray.origin, ray.direction, true, hit.t, radiance);
giSplitRay(after, ray.overlapDeposit, ray.lod + 1u, ray.origin, ray.direction, true, hit.t, clamped);
}
}

Expand Down
Loading
Loading