diff --git a/Wonderbox-screen-1.png b/Wonderbox-screen-1.png new file mode 100644 index 0000000..349966e Binary files /dev/null and b/Wonderbox-screen-1.png differ diff --git a/Wonderbox-screen-2.png b/Wonderbox-screen-2.png new file mode 100644 index 0000000..0b8d8ff Binary files /dev/null and b/Wonderbox-screen-2.png differ diff --git a/Wonderbox-screen-5.png b/Wonderbox-screen-5.png new file mode 100644 index 0000000..eb45fd9 Binary files /dev/null and b/Wonderbox-screen-5.png differ diff --git a/Wonderbox-screen-6.png b/Wonderbox-screen-6.png new file mode 100644 index 0000000..c193753 Binary files /dev/null and b/Wonderbox-screen-6.png differ diff --git a/shaders/voxelAOApplyCS.hlsl b/shaders/voxelAOApplyCS.hlsl index 04e33b1..16a1865 100644 --- a/shaders/voxelAOApplyCS.hlsl +++ b/shaders/voxelAOApplyCS.hlsl @@ -1,9 +1,10 @@ -// BVLE Voxels - AO Apply + Tone Mapping Compute Shader (Phase 6.3 + 7) -// Final post-process pass: applies AO, saturation boost, and tone mapping. +// BVLE Voxels - AO Apply + Sky + Tone Mapping Compute Shader (Phase 6.3 + 7) +// Final post-process pass: sky gradient for empty pixels, AO, saturation, tone mapping. #include "voxelCommon.hlsli" Texture2D aoBlurred : register(t0); +Texture2D depthTexture : register(t1); RWTexture2D colorOutput : register(u0); struct ApplyPush { @@ -17,8 +18,7 @@ struct ApplyPush { // Soft clamp tone mapping: linear up to shoulder, gentle roll-off to prevent harsh clipping float3 softClampToneMap(float3 color, float exposure) { color *= exposure; - // Soft exponential curve: gentler than Reinhard, preserves bright midtones - return 1.0 - exp(-color); // natural 1-e^-x curve + return 1.0 - exp(-color); } // Saturation adjustment in linear space @@ -27,28 +27,75 @@ float3 adjustSaturation(float3 color, float saturation) { return lerp(float3(luma, luma, luma), color, saturation); } +// Procedural sky gradient (Wonderbox-inspired warm atmosphere) +float3 computeSky(float2 uv) { + // Reconstruct view direction from screen UV + float2 ndc = float2(uv.x * 2.0 - 1.0, (1.0 - uv.y) * 2.0 - 1.0); + float4 clipDir = float4(ndc, 0.5, 1.0); + float4 worldDir4 = mul(inverseViewProjection, clipDir); + float3 viewDir = normalize(worldDir4.xyz / worldDir4.w - cameraPosition.xyz); + + // Vertical gradient: viewDir.y = +1 (zenith) to -1 (nadir) + float t = viewDir.y * 0.5 + 0.5; // 0=horizon/below, 1=zenith + + // Wonderbox palette: warm sandy horizon → soft blue-grey zenith + float3 horizonColor = float3(0.85, 0.75, 0.58); // warm sand/beige + float3 zenithColor = float3(0.55, 0.62, 0.72); // muted blue-grey + float3 nadirColor = float3(0.70, 0.62, 0.48); // darker warm below horizon + + float3 sky; + if (t > 0.5) { + // Above horizon: sand → blue + float h = (t - 0.5) * 2.0; // 0=horizon, 1=zenith + h = pow(h, 0.7); // non-linear: more horizon color in the lower sky + sky = lerp(horizonColor, zenithColor, h); + } else { + // Below horizon: sand → darker warm + float h = (0.5 - t) * 2.0; // 0=horizon, 1=nadir + sky = lerp(horizonColor, nadirColor, h); + } + + // Sun glow near sun direction (soft halo) + float3 L = normalize(-sunDirection.xyz); + float sunDot = saturate(dot(viewDir, L)); + float sunGlow = pow(sunDot, 32.0) * 0.4; + float sunHaze = pow(sunDot, 4.0) * 0.15; + sky += float3(1.0, 0.85, 0.5) * (sunGlow + sunHaze); + + return sky; +} + [RootSignature(VOXEL_ROOTSIG)] [numthreads(8, 8, 1)] void main(uint3 DTid : SV_DispatchThreadID) { if (DTid.x >= push.width || DTid.y >= push.height) return; + float depth = depthTexture[DTid.xy]; float ao = aoBlurred[DTid.xy]; if (push.debugMode == 2) { - // Debug AO: grayscale visualization of blurred AO colorOutput[DTid.xy] = float4(ao, ao, ao, 1); - } else { - float4 color = colorOutput[DTid.xy]; - - // Apply AO - color.rgb *= ao; - - // Saturation boost (toneMapParams.x) - color.rgb = adjustSaturation(color.rgb, toneMapParams.x); - - // Tone mapping (toneMapParams.y = exposure) - color.rgb = softClampToneMap(color.rgb, toneMapParams.y); - - colorOutput[DTid.xy] = color; + return; } + + // Sky pixels: depth == 0 in reverse-Z = far plane + if (depth == 0.0) { + float2 uv = (float2(DTid.xy) + 0.5) / float2(push.width, push.height); + float3 sky = computeSky(uv); + colorOutput[DTid.xy] = float4(sky, 1.0); + return; + } + + float4 color = colorOutput[DTid.xy]; + + // Apply AO + color.rgb *= ao; + + // Saturation boost (toneMapParams.x) + color.rgb = adjustSaturation(color.rgb, toneMapParams.x); + + // Tone mapping (toneMapParams.y = exposure) + color.rgb = softClampToneMap(color.rgb, toneMapParams.y); + + colorOutput[DTid.xy] = color; } diff --git a/src/app/main.cpp b/src/app/main.cpp index a11a9fd..d3a4d62 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -156,7 +156,6 @@ int APIENTRY wWinMain( // Initialize Wicked Engine application.SetWindow(hWnd); - // Redirect Wicked Engine log to file wi::backlog::SetLogFile("bvle_backlog.txt"); diff --git a/voxel_engine_spec.md b/voxel_engine_spec.md index 88ea553..6a5d099 100644 --- a/voxel_engine_spec.md +++ b/voxel_engine_spec.md @@ -322,4 +322,11 @@ Le VoxelRenderer s'insère dans le render path de Wicked via des hooks dans le R # Autres idées -J'aimerais tester quelque chose, c'est un nouveau type de block qui ne contient que des modèles 3D customs et qui aurait des comportements de jointure dynamique selon les blocs voisins identiques. Spécifiquement, j'aimerais créer des tuyaux qui se connectent les uns aux autres ou créent des nouvelles connexions pour toujours toucher les blocks tuyaux voisin. \ No newline at end of file +J'aimerais tester quelque chose, c'est un nouveau type de block qui ne contient que des modèles 3D customs et qui aurait des comportements de jointure dynamique selon les blocs voisins identiques. Spécifiquement, j'aimerais créer des tuyaux qui se connectent les uns aux autres ou créent des nouvelles connexions pour toujours toucher les blocks tuyaux voisin. + +Le ciel te plaît — parfait ! On continue vers Wonderbox. Qu'est-ce que tu voudrais améliorer ensuite ? En comparant avec la ref, je vois plusieurs pistes : + +Couleurs plus saturées/profondes — le vert de l'herbe Wonderbox est plus riche et profond +Fog atmosphérique — la brume chaude au loin qui fond le terrain dans le ciel +Ombres plus marquées — le contraste ombre/lumière est plus prononcé dans Wonderbox +Faces latérales des blocs — plus texturées/détaillées dans Wonderbox \ No newline at end of file