diff --git a/docs/used/SRP_URP_ExplicitSceneSetupPolicyPlan_2026-04-21_完成归档.md b/docs/used/SRP_URP_ExplicitSceneSetupPolicyPlan_2026-04-21_完成归档.md new file mode 100644 index 00000000..e62e397a --- /dev/null +++ b/docs/used/SRP_URP_ExplicitSceneSetupPolicyPlan_2026-04-21_完成归档.md @@ -0,0 +1,144 @@ +# SRP / URP Explicit Scene Setup Policy Plan + +## 背景 + +上一阶段已经把 request-level 的一部分策略从 native default 挪到了 managed URP: + +- `Camera.clearMode` +- `Camera.stackType` +- `CameraRenderRequestContext.clearFlags` +- `UniversalRenderPipelineAsset` 中的默认 clear / shadow request policy + +但 `RenderSceneSetup` 这一层还没有真正收口。 +当前 `UniversalRenderer.ConfigureRenderSceneSetup(...)` 仍然只是调用: + +- `UseDefaultEnvironment()` +- `UseDefaultGlobalShaderKeywords()` + +这意味着: + +- URP 还没有显式决定“这帧环境到底是什么” +- URP 还没有显式决定“全局 shader keyword 到底开哪些” +- native default 仍然在替 URP 做 scene setup policy + +这和目标中的 Unity 风格 `SRP substrate + URP package policy` 不一致。 + +## 本阶段目标 + +把 scene setup 从“调用 native 默认策略”收成“managed URP 显式配置策略”。 + +本阶段只做 seam 收口,不做 deferred,不改 Render Graph 主执行骨架。 + +### 目标 1 + +扩展 `RenderSceneSetupContext`,让 managed 层拿到显式决策所需的最小上下文: + +- `clearFlags` +- `hasMainSceneDepthAttachment` +- `hasMainDirectionalShadow` + +### 目标 2 + +扩展 managed `Camera` 只读能力,让 URP 可以显式决定 skybox policy: + +- `projectionType` +- `skyboxEnabled` +- `hasSkyboxMaterial` +- `skyboxTopColor` +- `skyboxHorizonColor` +- `skyboxBottomColor` + +### 目标 3 + +扩展 `RenderSceneSetupContext` 的显式写入口: + +- `SetEnvironmentNone()` +- `UseCameraSkyboxMaterial()` +- `SetProceduralSkybox(...)` +- `SetGlobalShaderKeyword(string keyword, bool enabled)` + +### 目标 4 + +把 `UniversalRenderer.ConfigureRenderSceneSetup(...)` 改成显式逻辑,复刻当前 native default 行为: + +- 先清空 environment / global keywords +- 再根据 camera + request + main scene surface 条件显式设置 skybox +- 再根据 `hasMainDirectionalShadow` 显式设置 `XC_MAIN_LIGHT_SHADOWS` + +## 实施步骤 + +### Step 1. 补齐 managed / native scene setup bridge + +在 `RenderSceneSetupContext` 与 `MonoScriptRuntime` 之间增加新的只读属性和显式写接口。 + +要求: + +- 不引入兼容层 +- 不保留“旧 API + 新 API 并存但无人使用”的半弃用状态 +- scene setup 的显式接口命名要直接表达意图 + +### Step 2. 补齐 Camera 的只读 skybox / projection seam + +通过 internal call 暴露 managed 决策所需的 camera 状态。 + +要求: + +- 只补当前 scene setup 确实需要的读取能力 +- 不顺手扩一堆暂时无用的 Camera API + +### Step 3. 切换 UniversalRenderer 的 scene setup 实现 + +把当前两句 `UseDefault...` 换成显式策略代码。 + +要求: + +- 行为尽量与当前默认行为一致 +- 不再依赖 native default 来决定 keyword / environment +- feature 后续仍可以在 `ConfigureRenderSceneSetup(...)` 链路里继续覆写 + +## 收口标准 + +- `UniversalRenderer.ConfigureRenderSceneSetup(...)` 不再调用 native default environment / keyword policy +- URP 可以显式配置: + - environment none + - camera material skybox + - procedural skybox + - global shader keyword on/off +- `XC_MAIN_LIGHT_SHADOWS` 由 managed scene setup 显式决定 +- `XCEditor` Debug 编译通过 +- 旧版 editor 冒烟通过 + +## 非目标 + +本阶段不做以下内容: + +- deferred rendering +- shadow 算法本体迁移 +- gaussian / volumetric pass 迁移 +- Render Graph 结构大改 +- editor / new_editor 相关重构 + +## 完成情况 + +- 已补齐 managed `Camera` 的 scene setup 只读 seam: + - `projectionType` + - `skyboxEnabled` + - `hasSkyboxMaterial` + - `skyboxTopColor` + - `skyboxHorizonColor` + - `skyboxBottomColor` +- 已补齐 `RenderSceneSetupContext` 的显式 scene setup seam: + - `clearFlags` + - `hasMainSceneDepthAttachment` + - `hasMainDirectionalShadow` + - `SetEnvironmentNone()` + - `UseCameraSkyboxMaterial()` + - `SetProceduralSkybox(...)` + - `SetGlobalShaderKeyword(string, bool)` +- 已删除不再使用的 managed scene setup default / 清空兼容 API,避免双轨状态继续存在 +- `UniversalRenderer.ConfigureRenderSceneSetup(...)` 已切换为显式策略: + - 显式决定 skybox environment 是否启用 + - 显式决定材质天空盒 / procedural skybox + - 显式决定 `XC_MAIN_LIGHT_SHADOWS` +- `XCEditor` Debug 编译通过 +- 旧版 editor 冒烟通过 diff --git a/engine/src/Scripting/Mono/MonoScriptRuntime.cpp b/engine/src/Scripting/Mono/MonoScriptRuntime.cpp index 99013fca..ab33fb0a 100644 --- a/engine/src/Scripting/Mono/MonoScriptRuntime.cpp +++ b/engine/src/Scripting/Mono/MonoScriptRuntime.cpp @@ -4044,6 +4044,62 @@ void InternalCall_Camera_SetStackType(uint64_t gameObjectUUID, int32_t value) { static_cast(value)); } +int32_t InternalCall_Camera_GetProjectionType(uint64_t gameObjectUUID) { + Components::CameraComponent* component = FindCameraComponent(gameObjectUUID); + return component != nullptr + ? static_cast(component->GetProjectionType()) + : 0; +} + +mono_bool InternalCall_Camera_GetSkyboxEnabled(uint64_t gameObjectUUID) { + Components::CameraComponent* component = FindCameraComponent(gameObjectUUID); + return (component && component->IsSkyboxEnabled()) ? 1 : 0; +} + +mono_bool InternalCall_Camera_GetHasSkyboxMaterial(uint64_t gameObjectUUID) { + Components::CameraComponent* component = FindCameraComponent(gameObjectUUID); + return (component && component->GetSkyboxMaterial() != nullptr) ? 1 : 0; +} + +void InternalCall_Camera_GetSkyboxTopColor( + uint64_t gameObjectUUID, + XCEngine::Math::Color* outColor) { + if (outColor == nullptr) { + return; + } + + Components::CameraComponent* component = FindCameraComponent(gameObjectUUID); + *outColor = component != nullptr + ? component->GetSkyboxTopColor() + : XCEngine::Math::Color(); +} + +void InternalCall_Camera_GetSkyboxHorizonColor( + uint64_t gameObjectUUID, + XCEngine::Math::Color* outColor) { + if (outColor == nullptr) { + return; + } + + Components::CameraComponent* component = FindCameraComponent(gameObjectUUID); + *outColor = component != nullptr + ? component->GetSkyboxHorizonColor() + : XCEngine::Math::Color(); +} + +void InternalCall_Camera_GetSkyboxBottomColor( + uint64_t gameObjectUUID, + XCEngine::Math::Color* outColor) { + if (outColor == nullptr) { + return; + } + + Components::CameraComponent* component = FindCameraComponent(gameObjectUUID); + *outColor = component != nullptr + ? component->GetSkyboxBottomColor() + : XCEngine::Math::Color(); +} + float InternalCall_Light_GetIntensity(uint64_t gameObjectUUID) { Components::LightComponent* component = FindLightComponent(gameObjectUUID); return component ? component->GetIntensity() : 0.0f; @@ -5613,60 +5669,41 @@ InternalCall_Rendering_RenderSceneSetupContext_GetIsConfigured( : 0; } -mono_bool -InternalCall_Rendering_RenderSceneSetupContext_UseDefaultSceneSetup( +int32_t InternalCall_Rendering_RenderSceneSetupContext_GetClearFlags( uint64_t nativeHandle) { - ManagedRenderSceneSetupContextState* const state = + const ManagedRenderSceneSetupContextState* const state = FindManagedRenderSceneSetupContextState(nativeHandle); - if (state == nullptr || - state->plan == nullptr || - state->sceneData == nullptr) { - return 0; - } - - Rendering::ApplyDefaultRenderPipelineSceneSetupPolicy( - *state->plan, - *state->sceneData); - state->explicitlyConfigured = true; - return 1; + return state != nullptr && + state->plan != nullptr + ? static_cast(state->plan->request.clearFlags) + : 0; } mono_bool -InternalCall_Rendering_RenderSceneSetupContext_UseDefaultEnvironment( +InternalCall_Rendering_RenderSceneSetupContext_GetHasMainSceneDepthAttachment( uint64_t nativeHandle) { - ManagedRenderSceneSetupContextState* const state = + const ManagedRenderSceneSetupContextState* const state = FindManagedRenderSceneSetupContextState(nativeHandle); - if (state == nullptr || - state->plan == nullptr || - state->sceneData == nullptr) { - return 0; - } - - state->sceneData->environment = - Rendering::BuildDefaultRenderPipelineEnvironmentData( - *state->plan); - state->explicitlyConfigured = true; - return 1; + return state != nullptr && + state->plan != nullptr && + state->plan->GetMainSceneSurface().GetDepthAttachment() != nullptr + ? 1 + : 0; } mono_bool -InternalCall_Rendering_RenderSceneSetupContext_UseDefaultGlobalShaderKeywords( +InternalCall_Rendering_RenderSceneSetupContext_GetHasMainDirectionalShadow( uint64_t nativeHandle) { - ManagedRenderSceneSetupContextState* const state = + const ManagedRenderSceneSetupContextState* const state = FindManagedRenderSceneSetupContextState(nativeHandle); - if (state == nullptr || state->sceneData == nullptr) { - return 0; - } - - state->sceneData->globalShaderKeywords = - Rendering:: - BuildDefaultRenderPipelineSceneGlobalShaderKeywords( - *state->sceneData); - state->explicitlyConfigured = true; - return 1; + return state != nullptr && + state->sceneData != nullptr && + state->sceneData->lighting.HasMainDirectionalShadow() + ? 1 + : 0; } -void InternalCall_Rendering_RenderSceneSetupContext_ClearEnvironment( +void InternalCall_Rendering_RenderSceneSetupContext_SetEnvironmentNone( uint64_t nativeHandle) { ManagedRenderSceneSetupContextState* const state = FindManagedRenderSceneSetupContextState(nativeHandle); @@ -5678,6 +5715,56 @@ void InternalCall_Rendering_RenderSceneSetupContext_ClearEnvironment( state->explicitlyConfigured = true; } +mono_bool +InternalCall_Rendering_RenderSceneSetupContext_UseCameraSkyboxMaterial( + uint64_t nativeHandle) { + ManagedRenderSceneSetupContextState* const state = + FindManagedRenderSceneSetupContextState(nativeHandle); + if (state == nullptr || + state->plan == nullptr || + state->sceneData == nullptr || + state->plan->request.camera == nullptr) { + return 0; + } + + const Resources::Material* skyboxMaterial = + state->plan->request.camera->GetSkyboxMaterial(); + if (skyboxMaterial == nullptr) { + return 0; + } + + state->sceneData->environment = {}; + state->sceneData->environment.mode = + Rendering::RenderEnvironmentMode::MaterialSkybox; + state->sceneData->environment.materialSkybox.material = + skyboxMaterial; + state->explicitlyConfigured = true; + return 1; +} + +void InternalCall_Rendering_RenderSceneSetupContext_SetProceduralSkybox( + uint64_t nativeHandle, + XCEngine::Math::Color* topColor, + XCEngine::Math::Color* horizonColor, + XCEngine::Math::Color* bottomColor) { + ManagedRenderSceneSetupContextState* const state = + FindManagedRenderSceneSetupContextState(nativeHandle); + if (state == nullptr || state->sceneData == nullptr) { + return; + } + + state->sceneData->environment = {}; + state->sceneData->environment.mode = + Rendering::RenderEnvironmentMode::ProceduralSkybox; + state->sceneData->environment.skybox.topColor = + topColor != nullptr ? *topColor : XCEngine::Math::Color(); + state->sceneData->environment.skybox.horizonColor = + horizonColor != nullptr ? *horizonColor : XCEngine::Math::Color(); + state->sceneData->environment.skybox.bottomColor = + bottomColor != nullptr ? *bottomColor : XCEngine::Math::Color(); + state->explicitlyConfigured = true; +} + void InternalCall_Rendering_RenderSceneSetupContext_ClearGlobalShaderKeywords( uint64_t nativeHandle) { @@ -5691,16 +5778,55 @@ InternalCall_Rendering_RenderSceneSetupContext_ClearGlobalShaderKeywords( state->explicitlyConfigured = true; } -void InternalCall_Rendering_RenderSceneSetupContext_ClearSceneSetup( - uint64_t nativeHandle) { +void InternalCall_Rendering_RenderSceneSetupContext_SetGlobalShaderKeyword( + uint64_t nativeHandle, + MonoString* keyword, + mono_bool enabled) { ManagedRenderSceneSetupContextState* const state = FindManagedRenderSceneSetupContextState(nativeHandle); if (state == nullptr || state->sceneData == nullptr) { return; } - state->sceneData->environment = {}; - state->sceneData->globalShaderKeywords = {}; + const XCEngine::Containers::String normalizedKeyword = + Resources::NormalizeShaderKeywordToken( + XCEngine::Containers::String( + MonoStringToUtf8(keyword).c_str())); + if (normalizedKeyword.Empty()) { + state->explicitlyConfigured = true; + return; + } + + Resources::ShaderKeywordSet& keywordSet = + state->sceneData->globalShaderKeywords; + bool foundKeyword = false; + size_t foundIndex = 0; + for (size_t keywordIndex = 0; + keywordIndex < keywordSet.enabledKeywords.Size(); + ++keywordIndex) { + if (keywordSet.enabledKeywords[keywordIndex] == + normalizedKeyword) { + foundKeyword = true; + foundIndex = keywordIndex; + break; + } + } + + if (enabled != 0) { + if (!foundKeyword) { + keywordSet.enabledKeywords.PushBack(normalizedKeyword); + } + } else if (foundKeyword) { + const size_t lastIndex = + keywordSet.enabledKeywords.Size() - 1; + if (foundIndex != lastIndex) { + keywordSet.enabledKeywords[foundIndex] = + keywordSet.enabledKeywords[lastIndex]; + } + keywordSet.enabledKeywords.PopBack(); + } + + Resources::NormalizeShaderKeywordSetInPlace(keywordSet); state->explicitlyConfigured = true; } @@ -6100,6 +6226,12 @@ void RegisterInternalCalls() { mono_add_internal_call("XCEngine.InternalCalls::Camera_SetClearMode", reinterpret_cast(&InternalCall_Camera_SetClearMode)); mono_add_internal_call("XCEngine.InternalCalls::Camera_GetStackType", reinterpret_cast(&InternalCall_Camera_GetStackType)); mono_add_internal_call("XCEngine.InternalCalls::Camera_SetStackType", reinterpret_cast(&InternalCall_Camera_SetStackType)); + mono_add_internal_call("XCEngine.InternalCalls::Camera_GetProjectionType", reinterpret_cast(&InternalCall_Camera_GetProjectionType)); + mono_add_internal_call("XCEngine.InternalCalls::Camera_GetSkyboxEnabled", reinterpret_cast(&InternalCall_Camera_GetSkyboxEnabled)); + mono_add_internal_call("XCEngine.InternalCalls::Camera_GetHasSkyboxMaterial", reinterpret_cast(&InternalCall_Camera_GetHasSkyboxMaterial)); + mono_add_internal_call("XCEngine.InternalCalls::Camera_GetSkyboxTopColor", reinterpret_cast(&InternalCall_Camera_GetSkyboxTopColor)); + mono_add_internal_call("XCEngine.InternalCalls::Camera_GetSkyboxHorizonColor", reinterpret_cast(&InternalCall_Camera_GetSkyboxHorizonColor)); + mono_add_internal_call("XCEngine.InternalCalls::Camera_GetSkyboxBottomColor", reinterpret_cast(&InternalCall_Camera_GetSkyboxBottomColor)); mono_add_internal_call("XCEngine.InternalCalls::Light_GetIntensity", reinterpret_cast(&InternalCall_Light_GetIntensity)); mono_add_internal_call("XCEngine.InternalCalls::Light_SetIntensity", reinterpret_cast(&InternalCall_Light_SetIntensity)); mono_add_internal_call("XCEngine.InternalCalls::Light_GetRange", reinterpret_cast(&InternalCall_Light_GetRange)); @@ -6239,12 +6371,14 @@ void RegisterInternalCalls() { mono_add_internal_call("XCEngine.InternalCalls::Rendering_RenderSceneSetupContext_GetRendererIndex", reinterpret_cast(&InternalCall_Rendering_RenderSceneSetupContext_GetRendererIndex)); mono_add_internal_call("XCEngine.InternalCalls::Rendering_RenderSceneSetupContext_GetCameraGameObjectUUID", reinterpret_cast(&InternalCall_Rendering_RenderSceneSetupContext_GetCameraGameObjectUUID)); mono_add_internal_call("XCEngine.InternalCalls::Rendering_RenderSceneSetupContext_GetIsConfigured", reinterpret_cast(&InternalCall_Rendering_RenderSceneSetupContext_GetIsConfigured)); - mono_add_internal_call("XCEngine.InternalCalls::Rendering_RenderSceneSetupContext_UseDefaultSceneSetup", reinterpret_cast(&InternalCall_Rendering_RenderSceneSetupContext_UseDefaultSceneSetup)); - mono_add_internal_call("XCEngine.InternalCalls::Rendering_RenderSceneSetupContext_UseDefaultEnvironment", reinterpret_cast(&InternalCall_Rendering_RenderSceneSetupContext_UseDefaultEnvironment)); - mono_add_internal_call("XCEngine.InternalCalls::Rendering_RenderSceneSetupContext_UseDefaultGlobalShaderKeywords", reinterpret_cast(&InternalCall_Rendering_RenderSceneSetupContext_UseDefaultGlobalShaderKeywords)); - mono_add_internal_call("XCEngine.InternalCalls::Rendering_RenderSceneSetupContext_ClearEnvironment", reinterpret_cast(&InternalCall_Rendering_RenderSceneSetupContext_ClearEnvironment)); + mono_add_internal_call("XCEngine.InternalCalls::Rendering_RenderSceneSetupContext_GetClearFlags", reinterpret_cast(&InternalCall_Rendering_RenderSceneSetupContext_GetClearFlags)); + mono_add_internal_call("XCEngine.InternalCalls::Rendering_RenderSceneSetupContext_GetHasMainSceneDepthAttachment", reinterpret_cast(&InternalCall_Rendering_RenderSceneSetupContext_GetHasMainSceneDepthAttachment)); + mono_add_internal_call("XCEngine.InternalCalls::Rendering_RenderSceneSetupContext_GetHasMainDirectionalShadow", reinterpret_cast(&InternalCall_Rendering_RenderSceneSetupContext_GetHasMainDirectionalShadow)); + mono_add_internal_call("XCEngine.InternalCalls::Rendering_RenderSceneSetupContext_SetEnvironmentNone", reinterpret_cast(&InternalCall_Rendering_RenderSceneSetupContext_SetEnvironmentNone)); + mono_add_internal_call("XCEngine.InternalCalls::Rendering_RenderSceneSetupContext_UseCameraSkyboxMaterial", reinterpret_cast(&InternalCall_Rendering_RenderSceneSetupContext_UseCameraSkyboxMaterial)); + mono_add_internal_call("XCEngine.InternalCalls::Rendering_RenderSceneSetupContext_SetProceduralSkybox", reinterpret_cast(&InternalCall_Rendering_RenderSceneSetupContext_SetProceduralSkybox)); mono_add_internal_call("XCEngine.InternalCalls::Rendering_RenderSceneSetupContext_ClearGlobalShaderKeywords", reinterpret_cast(&InternalCall_Rendering_RenderSceneSetupContext_ClearGlobalShaderKeywords)); - mono_add_internal_call("XCEngine.InternalCalls::Rendering_RenderSceneSetupContext_ClearSceneSetup", reinterpret_cast(&InternalCall_Rendering_RenderSceneSetupContext_ClearSceneSetup)); + mono_add_internal_call("XCEngine.InternalCalls::Rendering_RenderSceneSetupContext_SetGlobalShaderKeyword", reinterpret_cast(&InternalCall_Rendering_RenderSceneSetupContext_SetGlobalShaderKeyword)); mono_add_internal_call("XCEngine.InternalCalls::Rendering_DirectionalShadowExecutionContext_GetHasPlannedMainDirectionalShadow", reinterpret_cast(&InternalCall_Rendering_DirectionalShadowExecutionContext_GetHasPlannedMainDirectionalShadow)); mono_add_internal_call("XCEngine.InternalCalls::Rendering_DirectionalShadowExecutionContext_GetRendererIndex", reinterpret_cast(&InternalCall_Rendering_DirectionalShadowExecutionContext_GetRendererIndex)); mono_add_internal_call("XCEngine.InternalCalls::Rendering_DirectionalShadowExecutionContext_GetIsConfigured", reinterpret_cast(&InternalCall_Rendering_DirectionalShadowExecutionContext_GetIsConfigured)); diff --git a/managed/CMakeLists.txt b/managed/CMakeLists.txt index dc5f28c5..7d43ef23 100644 --- a/managed/CMakeLists.txt +++ b/managed/CMakeLists.txt @@ -145,6 +145,7 @@ set(XCENGINE_SCRIPT_CORE_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Behaviour.cs ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Camera.cs ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/CameraClearMode.cs + ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/CameraProjectionType.cs ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/CameraStackType.cs ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Color.cs ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Component.cs diff --git a/managed/XCEngine.RenderPipelines.Universal/Rendering/Universal/UniversalRenderer.cs b/managed/XCEngine.RenderPipelines.Universal/Rendering/Universal/UniversalRenderer.cs index 172f4c04..424c53ba 100644 --- a/managed/XCEngine.RenderPipelines.Universal/Rendering/Universal/UniversalRenderer.cs +++ b/managed/XCEngine.RenderPipelines.Universal/Rendering/Universal/UniversalRenderer.cs @@ -5,6 +5,8 @@ namespace XCEngine.Rendering.Universal { public sealed class UniversalRenderer : ScriptableRenderer { + private const string kMainLightShadowsKeyword = + "XC_MAIN_LIGHT_SHADOWS"; private readonly UniversalRendererData m_rendererData; private readonly BuiltinFinalColorPass m_builtinFinalColorPass = new BuiltinFinalColorPass(); @@ -81,8 +83,30 @@ namespace XCEngine.Rendering.Universal return; } - context.UseDefaultEnvironment(); - context.UseDefaultGlobalShaderKeywords(); + context.SetEnvironmentNone(); + context.ClearGlobalShaderKeywords(); + + Camera camera = context.camera; + if (ShouldUseSkyboxEnvironment( + context, + camera)) + { + if (camera.hasSkyboxMaterial) + { + context.UseCameraSkyboxMaterial(); + } + else + { + context.SetProceduralSkybox( + camera.skyboxTopColor, + camera.skyboxHorizonColor, + camera.skyboxBottomColor); + } + } + + context.SetGlobalShaderKeyword( + kMainLightShadowsKeyword, + context.hasMainDirectionalShadow); } protected override void ConfigureDirectionalShadowExecutionState( @@ -272,6 +296,23 @@ namespace XCEngine.Rendering.Universal finalOutputSource); } + private static bool ShouldUseSkyboxEnvironment( + RenderSceneSetupContext context, + Camera camera) + { + if (context == null || + camera == null || + !context.hasMainSceneDepthAttachment || + (context.clearFlags & RenderClearFlags.Color) == 0 || + !camera.skyboxEnabled) + { + return false; + } + + return camera.projectionType == + CameraProjectionType.Perspective; + } + private void EnqueueFinalOutputPasses( RenderingData renderingData) { diff --git a/managed/XCEngine.ScriptCore/Camera.cs b/managed/XCEngine.ScriptCore/Camera.cs index 02b1d99d..4d2b5c8b 100644 --- a/managed/XCEngine.ScriptCore/Camera.cs +++ b/managed/XCEngine.ScriptCore/Camera.cs @@ -100,5 +100,71 @@ namespace XCEngine get => StackType; set => StackType = value; } + + public CameraProjectionType ProjectionType => + (CameraProjectionType)InternalCalls + .Camera_GetProjectionType(GameObjectUUID); + + public CameraProjectionType projectionType => + ProjectionType; + + public bool SkyboxEnabled => + InternalCalls + .Camera_GetSkyboxEnabled(GameObjectUUID); + + public bool skyboxEnabled => + SkyboxEnabled; + + public bool HasSkyboxMaterial => + InternalCalls + .Camera_GetHasSkyboxMaterial(GameObjectUUID); + + public bool hasSkyboxMaterial => + HasSkyboxMaterial; + + public Color SkyboxTopColor + { + get + { + InternalCalls + .Camera_GetSkyboxTopColor( + GameObjectUUID, + out Color value); + return value; + } + } + + public Color skyboxTopColor => + SkyboxTopColor; + + public Color SkyboxHorizonColor + { + get + { + InternalCalls + .Camera_GetSkyboxHorizonColor( + GameObjectUUID, + out Color value); + return value; + } + } + + public Color skyboxHorizonColor => + SkyboxHorizonColor; + + public Color SkyboxBottomColor + { + get + { + InternalCalls + .Camera_GetSkyboxBottomColor( + GameObjectUUID, + out Color value); + return value; + } + } + + public Color skyboxBottomColor => + SkyboxBottomColor; } } diff --git a/managed/XCEngine.ScriptCore/CameraProjectionType.cs b/managed/XCEngine.ScriptCore/CameraProjectionType.cs new file mode 100644 index 00000000..7e4f0e62 --- /dev/null +++ b/managed/XCEngine.ScriptCore/CameraProjectionType.cs @@ -0,0 +1,8 @@ +namespace XCEngine +{ + public enum CameraProjectionType + { + Perspective = 0, + Orthographic + } +} diff --git a/managed/XCEngine.ScriptCore/InternalCalls.cs b/managed/XCEngine.ScriptCore/InternalCalls.cs index f8bd2e0f..4a9e53b9 100644 --- a/managed/XCEngine.ScriptCore/InternalCalls.cs +++ b/managed/XCEngine.ScriptCore/InternalCalls.cs @@ -264,6 +264,24 @@ namespace XCEngine [MethodImpl(MethodImplOptions.InternalCall)] internal static extern void Camera_SetStackType(ulong gameObjectUUID, int value); + [MethodImpl(MethodImplOptions.InternalCall)] + internal static extern int Camera_GetProjectionType(ulong gameObjectUUID); + + [MethodImpl(MethodImplOptions.InternalCall)] + internal static extern bool Camera_GetSkyboxEnabled(ulong gameObjectUUID); + + [MethodImpl(MethodImplOptions.InternalCall)] + internal static extern bool Camera_GetHasSkyboxMaterial(ulong gameObjectUUID); + + [MethodImpl(MethodImplOptions.InternalCall)] + internal static extern void Camera_GetSkyboxTopColor(ulong gameObjectUUID, out Color value); + + [MethodImpl(MethodImplOptions.InternalCall)] + internal static extern void Camera_GetSkyboxHorizonColor(ulong gameObjectUUID, out Color value); + + [MethodImpl(MethodImplOptions.InternalCall)] + internal static extern void Camera_GetSkyboxBottomColor(ulong gameObjectUUID, out Color value); + [MethodImpl(MethodImplOptions.InternalCall)] internal static extern float Light_GetIntensity(ulong gameObjectUUID); @@ -942,25 +960,38 @@ namespace XCEngine ulong nativeHandle); [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern bool - Rendering_RenderSceneSetupContext_UseDefaultSceneSetup( + internal static extern int + Rendering_RenderSceneSetupContext_GetClearFlags( ulong nativeHandle); [MethodImpl(MethodImplOptions.InternalCall)] internal static extern bool - Rendering_RenderSceneSetupContext_UseDefaultEnvironment( + Rendering_RenderSceneSetupContext_GetHasMainSceneDepthAttachment( ulong nativeHandle); [MethodImpl(MethodImplOptions.InternalCall)] internal static extern bool - Rendering_RenderSceneSetupContext_UseDefaultGlobalShaderKeywords( + Rendering_RenderSceneSetupContext_GetHasMainDirectionalShadow( ulong nativeHandle); [MethodImpl(MethodImplOptions.InternalCall)] internal static extern void - Rendering_RenderSceneSetupContext_ClearEnvironment( + Rendering_RenderSceneSetupContext_SetEnvironmentNone( ulong nativeHandle); + [MethodImpl(MethodImplOptions.InternalCall)] + internal static extern bool + Rendering_RenderSceneSetupContext_UseCameraSkyboxMaterial( + ulong nativeHandle); + + [MethodImpl(MethodImplOptions.InternalCall)] + internal static extern void + Rendering_RenderSceneSetupContext_SetProceduralSkybox( + ulong nativeHandle, + ref Color topColor, + ref Color horizonColor, + ref Color bottomColor); + [MethodImpl(MethodImplOptions.InternalCall)] internal static extern void Rendering_RenderSceneSetupContext_ClearGlobalShaderKeywords( @@ -968,8 +999,10 @@ namespace XCEngine [MethodImpl(MethodImplOptions.InternalCall)] internal static extern void - Rendering_RenderSceneSetupContext_ClearSceneSetup( - ulong nativeHandle); + Rendering_RenderSceneSetupContext_SetGlobalShaderKeyword( + ulong nativeHandle, + string keyword, + bool enabled); [MethodImpl(MethodImplOptions.InternalCall)] internal static extern bool diff --git a/managed/XCEngine.ScriptCore/Rendering/Core/RenderSceneSetupContext.cs b/managed/XCEngine.ScriptCore/Rendering/Core/RenderSceneSetupContext.cs index 03d937b8..d260ef03 100644 --- a/managed/XCEngine.ScriptCore/Rendering/Core/RenderSceneSetupContext.cs +++ b/managed/XCEngine.ScriptCore/Rendering/Core/RenderSceneSetupContext.cs @@ -38,34 +38,48 @@ namespace XCEngine.Rendering .Rendering_RenderSceneSetupContext_GetIsConfigured( m_nativeHandle); - public bool UseDefaultSceneSetup() - { - return InternalCalls - .Rendering_RenderSceneSetupContext_UseDefaultSceneSetup( + public RenderClearFlags clearFlags => + (RenderClearFlags)InternalCalls + .Rendering_RenderSceneSetupContext_GetClearFlags( m_nativeHandle); - } - public bool UseDefaultEnvironment() - { - return InternalCalls - .Rendering_RenderSceneSetupContext_UseDefaultEnvironment( + public bool hasMainSceneDepthAttachment => + InternalCalls + .Rendering_RenderSceneSetupContext_GetHasMainSceneDepthAttachment( m_nativeHandle); - } - public bool UseDefaultGlobalShaderKeywords() - { - return InternalCalls - .Rendering_RenderSceneSetupContext_UseDefaultGlobalShaderKeywords( + public bool hasMainDirectionalShadow => + InternalCalls + .Rendering_RenderSceneSetupContext_GetHasMainDirectionalShadow( m_nativeHandle); - } - public void ClearEnvironment() + public void SetEnvironmentNone() { InternalCalls - .Rendering_RenderSceneSetupContext_ClearEnvironment( + .Rendering_RenderSceneSetupContext_SetEnvironmentNone( m_nativeHandle); } + public bool UseCameraSkyboxMaterial() + { + return InternalCalls + .Rendering_RenderSceneSetupContext_UseCameraSkyboxMaterial( + m_nativeHandle); + } + + public void SetProceduralSkybox( + Color topColor, + Color horizonColor, + Color bottomColor) + { + InternalCalls + .Rendering_RenderSceneSetupContext_SetProceduralSkybox( + m_nativeHandle, + ref topColor, + ref horizonColor, + ref bottomColor); + } + public void ClearGlobalShaderKeywords() { InternalCalls @@ -73,11 +87,15 @@ namespace XCEngine.Rendering m_nativeHandle); } - public void ClearSceneSetup() + public void SetGlobalShaderKeyword( + string keyword, + bool enabled) { InternalCalls - .Rendering_RenderSceneSetupContext_ClearSceneSetup( - m_nativeHandle); + .Rendering_RenderSceneSetupContext_SetGlobalShaderKeyword( + m_nativeHandle, + keyword ?? string.Empty, + enabled); } internal ulong nativeHandle =>