doodlum / skyrim-community-shaders

SKSE core plugin for community-driven advanced graphics modifications for AE, SE and VR. Also fixes bugs and improves performance.
GNU General Public License v3.0
145 stars 44 forks source link

Dynamic Cubemap Failure to Apply Original Cubemap Colors #179

Open AceAmir opened 8 months ago

AceAmir commented 8 months ago

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.

alandtse commented 8 months ago

Thanks.

@doodlum assigning to you since you're the expert on dynamic cubemap; feel free to unassign yourself if not something you want to take on.