Skip to content

Conversation

@Jungzl
Copy link
Contributor

@Jungzl Jungzl commented Nov 28, 2025

follows up: #1232
close: #1210

like createRoot from @react-three/fiber or createThrelteContext from @threlte/core

finally, I can easily integrate tresjs in map app.

image

@Jungzl Jungzl requested a review from alvarosabu as a code owner November 28, 2025 10:06
@netlify
Copy link

netlify bot commented Nov 28, 2025

Deploy Preview for tresjs-docs ready!

Name Link
🔨 Latest commit ba36325
🔍 Latest deploy log https://app.netlify.com/projects/tresjs-docs/deploys/696ddb3cfe074b0008ac132e
😎 Deploy Preview https://deploy-preview-1233--tresjs-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify
Copy link

netlify bot commented Nov 28, 2025

Deploy Preview for tresjs-lab ready!

Name Link
🔨 Latest commit ba36325
🔍 Latest deploy log https://app.netlify.com/projects/tresjs-lab/deploys/696ddb3c56ac4700083a6cc4
😎 Deploy Preview https://deploy-preview-1233--tresjs-lab.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify
Copy link

netlify bot commented Dec 22, 2025

Deploy Preview for cientos-tresjs ready!

Name Link
🔨 Latest commit ba36325
🔍 Latest deploy log https://app.netlify.com/projects/cientos-tresjs/deploys/696ddb3cd0d99400089a6bb9
😎 Deploy Preview https://deploy-preview-1233--cientos-tresjs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

) {
const instance = getCurrentInstance()

const createInternalComponent = (context: TresContext, empty = false) =>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: Moving all this from the TresCanvas component to this composable is not desirable. The composables role is to initialize and orchestrate all the things around three.js while showing the dependencies between the respective elements (like renderer needs camera, event manager needs the renderer,...). The things that are moved here are very specific to the TresCanvas. Moving them harms the architecture and the readability imo. @Jungzl Maybe you can explain a bit what kind of fix or feature the change brings for you.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your feedback.

The motivation behind this PR is to enable rendering three.js content inside a host-provided WebGL layer (e.g., a map’s WebGL layer) while reusing Tres’s scene/camera lifecycle, scheduling, and state management—without duplicating the internal logic from the Context component.

But Tres doesn’t expose a low-level primitive equivalent to createRoot (from R3F) or createThrelteContext (from Threlte). If we attempt to integrate directly by mounting into an external canvas/context, we end up replicating much of Context.vue’s orchestration. To avoid that, this PR extracts and exports the logic as a composable (useTresContextManager), paired with useTresContextProvider.

The code looks like below:

<!--  CustomTresLayer.vue -->
<script setup lang="ts">

//...

const slots = defineSlots<{
  default: () => any
}>()

extend(THREE)

const createRenderer: RendererOptions['renderer'] = ctx => {
  const renderer = new WebGLRenderer({
    ...ctx,
    canvas: hostCanvas,
    context: hostGLContext,
  })
  renderer.autoClear = false
  return renderer as TresRenderer
}

const scene = shallowRef(new Scene())
const context = shallowRef(
  useTresContextProvider({
    scene: scene.value,
    canvas: hostCanvas,
    rendererOptions: { ...props, renderer: createRenderer }
  })
)

const { dispose } = useTresContextManager(scene, context, props, emit, slots)

// Bridge render requests to host
watchEffect(() => {
  context.value?.renderer?.replaceRenderFunction(notifySuccess => {
    host.render()  // Trigger host redraw
    notifySuccess()
  })
})

// Sync camera to host view in render callback
const render = () => {
  const { camera, scene } = context.value
  const activeCamera = camera.activeCamera.value
  
  // Apply host camera parameters
  const { near, far, fov, position, lookAt } = host.getCameraParams()
  activeCamera.near = near
  activeCamera.far = far
  activeCamera.fov = fov
  activeCamera.position.set(...position)
  activeCamera.lookAt(...lookAt)
  activeCamera.updateProjectionMatrix()
  
  // Render with host state
  renderer.render(scene.value, activeCamera)
  renderer.resetState()
}
</script>

<template>
  <CustomLayer :render="render" />
</template>

# Conflicts:
#	packages/core/src/components/Context.vue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants