diff --git a/ext/remix/remix.h b/ext/remix/remix.h index 5767d02..976cef4 100644 --- a/ext/remix/remix.h +++ b/ext/remix/remix.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2023-2025, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -173,6 +173,8 @@ namespace remix { Result< void > DestroyLight(remixapi_LightHandle handle); Result< void > DrawLightInstance(remixapi_LightHandle handle); Result< void > SetConfigVariable(const char* key, const char* value); + Result< void > AddTextureHash(const char* textureCategory, const char* textureHash); + Result< void > RemoveTextureHash(const char* textureCategory, const char* textureHash); // DXVK interoperability Result< IDirect3D9Ex* > dxvk_CreateD3D9(bool editorModeEnabled = false); @@ -208,7 +210,7 @@ namespace remix { return status; } - static_assert(sizeof(remixapi_Interface) == 168, + static_assert(sizeof(remixapi_Interface) == 184, "Change version, update C++ wrapper when adding new functions"); remix::Interface interfaceInCpp = {}; @@ -251,6 +253,20 @@ namespace remix { return m_CInterface.SetConfigVariable(key, value); } + inline Result< void > Interface::AddTextureHash(const char* textureCategory, const char* textureHash) { + if (!m_CInterface.AddTextureHash) { + return REMIXAPI_ERROR_CODE_NOT_INITIALIZED; + } + return m_CInterface.AddTextureHash(textureCategory, textureHash); + } + + inline Result< void > Interface::RemoveTextureHash(const char* textureCategory, const char* textureHash) { + if (!m_CInterface.RemoveTextureHash) { + return REMIXAPI_ERROR_CODE_NOT_INITIALIZED; + } + return m_CInterface.RemoveTextureHash(textureCategory, textureHash); + } + inline Result< void > Interface::Present(const remixapi_PresentInfo* info) { if (!m_CInterface.Present) { return REMIXAPI_ERROR_CODE_NOT_INITIALIZED; @@ -365,23 +381,30 @@ namespace remix { subsurfaceSingleScatteringAlbedoTexture = {}; subsurfaceTransmittanceColor = { 0.5f, 0.5f, 0.5f }; subsurfaceMeasurementDistance = 0.0f; - subsurfaceSingleScatteringAlbedo = { 0.5f, 0.5f, 0.5f };; + subsurfaceSingleScatteringAlbedo = { 0.5f, 0.5f, 0.5f }; subsurfaceVolumetricAnisotropy = 0.0f; - static_assert(sizeof remixapi_MaterialInfoOpaqueSubsurfaceEXT == 72); + subsurfaceDiffusionProfile = false; + subsurfaceRadius = { 0.5f, 0.5f, 0.5f }; + subsurfaceRadiusScale = 0.0f; + subsurfaceMaxSampleRadius = 0.0f; + subsurfaceRadiusTexture = {}; + static_assert(sizeof remixapi_MaterialInfoOpaqueSubsurfaceEXT == 104); } MaterialInfoOpaqueSubsurfaceEXT(const MaterialInfoOpaqueSubsurfaceEXT& other) : remixapi_MaterialInfoOpaqueSubsurfaceEXT(other) , cpp_subsurfaceTransmittanceTexture(other.cpp_subsurfaceTransmittanceTexture) , cpp_subsurfaceThicknessTexture(other.cpp_subsurfaceThicknessTexture) - , cpp_subsurfaceSingleScatteringAlbedoTexture(other.cpp_subsurfaceSingleScatteringAlbedoTexture) { + , cpp_subsurfaceSingleScatteringAlbedoTexture(other.cpp_subsurfaceSingleScatteringAlbedoTexture) + , cpp_subsurfaceRadiusTexture(other.cpp_subsurfaceRadiusTexture) { cpp_fixPointers(); } MaterialInfoOpaqueSubsurfaceEXT(MaterialInfoOpaqueSubsurfaceEXT&& other) noexcept : remixapi_MaterialInfoOpaqueSubsurfaceEXT(other) , cpp_subsurfaceTransmittanceTexture(std::move(other.cpp_subsurfaceTransmittanceTexture)) , cpp_subsurfaceThicknessTexture(std::move(other.cpp_subsurfaceThicknessTexture)) - , cpp_subsurfaceSingleScatteringAlbedoTexture(std::move(other.cpp_subsurfaceSingleScatteringAlbedoTexture)) { + , cpp_subsurfaceSingleScatteringAlbedoTexture(std::move(other.cpp_subsurfaceSingleScatteringAlbedoTexture)) + , cpp_subsurfaceRadiusTexture(std::move(other.cpp_subsurfaceRadiusTexture)) { cpp_fixPointers(); } MaterialInfoOpaqueSubsurfaceEXT& operator=(const MaterialInfoOpaqueSubsurfaceEXT& other) { @@ -392,6 +415,7 @@ namespace remix { cpp_subsurfaceTransmittanceTexture = other.cpp_subsurfaceTransmittanceTexture; cpp_subsurfaceThicknessTexture = other.cpp_subsurfaceThicknessTexture; cpp_subsurfaceSingleScatteringAlbedoTexture = other.cpp_subsurfaceSingleScatteringAlbedoTexture; + cpp_subsurfaceRadiusTexture = other.cpp_subsurfaceRadiusTexture; cpp_fixPointers(); return *this; } @@ -403,6 +427,7 @@ namespace remix { cpp_subsurfaceTransmittanceTexture = std::move(other.cpp_subsurfaceTransmittanceTexture); cpp_subsurfaceThicknessTexture = std::move(other.cpp_subsurfaceThicknessTexture); cpp_subsurfaceSingleScatteringAlbedoTexture = std::move(other.cpp_subsurfaceSingleScatteringAlbedoTexture); + cpp_subsurfaceRadiusTexture = std::move(other.cpp_subsurfaceRadiusTexture); cpp_fixPointers(); return *this; } @@ -419,18 +444,24 @@ namespace remix { cpp_subsurfaceSingleScatteringAlbedoTexture = std::move(v); subsurfaceSingleScatteringAlbedoTexture = cpp_subsurfaceSingleScatteringAlbedoTexture.c_str(); } + void set_subsurfaceRadiusTexture(std::filesystem::path v) { + cpp_subsurfaceRadiusTexture = std::move(v); + subsurfaceRadiusTexture = cpp_subsurfaceRadiusTexture.c_str(); + } private: void cpp_fixPointers() { subsurfaceTransmittanceTexture = cpp_subsurfaceTransmittanceTexture.c_str(); subsurfaceThicknessTexture = cpp_subsurfaceThicknessTexture.c_str(); subsurfaceSingleScatteringAlbedoTexture = cpp_subsurfaceSingleScatteringAlbedoTexture.c_str(); - static_assert(sizeof remixapi_MaterialInfoOpaqueSubsurfaceEXT == 72, "Recheck pointers"); + subsurfaceRadiusTexture = cpp_subsurfaceRadiusTexture.c_str(); + static_assert(sizeof remixapi_MaterialInfoOpaqueSubsurfaceEXT == 104, "Recheck pointers"); } std::filesystem::path cpp_subsurfaceTransmittanceTexture {}; std::filesystem::path cpp_subsurfaceThicknessTexture {}; std::filesystem::path cpp_subsurfaceSingleScatteringAlbedoTexture {}; + std::filesystem::path cpp_subsurfaceRadiusTexture{}; }; struct MaterialInfoTranslucentEXT : remixapi_MaterialInfoTranslucentEXT { @@ -759,6 +790,7 @@ namespace remix { radius = 0.05f; shaping_hasvalue = false; shaping_value = detail::defaultLightShaping(); + volumetricRadianceScale = 1.0f; static_assert(sizeof remixapi_LightInfoSphereEXT == 64); } @@ -779,6 +811,7 @@ namespace remix { direction = { 0.0f, 0.0f, 1.0f }; shaping_hasvalue = false; shaping_value = detail::defaultLightShaping(); + volumetricRadianceScale = 1.0f; static_assert(sizeof remixapi_LightInfoRectEXT == 104); } @@ -799,6 +832,7 @@ namespace remix { direction = { 0.0f, 0.0f, 1.0f }; shaping_hasvalue = false; shaping_value = detail::defaultLightShaping(); + volumetricRadianceScale = 1.0f; static_assert(sizeof remixapi_LightInfoDiskEXT == 104); } @@ -815,7 +849,8 @@ namespace remix { radius = 1.0f; axis = { 1.0f, 0.0f, 0.0f }; axisLength = 1.0f; - static_assert(sizeof remixapi_LightInfoCylinderEXT == 48); + volumetricRadianceScale = 1.0f; + static_assert(sizeof remixapi_LightInfoCylinderEXT == 56); } }; @@ -825,7 +860,8 @@ namespace remix { pNext = nullptr; direction = { 0.0f, -1.0f, 0.0f }; angularDiameterDegrees = 0.5f; - static_assert(sizeof remixapi_LightInfoDistantEXT == 32); + volumetricRadianceScale = 1.0f; + static_assert(sizeof remixapi_LightInfoDistantEXT == 40); } }; diff --git a/ext/remix/remix_c.h b/ext/remix/remix_c.h index 0834f02..7afcbcb 100644 --- a/ext/remix/remix_c.h +++ b/ext/remix/remix_c.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2023-2025, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -53,8 +53,8 @@ #define REMIXAPI_VERSION_GET_PATCH(version) (((uint64_t)(version) ) & (uint64_t)0xFFFF) #define REMIXAPI_VERSION_MAJOR 0 -#define REMIXAPI_VERSION_MINOR 4 -#define REMIXAPI_VERSION_PATCH 2 +#define REMIXAPI_VERSION_MINOR 6 +#define REMIXAPI_VERSION_PATCH 1 // External @@ -218,6 +218,11 @@ extern "C" { float subsurfaceMeasurementDistance; remixapi_Float3D subsurfaceSingleScatteringAlbedo; float subsurfaceVolumetricAnisotropy; + remixapi_Bool subsurfaceDiffusionProfile; + remixapi_Float3D subsurfaceRadius; + float subsurfaceRadiusScale; + float subsurfaceMaxSampleRadius; + remixapi_Path subsurfaceRadiusTexture; } remixapi_MaterialInfoOpaqueSubsurfaceEXT; typedef struct remixapi_MaterialInfoTranslucentEXT { @@ -395,20 +400,21 @@ extern "C" { REMIXAPI_INSTANCE_CATEGORY_BIT_IGNORE_ANTI_CULLING = 1 << 5, REMIXAPI_INSTANCE_CATEGORY_BIT_IGNORE_MOTION_BLUR = 1 << 6, REMIXAPI_INSTANCE_CATEGORY_BIT_IGNORE_OPACITY_MICROMAP = 1 << 7, - REMIXAPI_INSTANCE_CATEGORY_BIT_HIDDEN = 1 << 8, - REMIXAPI_INSTANCE_CATEGORY_BIT_PARTICLE = 1 << 9, - REMIXAPI_INSTANCE_CATEGORY_BIT_BEAM = 1 << 10, - REMIXAPI_INSTANCE_CATEGORY_BIT_DECAL_STATIC = 1 << 11, - REMIXAPI_INSTANCE_CATEGORY_BIT_DECAL_DYNAMIC = 1 << 12, - REMIXAPI_INSTANCE_CATEGORY_BIT_DECAL_SINGLE_OFFSET = 1 << 13, - REMIXAPI_INSTANCE_CATEGORY_BIT_DECAL_NO_OFFSET = 1 << 14, - REMIXAPI_INSTANCE_CATEGORY_BIT_ALPHA_BLEND_TO_CUTOUT = 1 << 15, - REMIXAPI_INSTANCE_CATEGORY_BIT_TERRAIN = 1 << 16, - REMIXAPI_INSTANCE_CATEGORY_BIT_ANIMATED_WATER = 1 << 17, - REMIXAPI_INSTANCE_CATEGORY_BIT_THIRD_PERSON_PLAYER_MODEL = 1 << 18, - REMIXAPI_INSTANCE_CATEGORY_BIT_THIRD_PERSON_PLAYER_BODY = 1 << 19, - REMIXAPI_INSTANCE_CATEGORY_BIT_IGNORE_BAKED_LIGHTING = 1 << 20, - REMIXAPI_INSTANCE_CATEGORY_BIT_IGNORE_ALPHA_CHANNEL = 1 << 21, + REMIXAPI_INSTANCE_CATEGORY_BIT_IGNORE_ALPHA_CHANNEL = 1 << 8, + REMIXAPI_INSTANCE_CATEGORY_BIT_HIDDEN = 1 << 9, + REMIXAPI_INSTANCE_CATEGORY_BIT_PARTICLE = 1 << 10, + REMIXAPI_INSTANCE_CATEGORY_BIT_BEAM = 1 << 11, + REMIXAPI_INSTANCE_CATEGORY_BIT_DECAL_STATIC = 1 << 12, + REMIXAPI_INSTANCE_CATEGORY_BIT_DECAL_DYNAMIC = 1 << 13, + REMIXAPI_INSTANCE_CATEGORY_BIT_DECAL_SINGLE_OFFSET = 1 << 14, + REMIXAPI_INSTANCE_CATEGORY_BIT_DECAL_NO_OFFSET = 1 << 15, + REMIXAPI_INSTANCE_CATEGORY_BIT_ALPHA_BLEND_TO_CUTOUT = 1 << 16, + REMIXAPI_INSTANCE_CATEGORY_BIT_TERRAIN = 1 << 17, + REMIXAPI_INSTANCE_CATEGORY_BIT_ANIMATED_WATER = 1 << 18, + REMIXAPI_INSTANCE_CATEGORY_BIT_THIRD_PERSON_PLAYER_MODEL = 1 << 19, + REMIXAPI_INSTANCE_CATEGORY_BIT_THIRD_PERSON_PLAYER_BODY = 1 << 20, + REMIXAPI_INSTANCE_CATEGORY_BIT_IGNORE_BAKED_LIGHTING = 1 << 21, + REMIXAPI_INSTANCE_CATEGORY_BIT_IGNORE_TRANSPARENCY_LAYER = 1 << 22, } remixapi_InstanceCategoryBit; typedef uint32_t remixapi_InstanceCategoryFlags; @@ -442,6 +448,7 @@ extern "C" { float radius; remixapi_Bool shaping_hasvalue; remixapi_LightInfoLightShaping shaping_value; + float volumetricRadianceScale; } remixapi_LightInfoSphereEXT; typedef struct remixapi_LightInfoRectEXT { @@ -459,6 +466,7 @@ extern "C" { remixapi_Float3D direction; remixapi_Bool shaping_hasvalue; remixapi_LightInfoLightShaping shaping_value; + float volumetricRadianceScale; } remixapi_LightInfoRectEXT; typedef struct remixapi_LightInfoDiskEXT { @@ -476,6 +484,7 @@ extern "C" { remixapi_Float3D direction; remixapi_Bool shaping_hasvalue; remixapi_LightInfoLightShaping shaping_value; + float volumetricRadianceScale; } remixapi_LightInfoDiskEXT; typedef struct remixapi_LightInfoCylinderEXT { @@ -486,6 +495,7 @@ extern "C" { // The "center" axis of the Cylinder Light. Must be normalized. remixapi_Float3D axis; float axisLength; + float volumetricRadianceScale; } remixapi_LightInfoCylinderEXT; typedef struct remixapi_LightInfoDistantEXT { @@ -494,6 +504,7 @@ extern "C" { // The direction the Distant Light is pointing in. Must be normalized. remixapi_Float3D direction; float angularDiameterDegrees; + float volumetricRadianceScale; } remixapi_LightInfoDistantEXT; typedef struct remixapi_LightInfoDomeEXT { @@ -512,19 +523,20 @@ extern "C" { void* pNext; remixapi_StructType lightType; remixapi_Transform transform; - const float* pRadius; // "radius" - const float* pWidth; // "width" - const float* pHeight; // "height" - const float* pLength; // "length" - const float* pAngleRadians; // "angle" - const remixapi_Bool* pEnableColorTemp; // "enableColorTemperature" - const remixapi_Float3D* pColor; // "color" - const float* pColorTemp; // "colorTemperature" - const float* pExposure; // "exposure" - const float* pIntensity; // "intensity" - const float* pConeAngleRadians; // "shaping:cone:angle" - const float* pConeSoftness; // "shaping:cone:softness" - const float* pFocus; // "shaping:focus" + const float* pRadius; // "radius" + const float* pWidth; // "width" + const float* pHeight; // "height" + const float* pLength; // "length" + const float* pAngleRadians; // "angle" + const remixapi_Bool* pEnableColorTemp; // "enableColorTemperature" + const remixapi_Float3D* pColor; // "color" + const float* pColorTemp; // "colorTemperature" + const float* pExposure; // "exposure" + const float* pIntensity; // "intensity" + const float* pConeAngleRadians; // "shaping:cone:angle" + const float* pConeSoftness; // "shaping:cone:softness" + const float* pFocus; // "shaping:focus" + const float* pVolumetricRadianceScale; // "volumetric_radiance_scale" } remixapi_LightInfoUSDEXT; typedef struct remixapi_LightInfo { @@ -550,6 +562,14 @@ extern "C" { const char* key, const char* value); + typedef remixapi_ErrorCode(REMIXAPI_PTR* PFN_remixapi_AddTextureHash)( + const char* textureCategory, + const char* textureHash); + + typedef remixapi_ErrorCode(REMIXAPI_PTR* PFN_remixapi_RemoveTextureHash)( + const char* textureCategory, + const char* textureHash); + typedef struct remixapi_PresentInfo { remixapi_StructType sType; void* pNext; @@ -630,6 +650,8 @@ extern "C" { PFN_remixapi_DestroyLight DestroyLight; PFN_remixapi_DrawLightInstance DrawLightInstance; PFN_remixapi_SetConfigVariable SetConfigVariable; + PFN_remixapi_AddTextureHash AddTextureHash; + PFN_remixapi_RemoveTextureHash RemoveTextureHash; // DXVK interoperability PFN_remixapi_dxvk_CreateD3D9 dxvk_CreateD3D9; diff --git a/src/client/remix_api.cpp b/src/client/remix_api.cpp index 2cd4400..0ca90f9 100644 --- a/src/client/remix_api.cpp +++ b/src/client/remix_api.cpp @@ -380,6 +380,32 @@ remixapi_ErrorCode REMIXAPI_CALL remixapi_SetConfigVariable(const char* var, con return REMIXAPI_ERROR_CODE_SUCCESS; } +remixapi_ErrorCode REMIXAPI_CALL remixapi_AddTextureHash(const char* var, const char* value) { + ASSERT_REMIXAPI_PFN_TYPE(remixapi_AddTextureHash); + if (!var || !value) { + return REMIXAPI_ERROR_CODE_INVALID_ARGUMENTS; + } + { + ClientMessage c(Commands::RemixApi_AddTextureHash); + send(c, var); + send(c, value); + } + return REMIXAPI_ERROR_CODE_SUCCESS; +} + +remixapi_ErrorCode REMIXAPI_CALL remixapi_RemoveTextureHash(const char* var, const char* value) { + ASSERT_REMIXAPI_PFN_TYPE(remixapi_RemoveTextureHash); + if (!var || !value) { + return REMIXAPI_ERROR_CODE_INVALID_ARGUMENTS; + } + { + ClientMessage c(Commands::RemixApi_RemoveTextureHash); + send(c, var); + send(c, value); + } + return REMIXAPI_ERROR_CODE_SUCCESS; +} + remixapi_ErrorCode REMIXAPI_CALL remixapi_dxvk_CreateD3D9( remixapi_Bool editorModeEnabled, IDirect3D9Ex** out_pD3D9) { @@ -441,6 +467,9 @@ extern "C" { interf.DestroyLight = remixapi_DestroyLight; interf.DrawLightInstance = remixapi_DrawLightInstance; interf.SetConfigVariable = remixapi_SetConfigVariable; + interf.AddTextureHash = remixapi_AddTextureHash; + interf.RemoveTextureHash = remixapi_RemoveTextureHash; + interf.dxvk_CreateD3D9 = remixapi_dxvk_CreateD3D9; interf.dxvk_RegisterD3D9Device = remixapi_dxvk_RegisterD3D9Device; // interf.dxvk_GetExternalSwapchain = remixapi_dxvk_GetExternalSwapchain; diff --git a/src/server/main.cpp b/src/server/main.cpp index aab0ddb..f01e24f 100644 --- a/src/server/main.cpp +++ b/src/server/main.cpp @@ -3127,6 +3127,8 @@ void ProcessDeviceCommandQueue() { } case RemixApi_SetConfigVariable: + case RemixApi_AddTextureHash: + case RemixApi_RemoveTextureHash: { void* var_ptr = nullptr; const uint32_t var_size = DeviceBridge::getReaderChannel().data->pull(&var_ptr); @@ -3136,7 +3138,14 @@ void ProcessDeviceCommandQueue() { const uint32_t value_size = DeviceBridge::getReaderChannel().data->pull(&value_ptr); std::string value_str((const char*) value_ptr, value_size); - remixapi::g_remix.SetConfigVariable(var_str.c_str(), value_str.c_str()); + switch (rpcHeader.command) + { + default: + case RemixApi_SetConfigVariable: remixapi::g_remix.SetConfigVariable(var_str.c_str(), value_str.c_str()); break; + case RemixApi_AddTextureHash: remixapi::g_remix.AddTextureHash(var_str.c_str(), value_str.c_str()); break; + case RemixApi_RemoveTextureHash: remixapi::g_remix.RemoveTextureHash(var_str.c_str(), value_str.c_str()); break; + } + break; } diff --git a/src/util/util_commands.h b/src/util/util_commands.h index e38f874..6c3a5f9 100644 --- a/src/util/util_commands.h +++ b/src/util/util_commands.h @@ -47,6 +47,8 @@ namespace Commands { RemixApi_DestroyLight, RemixApi_DrawLightInstance, RemixApi_SetConfigVariable, + RemixApi_AddTextureHash, + RemixApi_RemoveTextureHash, RemixApi_CreateD3D9, RemixApi_RegisterDevice,