0

I am attempting to use a raycast from the camera's position to detect collisions with a 3d model. But I'm not sure how to cast the ray within a Canvas, or how to detect collisions with a components 3d model.

Heres my code: code

I'm trying to hide the text when it is on the opposite side of the sphere.

Any tips or info would be appreciated!

Earth Model (".gltf" group mesh):

export default function Earth(props) {
  const group = useRef();
  const { nodes, materials } = useGLTF("/earthPinsGlowingCentered.gltf");
  const pStyle = {
    fontSize: "200%",
    color: "red"
  };
  return (
    <group scale={[0.01, 0.01, 0.01]} ref={group} {...props} dispose={null}>
      <group userData={{ name: "Pins" }}>
        <mesh
          material={materials.glowMat}
          geometry={nodes.australia_1.geometry}
          position={[95.98, -78.51, 64.8]}
          rotation={[1.91, -0.5, 2.23]}
          userData={{ name: "australia 1" }}
        >
          <Html>
            <p style={pStyle}></p>
          </Html>
        </mesh>
        <mesh
          material={materials.glowMat}
          geometry={nodes.australia_2.geometry}
          position={[62.18, -70.29, 103.77]}
          rotation={[1.85, -0.55, 2.58]}
          userData={{ name: "australia 2" }}
        >
          <Html>
            <p style={pStyle}>test</p>
          </Html>
        </mesh>
        <mesh
          material={materials.glowMat}
          geometry={nodes.phillipenes.geometry}
          position={[43.84, -5.37, 132.76]}
          rotation={[1.48, -0.37, 2.79]}
          userData={{ name: "phillipenes" }}
        >
          <Html>
            <p style={pStyle}>test</p>
          </Html>
        </mesh>
        <mesh
          material={materials.glowMat}
          geometry={nodes.asia_1.geometry}
          position={[43.61, 31.01, 129.27]}
          rotation={[1.26, -0.24, 2.8]}
          userData={{ name: "asia 1" }}
        >
          <Html>
            <p style={pStyle}>test</p>
          </Html>
        </mesh>
        <mesh
          material={materials.glowMat}
          geometry={nodes.japan.geometry}
          position={[88.31, 77.59, 75.88]}
          rotation={[1.02, 0.29, 2.41]}
          userData={{ name: "japan" }}
        >
          <Html>
            <p style={pStyle}>test</p>
          </Html>
        </mesh>
        <mesh
          material={materials.glowMat}
          geometry={nodes.russia.geometry}
          position={[-28.99, 118.4, 68.66]}
          rotation={[0.39, 0.57, -2.9]}
          userData={{ name: "russia" }}
        >
          <Html>
            <p style={pStyle}>test</p>
          </Html>
        </mesh>
        <mesh
          material={materials.glowMat}
          geometry={nodes.india.geometry}
          position={[-19.16, 30.82, 135.12]}
          rotation={[1.28, 0.47, -3]}
          userData={{ name: "india" }}
        >
          <Html>
            <p style={pStyle}>test</p>
          </Html>
        </mesh>
        <mesh
          material={materials.glowMat}
          geometry={nodes.egypt.geometry}
          position={[-102.43, 64.02, 70.6]}
          rotation={[0.65, 0.17, -2.31]}
          userData={{ name: "egypt" }}
        >
          <Html>
            <p style={pStyle}>test</p>
          </Html>
        </mesh>
        <mesh
          material={materials.glowMat}
          geometry={nodes.germany.geometry}
          position={[-76.96, 110.83, 37]}
          rotation={[0.19, 0.2, -2.56]}
          userData={{ name: "germany" }}
        >
          <Html>
            <p style={pStyle}>test</p>
          </Html>
        </mesh>
        <mesh
          material={materials.glowMat}
          geometry={nodes.canada.geometry}
          position={[28.65, 117.52, -70.31]}
          rotation={[-0.59, -0.26, 2.92]}
          userData={{ name: "canada" }}
        >
          <Html>
            <p style={pStyle}>test</p>
          </Html>
        </mesh>
        <mesh
          material={materials.glowMat}
          geometry={nodes.UK.geometry}
          position={[-46.89, 129.14, 26.43]}
          rotation={[0.01, 0.5, -2.76]}
          userData={{ name: "UK" }}
        >
          <Html>
            <p style={pStyle}>test</p>
          </Html>
        </mesh>
        <mesh
          material={materials.glowMat}
          geometry={nodes.spain.geometry}
          position={[-102.49, 95.08, -5.69]}
          rotation={[-0.25, 0.17, -2.31]}
          userData={{ name: "spain" }}
        >
          <Html>
            <p style={pStyle}>test</p>
          </Html>
        </mesh>
        <mesh
          material={materials.glowMat}
          geometry={nodes.africa_1.geometry}
          position={[-136.93, 19.5, -21.09]}
          rotation={[-0.12, -0.14, -1.74]}
          userData={{ name: "africa 1" }}
        >
          <Html>
            <p style={pStyle}>test</p>
          </Html>
        </mesh>
        <mesh
          material={materials.glowMat}
          geometry={nodes.africa_2.geometry}
          position={[-113.39, -68.7, 44.69]}
          rotation={[0.2, 0.47, -1.15]}
          userData={{ name: "africa 2" }}
        >
          <Html>
            <p style={pStyle}>test</p>
          </Html>
        </mesh>
        <mesh
          material={materials.glowMat}
          geometry={nodes.SA_1.geometry}
          position={[-32.87, -69.25, -117.04]}
          rotation={[0.6, -1.06, -0.51]}
          userData={{ name: "SA 1" }}
        >
          <Html>
            <p style={pStyle}>test</p>
          </Html>
        </mesh>
        <mesh
          material={materials.glowMat}
          geometry={nodes.SA_2.geometry}
          position={[-67.8, -24.99, -119.81]}
          rotation={[0.36, -0.99, -1.09]}
          userData={{ name: "SA 2" }}
        >
          <Html>
            <p style={pStyle}>test</p>
          </Html>
        </mesh>
        <mesh
          material={materials.glowMat}
          geometry={nodes.SA_3.geometry}
          position={[-18.66, -20.77, -137.1]}
          rotation={[1.14, -1.12, -0.32]}
          userData={{ name: "SA 3" }}
        >
          <Html>
            <p style={pStyle}>test</p>
          </Html>
        </mesh>
        <mesh
          material={materials.glowMat}
          geometry={nodes.NA_1.geometry}
          position={[-9.27, 100.21, -97.19]}
          rotation={[2.25, -1.08, -0.15]}
          userData={{ name: "NA 1" }}
        >
          <Html>
            <p style={pStyle}>test</p>
          </Html>
        </mesh>
        <mesh
          material={materials.glowMat}
          geometry={nodes.NA_2.geometry}
          position={[68.82, 118.36, -28.81]}
          rotation={[-3.06, -0.51, 0.59]}
          userData={{ name: "NA 2" }}
        >
          <Html>
            <p style={pStyle}>test</p>
          </Html>
        </mesh>
        <mesh
          material={materials.glowMat}
          geometry={nodes.NA_3.geometry}
          position={[57.08, 80.37, -99.29]}
          rotation={[2.95, -0.97, 0.79]}
          userData={{ name: "NA 3" }}
        >
          <Html>
            <p style={pStyle}>test</p>
          </Html>
        </mesh>
      </group>
      <mesh
        material={materials.Mat}
        geometry={nodes.globe.geometry}
        userData={{ name: "globe" }}
      />
    </group>
  );
}

Scene:

import React, { Suspense, useRef, useEffect } from "react";
import * as THREE from "three";
import { extend, useFrame, useThree } from "react-three-fiber";
import { Controls, useControl } from "react-three-gui";
import { a, config } from "react-spring/three";
import { OrbitControls, useHelper, softShadows } from "drei";
import { CameraHelper, SpotLightHelper } from "three";
import { EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer";
import { ShaderPass } from "three/examples/jsm/postprocessing/ShaderPass";
import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass";
import { SSAOPass } from "three/examples/jsm/postprocessing/SSAOPass";
import { UnrealBloomPass } from "three/examples/jsm/postprocessing/UnrealBloomPass";
import { FXAAShader } from "three/examples/jsm/shaders/FXAAShader";
import Earth from "./Earth";
softShadows();

extend({ EffectComposer, ShaderPass, RenderPass, UnrealBloomPass, SSAOPass });

function Effects() {
  const composer = useRef();
  const { scene, gl, size, camera } = useThree();
  useEffect(() => void composer.current.setSize(size.width, size.height), [
    size
  ]);
  useFrame(() => composer.current.render(), 1);
  return (
    <effectComposer ref={composer} args={[gl]}>
      <renderPass attachArray="passes" scene={scene} camera={camera} />
      <sSAOPass
        attachArray="passes"
        args={[scene, camera, 1024, 1024]}
        kernelRadius={0.8}
        maxDistance={0.4}
      />
      <unrealBloomPass attachArray="passes" args={[undefined, 1.6, 1, 0.5]} />
      <shaderPass
        attachArray="passes"
        args={[FXAAShader]}
        material-uniforms-resolution-value={[1 / size.width, 1 / size.height]}
      />
    </effectComposer>
  );
}

const Light = ({ color, xValue }) => {
  const refLight = useRef();
  useHelper(refLight, SpotLightHelper, 5);

  const posZ = useControl("Pos Z", {
    value: 0,
    type: "number",
    spring: config.wobbly,
    distance: 100,
    min: -100,
    max: 100
  });
  const posX = useControl("Pos X", {
    value: xValue,
    type: "number",
    spring: config.wobbly,
    distance: 100,
    min: -100,
    max: 100
  });
  const posY = useControl("Pos Y", {
    value: 0,
    type: "number",
    spring: config.wobbly,
    distance: 100,
    min: -100,
    max: 100
  });
  const intensity = useControl("Intensity", {
    value: 0.22,
    min: 0.01,
    max: 1,
    type: "number",
    distance: 1
  });
  return (
    <a.spotLight
      lookAt={[0, 0, 0]}
      width={100}
      height={100}
      castShadow
      color={color}
      ref={refLight}
      position-x={posX}
      position-y={posY}
      position-z={posZ}
      intensity={intensity}
    />
  );
};

const Lights = () => {
  return (
    <>
      <Light color={"#C1ECFF"} xValue={-10} />
      <Light color={"#E4F7FF"} xValue={10} />
      <ambientLight intensity={0.2} />
    </>
  );
};

const Model = () => {
  const modelContainerStyle = {
    height: "100%",
    width: "100%"
  };

  const labelsContainerStyle = {
    position: "relative",
    width: "100%",
    height: "100%",
    overflow: "hidden"
  };

  return (
    <div style={modelContainerStyle}>
      <Controls.Provider>
        <Controls.Canvas
          raycaster
          camera={{ position: [0, 0, 5], fov: 60 }}
          shadowMap
          colorManagement
          onCreated={({ gl }) => {
            gl.setClearColor(new THREE.Color("#040708"));
          }}
        >
          <OrbitControls
            enablePan={Boolean("Pan", true)}
            enableZoom={Boolean("Zoom", true)}
            enableRotate={Boolean("Rotate", true)}
          />
          <Suspense fallback={null}>
            <Earth />
          </Suspense>
          <Lights />
          <Effects />
        </Controls.Canvas>
        <Controls />
      </Controls.Provider>
      <div style={labelsContainerStyle}></div>
    </div>
  );
};

export default Model;
  • Can you please share a small re-producable chunk of the code here so we don't have to go off-site to help you? – Dominik Nov 29 '20 at 20:53
  • The code is simply a spherical earth model that has pins surrounding it. The pins represent the position of locations on earth. The positions also have some text centered on them. The issue is that the text doesn't obscure or disappear when the earth is rotated. Ill add some code to the original question. –  Nov 29 '20 at 21:22
  • there something new in r3f that just came in https://github.com/pmndrs/react-three-fiber/issues/848 could this solve your issue? – hpalu Dec 04 '20 at 22:49

0 Answers0