Coder Social home page Coder Social logo

react-ogl's Issues

React 18 conflict dependencies

I can't run npm install anymore once I installed react-ogl in a clean Next project due to conflicting dependencies between React 18 and React ^17. What am I missing?

NPM version: 8.18.0
Node version: 16.15.0

The log:

npm ERR! code ERESOLVE
npm ERR! ERESOLVE could not resolve
npm ERR!
npm ERR! While resolving: [email protected]
npm ERR! Found: [email protected]
npm ERR! node_modules/react
npm ERR!   peer react@"^17.0.2 || ^18.0.0-0" from [email protected]
npm ERR!   node_modules/next
npm ERR!     next@"12.2.5" from the root project
npm ERR!   peer react@"^18.2.0" from [email protected]
npm ERR!   node_modules/react-dom
npm ERR!     peer react-dom@"^17.0.2 || ^18.0.0-0" from [email protected]
npm ERR!     node_modules/next
npm ERR!       next@"12.2.5" from the root project
npm ERR!     peerOptional react-dom@">=17.0" from [email protected]
npm ERR!     node_modules/react-ogl
npm ERR!       react-ogl@"^0.6.4" from the root project
npm ERR!     2 more (react-use-measure, the root project)
npm ERR!   8 more (react-ogl, react-use-measure, styled-jsx, suspend-react, ...)
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer react@"17.0.1" from [email protected]
npm ERR! node_modules/react-native
npm ERR!   peer react-native@">=0.64.0-rc.0 || 0.0.0-*" from @react-native-community/[email protected]
npm ERR!   node_modules/react-native/node_modules/@react-native-community/cli
npm ERR!     @react-native-community/cli@"^5.0.1-alpha.1" from [email protected]
npm ERR!   peerOptional react-native@">=0.64" from [email protected]
npm ERR!   node_modules/react-ogl
npm ERR!     react-ogl@"^0.6.4" from the root project
npm ERR!   1 more (@expo/browser-polyfill)
npm ERR!
npm ERR! Conflicting peer dependency: [email protected]
npm ERR! node_modules/react
npm ERR!   peer react@"17.0.1" from [email protected]
npm ERR!   node_modules/react-native
npm ERR!     peer react-native@">=0.64.0-rc.0 || 0.0.0-*" from @react-native-community/[email protected]
npm ERR!     node_modules/react-native/node_modules/@react-native-community/cli
npm ERR!       @react-native-community/cli@"^5.0.1-alpha.1" from [email protected]
npm ERR!     peerOptional react-native@">=0.64" from [email protected]
npm ERR!     node_modules/react-ogl
npm ERR!       react-ogl@"^0.6.4" from the root project
npm ERR!     1 more (@expo/browser-polyfill)
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR!
npm ERR! See /Users/arno/.npm/eresolve-report.txt for a full report.

package.json

{
  "name": "my-app",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "next": "12.2.5",
    "ogl": "^0.0.97",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "react-ogl": "^0.6.4"
  },
  "devDependencies": {
    "@types/node": "18.7.13",
    "@types/react": "18.0.17",
    "@types/react-dom": "18.0.6",
    "eslint": "8.22.0",
    "eslint-config-next": "12.2.5",
    "typescript": "4.7.4"
  }
}

OGL TextureLoader and react-ogl useLoader are incompatible

useLoader passes url as url but TextureLoader only accepts src

https://github.com/oframe/ogl/blob/b9817c6b207507365471c8af0387e0df16a3f843/src/extras/TextureLoader.js#L13

urls.map(async (url: string) => {

urls.map(async (url: string) => {
  // @ts-ignore OGL's loaders don't have a consistent signature
  if (classExtends(loader, OGL.TextureLoader)) return loader.load(gl, { url })
  
  return await loader.load(gl, url)
}),

Can't pass custom renderer constructor to state

Follow props signature, we able to use a custom renderer, but it not make sense because we can't pass canvas reference, because canvas not exist when we create it.

https://github.com/pmndrs/react-ogl/blob/main/src/shared/utils.ts#L105

Need to allow use a functional argument of rendere that will return instance for allowing this:
image

Like this:
https://github.com/pmndrs/react-three-fiber/blob/0fd9337565e7ae264b539b0ef9be05c04f749b89/packages/fiber/src/web/index.tsx#L39

Next.js: 'unstable_act' is not exported from 'react'

When trying to build in next.js I am getting this error:

./node_modules/react-ogl/dist/reconciler.mjs
Attempted import error: 'unstable_act' is not exported from 'react' (imported as 'React').

Seems like the issue is coming from this in reconciler.ts:
export const act: Act = 'unstable_act' in React ? (React as any).unstable_act : (React as any).act

I don't have experience with testing in react, so I would really appreciate your help but let me know if I can help you debug this in any way.

[feature] Dispose

Dispose is required because we can't know when React kill node or only replace it.
For mesh this is critical, because Geometry allocating GPU memory, Textures too, and other GL objects.

Suggest add to this:
https://github.com/pmndrs/react-ogl/blob/main/src/reconciler.ts#L121

Or remove call:

https://github.com/oframe/ogl/blob/master/src/core/Program.js#L208
https://github.com/oframe/ogl/blob/master/src/core/Geometry.js#L266

Or dispose call with nullish check, dispose or destroy is convential, and can be implemented in subclasses.

Raycast not working when node has parent

Sample:

import { createRef, useRef, useState } from "react";
import { useFrame, Canvas } from "react-ogl/web";
import { render } from "react-dom";
import { Mesh, Renderer } from "ogl";

const Box = (props) => {
	const mesh = useRef<Mesh>();
	const [hovered, setHover] = useState(false);
	const [active, setActive] = useState(false);

	return (
		<mesh
			{...props}
			ref={mesh}
			scale={active ? 1.5 : 1}
			onClick={() => setActive((value) => !value)}
			onPointerOver={() => setHover(true)}
			onPointerOut={() => setHover(false)}
		>
			<plane {...props} />
			<program
				vertex={`
          attribute vec3 position;
          attribute vec3 normal;

          uniform mat4 modelViewMatrix;
          uniform mat4 projectionMatrix;
          uniform mat3 normalMatrix;

          varying vec3 vNormal;

          void main() {
            vNormal = normalize(normalMatrix * normal);
            gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
          }
        `}
				fragment={`
          precision highp float;

          uniform vec3 uColor;
          varying vec3 vNormal;

          void main() {
            vec3 normal = normalize(vNormal);
            float lighting = dot(normal, normalize(vec3(10)));

            gl_FragColor.rgb = uColor + lighting * 0.1;
            gl_FragColor.a = 1.0;
          }
        `}
				uniforms={{ uColor: hovered ? "hotpink" : "orange" }}
			/>
		</mesh>
	);
};

const ref = createRef<HTMLCanvasElement>();
render(
	<Canvas
		camera={{ position: [0, 1.6, 8] }}
		ref={ref}
		renderer={() =>
			new Renderer ({
				canvas: ref.current,
				dpr: 2,
				antialias: true,
				autoClear: true,
			})
		}
	>
		<transform position={[0, 1.6, 0]}>
			<Box key="grid" width={4} height={2} />

			<transform position={[-2, 0, 0]} rotation={[0, Math.PI / 6, 0]}>
				<Box
					key="left"
					position={[-0.5, 0, 0]}
					width={1}
					height={2}
				/>
			</transform>

			<transform position={[2, 0, 0]} rotation={[0, -Math.PI / 6, 0]}>
				<Box
					key="right"
					position={[0.5, 0, 0]}
					width={1}
					height={2}
				/>
			</transform>
		</transform>
	</Canvas>,
	document.getElementById("react-content")
);

Expected:
Paneles will be hover and color changed

Actual:
Paneles not react

react-devtools crash

When I inspect any react-ogl elements in devtools (React Developer Tools version 4.23.0) devtools crashes with an error that it “Could not find ID for Fiber ” (where is the name of the react-dom component that renders <Canvas />).

Screen Shot 2022-02-22 at 12 23 55 PM

[critical] Uniform diff check should update only known uniforms

Bug in this place:

acc[uniform] = entry

when you use a special material with internal state and custom uniforms, react will produce errors because default uniforms will be dropped.

This is critical, because witout this will not working a special components for program with attach!

for ex:

import { Program } from "ogl";
import { extend, Node } from "react-ogl";

import React from "react";

const FRAG = `
precision highp float;

uniform vec3 uColor;
uniform vec2 uPoint;
uniform sampler2D uSampler0;

varying vec3 vNormal;
varying vec2 vUv;

void main() {
	gl_FragColor = texture2D(uSampler0, vUv);
	gl_FragColor = mix (vec4(1.0, 0., 0., 1.), gl_FragColor, step(0.01, length(uPoint - vUv)));
}
`;

const VERT = `
attribute vec3 position;
attribute vec3 normal;
attribute vec2 uv;

uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
uniform mat3 normalMatrix;

varying vec3 vNormal;
varying vec2 vUv;

void main() {
	vNormal = normalize(normalMatrix * normal);
	vUv = uv;
	gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`;

export interface IProgProps {
	mousePoint?: Array<number>;
	color?: string | any;
	children: any[];
}

export class BaseProgramWithTexture extends Program {
	constructor(gl: GLContext) {
		super(gl, {
			vertex: VERT,
			fragment: FRAG,
			transparent: true,
			uniforms:{
				uColor: { value: [1,1,1] },
				uPoint: { value: [0,0] },
				uSampler0: { value: null },
			}
		});
	}

	set texture(v) {
		this.uniforms.uSampler0 = {value: v};
	}

	get texture() {
		return this.uniforms.uSampler0?.value;
	}
}

extend({BaseProgramWithTexture});

declare global {
	namespace JSX {
	  interface IntrinsicElements {
		baseProgramWithTexture: Node<BaseProgramWithTexture, typeof BaseProgramWithTexture>
	  }
	}
  }


export default React.forwardRef<Program, IProgProps>(
	({ color = "pink", mousePoint = [0, 0], children }, ref) => {
		return (
			<baseProgramWithTexture
				ref={ref}
				uniforms = {{
					uColor: color
				}}
			>
                        <ChessTexture/>
			</baseProgramWithTexture>
		);
	}
);

// ChessTexture.tsx
// which should apply texture to `texture` field that is setter
export default ({width = 256, height = 256, step = 64}) => {
	return React.createElement('texture', {
		attach: 'texture',
		image: generateCheckmate(width, height, step)
	})
}


//programRef is reference on to our baseProgramWithTexture and uPoint MUST BE AVAILABLE
	const handleMove = ({ hit }: any) => {
		(
			programRef.current.uniforms as Record<string, { value: any }>
		).uPoint.value = hit?.uv || [0, 0];
	};

Will have a a lot of warns:
image

And if we try to change uPoint manually - will crash, because reconciler remove required fields.

[feature] Custom GL required class

Now, ogl-react resolve only prebuilded classes from
https://github.com/pmndrs/react-ogl/blob/main/src/constants.ts#L7

But for some case need has a custom class that not extends from listed, and which requires a pass gl to args.

atm this resolved as hack:

image
That looks starange.

So, maybe we can check a static field to classes that required to construct with GL and will check it in this:
https://github.com/pmndrs/react-ogl/blob/main/src/reconciler.ts#L35

like :

if (!object && elem.requireGL || GL_ELEMENTS.some((elem) => Object.prototype.isPrototypeOf.call(elem, target) || elem === target)) {
}

Crash when try use texture from Unit8Array.

Some js native classes have a set method but not have a copy.
Map/Set/TypedArray (UInt8Array for example).
Ok, there are not reason handle a Map/Set as props because there are not API what use it, but should be way pass ArrayBuffer view.

This line try to use copy method that wrong for this case:
https://github.com/pmndrs/react-ogl/blob/main/src/utils.ts#L144

Possible fix:

// we should bypass set for array buffer, because it not resizable. You cant set a 4 values to array of 0. 
if (target?.set && !ArrayBuffer.isView(value)) {
      if (target.constructor.name === value.constructor.name && target.copy) {
        target.copy(value)
      } else if (Array.isArray(value)) {
        target.set(...value)
      } else {
        // Support shorthand scalar syntax like scale={1}
        const scalar = new Array(target.length).fill(value)
        target.set(...scalar)
      }
} else {

This sometime can be used for API's like a :

{ /* texture 2x2 filled to red */ }
<texture 
     width={2} 
     height={2} 
     image={new Uint8Array([255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255]} 
/>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.