alvarosabu 1 год назад
Родитель
Сommit
0555e5d08d

+ 2 - 0
playground/components.d.ts

@@ -16,6 +16,7 @@ declare module 'vue' {
     Box: typeof import('./src/components/Box.vue')['default']
     CameraOperator: typeof import('./src/components/CameraOperator.vue')['default']
     Cameras: typeof import('./src/components/Cameras.vue')['default']
+    Component: typeof import('./src/components/useFBO/component.vue')['default']
     copy: typeof import('./src/components/TheSphere copy.vue')['default']
     DanielTest: typeof import('./src/components/DanielTest.vue')['default']
     DebugUI: typeof import('./src/components/DebugUI.vue')['default']
@@ -23,6 +24,7 @@ declare module 'vue' {
     DirectiveSubComponent: typeof import('./src/components/DirectiveSubComponent.vue')['default']
     DynamicModel: typeof import('./src/components/DynamicModel.vue')['default']
     EventsPropogation: typeof import('./src/components/EventsPropogation.vue')['default']
+    FBOCube: typeof import('./src/components/FBOCube.vue')['default']
     FBXModels: typeof import('./src/components/FBXModels.vue')['default']
     Gltf: typeof import('./src/components/gltf/index.vue')['default']
     GraphPane: typeof import('./src/components/GraphPane.vue')['default']

+ 8 - 0
playground/src/components/AnimatedObjectUseUpdate.vue

@@ -26,6 +26,14 @@ watchEffect(() => {
   }
 })
 
+/* useUpdate(() => {
+  console.count('update loop 1')
+})
+
+useUpdate(() => {
+  console.count('update loop 2')
+}) */
+
 /* useUpdate(() => {
   console.count('before renderer')
 }, -1)

+ 22 - 0
playground/src/components/FBOCube.vue

@@ -0,0 +1,22 @@
+<script setup lang="ts">
+import { useFBO } from '../composables/useFBO'
+
+const fboTarget = useFBO({
+  depth: true,
+  width: 512,
+  height: 512,
+  settings: {
+    samples: 1,
+  },
+})
+</script>
+
+<template>
+  <TresMesh>
+    <TresBoxGeometry :args="[1, 1, 1]" />
+    <TresMeshBasicMaterial
+      :color="0xFF8833"
+      :map="fboTarget?.texture ?? null"
+    />
+  </TresMesh>
+</template>

+ 101 - 0
playground/src/composables/useFBO.ts

@@ -0,0 +1,101 @@
+import { useRender, useRenderLoop, useTresContext, useUpdate } from '@tresjs/core'
+import type { Camera, WebGLRenderTargetOptions } from 'three'
+import { DepthTexture, FloatType, HalfFloatType, LinearFilter, WebGLRenderTarget } from 'three'
+import type { Ref } from 'vue'
+import { isReactive, onBeforeUnmount, reactive, ref, toRefs, watchEffect } from 'vue'
+
+export interface FboOptions {
+  /*
+   * The width of the frame buffer object. Defaults to the width of the canvas.
+   *
+   * @type {number}
+   * @memberof FboProps
+   */
+  width?: number
+
+  /*
+   * The height of the frame buffer object. Defaults to the height of the canvas.
+   *
+   * @type {number}
+   * @memberof FboProps
+   */
+  height?: number
+
+  /*
+   * If set, the scene depth will be rendered into buffer.depthTexture.
+   *
+   * @default false
+   * @type {boolean}
+   * @memberof FboProps
+   */
+  depth?: boolean
+
+  /*
+   * Additional settings for the render target.
+   * See https://threejs.org/docs/#api/en/renderers/WebGLRenderTarget for more information.
+   *
+   * @default {}
+   * @type {WebGLRenderTargetOptions}
+   * @memberof FboProps
+   */
+  settings?: WebGLRenderTargetOptions
+}
+
+export function useFBO(options: FboOptions) {
+  const target: Ref<WebGLRenderTarget | null> = ref(null)
+
+  const { height, width, settings, depth } = isReactive(options) ? toRefs(options) : toRefs(reactive(options))
+
+  const { onLoop } = useRenderLoop()
+  const { camera, renderer, scene, sizes } = useTresContext()
+
+  watchEffect(() => {
+    target.value?.dispose()
+
+    target.value = new WebGLRenderTarget(width?.value || sizes.width.value, height?.value || sizes.height.value, {
+      minFilter: LinearFilter,
+      magFilter: LinearFilter,
+      type: HalfFloatType,
+      ...settings?.value,
+    })
+
+    if (depth?.value) {
+      target.value.depthTexture = new DepthTexture(
+        width?.value || sizes.width.value,
+        height?.value || sizes.height.value,
+        FloatType,
+      )
+    }
+  })
+
+  useUpdate(() => {
+    renderer.value.setRenderTarget(target.value)
+    renderer.value.clear()
+    renderer.value.render(scene.value, camera.value as Camera)
+  })
+
+  useUpdate(() => {
+    renderer.value.setRenderTarget(null)
+  }, 2)
+
+  /* onLoop(() => {
+    renderer.value.setRenderTarget(target.value)
+    renderer.value.clear()
+    renderer.value.render(scene.value, camera.value as Camera)
+
+    renderer.value.setRenderTarget(null)
+  }) */
+  /* useRender(() => {
+    renderer.value.setRenderTarget(target.value)
+    renderer.value.clear()
+    renderer.value.render(scene.value, camera.value as Camera)
+
+    renderer.value.setRenderTarget(null)
+  }) */
+
+  onBeforeUnmount(() => {
+    target.value?.dispose()
+  })
+
+  return target
+}

+ 36 - 0
playground/src/pages/advanced/FBO.vue

@@ -0,0 +1,36 @@
+<script setup lang="ts">
+import { TresCanvas } from '@tresjs/core'
+import { BasicShadowMap, NoToneMapping, SRGBColorSpace } from 'three'
+
+import { OrbitControls } from '@tresjs/cientos'
+import { ref, shallowRef } from 'vue'
+import { TresLeches, useControls } from '@tresjs/leches'
+import Fbo from '../../components/useFBO/component.vue'
+import { useFbo } from '../../components/useFBO'
+import '@tresjs/leches/styles'
+
+const gl = {
+  clearColor: '#82DBC5',
+  shadows: true,
+  alpha: false,
+  shadowMapType: BasicShadowMap,
+  outputColorSpace: SRGBColorSpace,
+  toneMapping: NoToneMapping,
+}
+</script>
+
+<template>
+  <TresCanvas v-bind="gl">
+    <TresPerspectiveCamera :position="[3, 3, 3]" />
+    <OrbitControls />
+    <TresGridHelper />
+    <!--  <Fbo
+      ref="fboRef"
+      v-bind="state"
+    /> -->
+
+    <FBOCube />
+    <AnimatedObjectUseUpdate />
+    <TresAmbientLight :intensity="1" />
+  </TresCanvas>
+</template>

+ 5 - 0
playground/src/router/routes/advanced.ts

@@ -9,4 +9,9 @@ export const advancedRoutes = [
     name: 'Take Over loop',
     component: () => import('../../pages/advanced/TakeOverLoop.vue'),
   },
+  {
+    path: '/advanced/fbo',
+    name: 'FBO',
+    component: () => import('../../pages/advanced/FBO.vue'),
+  },
 ]