React Three Drei Svg

i want to load an svg icon in a 3d scene, i used the Svg Component from drei to do that, but the svg appears in black color although i designed it with colors

this is how it should look like

and this is my code
image

first, what materials do you use? if they are not meshbasic you would need at least an ambientlight.

other than that, the svg implementation in threejs seems incomplete, it’s often missing detail or geometry, i don’t think you can rely on it to be 100% accurate. i would prefer an image, way too resource heavy imo to use dozens of meshes just for an icon.

Do you mind posting a quick piece of code as the current docs are much too minimal to understand how to use it.

other than that, the svg implementation in threejs seems incomplete, it’s often missing detail or geometry,

Just a basic example how to correctly use Drei Svg comp would help others online finding this thread.

:folded_hands:

Here is a minimal with SVGLoader

import { MeshProps, useLoader } from "@react-three/fiber";
import { useMemo } from "react";
import * as T from "three";
import { SVGLoader } from "three/examples/jsm/loaders/SVGLoader";

const Logo = (props: MeshProps) => {
  const svgData = useLoader(SVGLoader, "/lvup_icon.svg");
  const shapes = useMemo(() => {
    return svgData.paths.map((p) => p.toShapes(true));
  }, [svgData]);

  return (
    <mesh scale={0.05} rotation={[1 * Math.PI, 0, 0]} position={[-0.7, 0.5, 0]}>
      {shapes.map((s, i) => (
        <extrudeBufferGeometry
          key={i}
          args={[
            s,
            {
              depth: 1,
              bevelEnabled: false,
              steps: 30
            }
          ]}
        />
      ))}
      <meshPhongMaterial color="red" side={T.DoubleSide} />
    </mesh>
  );
};

export default Logo;

What would this look like with Svg from Drei?

Draw your SVG onto a canvas and use a CanvasTexture.

I appreciate the rapid reply.
But let me know if you’ve actually used the Svg Drei comp?

So I know what’s what I am doing incorrectly.

export function SvgComp(props) {
     <Svg  src={"/tiger.svg"} {...props}  position={[0, 0, 2]}  scale={0.25} skipFill={false}   fillMaterial={{ wireframe: false }}  strokeMaterial={{ wireframe: false }} />
}

Your SvgComp function isn’t returning anything, there’s not much need to wrap dreis Svg component in another wrapper but if it’s a requirement to do so you need to change it to this…

export function SvgComp(props) {
     return <Svg  src={"/tiger.svg"} {...props}  position={[0, 0, 2]}  scale={0.25} skipFill={false}   fillMaterial={{ wireframe: false }}  strokeMaterial={{ wireframe: false }} />
}
1 Like

:rofl: Yeah I just realized before the comment!

but thanks for the lookout!

I haven’t used the drei component but I’ve used the SVGLoader a lot, and that tiger.svg is one of the examples and works fine.

@manthrax Thanks forgot to add my return statement… But try it out!

1 Like

Glad you got it working!

I was going to revert to the SVGLoader but might as well get the most out of this Drei comp…
Docs are lacking I made a github issue.

Let me know when you get your hands dirty with this I’m still shooting in the dark with doing anything else but loading the svg file, and the props I have… Fyi those are working.. Those props should be in the Drei docs at a minimum.

pulled form source.

export interface SvgProps extends Omit<ThreeElements['object3D'], 'ref'> {
  /** src can be a URL or SVG data */
  src: string
  skipFill?: boolean
  skipStrokes?: boolean
  fillMaterial?: ThreeElements['meshBasicMaterial']
  strokeMaterial?: ThreeElements['meshBasicMaterial']
  fillMeshProps?: ThreeElements['mesh']
  strokeMeshProps?: ThreeElements['mesh']
}