Failed to execute 'shaderSource' on 'WebGL2RenderingContext'

Hi everyone, I am facing this error: TypeError: Failed to execute 'shaderSource' on 'WebGL2RenderingContext': parameter 1 is not of type 'WebGLShader'.

The problem only appears if I render more than 16 objects at the same time; I tried with 15 objects, and it still works.

//tech
<div className="flex flex-row flex-wrap justify-center gap-10">
        {/* {console.log(data)} */}
        {data.map((tech: any, index: any) => (
          <div className="h-28 w-28" key={tech.index}>
            {/* <BallTech icon={tech.icon} wait={(index + 3) * 1000} /> */}
            <div className="bg-blue-900 text-white">{tech.icon}</div>
          </div>
        ))}
      </div>
// BallTech.tsx
import {
  Decal,
  Float,
  useTexture,
  OrbitControls,
  Preload,
  Html,
} from "@react-three/drei";
import { Canvas } from "@react-three/fiber";
import React, { Suspense, useEffect, useState } from "react";
import CanvasLoader from "./Loader";

const BallTech = (props: any) => {
  const [decal] = useTexture([props.imgUrl]);
  return (
    <Float speed={2} rotationIntensity={1} floatIntensity={2}>
      <ambientLight intensity={1} />
      <directionalLight position={[0, 0, 0.05]} intensity={1} />
      <mesh castShadow receiveShadow scale={2.75}>
        <icosahedronGeometry args={[1, 1]} />
        <meshStandardMaterial
          color="#ffffff"
          polygonOffset
          polygonOffsetFactor={-10}
          flatShading
          roughness={0}
        />
        <Decal
          position={[0, 0, 1]}
          rotation={[0, 0, 0]}
          scale={1}
          map={decal}
        />
      </mesh>
    </Float>
  );
};



const BallCanvas: React.FC<any> = ({ icon, wait }) => {
  const [hidden, setHidden] = useState("hidden");
  console.log(wait);
  console.log(icon);

  useEffect(() => {
    const timerId = setTimeout(() => {
      show();
    }, wait);

    return () => {
      clearTimeout(timerId);
    };
  }, [wait]);

  const show = () => {
    setHidden("");
  };

  return (
    <Canvas frameloop="always" gl={{ preserveDrawingBuffer: true }}>
      <Suspense fallback={<CanvasLoader />}>
        {/* <OrbitControls enableZoom={false} maxPolarAngle={2} minPolarAngle={1} /> */}
        <OrbitControls enableZoom={false} />
        <BallTech imgUrl={`/tech/${icon}`} />
        <Preload all />
      </Suspense>
    </Canvas>
  );
};

export default BallCanvas;

I am using NextJS, typescript, ThreeJS, TailwindCSS
Thank you guys

Since each of your objects contains a point light and an ambient light - you’re effectively trying to render (at least) 32 lights - which is (at least) 16 too many.

Consider adding the lights as children of the canvas scene, not as part of the objects.

I tried to reduce the number of light. I’m not sure it can solve the problem or not. But rendering many objects leads to THREE.WebGLRenderer: Context Lost too. For now I do not see this shaderSource error. but all object cannot render correctly due to “THREE.WebGLRenderer: Context Lost.”

“Context lost” usually happens when you create a lot of canvases or allocate way too many resources (but “way to many” means waaaaaay too many - so the first scenario is more likely.)

Make sure you’re creating only one canvas and don’t recreate it on state update.

I really impressed with this example: ‘three.js examples’. But this code write by HTML. I am new to React/NextJS, do you have any hint or advice to recreate like this example? I see it can render 40 objects without error.

"use client";
import React, { useRef, useState } from "react";
import { Canvas, useFrame } from "@react-three/fiber";
import {
  Float,
  MeshWobbleMaterial,
  OrbitControls,
  useHelper,
} from "@react-three/drei";

const Cube = ({ position, side, color }: any) => {
  return (
    <Float speed={2} rotationIntensity={1} floatIntensity={2}>
      <ambientLight intensity={1} />
      <directionalLight position={[0, 0, 0.05]} intensity={1} />
      <mesh castShadow receiveShadow scale={0.5}>
        <icosahedronGeometry args={[1, 1]} />
        <meshStandardMaterial
          color="#ffffff"
          polygonOffset
          polygonOffsetFactor={-10}
          flatShading
          roughness={0}
        />
      </mesh>
    </Float>
  );
};

const Scene = () => {
  return (
    <>
      <directionalLight position={[0, 1, 2]} intensity={1} color={"white"} />
      {/* <pointLight ref={pointLightRef} position={[0, 1, 1]} /> */}
      <ambientLight intensity={0.5} />
      <group position={[0, -1, 0]}>
        <Cube position={[1, 0, 0]} color={"green"} side={1} />
        <Cube position={[3, 0, 0]} color={"green"} side={1} />
        <Cube position={[5, 0, 0]} color={"green"} side={1} />
        <Cube position={[7, 0, 0]} color={"green"} side={1} />

        <Cube position={[1, 2, 0]} color={"green"} side={1} />
        <Cube position={[1, 4, 0]} color={"green"} side={1} />
        <Cube position={[1, 6, 0]} color={"green"} side={1} />
        <Cube position={[1, 8, 0]} color={"green"} side={1} />

        <Cube position={[-1, 0, 0]} color={"hotpink"} side={1} />
        <Cube position={[-3, 0, 0]} color={"hotpink"} side={1} />
        <Cube position={[-5, 0, 0]} color={"hotpink"} side={1} />
        <Cube position={[-7, 0, 0]} color={"hotpink"} side={1} />

        <Cube position={[-1, 2, 0]} color={"blue"} side={1} />
        <Cube position={[-3, 2, 0]} color={"blue"} side={1} />
        <Cube position={[-5, 2, 0]} color={"blue"} side={1} />
        <Cube position={[-7, 2, 0]} color={"blue"} side={1} />

        <Cube position={[1, 2, 0]} color={"yellow"} side={1} />
        <Cube position={[3, 2, 0]} color={"yellow"} side={1} />
        <Cube position={[5, 2, 0]} color={"yellow"} side={1} />
        <Cube position={[7, 2, 0]} color={"yellow"} side={1} />
      </group>
    </>
  );
};

const TestLoad = () => {
  return (
    <Canvas>
      <OrbitControls enableZoom={true} />
      <Scene />
    </Canvas>
  );
};

export default TestLoad;

I tried to write this with only 1 Canvas render. but with this I cannot put

inside . :frowning:

Every time you create a Cube, you create an AmbientLight and DirectionalLight as well. Remove these two from the Cube component and try again.

Yes, it seem work if I remove lights. But there is another issue “THREE.WebGLRenderer: Context Lost”.
I want to remake ‘three.js examples’ this site on Nextjs. But really dont know how. The example is written on Html css vanilla :frowning: