skyrim-community-shaders icon indicating copy to clipboard operation
skyrim-community-shaders copied to clipboard

Dynamic Cubemap Failure to Apply Original Cubemap Colors

Open AceAmir opened this issue 4 months ago • 1 comments

I was testing the Dynamic Cubemap feature and ran into a problem where the color of the included 1x1 cubemaps were not being applied to the dynamic, generated cubemaps.

This is the Aetherial shield with the packaged "bronze_e.dds" cubemap applied: 20240206203935_1

And this is the same shield with the packaged "orcish_e.dds" cubemap applied: 20240206203155_1

After some investigation, I isolated the issue to the following section of code:

#        if defined(DYNAMIC_CUBEMAPS)
     uint2 envSize;
     TexEnvSampler.GetDimensions(envSize.x, envSize.y);
     bool dynamicCubemap = envMask != 0 && envSize.x == 1;
     if (dynamicCubemap) {
         float envFade = saturate(viewPosition.z / 512.0);
 #            if defined(CPM_AVAILABLE) && defined(ENVMAP)
         float3 F0 = lerp(envColorBase, 1.0, envColorBase.x == 0.0 && envColorBase.y == 0.0 && envColorBase.z == 0.0);
         envColor = GetDynamicCubemap(worldSpaceNormal, worldSpaceViewDirection, lerp(1.0 / 9.0, 1.0 - complexMaterialColor.y, complexMaterial), complexSpecular, complexMaterial) * envMask;
 #            else
         float3 F0 = lerp(envColorBase, 1.0, envColorBase.x == 0.0 && envColorBase.y == 0.0 && envColorBase.z == 0.0);
         envColor = GetDynamicCubemap(worldSpaceNormal, worldSpaceViewDirection, 1.0 / 9.0, F0, 0.0) * envMask;
 #            endif
         if (shaderDescriptors[0].PixelShaderDescriptor & _DefShadow && shaderDescriptors[0].PixelShaderDescriptor & _ShadowDir) {
             float upAngle = saturate(dot(float3(0, 0, 1), normalizedDirLightDirectionWS.xyz));
             envColor *= lerp(1.0, shadowColor.x, saturate(upAngle) * 0.2);
         }
     }
 #        endif 

The check for complex materials appears to be failing: the Aetherial Shield model does not have complex materials assigned to it, and yet only when I edited the first check ("if defined(CPM_AVAILABLE) &&(ENVMAP)") does it have any effect in-game. This is true of other models without complex materials assigned (in my case, the Cathedral Armory steel armor model).

Swapping the first check with the second check, like so...

#            if defined(CPM_AVAILABLE) && defined(ENVMAP)
        float3 F0 = lerp(envColorBase, 1.0, envColorBase.x == 0.0 && envColorBase.y == 0.0 && envColorBase.z == 0.0);
         envColor = GetDynamicCubemap(worldSpaceNormal, worldSpaceViewDirection, 1.0 / 9.0, F0, 0.0) * envMask;
 #            else
         float3 F0 = lerp(envColorBase, 1.0, envColorBase.x == 0.0 && envColorBase.y == 0.0 && envColorBase.z == 0.0);
         envColor = GetDynamicCubemap(worldSpaceNormal, worldSpaceViewDirection, 1.0 / 9.0, F0, 0.0) * envMask;
 #            endif

...produced this result (still the Aetherial Shield with the "orcish_e.dds" cubemap assigned):

20240206233333_1

The effect is faint, but at least it's there now. However, if I multiply F0 by two...

envColor = GetDynamicCubemap(worldSpaceNormal, worldSpaceViewDirection, 1.0 / 9.0, (2*F0), 0.0) * envMask;

...I get the following result:

20240206233515_1

I don't know if it's correct to multiply F0 in this way (why I originally didn't submit this as a bug report and instead pinged on Discord), but at the very least the check for Complex Materials seems to be broken.

AceAmir avatar Feb 09 '24 21:02 AceAmir