New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(web): accept function as gl that returns a renderer #1717
Conversation
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit 823e5e5:
|
@CodyJasonBennett I am not sure how this would work together with your change in #1714 |
That is funny timing, but I don't see anything problematic between the two. I'd merge them like this: const createRendererInstance = <TElement extends Element>(
gl:
| THREE.WebGLRenderer
| ((canvas: TElement) => THREE.WebGLRenderer)
| Partial<Properties<THREE.WebGLRenderer> | THREE.WebGLRendererParameters>
| undefined,
canvas: TElement,
): THREE.WebGLRenderer => {
const customRenderer = (typeof gl === 'function' ? gl(canvas) : gl) as THREE.WebGLRenderer
if (isRenderer(customRenderer)) return customRenderer
const renderer = new THREE.WebGLRenderer({
powerPreference: 'high-performance',
canvas: canvas as unknown as HTMLCanvasElement,
antialias: true,
alpha: true,
...gl,
})
if (gl) applyProps(renderer as any, gl as any)
return renderer
} |
good idea! is this ready to merge? |
If you guys are happy with my code then it's ready to merge. @CodyJasonBennett are you happy to rebase your branch on this and apply your changes in your branch or would you like me to apply your changes to my branch? |
If possible it'd be better to have one PR that does both. Maybe @CodyJasonBennett you can move your changes over incl tests? |
@joshuaellis, sure thing. My only concern would be how to handle asynchronous callbacks and whether that should be our responsibility. Currently, R3F's render method is entirely synchronous. Taking the WebGPU example, users must asynchronously call This is how it would be done in userland: const [frameloop, setFrameLoop] = React.useState('never')
return (
<Canvas
frameloop={frameloop}
gl={(canvas) => {
const renderer = new WebGPURenderer({ canvas })
renderer.init().then(() => setFrameLoop('always'))
return renderer
}}>
<gridHelper />
</Canvas>
) |
I'll take a look at how to handle that now, shouldn't be an issue though. |
update before I park it for the evening. I'm overloading the functions, I just need typescript to figure out if there is a GL prop added to the |
Didn't mean to close. |
Hi @joshuaelli / @CodyJasonBennett, Is there anything I can help with to wrap up the PR? Happy to help! |
So I think we're going to move this into If you desperately need it, you could use |
No problem at all, completely understand it. Looking forward to v8. In the meantime I'll Thanks for all your help. The Poimandres open source developer collective is amazing ❤️ |
you dont need patch package, you can outright build your own canvas using the render api. https://github.com/pmndrs/react-three-fiber/blob/master/packages/fiber/src/web/Canvas.tsx everything in there is exported. i think the only change is that createPointerEvents is just events. but you can just copy that file, add the gl logic. |
what happens if gl.render is called before init has completed? |
this is where it would have to await gl function. This would turn |
looking through the webgpu code it looks like render itself isnt async, just init. i think it would already be solveable in userland: <Canvas gl={(canvas) => new WebGPURenderer({ canvas })} frameloop="never" onCreated={async (state) => {
await state.gl.init()
state.set({ frameloop: 'always' })
}> to me that's perhaps even cleaner than adding some async stuff to something as simple as the ps. this needs the PR of course due to the |
If we can avoid async behaviour in the |
@joshuaellis @CodyJasonBennett @Tirzono if this works i think let's merge. it is a feature, but so small and helpful, i could just cherry-pick it into v8 later on. |
@drcmda, @joshuaellis, both snippets work with the current implementation. If you call |
While I gave the example of |
@Tirzono could you fix the merge conflict? @CodyJasonBennett says it's working so async is not a blocker. |
I went ahead and fixed the conflict. Any accompanying documentation on here or the website repo would need to note that |
the docs in this repo are out of date imo. im not sure if the website/docs site can already use remote mdx, that would be optimal. if not it needs to be documented over there. |
I'll make a note there. I've fixed a bunch of stuff for various repos' docs that weren't updated upstream, but we can start with R3F since stuff shouldn't change until v8. |
This allows passing in another renderer without having to create a canvas element yourself:
I do need some advice on how to JavaScript -> TypeScript this bit of code :)