Repository navigation
GL: fix dynamic sun shadows on macOS (Apple GL) - #2196
Open
Stepan-sovok1917 wants to merge 1 commit into
Open
Stepan-sovok1917 wants to merge 1 commit into
Stepan-sovok1917 wants to merge 1 commit into
Conversation
Three defects in the GL port produced the same symptom set - sunlight leaking through roofs/walls into interiors, no shadows from opaque geometry, only alpha-tested foliage casting shadows: - SE_R2_SHADOW passes were compiled with the 'null' pixel shader. In an OpenGL core profile a draw without a valid fragment shader is not executed, so opaque casters never got written into the sun shadow map. The DX branches of the same blenders already use the trivial 'dumb' PS; switch the GL branches to it as well. The tree caster case sits in a branch shared with R_R3/R_R4, so it is wrapped in '#if RENDER == R_GL'. - s_smap is declared as sampler2DShadow in the GLSL shaders, but the sampler object bound to that unit had no comparison mode. textureProj() on such a pair is undefined; Apple's Metal-backed GL silently returns raw depth (~0.9-1.0) which disables dynamic shadows. Bind a comparison sampler (r_Sampler_cmp) under USE_OGL, matching what DX11 does with smp_smap. - The sun shadow camera was wrong: glm::lookAt takes a target point, not a direction, so passing L_dir aimed the camera at the world origin instead of along the sun direction (the DX counterpart uses build_camera_dir). The orthographic projection also passed raw view- space z (negative in front of a right-handed lookAt) as near/far, which mapped the geometry outside the [-1,1] clip range and left the near shadow map empty. Aim the camera along L_dir and negate the z bounds, as the GL convention requires. Verified on macOS (Apple M4, OpenGL 4.1 core, CoP): without the fix a frame with the sun on rendered at 64.4% of full brightness (light leaking into interiors); after the fix 57.6% with the sun on vs 57.3% with it off, shadows from trunks/roofs/gates are present.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Проблема
На macOS (OpenGL 4.1 core profile от Apple поверх Metal) динамические тени от солнца не
работали:
Причина
Три независимых дефекта GL-порта, каждый вносил свою часть в одну и ту же картину:
SE_R2_SHADOWблендеровотложенного рендера собирались с пиксельным шейдером
"null". В OpenGL core profiledraw без валидного фрагментного шейдера не выполняется (Apple'овский GL молча
игнорирует его), поэтому стволы/крыши/стены никогда не записывались в карту теней.
В DX-ветках тех же блендеров уже стоит тривиальный
"dumb"—"null"был ошибкойименно GL-порта.
s_smapне был comparison-сэмплером. GLSL-шейдеры объявляютsampler2DShadow, носэмплер-объект, привязанный к этой текстурной единице, не имел режима сравнения.
textureProj()на такой паре даёт неопределённое поведение; Apple'овскийMetal-бэкенд молча возвращает сырую глубину (~0.9–1.0), что отключает динамические
тени. DX11 для того же прохода использует comparison-сэмплер (
smp_smap).glm::lookAt(eye, center, up)принимаетцелевую точку, а не направление: передача
L_dirнаправляла теневую камеру вначало координат вместо хода по направлению солнца (DX-аналог использует
build_camera_dir). Кроме того,glm::ortho()(GL-конвенция) ожидает положительныеnear/far, а z ограничивающего бокса приходит из right-handed view, где геометрия
перед источником света имеет отрицательный z — старый вызов передавал около
−530..−480 и выводил всю геометрию за пределы диапазона клипа [−1,1], из-за чего
ближняя shadow map оставалась пустой.
Фикс
blender_deffer_flat,blender_deffer_model}.cpp
:"null"→"dumb"вSE_R2_SHADOW(эти ветки лежат внутри
RENDER == R_GL; DX-ветки не тронуты).src/Layers/xrRender/blenders/Blender_tree_deferred.cpp: случай теневого проходадерева лежит в ветке, общей с R_R3/R_R4, поэтому GL-изменение обёрнуто в
#if RENDER == R_GL.src/Layers/xrRender/blenders/{blender_light_direct,blender_light_direct_cascade}.cpp:C.r_Sampler_cmp("s_smap", r2_RT_smap_depth)под#if defined(USE_OGL)(настройкаDX-сэмплеров не менялась).
src/Layers/xrRenderPC_GL/r2_R_sun.cpp:glm::lookAt(L_pos, L_pos + L_dir, L_up)и-bb.vMax.z … -bb.vMin.zдля near/far вrender_sun()иrender_sun_near().Проверка
macOS 27.0.1, Apple M4, OpenGL 4.1 core, S.T.A.L.K.E.R. CoP, сборка Release:
после: 57.6 % с солнцем против 57.3 % с выключенным солнцем — интерьеры
совпадают с базой «только запечённый свет»;
RENDER == R_GL/USE_OGL).Влияние на платформы
Только OpenGL-рендер (ветки
RENDER == R_GL/USE_OGLи GL-единственныйr2_R_sun.cpp). Рендеры D3D9/10/11 не затронуты.Примечания
Первый вклад в проект; дефекты локализованы и проверены на реальном железе совместно с
ИИ-ассистентом.