浏览代码

Merge pull request #181 from Tresjs/feature/177-v2-shaders-are-not-working-100

chore: added shader example to playground
Alvaro Saburido 2 年之前
父节点
当前提交
5d28fb7ab2

+ 0 - 1
package.json

@@ -90,7 +90,6 @@
     "vite": "^4.1.4",
     "vite-plugin-banner": "^0.7.0",
     "vite-plugin-dts": "2.1.0",
-    "vite-plugin-glsl": "^1.1.2",
     "vite-plugin-inspect": "^0.7.16",
     "vite-plugin-require-transform": "^1.0.9",
     "vite-svg-loader": "^4.0.0",

+ 5 - 0
playground/components.d.ts

@@ -12,9 +12,12 @@ declare module '@vue/runtime-core' {
     AkuAku: typeof import('./src/components/gltf/AkuAku.vue')['default']
     AnimatedModel: typeof import('./src/components/AnimatedModel.vue')['default']
     FBXModels: typeof import('./src/components/FBXModels.vue')['default']
+    PortalJourney: typeof import('./src/components/portal-journey/index.vue')['default']
     Responsiveness: typeof import('./src/components/Responsiveness.vue')['default']
     RouterLink: typeof import('vue-router')['RouterLink']
     RouterView: typeof import('vue-router')['RouterView']
+    ShadersExperiment: typeof import('./src/components/shaders-experiment/index.vue')['default']
+    'ShadersExperiment.vue': typeof import('./src/components/shadersExperiment.vue/index.vue')['default']
     Shapes: typeof import('./src/components/Shapes.vue')['default']
     TestSphere: typeof import('./src/components/TestSphere.vue')['default']
     Text3D: typeof import('./src/components/Text3D.vue')['default']
@@ -23,9 +26,11 @@ declare module '@vue/runtime-core' {
     TheEvents: typeof import('./src/components/TheEvents.vue')['default']
     TheExperience: typeof import('./src/components/TheExperience.vue')['default']
     TheExperiment: typeof import('./src/components/gltf/TheExperiment.vue')['default']
+    TheFireFlies: typeof import('./src/components/portal-journey/TheFireFlies.vue')['default']
     TheGizmos: typeof import('./src/components/TheGizmos.vue')['default']
     TheGroups: typeof import('./src/components/TheGroups.vue')['default']
     TheParticles: typeof import('./src/components/TheParticles.vue')['default']
+    ThePortal: typeof import('./src/components/portal-journey/ThePortal.vue')['default']
     TheSmallExperience: typeof import('./src/components/TheSmallExperience.vue')['default']
     VectorSetProps: typeof import('./src/components/VectorSetProps.vue')['default']
   }

+ 3 - 2
playground/package.json

@@ -16,10 +16,11 @@
   "devDependencies": {
     "@tresjs/cientos": "2.0.0-alpha.5",
     "@vitejs/plugin-vue": "^4.1.0",
-    "typescript": "^4.9.3",
+    "typescript": "^5.0.2",
     "unplugin-auto-import": "^0.15.2",
     "unplugin-vue-components": "^0.24.1",
-    "vite": "^4.2.0",
+    "vite": "^4.2.1",
+    "vite-plugin-glsl": "^1.1.2",
     "vue-tsc": "^1.2.0"
   }
 }

+ 23 - 9
playground/pnpm-lock.yaml

@@ -4,10 +4,11 @@ specifiers:
   '@tresjs/cientos': 2.0.0-alpha.5
   '@vitejs/plugin-vue': ^4.1.0
   three: ^0.150.1
-  typescript: ^4.9.3
+  typescript: ^5.0.2
   unplugin-auto-import: ^0.15.2
   unplugin-vue-components: ^0.24.1
-  vite: ^4.2.0
+  vite: ^4.2.1
+  vite-plugin-glsl: ^1.1.2
   vue: ^3.2.47
   vue-router: ^4.1.6
   vue-tsc: ^1.2.0
@@ -20,11 +21,12 @@ dependencies:
 devDependencies:
   '@tresjs/cientos': 2.0.0-alpha.5_three@0.150.1+vue@3.2.47
   '@vitejs/plugin-vue': 4.1.0_vite@4.2.1+vue@3.2.47
-  typescript: 4.9.5
+  typescript: 5.0.2
   unplugin-auto-import: 0.15.2
   unplugin-vue-components: 0.24.1_vue@3.2.47
   vite: 4.2.1
-  vue-tsc: 1.2.0_typescript@4.9.5
+  vite-plugin-glsl: 1.1.2_vite@4.2.1
+  vue-tsc: 1.2.0_typescript@5.0.2
 
 packages:
 
@@ -982,9 +984,9 @@ packages:
       is-number: 7.0.0
     dev: true
 
-  /typescript/4.9.5:
-    resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==}
-    engines: {node: '>=4.2.0'}
+  /typescript/5.0.2:
+    resolution: {integrity: sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==}
+    engines: {node: '>=12.20'}
     hasBin: true
     dev: true
 
@@ -1071,6 +1073,18 @@ packages:
       webpack-virtual-modules: 0.5.0
     dev: true
 
+  /vite-plugin-glsl/1.1.2_vite@4.2.1:
+    resolution: {integrity: sha512-zmXsfc1vn2MlYve9t3FAoWuhLyoCkNS1TuQL+TkXZL7tGmBjRErp10eNYxcse5tK9oUC5MyJpNc4ElpQnx8DoA==}
+    engines: {node: '>= 16.15.1', npm: '>= 8.11.0'}
+    peerDependencies:
+      vite: ^3.0.0 || ^4.0.0
+    dependencies:
+      '@rollup/pluginutils': 5.0.2
+      vite: 4.2.1
+    transitivePeerDependencies:
+      - rollup
+    dev: true
+
   /vite/4.2.1:
     resolution: {integrity: sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg==}
     engines: {node: ^14.18.0 || >=16.0.0}
@@ -1135,7 +1149,7 @@ packages:
       he: 1.2.0
     dev: true
 
-  /vue-tsc/1.2.0_typescript@4.9.5:
+  /vue-tsc/1.2.0_typescript@5.0.2:
     resolution: {integrity: sha512-rIlzqdrhyPYyLG9zxsVRa+JEseeS9s8F2BbVVVWRRsTZvJO2BbhLEb2HW3MY+DFma0378tnIqs+vfTzbcQtRFw==}
     hasBin: true
     peerDependencies:
@@ -1143,7 +1157,7 @@ packages:
     dependencies:
       '@volar/vue-language-core': 1.2.0
       '@volar/vue-typescript': 1.2.0
-      typescript: 4.9.5
+      typescript: 5.0.2
     dev: true
 
   /vue/3.2.47:

+ 6 - 4
playground/src/components/gltf/TheExperiment.vue

@@ -3,7 +3,6 @@ import { sRGBEncoding, BasicShadowMap, NoToneMapping } from 'three'
 import { TresCanvas } from '/@/'
 import { GLTFModel, OrbitControls } from '@tresjs/cientos'
 
-
 const state = reactive({
   clearColor: '#82DBC5',
   shadows: true,
@@ -17,12 +16,11 @@ const state = reactive({
 const akuAkuRef = ref(null)
 
 watchEffect(() => {
-  if(akuAkuRef.value) {
+  if (akuAkuRef.value) {
     const model = akuAkuRef.value.getModel().children[0]
     console.log('akuAkuRef', model)
   }
 })
-
 </script>
 <template>
   <TresCanvas v-bind="state">
@@ -31,7 +29,11 @@ watchEffect(() => {
     <TresAmbientLight :intensity="0.5" />
 
     <Suspense>
-        <GLTFModel ref="akuAkuRef" path="https://raw.githubusercontent.com/Tresjs/assets/main/models/gltf/aku-aku/AkuAku.gltf" draco />
+      <GLTFModel
+        ref="akuAkuRef"
+        path="https://raw.githubusercontent.com/Tresjs/assets/main/models/gltf/aku-aku/AkuAku.gltf"
+        draco
+      />
       <!--   <AkuAku /> -->
     </Suspense>
     <TresAxesHelper />

+ 43 - 0
playground/src/components/portal-journey/TheFireFlies.vue

@@ -0,0 +1,43 @@
+<script setup lang="ts">
+import { useRenderLoop } from '/@/'
+import { AdditiveBlending } from 'three'
+import FirefliesVertex from './shaders/fireflies/vertex.glsl'
+import FirefliesFragment from './shaders/fireflies/fragment.glsl'
+
+const shader = {
+  transparent: true,
+  blending: AdditiveBlending,
+  depthWrite: false,
+
+  vertexShader: FirefliesVertex,
+  fragmentShader: FirefliesFragment,
+  uniforms: {
+    uSize: { value: 100 },
+    uPixelRatio: { value: Math.min(window.devicePixelRatio, 2) },
+    uTime: { value: 0 },
+  },
+}
+
+const firefliesCount = 60
+const positionArray = new Float32Array(firefliesCount * 3)
+const scaleArray = new Float32Array(firefliesCount)
+
+for (let i = 0; i < firefliesCount; i++) {
+  positionArray[i * 3 + 0] = (Math.random() - 0.5) * 4
+  positionArray[i * 3 + 1] = Math.random() * 4
+  positionArray[i * 3 + 2] = (Math.random() - 0.5) * 4
+  scaleArray[i] = Math.random()
+}
+
+const { onLoop } = useRenderLoop()
+
+onLoop(({ elapsed }) => {
+  shader.uniforms.uTime.value = elapsed
+})
+</script>
+<template>
+  <TresPoints>
+    <TresBufferGeometry :position="[positionArray, 3]" :a-scale="[scaleArray, 1]" />
+    <TresShaderMaterial v-bind="shader" />
+  </TresPoints>
+</template>

+ 83 - 0
playground/src/components/portal-journey/ThePortal.vue

@@ -0,0 +1,83 @@
+<script setup lang="ts">
+import { sRGBEncoding, DoubleSide, MeshBasicMaterial, ShaderMaterial, Color, Mesh } from 'three'
+import { useRenderLoop, useTexture } from '/@/'
+import { useGLTF, useTweakPane } from '@tresjs/cientos'
+
+import PortalVertex from './shaders/portal/vertex.glsl'
+import PortalFragment from './shaders/portal/fragment.glsl'
+
+const experiment = {
+  portalColorStart: '#7030eb',
+  portalColorEnd: '#ddc0ff',
+}
+
+const { pane } = useTweakPane()
+
+const portalCtrls = pane.addFolder({ title: 'Portal' })
+portalCtrls
+  .addInput(experiment, 'portalColorStart', {
+    label: 'color start',
+    min: 0,
+    max: 1,
+    step: 0.01,
+  })
+  .on('change', ({ value }) => {
+    portalLightMaterial.uniforms.uColorStart.value.set(value)
+  })
+portalCtrls
+  .addInput(experiment, 'portalColorEnd', {
+    label: 'color end',
+    min: 0,
+    max: 1,
+    step: 0.01,
+  })
+  .on('change', ({ value }) => {
+    portalLightMaterial.uniforms.uColorEnd.value.set(value)
+  })
+
+const { scene: portal } = await useGLTF(
+  'https://raw.githubusercontent.com/Tresjs/assets/main/models/gltf/portal/portal.glb',
+  {
+    draco: true,
+  },
+)
+
+const bakedTexture = await useTexture([
+  'https://raw.githubusercontent.com/Tresjs/assets/main/models/gltf/portal/baked.jpg',
+])
+
+bakedTexture.flipY = false
+bakedTexture.encoding = sRGBEncoding
+
+// Baked material
+const bakedMaterial = new MeshBasicMaterial({
+  map: bakedTexture,
+  side: DoubleSide,
+})
+
+const portalLightMaterial = new ShaderMaterial({
+  uniforms: {
+    uTime: { value: 0 },
+    uColorStart: { value: new Color(experiment.portalColorStart) },
+    uColorEnd: { value: new Color(experiment.portalColorEnd) },
+  },
+  vertexShader: PortalVertex,
+  fragmentShader: PortalFragment,
+  side: DoubleSide,
+})
+
+const portalObj = portal
+const bakedMesh = portalObj.children.find(child => child.name === 'baked')
+;(bakedMesh as Mesh).material = bakedMaterial
+const portalCircle = portalObj.children.find(child => child.name === 'portalCircle')
+;(portalCircle as Mesh).material = portalLightMaterial
+
+const { onLoop } = useRenderLoop()
+
+onLoop(({ _delta, elapsed }) => {
+  portalLightMaterial.uniforms.uTime.value = elapsed
+})
+</script>
+<template>
+  <TresMesh v-bind="portal" />
+</template>

+ 25 - 0
playground/src/components/portal-journey/index.vue

@@ -0,0 +1,25 @@
+<script setup lang="ts">
+import { TresCanvas } from '/@/'
+import { OrbitControls } from '@tresjs/cientos'
+import ThePortal from './ThePortal.vue'
+import TheFireFlies from './TheFireFlies.vue'
+
+const gl = {
+  clearColor: '#202020',
+  shadows: true,
+  alpha: false,
+}
+</script>
+
+<template>
+  <TresCanvas v-bind="gl">
+    <OrbitControls />
+    <TresPerspectiveCamera :position="[5, 5, 5]" :fov="45" :aspect="1" :near="0.1" :far="1000" />
+    <TresFog :args="[gl.clearColor, 0.1, 75]" />
+    <Suspense>
+      <ThePortal />
+    </Suspense>
+    <TheFireFlies />
+    <TresAmbientLight :position="[10, 10, 10]" :intensity="1.5" color="#00ff00" />
+  </TresCanvas>
+</template>

+ 7 - 0
playground/src/components/portal-journey/shaders/fireflies/fragment.glsl

@@ -0,0 +1,7 @@
+void main()
+{
+  float distanceToCenter = distance(gl_PointCoord, vec2(0.5));
+  float strength = 0.05 / distanceToCenter - 0.1;
+
+  gl_FragColor = vec4(1.0, 1.0, 1.0, strength);
+}

+ 16 - 0
playground/src/components/portal-journey/shaders/fireflies/vertex.glsl

@@ -0,0 +1,16 @@
+uniform float uPixelRatio;
+uniform float uSize;
+uniform float uTime;
+attribute float aScale;
+
+void main()
+{
+    vec4 modelPosition = modelMatrix * vec4(position, 1.0);
+    modelPosition.y += sin(uTime + modelPosition.x * 100.0) * aScale * 0.2;
+    vec4 viewPosition = viewMatrix * modelPosition;
+    vec4 projectionPosition = projectionMatrix * viewPosition;
+
+    gl_Position = projectionPosition;
+    gl_PointSize = aScale * uSize * uPixelRatio;
+    gl_PointSize *= (1.0 / - viewPosition.z);
+}

+ 101 - 0
playground/src/components/portal-journey/shaders/portal/fragment.glsl

@@ -0,0 +1,101 @@
+varying vec2 vUv;
+uniform float uTime;
+uniform vec3 uColorStart;
+uniform vec3 uColorEnd;
+
+//	Classic Perlin 3D Noise 
+//	by Stefan Gustavson
+//
+vec4 permute(vec4 x){return mod(((x*34.0)+1.0)*x, 289.0);}
+vec4 taylorInvSqrt(vec4 r){return 1.79284291400159 - 0.85373472095314 * r;}
+vec3 fade(vec3 t) {return t*t*t*(t*(t*6.0-15.0)+10.0);}
+
+float cnoise(vec3 P){
+  vec3 Pi0 = floor(P); // Integer part for indexing
+  vec3 Pi1 = Pi0 + vec3(1.0); // Integer part + 1
+  Pi0 = mod(Pi0, 289.0);
+  Pi1 = mod(Pi1, 289.0);
+  vec3 Pf0 = fract(P); // Fractional part for interpolation
+  vec3 Pf1 = Pf0 - vec3(1.0); // Fractional part - 1.0
+  vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
+  vec4 iy = vec4(Pi0.yy, Pi1.yy);
+  vec4 iz0 = Pi0.zzzz;
+  vec4 iz1 = Pi1.zzzz;
+
+  vec4 ixy = permute(permute(ix) + iy);
+  vec4 ixy0 = permute(ixy + iz0);
+  vec4 ixy1 = permute(ixy + iz1);
+
+  vec4 gx0 = ixy0 / 7.0;
+  vec4 gy0 = fract(floor(gx0) / 7.0) - 0.5;
+  gx0 = fract(gx0);
+  vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0);
+  vec4 sz0 = step(gz0, vec4(0.0));
+  gx0 -= sz0 * (step(0.0, gx0) - 0.5);
+  gy0 -= sz0 * (step(0.0, gy0) - 0.5);
+
+  vec4 gx1 = ixy1 / 7.0;
+  vec4 gy1 = fract(floor(gx1) / 7.0) - 0.5;
+  gx1 = fract(gx1);
+  vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1);
+  vec4 sz1 = step(gz1, vec4(0.0));
+  gx1 -= sz1 * (step(0.0, gx1) - 0.5);
+  gy1 -= sz1 * (step(0.0, gy1) - 0.5);
+
+  vec3 g000 = vec3(gx0.x,gy0.x,gz0.x);
+  vec3 g100 = vec3(gx0.y,gy0.y,gz0.y);
+  vec3 g010 = vec3(gx0.z,gy0.z,gz0.z);
+  vec3 g110 = vec3(gx0.w,gy0.w,gz0.w);
+  vec3 g001 = vec3(gx1.x,gy1.x,gz1.x);
+  vec3 g101 = vec3(gx1.y,gy1.y,gz1.y);
+  vec3 g011 = vec3(gx1.z,gy1.z,gz1.z);
+  vec3 g111 = vec3(gx1.w,gy1.w,gz1.w);
+
+  vec4 norm0 = taylorInvSqrt(vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110)));
+  g000 *= norm0.x;
+  g010 *= norm0.y;
+  g100 *= norm0.z;
+  g110 *= norm0.w;
+  vec4 norm1 = taylorInvSqrt(vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111)));
+  g001 *= norm1.x;
+  g011 *= norm1.y;
+  g101 *= norm1.z;
+  g111 *= norm1.w;
+
+  float n000 = dot(g000, Pf0);
+  float n100 = dot(g100, vec3(Pf1.x, Pf0.yz));
+  float n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z));
+  float n110 = dot(g110, vec3(Pf1.xy, Pf0.z));
+  float n001 = dot(g001, vec3(Pf0.xy, Pf1.z));
+  float n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z));
+  float n011 = dot(g011, vec3(Pf0.x, Pf1.yz));
+  float n111 = dot(g111, Pf1);
+
+  vec3 fade_xyz = fade(Pf0);
+  vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z);
+  vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y);
+  float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); 
+  return 2.2 * n_xyz;
+}
+
+void main() 
+{
+    float speed = 0.1;
+    // Displace the UV coordinates by a noise value
+    vec2 displacedUv = vUv + cnoise(vec3(vUv* 5.0, uTime * speed));
+    // Get the color from the texture
+    float strength = cnoise(vec3(displacedUv * 5.0, uTime * speed * 2.0));
+
+    // Outer Glow
+
+    float outerGlow = distance(vUv, vec2(0.5)) * 5.0 - 1.4;
+    strength += outerGlow;
+
+    strength += step(- 0.2, strength) * 0.8;
+
+    strength = clamp(strength, 0.0, 1.0);
+
+    vec3 color = mix(uColorStart, uColorEnd, strength);
+
+    gl_FragColor = vec4(color, 1.0);
+}

+ 11 - 0
playground/src/components/portal-journey/shaders/portal/vertex.glsl

@@ -0,0 +1,11 @@
+varying vec2 vUv;
+
+void main() 
+{
+    vec4 modelPosition = modelMatrix * vec4(position, 1.0);
+    vec4 viewPosition = viewMatrix * modelPosition;
+    vec4 projectionPosition = projectionMatrix * viewPosition;
+
+    gl_Position = projectionPosition;
+    vUv = uv;
+}

+ 48 - 0
playground/src/components/shaders-experiment/index.vue

@@ -0,0 +1,48 @@
+<script setup lang="ts">
+import { BasicShadowMap, sRGBEncoding, NoToneMapping, Vector2 } from 'three'
+import { TresCanvas, TresInstance, useRenderLoop } from '@tresjs/core'
+import { OrbitControls } from '@tresjs/cientos'
+import vertexShader from './shaders/vertex.glsl'
+import fragmentShader from './shaders/fragment.glsl'
+import { ShallowRef } from 'vue'
+
+const gl = {
+  clearColor: '#4f4f4f',
+  shadows: true,
+  alpha: false,
+  shadowMapType: BasicShadowMap,
+  outputEncoding: sRGBEncoding,
+  toneMapping: NoToneMapping,
+}
+
+const blobRef: ShallowRef<TresInstance | null> = shallowRef(null)
+
+const uniforms = {
+  uTime: { value: 0 },
+  uAmplitude: { value: new Vector2(0.1, 0.1) },
+  uFrequency: { value: new Vector2(20, 5) },
+}
+
+const { onLoop } = useRenderLoop()
+onLoop(({ elapsed }) => {
+  if (blobRef.value) {
+    blobRef.value.material.uniforms.uTime.value = elapsed
+  }
+})
+</script>
+
+<template>
+  <TresCanvas v-bind="gl">
+    <OrbitControls />
+    <TresPerspectiveCamera :position="[11, 11, 11]" />
+    <TresMesh ref="blobRef" :position="[0, 4, 0]">
+      <TresSphereGeometry :args="[2, 32, 32]" />
+      <TresShaderMaterial :vertex-shader="vertexShader" :fragment-shader="fragmentShader" :uniforms="uniforms" />
+    </TresMesh>
+    <TresMesh :rotation="[-Math.PI / 2, 0, 0]">
+      <TresPlaneGeometry :args="[10, 10, 10, 10]" />
+      <TresMeshBasicMaterial color="#444" />
+    </TresMesh>
+    <TresAmbientLight :intensity="1" />
+  </TresCanvas>
+</template>

+ 6 - 0
playground/src/components/shaders-experiment/shaders/fragment.glsl

@@ -0,0 +1,6 @@
+precision mediump float;
+varying vec2 vUv;
+
+void main() {
+    gl_FragColor = vec4(1.0, vUv.y, 0.5, 1.0);
+}

+ 15 - 0
playground/src/components/shaders-experiment/shaders/vertex.glsl

@@ -0,0 +1,15 @@
+uniform vec2 uAmplitude;
+uniform vec2 uFrequency;
+uniform float uTime;
+
+varying vec2 vUv;
+
+void main() {
+    vec4 modelPosition = modelMatrix * vec4(position, 1.0);
+    modelPosition.y += sin(modelPosition.x * uFrequency.x - uTime) * uAmplitude.x;
+    modelPosition.x += cos(modelPosition.y * uFrequency.y - uTime) * uAmplitude.y;
+
+    vec4 viewPosition = viewMatrix * modelPosition;
+    gl_Position = projectionMatrix * viewPosition;
+    vUv = uv;
+}

+ 6 - 8
playground/src/pages/index.vue

@@ -1,9 +1,7 @@
-<script setup lang="ts">
-
-</script>
+<script setup lang="ts"></script>
 <template>
-    <router-link to="/shapes">Shapes</router-link>
-    <Suspense>
-        <TheBasic />
-    </Suspense>
-</template>
+  <router-link to="/shapes">Shapes</router-link>
+  <Suspense>
+    <PortalJourney />
+  </Suspense>
+</template>

+ 1 - 1
playground/src/style.css

@@ -8,4 +8,4 @@ body {
 #app {
   height: 100%;
   width: 100%;
-}
+}

+ 20 - 16
playground/vite.config.ts

@@ -3,28 +3,32 @@ import vue from '@vitejs/plugin-vue'
 import { resolve } from 'pathe'
 import AutoImport from 'unplugin-auto-import/vite'
 import Components from 'unplugin-vue-components/vite'
-
+import glsl from 'vite-plugin-glsl'
 // https://vitejs.dev/config/
 export default defineConfig({
-  plugins: [vue({
-    template: {
-      compilerOptions: {
-        isCustomElement: tag => tag.startsWith('Tres') && tag !== 'TresCanvas',
+  plugins: [
+    glsl(),
+    vue({
+      template: {
+        compilerOptions: {
+          isCustomElement: tag => tag.startsWith('Tres') && tag !== 'TresCanvas',
+        },
       },
-    },
-  }),
-  AutoImport({
-    dts: true,
-    eslintrc: {
-      enabled: true, // <-- this
-    },
-    imports: ['vue'],
-  }),
-  Components({ /* options */ }),],
+    }),
+    AutoImport({
+      dts: true,
+      eslintrc: {
+        enabled: true, // <-- this
+      },
+      imports: ['vue'],
+    }),
+    Components({
+      /* options */
+    }),
+  ],
   resolve: {
     alias: {
       '/@': resolve(__dirname, '../src'),
-      
     },
     dedupe: ['@tresjs/core', 'three'],
   },

+ 18 - 1
pnpm-lock.yaml

@@ -51,7 +51,7 @@ importers:
       '@release-it/conventional-changelog': 5.1.1_release-it@15.9.1
       '@stackblitz/sdk': 1.8.2
       '@tresjs/cientos': 2.0.0-alpha.5_three@0.150.1
-      '@types/three': 0.149.0
+      '@types/three': 0.150.0
       '@typescript-eslint/eslint-plugin': 5.56.0_cnkxirszkzb4o6ts7gbclno24e
       '@typescript-eslint/parser': 5.56.0_eslint@8.36.0
       '@vitejs/plugin-vue': 4.0.0_vite@4.1.4
@@ -1235,12 +1235,25 @@ packages:
     resolution: {integrity: sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==}
     dev: true
 
+  /@types/stats.js/0.17.0:
+    resolution: {integrity: sha512-9w+a7bR8PeB0dCT/HBULU2fMqf6BAzvKbxFboYhmDtDkKPiyXYbjoe2auwsXlEFI7CFNMF1dCv3dFH5Poy9R1w==}
+    dev: true
+
   /@types/three/0.149.0:
     resolution: {integrity: sha512-fgNBm9LWc65ER/W0cvoXdC0iMy7Ke9e2CONmEr6Jt8sDSY3sw4DgOubZfmdZ747dkPhbQrgRQAWwDEr2S/7IEg==}
     dependencies:
       '@types/webxr': 0.5.1
     dev: true
 
+  /@types/three/0.150.0:
+    resolution: {integrity: sha512-AGhnz/pfV9lajfPMrzRyP/nySpZYfpoXdayGk0Tiwkzc6hsWOCkz/Q696Muxn9HV2EkQJ3u8g/dDt7jcP5Tecg==}
+    dependencies:
+      '@types/stats.js': 0.17.0
+      '@types/webxr': 0.5.1
+      fflate: 0.6.10
+      lil-gui: 0.17.0
+    dev: true
+
   /@types/web-bluetooth/0.0.16:
     resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==}
 
@@ -4504,6 +4517,10 @@ packages:
       type-check: 0.4.0
     dev: true
 
+  /lil-gui/0.17.0:
+    resolution: {integrity: sha512-MVBHmgY+uEbmJNApAaPbtvNh1RCAeMnKym82SBjtp5rODTYKWtM+MXHCifLe2H2Ti1HuBGBtK/5SyG4ShQ3pUQ==}
+    dev: true
+
   /lines-and-columns/1.2.4:
     resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
     dev: true

+ 4 - 6
src/core/nodeOps.ts

@@ -119,7 +119,6 @@ export const nodeOps: RendererOptions<TresObject, TresObject> = {
   },
   patchProp(node, prop, _prevValue, nextValue) {
     if (node) {
-      
       let root = node
       let key = prop
       const camelKey = kebabToCamel(key)
@@ -129,13 +128,12 @@ export const nodeOps: RendererOptions<TresObject, TresObject> = {
         node.parent = scene as TresObject
       }
 
-      if(root.type === 'BufferGeometry') {
-        const chain = key.split('-')
-        key = chain.pop() as string
+      if (root.type === 'BufferGeometry') {
         root.setAttribute(
-          kebabToCamel(key), 
-          new BufferAttribute(...(nextValue as ConstructorParameters<typeof BufferAttribute>))
+          kebabToCamel(key),
+          new BufferAttribute(...(nextValue as ConstructorParameters<typeof BufferAttribute>)),
         )
+        return
       }
 
       // Traverse pierced props (e.g. foo-bar=value => foo.bar = value)