ektogamat / fake-glow-material-r3f

A fake glow material for react three fiber.
https://r3f-fake-glow-material.vercel.app/
MIT License
126 stars 7 forks source link

Geting a type error when attempting to use this in a TS project #2

Open rogersanick opened 8 months ago

rogersanick commented 8 months ago

The error:

Property 'fakeGlowMaterial' does not exist on type 'JSX.IntrinsicElements'.ts(2339)

Steps to reproduce:

Copy the code from the gist in the readme

Versions used currently: "three": "^0.160.0", "@react-three/drei": "9.96.0", "@react-three/fiber": "8.15.13",

ektogamat commented 8 months ago

Hey Roger. Thank you very much. Unfortunately, I can't provide support due to my lack of knowledge in this field. I'm very sorry about that. Maybe someone more experienced can contribute and give us help on this ;).

nirtamir2 commented 8 months ago

Here you go:

import React, { useMemo } from "react";
import { shaderMaterial } from "@react-three/drei";
import type { Object3DNode } from "@react-three/fiber";
import { extend } from "@react-three/fiber";
import type { Material, Side } from "three";
import { AdditiveBlending, Color, FrontSide } from "three";
import type { ColorRepresentation } from "three";

/**
 * @typedef {Object} FakeGlowMaterialProps
 * @property {Number} [falloff=0.1] - Controls the value of the Falloff effect. Ranges from 0.0 to 1.0.
 * @property {Number} [glowInternalRadius=6.0] - Controls the internal glow radius. Ranges from -1.0 to 1.0. Set a darker color to get the fresnel effect only.
 * @property {String} [glowColor='#00ff00'] - Specifies the color of the hologram. Use hexadecimal format.
 * @property {Number} [glowSharpness=1.0] - Specifies the edges sharpness. Defaults to 1.0.
 * @property {Number} [side=THREE.FrontSide] - Specifies side for the material, as THREE.DoubleSide. Options are "THREE.FrontSide", "THREE.BackSide", "THREE.DoubleSide". Defaults to "THREE.FrontSide".
 */

/**
 * FakeGlow material component by Anderson Mancini - Feb 2024.
 * @param {FakeGlowMaterialProps} props - Props for the FakeGlowMaterial component.
 */

declare module "@react-three/fiber" {
  interface ThreeElements {
    fakeGlowMaterial: Object3DNode<Material, typeof FakeGlowMaterial>;
  }
}

type Props = {
  falloff?: number;
  glowInternalRadius?: number;
  glowColor?: ColorRepresentation;
  glowSharpness?: number;
  side?: Side;
};

export const FakeGlowMaterial = ({
  falloff = 0.1,
  glowInternalRadius = 6,
  glowColor = "#00ff00",
  glowSharpness = 1,
  side = FrontSide, // Adjust the PropTypes as per your requirements
}: Props) => {
  const FakeGlowMaterial = useMemo(() => {
    return shaderMaterial(
      {
        falloffAmount: falloff,
        glowInternalRadius,
        glowColor: new Color(glowColor),
        glowSharpness,
      },
      /*GLSL */
      `
      varying vec3 vPosition;
      varying vec3 vNormal;

      void main() {
        vec4 modelPosition = modelMatrix * vec4(position, 1.0);
        gl_Position = projectionMatrix * viewMatrix * modelPosition;
        vec4 modelNormal = modelMatrix * vec4(normal, 0.0);
        vPosition = modelPosition.xyz;
        vNormal = modelNormal.xyz;

      }`,
      /*GLSL */
      ` 
      uniform vec3 glowColor;
      uniform float falloffAmount;
      uniform float glowSharpness;
      uniform float glowInternalRadius;

      varying vec3 vPosition;
      varying vec3 vNormal;

      void main()
      {
        // Normal
        vec3 normal = normalize(vNormal);
        if(!gl_FrontFacing)
            normal *= - 1.0;
        vec3 viewDirection = normalize(cameraPosition - vPosition);
        float fresnel = dot(viewDirection, normal);
        fresnel = pow(fresnel, glowInternalRadius + 0.1);
        float falloff = smoothstep(0., falloffAmount, fresnel);
        float fakeGlow = fresnel;
        fakeGlow += fresnel * glowSharpness;
        fakeGlow *= falloff;
        gl_FragColor = vec4(clamp(glowColor * fresnel, 0., 1.0), clamp(fakeGlow, 0., 1.0));

      }`,
    );
  }, [falloff, glowInternalRadius, glowColor, glowSharpness]);

  extend({ FakeGlowMaterial });

  return (
    <fakeGlowMaterial
      key={FakeGlowMaterial.key}
      side={side}
      transparent={true}
      blending={AdditiveBlending}
      depthTest={false}
    />
  );
};

Notice: I change the export to named (because I prefer it instead of default export) I remove propTypes and I change the size to be the number constant that represents the size (import {FrontSide} from "three". I also remove the shader's last 2 rows

        #include <tonemapping_fragment
        #include <colorspace_fragment

Because they did not work for me (see #3 )

rogersanick commented 8 months ago

This worked brilliantly! Thank you @nirtamir2!

ektogamat commented 8 months ago

Thank you so much @nirtamir2! I will create another gist for those interested in a TS version. I have other components with TS errors it could be great to have your help if you become available someday hehe. Thank you very much!

nirtamir2 commented 8 months ago

No problem - it will be my pleasure to help you 😀

tkalejandro commented 8 months ago

@ektogamat Will this be merge??? or a TS solution comming soon...?? :D . Thanks for this glow tho

ektogamat commented 8 months ago

Hey. It is available in another gist that I created. I'm sorry, but I'm so newbie to this that I don't know how to merge, to be honest hehe. If I merge this TS version, that would break the JS version, isn't it?

Thanks for your patience!

tkalejandro commented 8 months ago

Hey. It is available in another gist that I created. I'm sorry, but I'm so newbie to this that I don't know how to merge, to be honest hehe. If I merge this TS version, that would break the JS version, isn't it?

Thanks for your patience!

Yes I found the gist in the README! I think I found another bug....but I will create another ticket for that.

Regarding this TS..... Maybe start a new project in TS or initiate TS in the current project , and then you add a JS example and TS example. Im not really sure that you can write TS without initialization. Maybe can, but wont work.