I have a texture flags for globe with white background like this:
I tried to configure the shader to remove the white background and keep the colors of the flags, but the flags still aren’t clear. How can I fix this:
The texture flags is location2:
index.tsx:
import { Sphere } from "@react-three/drei";
import { SRGBColorSpace, ShaderMaterial, Vector3 } from "three";
import { TextureLoader } from "three/src/loaders/TextureLoader";
import { useFrame, useLoader } from "@react-three/fiber";
import { earthFragmentShader, earthVertexShader } from "./shaders";
import { useEffect, useRef } from "react";
import { Atmosphere } from "../Atmosphere";
const verteces = Math.pow(2, 9);
export const Earth = ({ lightDirection }) => {
const [earthDayTexture, cloudTexture, location1Texture, location2Texture] = useLoader(
TextureLoader,
[
"/experiment-earth-assets/8k_earth_daymap.jpg",
"/experiment-earth-assets/8k_earth_clouds.jpg",
"/experiment-earth-assets/location1.jpg",
"/experiment-earth-assets/location2.png",
]
);
earthDayTexture.colorSpace = cloudTexture.colorSpace =
location1Texture.colorSpace = location2Texture.colorSpace = SRGBColorSpace;
const uniformsRef = useRef({
dayMap: { value: earthDayTexture },
cloudMap: { value: cloudTexture },
location1Map: { value: location1Texture },
location2Map: { value: location2Texture },
uTime: { value: 0 },
lightDirection: { value: new Vector3() },
});
useFrame((_, delta) => {
uniformsRef.current.uTime.value += delta;
});
useEffect(() => {
if (lightDirection) {
uniformsRef.current.lightDirection.value.copy(lightDirection);
}
}, [lightDirection]);
return (
<>
<Sphere args={[1, verteces, verteces]}>
<shaderMaterial
vertexShader={earthVertexShader}
fragmentShader={earthFragmentShader}
uniforms={uniformsRef.current}
/>
</Sphere>
<Atmosphere lightDirection={lightDirection} />
</>
);
};
shader.js:
import {
curveUp,
perturbNormalArb,
simplexNoise,
valueRemap,
} from "../../../utils/shader-utils";
export const earthVertexShader = /*glsl*/ `
varying vec3 vNormal;
varying vec2 vUv;
varying vec3 wPos;
void main() {
vUv = uv;
vNormal = normal;
wPos = (modelMatrix * vec4(position, 1.0)).xyz;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`;
export const earthFragmentShader = /*glsl*/ `
varying vec3 vNormal;
varying vec2 vUv;
varying vec3 wPos;
const float PI = 3.141592653;
uniform sampler2D dayMap;
uniform sampler2D cloudMap;
uniform sampler2D location1Map;
uniform sampler2D location2Map;
uniform float uTime;
${valueRemap}
${perturbNormalArb}
${curveUp}
${simplexNoise}
void main() {
vec3 normal = normalize(vNormal);
vec3 viewDirection = normalize(cameraPosition - wPos);
// Sample textures with increased brightness
vec3 finalColor = texture2D(dayMap, vUv).rgb * 1.4; // Simple brightness multiplier
vec4 cloudColor = texture2D(cloudMap, vUv);
vec4 location1Color = texture2D(location1Map, vUv);
vec4 location2Color = texture2D(location2Map, vUv);
// Add location1 (black background)
if (location1Color.r > 0.1) { // Only blend if it's not part of the black background
finalColor = mix(finalColor, vec3(1.0), location1Color.r);
}
// if (location2Color.a > 0.1) { // Check alpha to ensure flags are visible // location2.png
// vec3 flagColor = location2Color.rgb;
// // Optionally, enhance the flag colors for better visibility
// flagColor = flagColor * 1.5; // Brighten flags
// finalColor = mix(finalColor, flagColor, location2Color.a);
// }
// Add location2 (flags) with stricter white removal
if (location2Color.a > 0.1) { // Check alpha to ensure flags are visible
vec3 flagColor = location2Color.rgb;
// Remove near-white areas using a stricter threshold
if (max(flagColor.r, max(flagColor.g, flagColor.b)) < 0.95 || // Not pure white
min(flagColor.r, min(flagColor.g, flagColor.b)) < 0.8) { // Not near-white
// Enhance the remaining flag colors for clarity
flagColor = pow(flagColor, vec3(0.8)) * 1.6; // Adjust gamma and brightness
finalColor = mix(finalColor, flagColor, location2Color.a);
}
}
// Add clouds
float cloudIntensity = cloudColor.r;
finalColor = mix(finalColor, vec3(1.0), cloudIntensity * 0.3);
// Add atmosphere glow
float fresnel = pow(1.0 - dot(normal, viewDirection), 2.0);
float atmosphereIntensity = fresnel * 0.3;
finalColor = mix(finalColor, vec3(0.6, 0.8, 1.0), atmosphereIntensity);
// Ensure we don't exceed maximum brightness
finalColor = min(finalColor, vec3(1.0));
gl_FragColor = vec4(finalColor, 1.0);
}
`;