1
0
Эх сурвалжийг харах

feat(cientos): baseline for Environment abstraction

alvarosabu 2 жил өмнө
parent
commit
4a7ce990e7

+ 73 - 0
packages/cientos/src/core/useEnvironment/component.ts

@@ -0,0 +1,73 @@
+/* import { useLoader } from '../../../../tres/src/core/useLoader' */
+import { useLoader } from '@tresjs/core'
+import { EnvironmentPresetsType } from './const'
+import {
+  CubeReflectionMapping,
+  CubeTexture,
+  CubeTextureLoader,
+  EquirectangularReflectionMapping,
+  LinearEncoding,
+  sRGBEncoding,
+  Texture,
+  TextureEncoding,
+} from 'three'
+import { defineComponent, PropType } from 'vue'
+
+import { useCientos } from '../useCientos'
+import { RGBELoader } from 'three-stdlib'
+
+export const Environment = defineComponent({
+  name: 'Environment',
+  props: {
+    background: {
+      type: Boolean,
+      default: false,
+    },
+    blur: {
+      type: Number,
+      default: 0,
+    },
+    files: {
+      type: [String, Array],
+      required: true,
+    },
+    encoding: Object as PropType<TextureEncoding>,
+    path: {
+      type: String,
+      default: '/',
+    },
+    preset: Object as PropType<EnvironmentPresetsType>,
+  },
+  async setup(props, { expose }) {
+    const { state } = useCientos()
+    let texture: Texture | CubeTexture | null = null
+    const isCubeMap = Array.isArray(props.files)
+
+    expose({ getTexture: () => texture })
+    const loader = isCubeMap ? CubeTextureLoader : RGBELoader
+
+    const result = await useLoader(loader, isCubeMap ? [props.files] : props.files, (loader: any) => {
+      /* if (props.path) loader.setPath(props.path) */
+      if (props.encoding) loader.encoding = props.encoding
+    })
+
+    texture = isCubeMap ? result[0] : result
+
+    if (texture) {
+      texture.mapping = isCubeMap ? CubeReflectionMapping : EquirectangularReflectionMapping
+      texture.encoding = props.encoding ?? isCubeMap ? sRGBEncoding : LinearEncoding
+    }
+
+    if (props.background && state.scene) {
+      state.scene.environment = texture
+      state.scene.background = texture
+
+      if (props.blur) {
+        state.scene.backgroundBlurriness = props.blur | 0
+      }
+    }
+    return () => {
+      texture
+    }
+  },
+})

+ 5 - 0
packages/cientos/src/core/useEnvironment/const.ts

@@ -0,0 +1,5 @@
+export const environmentPresets = {
+  sunset: 'venice/venice_sunset_1k.hdr',
+}
+
+export type EnvironmentPresetsType = keyof typeof environmentPresets

+ 3 - 0
packages/cientos/src/core/useEnvironment/index.ts

@@ -0,0 +1,3 @@
+export async function useEnvironment(): Promise<null> {
+  return null
+}

+ 3 - 0
packages/cientos/src/index.ts

@@ -18,9 +18,11 @@ import Tetrahedron from './core/Tetrahedron.vue'
 import Icosahedron from './core/Icosahedron.vue'
 import Octahedron from './core/Octahedron.vue'
 import Dodecahedron from './core/Dodecahedron.vue'
+import { Environment } from './core/useEnvironment/component'
 
 export * from './core/useGLTF'
 export * from './core/useFBX'
+export * from './core/useEnvironment'
 export * from './types'
 export {
   OrbitControls,
@@ -43,4 +45,5 @@ export {
   Octahedron,
   Dodecahedron,
   useAnimations,
+  Environment,
 }

+ 2 - 2
packages/tres/src/App.vue

@@ -1,12 +1,12 @@
 <script setup lang="ts">
 import { useTweakPane } from '@tresjs/cientos'
-import TheEvents from '/@/components/TheEvents.vue'
+import TheEnvironment from '/@/components/TheEnvironment.vue'
 
 useTweakPane()
 </script>
 
 <template>
   <Suspense>
-    <TheEvents />
+    <TheEnvironment />
   </Suspense>
 </template>

+ 127 - 0
packages/tres/src/components/TheEnvironment.vue

@@ -0,0 +1,127 @@
+<script setup lang="ts">
+import {
+  sRGBEncoding,
+  LinearEncoding,
+  BasicShadowMap,
+  PCFShadowMap,
+  PCFSoftShadowMap,
+  VSMShadowMap,
+  NoToneMapping,
+  LinearToneMapping,
+  ReinhardToneMapping,
+  CineonToneMapping,
+  ACESFilmicToneMapping,
+  CustomToneMapping,
+} from 'three'
+import { reactive, ref, shallowRef, watch } from 'vue'
+import { OrbitControls, useTweakPane, TransformControls, Environment } from '../../../cientos/src'
+import { TresCanvas } from '../core/useRenderer/component'
+/* import { OrbitControls, GLTFModel } from '@tresjs/cientos' */
+
+const state = reactive({
+  shadows: true,
+  alpha: true,
+  physicallyCorrectLights: true,
+  shadowMapType: BasicShadowMap,
+  outputEncoding: sRGBEncoding,
+  toneMapping: NoToneMapping,
+})
+
+const sphereRef = ref()
+
+const { pane } = useTweakPane()
+
+const environmentFiles = [
+  'https://raw.githubusercontent.com/Tresjs/assets/main/textures/environmentMap/px.jpg',
+  'https://raw.githubusercontent.com/Tresjs/assets/main/textures/environmentMap/nx.jpg',
+  'https://raw.githubusercontent.com/Tresjs/assets/main/textures/environmentMap/py.jpg',
+  'https://raw.githubusercontent.com/Tresjs/assets/main/textures/environmentMap/ny.jpg',
+  'https://raw.githubusercontent.com/Tresjs/assets/main/textures/environmentMap/pz.jpg',
+  'https://raw.githubusercontent.com/Tresjs/assets/main/textures/environmentMap/nz.jpg',
+]
+
+let envMap = null
+
+const environmentTexture = shallowRef()
+
+watch(environmentTexture, ({ getTexture }) => {
+  envMap = getTexture()
+})
+
+pane.addInput(state, 'shadows', {
+  label: 'Shadows',
+})
+pane.addInput(state, 'physicallyCorrectLights', {
+  label: 'physicallyCorrectLights',
+})
+
+pane
+  .addBlade({
+    view: 'list',
+    label: 'outputEncoding',
+    options: [
+      { text: 'sRGBEncoding', value: sRGBEncoding },
+      { text: 'LinearEncoding', value: LinearEncoding },
+    ],
+    value: sRGBEncoding,
+  })
+  .on('change', ev => {
+    state.outputEncoding = ev.value
+  })
+
+pane
+  .addBlade({
+    view: 'list',
+    label: 'ShadowMap Type',
+    options: [
+      { text: 'BasicShadowMap', value: BasicShadowMap },
+      { text: 'PCFShadowMap', value: PCFShadowMap },
+      { text: 'PCFSoftShadowMap', value: PCFSoftShadowMap },
+      { text: 'VSMShadowMap', value: VSMShadowMap },
+    ],
+    value: BasicShadowMap,
+  })
+  .on('change', ev => {
+    state.shadowMapType = ev.value
+  })
+
+pane
+  .addBlade({
+    view: 'list',
+    label: 'toneMapping',
+    options: [
+      { text: 'NoToneMapping', value: NoToneMapping },
+      { text: 'LinearToneMapping', value: LinearToneMapping },
+      { text: 'ReinhardToneMapping', value: ReinhardToneMapping },
+      { text: 'CineonToneMapping', value: CineonToneMapping },
+      { text: 'ACESFilmicToneMapping', value: ACESFilmicToneMapping },
+      { text: 'CustomToneMapping', value: CustomToneMapping },
+    ],
+    value: NoToneMapping,
+  })
+  .on('change', ev => {
+    console.log(ev.value)
+    state.toneMapping = ev.value
+  })
+</script>
+<template>
+  <TresCanvas v-bind="state">
+    <TresPerspectiveCamera :position="[8, 8, 8]" :fov="45" :near="0.1" :far="1000" :look-at="[-8, 3, -3]" />
+    <OrbitControls make-default />
+    <TresScene>
+      <Environment ref="environmentTexture" background :files="environmentFiles" />
+      <TresAmbientLight :intensity="0.5" />
+
+      <TresMesh ref="sphereRef" :position="[0, 4, 0]" cast-shadow>
+        <TresSphereGeometry />
+        <TresMeshStandardMaterial color="#FBB03B" :map="envMap" :metalness="1" :roughness="0" />
+      </TresMesh>
+      <TresDirectionalLight :position="[0, 8, 4]" :intensity="0.7" cast-shadow />
+      <TresMesh :rotation="[-Math.PI / 2, 0, 0]" receive-shadow>
+        <TresPlaneGeometry :args="[10, 10, 10, 10]" />
+        <TresMeshToonMaterial />
+      </TresMesh>
+      <TresDirectionalLight :position="[0, 2, 4]" :intensity="1" cast-shadow />
+    </TresScene>
+  </TresCanvas>
+</template>