skyrim-community-shaders
skyrim-community-shaders copied to clipboard
Dynamic Cubemap Failure to Apply Original Cubemap Colors
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:
And this is the same shield with the packaged "orcish_e.dds" cubemap applied:
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):
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:
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.