From f56ffdaa133f6edf85521e9d72e3d306fa4f59fe Mon Sep 17 00:00:00 2001 From: Asuro Date: Fri, 28 Mar 2025 00:11:56 +0100 Subject: [PATCH] shader changes & screen quads --- src/engine/main.cpp | 12 +- src/game/Level.cpp | 6 +- .../dx11/{ => dither}/frag.bin | 0 .../dx11/{ => dither}/vert.bin | 0 .../compiled-shaders/dx11/normal/frag.bin | 3 + .../compiled-shaders/dx11/normal/vert.bin | 3 + src/game/compiled-shaders/glsl/frag.bin | 3 - src/game/compiled-shaders/glsl/vert.bin | 3 - src/game/compiled-shaders/spirv/frag.bin | 3 - src/game/compiled-shaders/spirv/vert.bin | 3 - src/game/rendering/Rendering.cpp | 34 +++--- src/game/rendering/Rendering.h | 1 + src/game/shaders/{ => dither}/frag.sc | 3 +- src/game/shaders/{ => dither}/varying.def.sc | 0 src/game/shaders/{ => dither}/vert.sc | 2 +- src/game/shaders/normal/frag.sc | 112 ++++++++++++++++++ src/game/shaders/normal/varying.def.sc | 9 ++ src/game/shaders/normal/vert.sc | 13 ++ src/shadercompile.bat | 6 - src/shadercompile.ps1 | 20 ++++ 20 files changed, 193 insertions(+), 43 deletions(-) rename src/game/compiled-shaders/dx11/{ => dither}/frag.bin (100%) rename src/game/compiled-shaders/dx11/{ => dither}/vert.bin (100%) create mode 100644 src/game/compiled-shaders/dx11/normal/frag.bin create mode 100644 src/game/compiled-shaders/dx11/normal/vert.bin delete mode 100644 src/game/compiled-shaders/glsl/frag.bin delete mode 100644 src/game/compiled-shaders/glsl/vert.bin delete mode 100644 src/game/compiled-shaders/spirv/frag.bin delete mode 100644 src/game/compiled-shaders/spirv/vert.bin rename src/game/shaders/{ => dither}/frag.sc (99%) rename src/game/shaders/{ => dither}/varying.def.sc (100%) rename src/game/shaders/{ => dither}/vert.sc (93%) create mode 100644 src/game/shaders/normal/frag.sc create mode 100644 src/game/shaders/normal/varying.def.sc create mode 100644 src/game/shaders/normal/vert.sc delete mode 100644 src/shadercompile.bat create mode 100644 src/shadercompile.ps1 diff --git a/src/engine/main.cpp b/src/engine/main.cpp index ec53907..2276b2b 100644 --- a/src/engine/main.cpp +++ b/src/engine/main.cpp @@ -98,6 +98,10 @@ void FileChangeCheck(HANDLE dirHandle, FileChangeType changeType, const wchar_t* { if (compName == nullptr || compName[0] == 0 || wcscmp(notifyData->FileName, compName) == 0) { + char buf[1024]{0}; + wcstombs(buf, notifyData->FileName, sizeof(buf)); + printf("file change of type %u: %s\n", changeType, buf); + FileChangeNotification notif; wcscpy(notif.FileName, notifyData->FileName); if (changeType == FileChangeType::DLL) @@ -106,23 +110,25 @@ void FileChangeCheck(HANDLE dirHandle, FileChangeType changeType, const wchar_t* } else if (changeType == FileChangeType::Shader) { - std::system("shadercompile.bat > shadercompile.log"); + printf("shader source change!\n"); + std::system("powershell.exe .\\shadercompile.ps1 > shadercompile.log"); Sleep(1000); std::ifstream shaderLogFile("shadercompile.log"); if (shaderLogFile.is_open()) { shaderLogFile.seekg(0, std::ios::end); - uint32_t size = bx::min(BX_COUNTOF(Shared.Dev.ShaderLog), shaderLogFile.tellg()); + uint32_t size = bx::min(BX_COUNTOF(Shared.Dev.ShaderLog) - 1, shaderLogFile.tellg()); shaderLogFile.seekg(0); shaderLogFile.read(Shared.Dev.ShaderLog, size); shaderLogFile.close(); + Shared.Dev.ShaderLog[size] = 0; } } else if (changeType == FileChangeType::CompiledShader) { + printf("compiled shader change!\n"); DevData.FileWatcher.ShaderQueue.push(¬if); } - printf("detected file change of type %u!\n", changeType); } } diff --git a/src/game/Level.cpp b/src/game/Level.cpp index 5a18a93..1a9e354 100644 --- a/src/game/Level.cpp +++ b/src/game/Level.cpp @@ -325,7 +325,7 @@ namespace Game UIPlacedCards[i] = level.UIQuads.New(); auto& quad = level.UIQuads.Get(UIPlacedCards[i]); quad.EData.ModelH = GameRendering::Get().GetModelHandleFromPath("models/plane.glb"); - quad.EData.MaterialHandle = EMaterial::Default; + quad.EData.MaterialHandle = EMaterial::UI; quad.EData.Visible = false; } IsSetup = true; @@ -349,7 +349,7 @@ namespace Game bool IsValid = Puzzle::IsValid(card.RefCard); tile.EData.Visible = true; - quad.EData.Visible = true; + quad.EData.Visible = IsValid; tile.EData.ModelH = IsValid ? staticCards[card.RefCard.Idx].ModelHandle : staticCards[0].ModelHandle; Vec3 cardPos = { @@ -368,7 +368,9 @@ namespace Game Vec3 fw = {camTransform.M.M[2], camTransform.M.M[6], camTransform.M.M[10]}; Vec3 pos = camTransform.GetPosition() * -1; pos += fw; + pos += Vec3{cardPos.x, cardPos.z, 0.0f} * 0.025f; quad.EData.Transform.SetPosition(pos); + quad.EData.Transform.Scale = {0.1f, 0.1f, 0.1f}; quad.EData.Transform.Rotation = camTransform.Rotation.Inverse(); quad.EData.Transform.Rotate(Vec3{bx::kPi * 0.5f, 0.0f, 0.0f}); } diff --git a/src/game/compiled-shaders/dx11/frag.bin b/src/game/compiled-shaders/dx11/dither/frag.bin similarity index 100% rename from src/game/compiled-shaders/dx11/frag.bin rename to src/game/compiled-shaders/dx11/dither/frag.bin diff --git a/src/game/compiled-shaders/dx11/vert.bin b/src/game/compiled-shaders/dx11/dither/vert.bin similarity index 100% rename from src/game/compiled-shaders/dx11/vert.bin rename to src/game/compiled-shaders/dx11/dither/vert.bin diff --git a/src/game/compiled-shaders/dx11/normal/frag.bin b/src/game/compiled-shaders/dx11/normal/frag.bin new file mode 100644 index 0000000..7d526d3 --- /dev/null +++ b/src/game/compiled-shaders/dx11/normal/frag.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a7816b117c34da40d016175cd3968a4012ea3a8a502eb3d7fc46df0266cba904 +size 630 diff --git a/src/game/compiled-shaders/dx11/normal/vert.bin b/src/game/compiled-shaders/dx11/normal/vert.bin new file mode 100644 index 0000000..aa2065a --- /dev/null +++ b/src/game/compiled-shaders/dx11/normal/vert.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:94e8596a84796ff4bc78d6112218cf3e4eb7656df839f511973a5624184e42fc +size 1410 diff --git a/src/game/compiled-shaders/glsl/frag.bin b/src/game/compiled-shaders/glsl/frag.bin deleted file mode 100644 index 705a83e..0000000 --- a/src/game/compiled-shaders/glsl/frag.bin +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:85a99cbada51961bbc111a17f67f8c9dd5c582ac890cb9a0b2e0087d3e038c2b -size 13315 diff --git a/src/game/compiled-shaders/glsl/vert.bin b/src/game/compiled-shaders/glsl/vert.bin deleted file mode 100644 index 988e2e9..0000000 --- a/src/game/compiled-shaders/glsl/vert.bin +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6c18b10f56fd73d05c147100af03743b0f388e7be5e22c0c470c7d0595700f19 -size 10642 diff --git a/src/game/compiled-shaders/spirv/frag.bin b/src/game/compiled-shaders/spirv/frag.bin deleted file mode 100644 index 7106766..0000000 --- a/src/game/compiled-shaders/spirv/frag.bin +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:56e998b9752a86a9b1b15ea3341535b104c4368692d9ab38407d98ad5beac262 -size 4430 diff --git a/src/game/compiled-shaders/spirv/vert.bin b/src/game/compiled-shaders/spirv/vert.bin deleted file mode 100644 index c9731f5..0000000 --- a/src/game/compiled-shaders/spirv/vert.bin +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:94a8c30ea54598a4e2b1087a6319d2202af1e8ea652dbc36575465b7baf3db8c -size 2302 diff --git a/src/game/rendering/Rendering.cpp b/src/game/rendering/Rendering.cpp index 9f8ce37..37a779d 100644 --- a/src/game/rendering/Rendering.cpp +++ b/src/game/rendering/Rendering.cpp @@ -377,8 +377,7 @@ namespace Game Textures[0].SamplerHandle = DefaultSampler; LoadModels(Models, ModelCount); - Materials[(uint16_t)EMaterial::Default] = - Material::LoadFromShader("vert", "frag", MainViewID, Textures[0].Handle, Textures[0].SamplerHandle); + ReloadShaders(); imguiCreate(); SetImguiStyle(); @@ -439,26 +438,17 @@ namespace Game FileChangeNotification* shaderChange = nullptr; if (shared.Dev.ChangedShaderCount > 0) { + char buf[1024]{0}; + for (int32_t i = 0; i < shared.Dev.ChangedShaderCount; ++i) + { + wcstombs(buf, shared.Dev.ChangedShaders[i].FileName, sizeof(buf)); + LOG("Changed: %s", buf); + } shared.Dev.ChangedShaderCount = 0; // TODO: when to destroy shader? // TODO: only reload changed shaders - bgfx::ShaderHandle vertexShader = loadShader("vert"); - bgfx::ShaderHandle fragmentShader = loadShader("frag"); - if (isValid(vertexShader) && isValid(fragmentShader)) - { - bgfx::ProgramHandle newProgram = bgfx::createProgram(vertexShader, fragmentShader, true); - if (isValid(newProgram)) - { - Materials[(uint16_t)EMaterial::Default].Shader = newProgram; - LastShaderLoadTime = GetInstance().Time.Now; - } - else - { - LOG_WARN("Failed to load shader!"); - LastShaderLoadTime = -1.0f; - } - } + ReloadShaders(); } } @@ -697,6 +687,14 @@ namespace Game ImGui::End(); } + void GameRendering::ReloadShaders() + { + Materials[(uint16_t)EMaterial::Default] = Material::LoadFromShader( + "dither/vert", "dither/frag", MainViewID, Textures[0].Handle, Textures[0].SamplerHandle); + Materials[(uint16_t)EMaterial::UI] = Material::LoadFromShader( + "normal/vert", "normal/frag", MainViewID, Textures[0].Handle, Textures[0].SamplerHandle); + } + void GameRendering::Update() { ZoneScopedN("Rendering"); diff --git a/src/game/rendering/Rendering.h b/src/game/rendering/Rendering.h index 27054e5..3e41595 100644 --- a/src/game/rendering/Rendering.h +++ b/src/game/rendering/Rendering.h @@ -125,6 +125,7 @@ namespace Game void Update(); void HandleEvents(); void RenderDebugUI(); + void ReloadShaders(); void Shutdown(); Generated::ModelHandle GetModelHandleFromPath(const char* path); }; diff --git a/src/game/shaders/frag.sc b/src/game/shaders/dither/frag.sc similarity index 99% rename from src/game/shaders/frag.sc rename to src/game/shaders/dither/frag.sc index e656233..3b924d8 100644 --- a/src/game/shaders/frag.sc +++ b/src/game/shaders/dither/frag.sc @@ -3,7 +3,7 @@ $input v_normal $input v_uv0 $input v_wpos -#include "common.sh" +#include "../common.sh" SAMPLER2D(s_texColor, 0); SAMPLER3D(s_ditherSampler, 1); @@ -107,4 +107,5 @@ void main() float3 ditheredColor = dither(brightness, v_uv0); float3 finalColor = mix(u_baseColor, texColor, ditheredColor); gl_FragColor = vec4(finalColor, 1.0); + } diff --git a/src/game/shaders/varying.def.sc b/src/game/shaders/dither/varying.def.sc similarity index 100% rename from src/game/shaders/varying.def.sc rename to src/game/shaders/dither/varying.def.sc diff --git a/src/game/shaders/vert.sc b/src/game/shaders/dither/vert.sc similarity index 93% rename from src/game/shaders/vert.sc rename to src/game/shaders/dither/vert.sc index f831c3c..858e11b 100644 --- a/src/game/shaders/vert.sc +++ b/src/game/shaders/dither/vert.sc @@ -1,7 +1,7 @@ $input a_position, a_normal, a_color0, a_texcoord0 $output v_color0, v_normal, v_uv0, v_wpos -#include "common.sh" +#include "../common.sh" void main() { diff --git a/src/game/shaders/normal/frag.sc b/src/game/shaders/normal/frag.sc new file mode 100644 index 0000000..9975f90 --- /dev/null +++ b/src/game/shaders/normal/frag.sc @@ -0,0 +1,112 @@ +$input v_color0 +$input v_normal +$input v_uv0 +$input v_wpos + +#include "../common.sh" + +SAMPLER2D(s_texColor, 0); +SAMPLER3D(s_ditherSampler, 1); +SAMPLER2D(s_rampSampler, 2); +uniform vec4 u_time; +uniform vec4 u_testColor; +uniform vec4 u_texInfo; +uniform vec4 u_baseColor; + +float calcBrightness(vec3 lightPos, vec3 vertPos, vec3 normal) +{ + vec3 lightDir = normalize(lightPos - vertPos); + float diffuse = max(0.0, dot(lightDir, normal)); + return diffuse * clamp(1.0 - distance(lightPos, vertPos) * 0.01, 0.0, 1.0); +} + +float calcBrightnessDirectional(vec3 sunDir, vec3 normal) +{ + return max(0.0, dot(sunDir, normal)); +} + +vec3 desaturate(vec3 color) +{ + return vec3_splat(dot(color, vec3(0.33, 0.34, 0.33))); +} + +float dither(float brightness, vec2 inputUv) +{ + float globalScale = 8; + + // constants + float xRes = u_texInfo.z; + float dotsPerSide = xRes / 16; + float dotsTotal = dotsPerSide * dotsPerSide; + float invXRes = 1 / xRes; + float zRes = dotsTotal; + float invZRes = 1 / zRes; + + float2 rampLookupUv = vec2((0.5 * invXRes + (1 - invXRes) * brightness), 0.5); + float brightnessCurve = texture2D(s_rampSampler, rampLookupUv).r; + + // Magic dot frequency calculation + float2 dx = ddx(inputUv); + float2 dy = ddy(inputUv); + float2x2 mat = float2x2(dx, dy); + float4 vectorized = float4(dx, dy); + float qq = dot(vectorized, vectorized); + float rr = determinant(mat); + float discriminantSqr = max(0.0, qq*qq - 4.0*rr*rr); + float discriminant = sqrt(discriminantSqr); + float2 freq = sqrt(float2(qq + discriminant, qq - discriminant) / 2.0); + + // Figuring out how many dots we want + float scaleExp = exp2(globalScale); + float spacing = freq.y * scaleExp; + spacing *= dotsPerSide * 0.125; + + float brightnessSpacingMultiplier = pow(brightnessCurve * 2 + 0.001, -(1 - 0.5)); + // float brightnessSpacingMultiplier = 1; + spacing *= brightnessSpacingMultiplier; + + float spacingLog = log2(spacing); + int patternScaleLevel = floor(spacingLog); + float patternFractional = spacingLog - patternScaleLevel; + vec2 uv = inputUv / exp2(patternScaleLevel); + + // patternFractional *= patternFractional; + // patternFractional = smoothstep(0, 1, patternFractional); + float subLayer = lerp(0.25 * dotsTotal, dotsTotal, 1 - patternFractional); + subLayer = (subLayer - 0.5) * invZRes; + + float pattern = texture3D(s_ditherSampler, vec3(uv, subLayer)).r; + + float contrast = 2 * scaleExp * brightnessSpacingMultiplier * 0.1; + contrast *= pow(freq.y / freq.x, 1.0); + float baseVal = lerp(0.5, brightness, saturate(1.05 / (1 + contrast))); + float threshold = 1 - brightnessCurve + 0.6; + + return saturate((pattern - threshold) * contrast + baseVal); +} + +void main() +{ + // setup + float testRadius = 30.0; + float testSpeed = 1.0; + vec3 testOffset = vec3(0.0, 0.0, 50.0); + float3 lightPos = vec3(sin(u_time.x * testSpeed) * testRadius, 5.0, cos(u_time.x * testSpeed) * testRadius); + vec3 texColor = u_testColor.x > 0.1 ? u_testColor.xyz : texture2D(s_texColor, v_uv0).xyz; + + // lighting + // float brightness = calcBrightness(lightPos, v_wpos, v_normal); + float brightness = lerp(0.5, 0.9, calcBrightnessDirectional(vec3(0.5, 0.3, 1.0), v_normal)); + // float brightness = 0.5; + // brightness = lerp(0.2, 1.0, sin(u_time.x) * 0.5 + 0.5); + + float r = dither(brightness * texColor.r, v_uv0); + float g = dither(brightness * texColor.g, v_uv0); + float b = dither(brightness * texColor.b, v_uv0); + // float3 finalColor = vec3(r, g, b); + float3 ditheredColor = dither(brightness, v_uv0); + float3 finalColor = mix(u_baseColor, texColor, ditheredColor); + gl_FragColor = vec4(finalColor, 1.0); + gl_FragColor = vec4(texColor, 1.0); + +} diff --git a/src/game/shaders/normal/varying.def.sc b/src/game/shaders/normal/varying.def.sc new file mode 100644 index 0000000..cdd8009 --- /dev/null +++ b/src/game/shaders/normal/varying.def.sc @@ -0,0 +1,9 @@ +vec4 v_color0 : COLOR0 = vec4(1.0, 1.0, 0.0, 1.0); +vec3 v_normal : NORMAL = vec3(0.0, 0.0, 1.0); +vec2 v_uv0 : TEXCOORD0 = vec2(0.0, 0.0); +vec3 v_wpos : TEXCOORD1 = vec3(0.0, 0.0, 0.0); + +vec3 a_position : POSITION; +vec3 a_normal : NORMAL; +vec4 a_color0 : COLOR0; +vec2 a_texcoord0 : TEXCOORD0; diff --git a/src/game/shaders/normal/vert.sc b/src/game/shaders/normal/vert.sc new file mode 100644 index 0000000..858e11b --- /dev/null +++ b/src/game/shaders/normal/vert.sc @@ -0,0 +1,13 @@ +$input a_position, a_normal, a_color0, a_texcoord0 +$output v_color0, v_normal, v_uv0, v_wpos + +#include "../common.sh" + +void main() +{ + gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0)); + v_color0 = a_color0; + v_uv0 = a_texcoord0; + v_wpos = mul(u_model[0], vec4(a_position, 1.0)).xyz; + v_normal = normalize(mul(u_model[0], a_normal)); +} diff --git a/src/shadercompile.bat b/src/shadercompile.bat deleted file mode 100644 index 6095027..0000000 --- a/src/shadercompile.bat +++ /dev/null @@ -1,6 +0,0 @@ -.\cmake-build\shaderc.exe -f .\game\shaders\vert.sc -o .\game\compiled-shaders\dx11\vert.bin -i .\dependency\bgfx.cmake\bgfx\src\ --type v --platform windows --profile s_5_0 -.\cmake-build\shaderc.exe -f .\game\shaders\frag.sc -o .\game\compiled-shaders\dx11\frag.bin -i .\dependency\bgfx.cmake\bgfx\src\ --type f --platform windows --profile s_5_0 -.\cmake-build\shaderc.exe -f .\game\shaders\vert.sc -o .\game\compiled-shaders\glsl\vert.bin -i .\dependency\bgfx.cmake\bgfx\src\ --type v --platform windows --profile 430 -.\cmake-build\shaderc.exe -f .\game\shaders\frag.sc -o .\game\compiled-shaders\glsl\frag.bin -i .\dependency\bgfx.cmake\bgfx\src\ --type f --platform windows --profile 430 -.\cmake-build\shaderc.exe -f .\game\shaders\vert.sc -o .\game\compiled-shaders\spirv\vert.bin -i .\dependency\bgfx.cmake\bgfx\src\ --type v --platform windows --profile spirv16-13 -.\cmake-build\shaderc.exe -f .\game\shaders\frag.sc -o .\game\compiled-shaders\spirv\frag.bin -i .\dependency\bgfx.cmake\bgfx\src\ --type f --platform windows --profile spirv16-13 diff --git a/src/shadercompile.ps1 b/src/shadercompile.ps1 new file mode 100644 index 0000000..8d6e753 --- /dev/null +++ b/src/shadercompile.ps1 @@ -0,0 +1,20 @@ +$shadercPath = ".\cmake-build\shaderc.exe" +$shadersDir = ".\game\shaders" +$outputBaseDir = ".\game\compiled-shaders" +$includeDir = ".\dependency\bgfx.cmake\bgfx\src" + +function Process-Directory { + param ([string]$DirectoryFull, [string]$DirectoryName) + Write-Host "Dir: $DirectoryName" + $outDir = "$outputBaseDir\dx11\$DirectoryName" + New-Item -ItemType Directory -Path $outDir -Force -ErrorAction Stop | Out-Null + Write-Host "Frag" + & $shadercPath -f "$DirectoryFull\vert.sc" -o "$outDir\vert.bin" -i $includeDir --type v --platform windows --profile s_5_0 + Write-Host "Vert" + & $shadercPath -f "$DirectoryFull\frag.sc" -o "$outDir\frag.bin" -i $includeDir --type f --platform windows --profile s_5_0 +} + +$subdirectories = Get-ChildItem -Path $shadersDir -Directory -Recurse -ErrorAction Stop +foreach ($subdirectory in $subdirectories) { + Process-Directory -DirectoryFull $subdirectory.FullName -DirectoryName $subdirectory.Name +}