OSX specific: Fixed darker colors of objects inside multi-material gizmo on macOS running on Arm64 CPU.

For Apple's on Arm CPU computed triangle normals inside fragment shader using dFdx and dFdy has the opposite direction. Because of this, objects had darker colors inside the multi-material gizmo.
Based on https://stackoverflow.com/a/66206648, the similar behavior was also spotted on some other devices with Arm CPU.
This commit is contained in:
Lukáš Hejl 2021-08-02 14:03:17 +02:00
parent ab9dfb7932
commit bad51cdb52
4 changed files with 61 additions and 4 deletions

View File

@ -64,6 +64,9 @@ void main()
float world_normal_z_fs = world_normal_z;
if (compute_triangle_normals_in_fs) {
vec3 triangle_normal = normalize(cross(dFdx(model_pos.xyz), dFdy(model_pos.xyz)));
#ifdef FLIP_TRIANGLE_NORMALS
triangle_normal = -triangle_normal;
#endif
// First transform the normal into camera space and normalize the result.
eye_normal_fs = normalize(gl_NormalMatrix * triangle_normal);

View File

@ -3,6 +3,12 @@
#include <boost/log/trivial.hpp>
#include <boost/filesystem/operations.hpp>
#if defined(__APPLE__)
#include <sys/types.h>
#include <sys/sysctl.h>
#include <mach/machine.h>
#endif
namespace Slic3r {
static auto s_platform = Platform::Uninitialized;
@ -16,8 +22,39 @@ void detect_platform()
s_platform_flavor = PlatformFlavor::Generic;
#elif defined(__APPLE__)
BOOST_LOG_TRIVIAL(info) << "Platform: OSX";
s_platform = Platform::OSX;
s_platform_flavor = PlatformFlavor::Generic;
s_platform = Platform::OSX;
s_platform_flavor = PlatformFlavor::GenericOSX;
{
cpu_type_t type = 0;
size_t size = sizeof(type);
if (sysctlbyname("hw.cputype", &type, &size, NULL, 0) == 0) {
type &= ~CPU_ARCH_MASK;
if (type == CPU_TYPE_X86) {
int proc_translated = 0;
size = sizeof(proc_translated);
// Detect if native CPU is really X86 or PrusaSlicer runs through Rosetta.
if (sysctlbyname("sysctl.proc_translated", &proc_translated, &size, NULL, 0) == -1) {
if (errno == ENOENT) {
// Native CPU is X86, and property sysctl.proc_translated doesn't exist.
s_platform_flavor = PlatformFlavor::OSXOnX86;
BOOST_LOG_TRIVIAL(info) << "Platform flavor: OSXOnX86";
}
} else if (proc_translated == 1) {
// Native CPU is ARM and PrusaSlicer runs through Rosetta.
s_platform_flavor = PlatformFlavor::OSXOnArm;
BOOST_LOG_TRIVIAL(info) << "Platform flavor: OSXOnArm";
} else {
// Native CPU is X86.
s_platform_flavor = PlatformFlavor::OSXOnX86;
BOOST_LOG_TRIVIAL(info) << "Platform flavor: OSXOnX86";
}
} else if (type == CPU_TYPE_ARM) {
// Native CPU is ARM
s_platform_flavor = PlatformFlavor::OSXOnArm;
BOOST_LOG_TRIVIAL(info) << "Platform flavor: OSXOnArm";
}
}
}
#elif defined(__linux__)
BOOST_LOG_TRIVIAL(info) << "Platform: Linux";
s_platform = Platform::Linux;

View File

@ -28,6 +28,12 @@ enum class PlatformFlavor
WSL2,
// For Platform::BSDUnix
OpenBSD,
// For Platform::OSX
GenericOSX,
// For Apple's on Intel X86 CPU
OSXOnX86,
// For Apple's on Arm CPU
OSXOnArm,
};
// To be called on program start-up.

View File

@ -1,4 +1,5 @@
#include "libslic3r/libslic3r.h"
#include "libslic3r/Platform.hpp"
#include "GLShadersManager.hpp"
#include "3DScene.hpp"
#include "GUI_App.hpp"
@ -43,9 +44,19 @@ std::pair<bool, std::string> GLShadersManager::init()
// used to render extrusion and travel paths as lines in gcode preview
valid &= append_shader("toolpaths_lines", { "toolpaths_lines.vs", "toolpaths_lines.fs" });
// used to render objects in 3d editor
valid &= append_shader("gouraud", { "gouraud.vs", "gouraud.fs" }
// For Apple's on Arm CPU computed triangle normals inside fragment shader using dFdx and dFdy has the opposite direction.
// Because of this, objects had darker colors inside the multi-material gizmo.
// Based on https://stackoverflow.com/a/66206648, the similar behavior was also spotted on some other devices with Arm CPU.
if (platform_flavor() == PlatformFlavor::OSXOnArm)
valid &= append_shader("gouraud", { "gouraud.vs", "gouraud.fs" }, { "FLIP_TRIANGLE_NORMALS"sv
#if ENABLE_ENVIRONMENT_MAP
, { "ENABLE_ENVIRONMENT_MAP"sv }
, "ENABLE_ENVIRONMENT_MAP"sv
#endif
});
else
valid &= append_shader("gouraud", { "gouraud.vs", "gouraud.fs" }
#if ENABLE_ENVIRONMENT_MAP
, { "ENABLE_ENVIRONMENT_MAP"sv }
#endif
);
// used to render variable layers heights in 3d editor