Преглед изворни кода

feat: context (TresContext) is now exposed from TresCanvas (#404)

* feat: context (TresContext) is now exposed from TresCanvas

* docs: improved TresCanvas docs

* docs: added exposed properties to TresCanvas docs

* docs: added docs for useTresContext

* chore: changes concerning code review

---------

Co-authored-by: Tino Koch <tinoooo@users.noreply.github.com>
Tino Koch пре 1 година
родитељ
комит
838d779e59

+ 1 - 1
docs/.vitepress/config.ts

@@ -49,7 +49,7 @@ export default defineConfig({
       {
       {
         text: 'API',
         text: 'API',
         items: [
         items: [
-          { text: 'Renderer', link: '/api/renderer' },
+          { text: 'TresCanvas', link: '/api/tres-canvas' },
           {
           {
             text: 'Instances, arguments and props',
             text: 'Instances, arguments and props',
             link: '/api/instances-arguments-and-props',
             link: '/api/instances-arguments-and-props',

+ 3 - 3
docs/advanced/primitive.md

@@ -1,12 +1,12 @@
 # Primitives
 # Primitives
 
 
-The `<primitive />` component is a versatile low-level component in TresJS that allows you to directly use any Three.js object within your Vue application without an abstraction. It acts as a bridge between Vue's reactivity system and Three.js's scene graph.
+The `<primitive />` component is a versatile low-level component in TresJS that allows you to directly use any three.js object within your Vue application without an abstraction. It acts as a bridge between Vue's reactivity system and three.js's scene graph.
 
 
 ## Usage
 ## Usage
 
 
 ```html
 ```html
 <script setup lang="ts">
 <script setup lang="ts">
-  // Import necessary Three.js classes
+  // Import necessary three.js classes
   import { Mesh, BoxGeometry, MeshBasicMaterial } from 'three';
   import { Mesh, BoxGeometry, MeshBasicMaterial } from 'three';
 
 
   // Create a box geometry and a basic material
   // Create a box geometry and a basic material
@@ -26,7 +26,7 @@ The `<primitive />` component is a versatile low-level component in TresJS that
 
 
 ## Props
 ## Props
 
 
-`object`: This prop expects a Three.js Object3D or any of its derived classes. It is the primary object that the `<primitive />` component will render. In the updated example, a `Mesh` object with an associated `Material` is passed to this prop.
+`object`: This prop expects a three.js Object3D or any of its derived classes. It is the primary object that the `<primitive />` component will render. In the updated example, a `Mesh` object with an associated `Material` is passed to this prop.
 
 
 ## Usage with Models 
 ## Usage with Models 
 
 

+ 27 - 14
docs/api/composables.md

@@ -14,7 +14,7 @@ The `useRenderLoop` composable is the core of **TresJS** animations. It allows y
 const { onLoop, resume } = useRenderLoop()
 const { onLoop, resume } = useRenderLoop()
 
 
 onLoop(({ delta, elapsed, clock, dt }) => {
 onLoop(({ delta, elapsed, clock, dt }) => {
-  // I will run at every frame ~ 60FPS (depending of your monitor)
+  // I will run at every frame ~60FPS (depending of your monitor)
 })
 })
 ```
 ```
 
 
@@ -136,12 +136,12 @@ Then you can bind the textures to the material.
       <TresSphereGeometry />
       <TresSphereGeometry />
       <TresMeshStandardMaterial
       <TresMeshStandardMaterial
         :map="map"
         :map="map"
-        :displacementMap="displacementMap"
-        :normalMap="normalMap"
-        :roughnessMap="roughnessMap"
-        :metalnessMap="metalnessMap"
-        :aoMap="aoMap"
-        :alphaMap="alphaMap"
+        :displacement-map="displacementMap"
+        :normal-map="normalMap"
+        :roughness-map="roughnessMap"
+        :metalness-map="metalnessMap"
+        :ao-map="aoMap"
+        :alpha-map="alphaMap"
       />
       />
     </TresMesh>
     </TresMesh>
   </TresCanvas>
   </TresCanvas>
@@ -179,19 +179,16 @@ watch(carRef, ({ model }) => {
 })
 })
 ```
 ```
 
 
-## useTresContext (former useTres)
-
-This composable aims to provide access to the state model which contains the default renderer, camera, scene, and other useful properties.
+## useTresContext
+This composable aims to provide access to the state model which contains multiple useful properties.
 
 
 ```ts
 ```ts
-const { camera, renderer } = useTresContext()
+const { camera, renderer, camera, cameras } = useTresContext()
 
 
-console.log(camera.value) // THREE.PerspectiveCamera
-console.log(renderer.value) // THREE.WebGLRenderer
 ```
 ```
 
 
 ::: warning
 ::: warning
-`useTresContext` can be only be used inside of a `TresCanvas` since `TresCanvas` acts as the provider for the context data.
+`useTresContext` can be only be used inside of a `TresCanvas` since `TresCanvas` acts as the provider for the context data. Use [the context exposed by TresCanvas](tres-canvas#exposed-public-properties) if you find yourself needing it in parent components of TresCanvas. 
 :::
 :::
 
 
 ```vue
 ```vue
@@ -209,3 +206,19 @@ import { useTresContext } from '@tresjs/core'
 const context = useTresContext()
 const context = useTresContext()
 </script>
 </script>
 ```
 ```
+
+### Properties of context
+| Property | Description |
+| --- | --- |
+| **camera** | the currently active camera |
+| **cameras** | the cameras that exist in the scene |
+| **controls** | the controls of your scene |
+| **deregisterCamera** | a method to deregister a camera. This is only required if you manually create a camera. Cameras in the template are deregistered automatically. |
+| **extend** | Extends the component catalogue. See [extending](/advanced/extending) |
+| **raycaster** | the global raycaster used for pointer events |
+| **registerCamera** | a method to register a camera. This is only required if you manually create a camera. Cameras in the template are registered automatically. |
+| **renderer** | the [WebGLRenderer](https://threejs.org/docs/#api/en/renderers/WebGLRenderer) of your scene |
+| **scene** | the [scene](https://threejs.org/docs/?q=sce#api/en/scenes/Scene). |
+| **setCameraActive** | a method to set a camera active |
+| **sizes** | contains width, height and aspect ratio of your canvas |
+

+ 1 - 1
docs/api/events.md

@@ -1,6 +1,6 @@
 # Events
 # Events
 
 
-**TresJS** components emit pointer events when they are interacted with. This is the case for the components that represent Three.js classes that derive from [THREE.Object3D](https://threejs.org/docs/index.html?q=object#api/en/core/Object3D) (like meshes, groups,...).
+**TresJS** components emit pointer events when they are interacted with. This is the case for the components that represent three.js classes that derive from [THREE.Object3D](https://threejs.org/docs/index.html?q=object#api/en/core/Object3D) (like meshes, groups,...).
 
 
 <StackBlitzEmbed project-id="tresjs-events" />
 <StackBlitzEmbed project-id="tresjs-events" />
 
 

+ 0 - 90
docs/api/renderer.md

@@ -1,90 +0,0 @@
-# Renderer
-
-The `Renderer` component is the main component of Tres. It's the one that creates the ThreeJS `WebGLRenderer` and define your Tres Scene.
-
-```vue{2,5}
-<template>
-  <TresCanvas shadows :output-encoding="SRGBColorSpace">
-    <TresPerspectiveCamera />
-      <!-- Your scene goes here -->
-  </TresCanvas>
-</template>
-```
-
-## Canvas size
-
-The `Renderer` component will use the parent element size as the canvas size. If you want to use the window size as the canvas size, you can set the `window-size` prop to `true`.
-
-```vue
-<template>
-  <TresCanvas window-size>
-    <!-- Your scene goes here -->
-  </TresCanvas>
-</template>
-```
-
-Or you can use CSS to set your app size.
-
-```css
-html,
-body {
-  margin: 0;
-  padding: 0;
-  height: 100%;
-  width: 100%;
-}
-#app {
-  height: 100%;
-  width: 100%;
-  background-color: #000;
-}
-```
-
-## Presets
-
-Tres comes with a few presets for the `Renderer` component. You can use them by setting the `preset` prop.
-
-### Realistic
-
-The `realistic` preset makes easy to setup the renderer for more realistic 3D scenes.
-
-```vue
-<template>
-  <TresCanvas preset="realistic">
-    <!-- Your scene goes here -->
-  </TresCanvas>
-</template>
-```
-
-It's equivalent to:
-
-```ts
-renderer.shadows: true,
-renderer.physicallyCorrectLights: true,
-renderer.outputColorSpace: SRGBColorSpace,
-renderer.toneMapping: ACESFilmicToneMapping,
-renderer.toneMappingExposure: 3,
-renderer.shadowMap.enabled: true,
-renderer.shadowMap.type: PCFSoftShadowMap
-```
-
-## Props
-
-| Prop                      | Description                                                                                                                                                     | Default            |
-| :------------------------ | :-------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ |
-| **shadows**               | Enable shadows in the Renderer                                                                                                                                  | `false`            |
-| **shadowMapType**         | Set the shadow map type                                                                                                                                         | `PCFSoftShadowMap` |
-| **useLegacyLights**       | Whether to use the legacy lighting mode or not                                                                                                                  | `true`             |
-| **outputColorSpace**      | Defines the output encoding                                                                                                                                     | `LinearEncoding`   |
-| **toneMapping**           | Defines the tone mapping exposure used by the renderer.                                                                                                         | `NoToneMapping`    |
-| **context**               | This can be used to attach the renderer to an existing [RenderingContext](https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext)               |                    |
-| **powerPreference**       | Provides a hint to the user agent indicating what configuration of GPU is suitable for this WebGL context. Can be "high-performance", "low-power" or "default". | `default`          |
-| **preserveDrawingBuffer** | Whether to preserve the buffers until manually cleared or overwritten..                                                                                         | `false`            |
-| **clearColor**            | The color the renderer will use to clear the canvas.                                                                                                            | `#000000`          |
-| **windowSize**            | Whether to use the window size as the canvas size or the parent element.                                                                                        | `false`            |
-| **disableRender**         | Disable render on requestAnimationFrame, usefull for PostProcessing                                                                                             | `false`            |
-| **camera**                | A manual camera to be used by the renderer.                                                                                                                     |                    |
-
-## Defaults
-
-Tres tries to be as less opinionated as possible. That's why it doesn't set almost any default value for the `Renderer` component. You need to set the props you want to use. The only exception is the `antialias` prop. It's set to `true` by default.

+ 104 - 0
docs/api/tres-canvas.md

@@ -0,0 +1,104 @@
+# TresCanvas
+
+The `TresCanvas` component is the main component of Tres. It's the one that creates the ThreeJS `WebGLRenderer`.
+
+```vue{2,5}
+<template>
+  <TresCanvas shadows :output-encoding="SRGBColorSpace">
+    <TresPerspectiveCamera />
+      <!-- Your scene goes here -->
+  </TresCanvas>
+</template>
+```
+
+## Canvas size
+
+The `TresCanvas` component will use the parent element size as the canvas size. If you want to use the window size as the canvas size, you can set the `window-size` prop to `true`.
+
+```vue
+<template>
+  <TresCanvas window-size>
+    <!-- Your scene goes here -->
+  </TresCanvas>
+</template>
+```
+
+Or you can use CSS to set your canvas size.
+
+```css
+html,
+body {
+  margin: 0;
+  padding: 0;
+  height: 100%;
+  width: 100%;
+}
+#canvas {
+  height: 100%;
+  width: 100%;
+}
+```
+
+## Presets
+
+Tres comes with a few presets for the `TresCanvas` component. You can use them by setting the `preset` prop.
+
+### Realistic
+
+The `realistic` preset makes easy to setup the renderer for more realistic 3D scenes.
+
+```vue
+<template>
+  <TresCanvas preset="realistic">
+    <!-- Your scene goes here -->
+  </TresCanvas>
+</template>
+```
+
+It's equivalent to:
+
+```ts
+renderer.shadows = true
+renderer.physicallyCorrectLights = true
+renderer.outputColorSpace = SRGBColorSpace
+renderer.toneMapping = ACESFilmicToneMapping
+renderer.toneMappingExposure = 3
+renderer.shadowMap.enabled = true
+renderer.shadowMap.type = PCFSoftShadowMap
+```
+
+## Props
+
+| Prop | Description | Default |
+| ---- | ---- | --- |
+| **alpha** | Controls the default clear alpha value. When set to true, the value is 0. Otherwise it's 1. | false |
+| **antialias** | Whether to perform antialiasing. | `true` |
+| **camera** | A manual camera to be used by the renderer. | |
+| **clearColor** | The color the renderer will use to clear the canvas. | `#000000` |
+| **context** | This can be used to attach the renderer to an existing [RenderingContext](https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext) | |
+| **depth** | Whether the drawing buffer has a [depth buffer](https://en.wikipedia.org/wiki/Z-buffering) of at least 16 bits. | `true` |
+| **disableRender** | Disable render on requestAnimationFrame, usefull for PostProcessing | `false` |
+| **failIfMajorPerformanceCaveat** | Whether the renderer creation will fail upon low performance is detected. See [WebGL spec](https://registry.khronos.org/webgl/specs/latest/1.0/#5.2) for details. | `false` |
+| **logarithmicDepthBuffer** | Whether to use a logarithmic depth buffer. It may be necessary to use this if dealing with huge differences in scale in a single scene. Note that this setting uses gl_FragDepth if available which disables the [Early Fragment Test](https://www.khronos.org/opengl/wiki/Early_Fragment_Test) optimization and can cause a decrease in performance. | `false` |
+| **outputColorSpace** | Defines the output encoding | `LinearEncoding` |
+| **powerPreference** | Provides a hint to the user agent indicating what configuration of GPU is suitable for this WebGL context. Can be "high-performance", "low-power" or "default". | `default` |
+| **precision** | Shader precision. Can be "highp", "mediump" or "lowp". | "highp" if supported by the device |
+| **premultipliedAlpha** | Whether the renderer will assume that colors have [premultiplied alpha](https://en.wikipedia.org/wiki/Glossary_of_computer_graphics#premultiplied_alpha). | `true` |
+| **preserveDrawingBuffer** | Whether to preserve the buffers until manually cleared or overwritten.. | `false` |
+| **shadows** | Enable shadows in the renderer | `false` |
+| **shadowMapType** | Set the shadow map type | `PCFSoftShadowMap` |
+| **stencil** | Whether the drawing buffer has a [stencil buffer](https://en.wikipedia.org/wiki/Stencil_buffer) of at least 8 bits. | `true` |
+| **toneMapping** | Defines the tone mapping exposure used by the renderer. | `NoToneMapping` |
+| **toneMappingExposure** | Exposure level of tone mapping. | `1` |
+| **useLegacyLights** | Whether to use the legacy lighting mode or not | `true` |
+| **windowSize** | Whether to use the window size as the canvas size or the parent element. | `false` |
+
+### Defaults
+
+Tres tries to be as little opinionated as possible. That's why it doesn't set almost any default value for the `TresCanvas` component. It uses the defaults from [three.js](https://threejs.org/). The only exception is the `antialias` prop. It's set to `true` by default.
+
+## Exposed public properties
+
+| Property | Description |
+| ---- | ---- |
+| context | see [useTresContext](composables#usetrescontext) |

+ 2 - 2
docs/examples/load-models.md

@@ -12,7 +12,7 @@ There are several ways to load models on TresJS:
 
 
 ## Using `useLoader`
 ## Using `useLoader`
 
 
-The `useLoader` composable allows you to pass any type of Three.js loader and a URL to load the resource from. It returns a `Promise` with the loaded resource.
+The `useLoader` composable allows you to pass any type of three.js loader and a URL to load the resource from. It returns a `Promise` with the loaded resource.
 
 
 For a detailed explanation of how to use `useLoader`, check out the [useLoader](/api/composables#useloader) documentation.
 For a detailed explanation of how to use `useLoader`, check out the [useLoader](/api/composables#useloader) documentation.
 
 
@@ -33,7 +33,7 @@ Then you can pass the model scene to a TresJS [`primitive`](/advanced/primitive)
 </TresCanvas>
 </TresCanvas>
 ```
 ```
 
 
-> The `<primitive />` component is not a standalone component in the Tres source code. Instead, it's a part of the Tres core functionality. When you use `<primitive>`, it is translated to a `createElement` call, which creates the appropriate Three.js object based on the provided "object" prop.
+> The `<primitive />` component is not a standalone component in the Tres source code. Instead, it's a part of the Tres core functionality. When you use `<primitive>`, it is translated to a `createElement` call, which creates the appropriate three.js object based on the provided "object" prop.
 
 
 Notice in the example above that we are using the `Suspense` component to wrap the `TresCanvas` component. This is because `useLoader` returns a `Promise` and we need to wait for it to resolve before rendering the scene.
 Notice in the example above that we are using the `Suspense` component to wrap the `TresCanvas` component. This is because `useLoader` returns a `Promise` and we need to wait for it to resolve before rendering the scene.
 
 

+ 1 - 1
docs/examples/load-textures.md

@@ -10,7 +10,7 @@ There are two ways of loading 3D textures in TresJS:
 
 
 ## Using `useLoader`
 ## Using `useLoader`
 
 
-The `useLoader` composable allows you to pass any type of Three.js loader and a URL to load the resource from. It returns a `Promise` with the loaded resource.
+The `useLoader` composable allows you to pass any type of three.js loader and a URL to load the resource from. It returns a `Promise` with the loaded resource.
 
 
 For a detailed explanation of how to use `useLoader`, check out the [useLoader](/api/composables#use-loader) documentation.
 For a detailed explanation of how to use `useLoader`, check out the [useLoader](/api/composables#use-loader) documentation.
 
 

+ 4 - 4
playground/src/components/TheExperience.vue

@@ -16,11 +16,11 @@ const gl = {
 
 
 const wireframe = ref(true)
 const wireframe = ref(true)
 
 
-const context = ref()
+const canvas = ref()
 
 
 watchEffect(() => {
 watchEffect(() => {
-  if (context.value) {
-    console.log({ context: context.value })
+  if (canvas.value) {
+    console.log(canvas.value.context)
   }
   }
 })
 })
 </script>
 </script>
@@ -34,7 +34,7 @@ watchEffect(() => {
   <pre>{{ wireframe }}</pre>
   <pre>{{ wireframe }}</pre>
   <TresCanvas
   <TresCanvas
     v-bind="gl"
     v-bind="gl"
-    ref="context"
+    ref="canvas"
   >
   >
     <TresPerspectiveCamera
     <TresPerspectiveCamera
       :position="[7, 7, 7]"
       :position="[7, 7, 7]"

Разлика између датотеке није приказан због своје велике величине
+ 216 - 246
pnpm-lock.yaml


+ 10 - 6
src/components/TresCanvas.vue

@@ -109,10 +109,14 @@ const dispose = (context: TresContext) => {
 
 
 const disableRender = computed(() => props.disableRender)
 const disableRender = computed(() => props.disableRender)
 
 
+const context = shallowRef<TresContext | null>(null)
+
+defineExpose({ context })
+
 onMounted(() => {
 onMounted(() => {
   const existingCanvas = canvas as Ref<HTMLCanvasElement>
   const existingCanvas = canvas as Ref<HTMLCanvasElement>
 
 
-  const context = useTresContextProvider({
+  context.value = useTresContextProvider({
     scene: scene.value,
     scene: scene.value,
     canvas: existingCanvas,
     canvas: existingCanvas,
     windowSize: props.windowSize,
     windowSize: props.windowSize,
@@ -120,11 +124,11 @@ onMounted(() => {
     rendererOptions: props,
     rendererOptions: props,
   })
   })
 
 
-  usePointerEventHandler({ scene: scene.value, contextParts: context })
+  usePointerEventHandler({ scene: scene.value, contextParts: context.value })
 
 
-  const { registerCamera, camera, cameras, deregisterCamera } = context
+  const { registerCamera, camera, cameras, deregisterCamera } = context.value
 
 
-  mountCustomRenderer(context)
+  mountCustomRenderer(context.value)
 
 
   const addDefaultCamera = () => {
   const addDefaultCamera = () => {
     const camera = new PerspectiveCamera(
     const camera = new PerspectiveCamera(
@@ -168,8 +172,8 @@ onMounted(() => {
     addDefaultCamera()
     addDefaultCamera()
   }
   }
 
 
-  if (import.meta.hot)
-    import.meta.hot.on('vite:afterUpdate', () => dispose(context))
+  if (import.meta.hot && context.value)
+    import.meta.hot.on('vite:afterUpdate', () => dispose(context.value as TresContext))
 })
 })
 </script>
 </script>
 
 

+ 2 - 0
src/composables/useRenderer/const.ts

@@ -2,6 +2,8 @@ import { ACESFilmicToneMapping, PCFSoftShadowMap, SRGBColorSpace } from 'three'
 
 
 export const rendererPresets = {
 export const rendererPresets = {
   realistic: {
   realistic: {
+    shadows: true,
+    physicallyCorrectLights: true,
     outputColorSpace: SRGBColorSpace,
     outputColorSpace: SRGBColorSpace,
     toneMapping: ACESFilmicToneMapping,
     toneMapping: ACESFilmicToneMapping,
     toneMappingExposure: 3,
     toneMappingExposure: 3,

+ 1 - 1
src/composables/useRenderer/index.ts

@@ -99,7 +99,7 @@ export interface UseRendererOptions extends TransformToMaybeRefOrGetter<WebGLRen
 }
 }
 
 
 /**
 /**
- * Reactive Three.js WebGLRenderer instance
+ * Reactive three.js WebGLRenderer instance
  *
  *
  * @param canvas
  * @param canvas
  * @param {UseRendererOptions} [options]
  * @param {UseRendererOptions} [options]

Неке датотеке нису приказане због велике количине промена