Browse Source

feat(core): added camel keys to set attributes

Alvaro 2 years ago
parent
commit
fd603802a0

+ 85 - 0
packages/tres/src/components/TheParticles.vue

@@ -0,0 +1,85 @@
+<script setup lang="ts">
+import { reactive } from 'vue'
+import { OrbitControls } from '@tresjs/cientos/src'
+import { TresCanvas } from '../core/useRenderer/component'
+import { AdditiveBlending } from 'three'
+import { useRenderLoop } from '../core/useRenderLoop'
+/* import { OrbitControls, GLTFModel } from '@tresjs/cientos' */
+
+const state = reactive({
+  clearColor: 'teal',
+  shadows: true,
+  alpha: false,
+  physicallyCorrectLights: true,
+})
+
+const shader = {
+  transparent: true,
+  blending: AdditiveBlending,
+  depthWrite: false,
+
+  vertexShader: `
+  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);
+  }
+  `,
+  fragmentShader: `
+  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);
+    }
+  `,
+  uniforms: {
+    uSize: { value: 100 },
+    uPixelRatio: { value: Math.min(window.devicePixelRatio, 2) },
+    uTime: { value: 0 },
+  },
+}
+
+const firefliesCount = 30
+const positionArray = new Float32Array(firefliesCount * 3)
+const scaleArray = new Float32Array(firefliesCount)
+
+for (let i = 0; i < firefliesCount; i++) {
+  positionArray[i * 3 + 0] = Math.random() * 4
+  positionArray[i * 3 + 1] = Math.random() * 4
+  positionArray[i * 3 + 2] = Math.random() * 4
+  scaleArray[i] = Math.random()
+}
+
+const { onLoop } = useRenderLoop()
+
+onLoop(({ elapsed }) => {
+  shader.uniforms.uTime.value = elapsed
+})
+</script>
+<template>
+  <TresCanvas v-bind="state">
+    <TresPerspectiveCamera :position="[5, 5, 5]" :fov="45" :near="0.1" :far="1000" :look-at="[-8, 3, -3]" />
+    <TresScene>
+      <OrbitControls />
+      <TresAmbientLight :intensity="0.5" />
+      <TresPoints>
+        <TresBufferGeometry :position="[positionArray, 3]" :a-scale="[scaleArray, 1]" />
+        <TresShaderMaterial v-bind="shader" />
+      </TresPoints>
+      <TresDirectionalLight :position="[0, 2, 4]" :intensity="1" cast-shadow />
+    </TresScene>
+  </TresCanvas>
+</template>

+ 16 - 2
packages/tres/src/core/useInstanceCreator/index.ts

@@ -1,6 +1,6 @@
 /* eslint-disable new-cap */
 /* eslint-disable @typescript-eslint/no-empty-function */
-import { FogBase, OrthographicCamera, PerspectiveCamera, Scene } from 'three'
+import { BufferAttribute, FogBase, OrthographicCamera, PerspectiveCamera, Scene } from 'three'
 import { defineComponent, inject, Ref } from 'vue'
 import { isArray, isDefined, isFunction } from '@alvarosabu/utils'
 import { normalizeVectorFlexibleParam } from '/@/utils/normalize'
@@ -13,6 +13,16 @@ const VECTOR3_PROPS = ['rotation', 'scale', 'position']
 export function useInstanceCreator(prefix: string) {
   const { logMessage, logError } = useLogger()
 
+  function processSetAttributes(props: Record<string, any>, instance: TresInstance) {
+    if (!isDefined(props)) return
+    if (!isDefined(instance)) return
+
+    Object.entries(props).forEach(([key, value]) => {
+      const camelKey = key.replace(/(-\w)/g, m => m[1].toUpperCase())
+      instance.setAttribute(camelKey, new BufferAttribute(...value))
+    })
+  }
+
   function processProps(props: Record<string, any>, instance: TresInstance) {
     if (!isDefined(props)) return
     if (!isDefined(instance)) return
@@ -91,7 +101,11 @@ export function useInstanceCreator(prefix: string) {
       // check if props is defined on the vnode
       if (vnode?.props) {
         // if props is defined, process the props and pass the internalInstance to update its properties
-        processProps(vnode.props, internalInstance)
+        if (vNodeType === 'BufferGeometry') {
+          processSetAttributes(vnode.props, internalInstance)
+        } else {
+          processProps(vnode.props, internalInstance)
+        }
       }
 
       return internalInstance