Browse Source

feat(playground): add textures example

Alvaro 2 năm trước cách đây
mục cha
commit
4d08cf5827

+ 1 - 0
apps/playground/package.json

@@ -23,6 +23,7 @@
     "@astrojs/mdx": "^0.14.0",
     "@astrojs/vue": "^1.2.2",
     "astro": "^1.9.2",
+    "astro-seo": "^0.7.0",
     "vue": "^3.2.45"
   },
   "devDependencies": {

BIN
apps/playground/public/textures.png


+ 13 - 0
apps/playground/src/components/SuspenseWrapper.vue

@@ -0,0 +1,13 @@
+<script setup lang="ts">
+defineProps<{
+  component: any
+}>()
+
+/* import Textures from './Textures.vue' */
+</script>
+<template>
+  <pre>{{ component }}.</pre>
+  <Suspense>
+    <component :is="component.__name" />
+  </Suspense>
+</template>

+ 50 - 0
apps/playground/src/components/Textures.vue

@@ -0,0 +1,50 @@
+<script setup lang="ts">
+import { Ref, ref } from 'vue'
+
+import { useTexture, useRenderLoop } from '@tresjs/core'
+import { OrbitControls } from '@tresjs/cientos'
+import { TresInstance } from '@tresjs/core/dist/types'
+
+const pbrTexture = await useTexture({
+  map: 'https://raw.githubusercontent.com/Tresjs/assets/main/textures/black-rock/Rock035_2K_Displacement.jpg',
+  displacementMap:
+    'https://raw.githubusercontent.com/Tresjs/assets/main/textures/black-rock/Rock035_2K_Displacement.jpg',
+  roughnessMap: 'https://raw.githubusercontent.com/Tresjs/assets/main/textures/black-rock/Rock035_2K_Roughness.jpg',
+  normalMap: 'https://raw.githubusercontent.com/Tresjs/assets/main/textures/black-rock/Rock035_2K_NormalGL.jpg',
+  ambientOcclusion:
+    'https://raw.githubusercontent.com/Tresjs/assets/main/textures/black-rock/Rock035_2K_AmbientOcclusion.jpg',
+})
+
+const sphereRef: Ref<TresInstance | null> = ref(null)
+
+const { onLoop } = useRenderLoop()
+
+onLoop(({ delta }) => {
+  // I will run at every frame ~ 60FPS (depending of your monitor)
+  if (sphereRef.value) {
+    sphereRef.value.rotation.y = delta
+  }
+})
+</script>
+
+<template>
+  <TresCanvas
+    clear-color="#82DBC5"
+    shadows
+    alpha
+    window-size
+    power-preference="high-performance"
+    preserve-drawing-buffer
+    physically-correct-lights
+  >
+    <OrbitControls />
+    <TresPerspectiveCamera :position="[1, 2, 5]" :fov="45" :aspect="1" :near="0.1" :far="1000" />
+    <TresScene>
+      <TresMesh ref="sphereRef" :scale="1" cast-shadow>
+        <TresSphereGeometry :args="[1, 100, 100]" />
+        <TresMeshStandardMaterial v-bind="pbrTexture" displacement-scale="0.2" />
+      </TresMesh>
+      <TresDirectionalLight :position="[0, 2, 4]" :intensity="2" cast-shadow />
+    </TresScene>
+  </TresCanvas>
+</template>

+ 8 - 0
apps/playground/src/components/textures/Textures.vue

@@ -0,0 +1,8 @@
+<script setup lang="ts">
+import TheExperience from './TheExperience.vue'
+</script>
+<template>
+  <Suspense>
+    <TheExperience />
+  </Suspense>
+</template>

+ 62 - 0
apps/playground/src/components/textures/TheExperience.vue

@@ -0,0 +1,62 @@
+<script setup lang="ts">
+import { Ref, ref } from 'vue'
+
+import { useTexture, useRenderLoop } from '@tresjs/core'
+import { OrbitControls, Plane } from '@tresjs/cientos'
+import { TresInstance } from '@tresjs/core/dist/types'
+
+const pbrTexture = await useTexture({
+  map: 'https://raw.githubusercontent.com/Tresjs/assets/main/textures/black-rock/Rock035_2K_Displacement.jpg',
+  displacementMap:
+    'https://raw.githubusercontent.com/Tresjs/assets/main/textures/black-rock/Rock035_2K_Displacement.jpg',
+  roughnessMap: 'https://raw.githubusercontent.com/Tresjs/assets/main/textures/black-rock/Rock035_2K_Roughness.jpg',
+  normalMap: 'https://raw.githubusercontent.com/Tresjs/assets/main/textures/black-rock/Rock035_2K_NormalGL.jpg',
+  ambientOcclusion:
+    'https://raw.githubusercontent.com/Tresjs/assets/main/textures/black-rock/Rock035_2K_AmbientOcclusion.jpg',
+})
+
+const blackRock = await useTexture({
+  map: 'https://raw.githubusercontent.com/Tresjs/assets/main/textures/black-rock/Rock035_2K_Color.jpg',
+  displacementMap:
+    'https://raw.githubusercontent.com/Tresjs/assets/main/textures/black-rock/Rock035_2K_Displacement.jpg',
+  roughnessMap: 'https://raw.githubusercontent.com/Tresjs/assets/main/textures/black-rock/Rock035_2K_Roughness.jpg',
+  normalMap: 'https://raw.githubusercontent.com/Tresjs/assets/main/textures/black-rock/Rock035_2K_NormalGL.jpg',
+  ambientOcclusion:
+    'https://raw.githubusercontent.com/Tresjs/assets/main/textures/black-rock/Rock035_2K_AmbientOcclusion.jpg',
+})
+
+const sphereRef: Ref<TresInstance | null> = ref(null)
+
+const { onLoop } = useRenderLoop()
+
+onLoop(({ delta }) => {
+  // I will run at every frame ~ 60FPS (depending of your monitor)
+  if (sphereRef.value) {
+    sphereRef.value.rotation.y += delta
+  }
+})
+</script>
+
+<template>
+  <TresCanvas
+    clear-color="#82DBC5"
+    shadows
+    alpha
+    window-size
+    power-preference="high-performance"
+    preserve-drawing-buffer
+  >
+    <OrbitControls />
+    <TresPerspectiveCamera :position="[11, 11, 11]" :fov="45" :aspect="1" :near="0.1" :far="1000" />
+    <TresScene>
+      <TresMesh ref="sphereRef" :position="[0, 4, 0]" :scale="1" cast-shadow>
+        <TresSphereGeometry :args="[1, 500, 500]" />
+        <TresMeshStandardMaterial v-bind="blackRock" displacement-scale="0.2" />
+      </TresMesh>
+      <Plane :args="[10, 10, 500, 500]">
+        <TresMeshStandardMaterial v-bind="pbrTexture" displacement-scale="0.6" />
+      </Plane>
+      <TresDirectionalLight :position="[0, 2, 4]" :intensity="1" cast-shadow />
+    </TresScene>
+  </TresCanvas>
+</template>

+ 56 - 17
apps/playground/src/layouts/ExperimentLayout.astro

@@ -1,4 +1,5 @@
 ---
+import { SEO } from 'astro-seo'
 import '@kidonng/daisyui/index.css'
 
 const { frontmatter } = Astro.props
@@ -11,26 +12,64 @@ const { frontmatter } = Astro.props
     <meta name="viewport" content="width=device-width" />
     <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
     <meta name="generator" content={Astro.generator} />
+    <SEO
+      title={frontmatter.title}
+      description={frontmatter.description}
+      openGraph={{
+        basic: {
+          title: frontmatter.title,
+          type: 'website',
+          image: frontmatter.thumbnail,
+        },
+        image: {
+          alt: 'TresJS',
+        },
+      }}
+      twitter={{
+        creator: '@alvarosabu',
+      }}
+      extend={{
+        // extending the default link tags
+        link: [{ rel: 'icon', href: '/favicon.ico' }],
+        // extending the default meta tags
+        meta: [
+          {
+            name: 'twitter:image',
+            content: frontmatter.thumbnail,
+          },
+          { name: 'twitter:title', content: frontmatter.title },
+          { name: 'twitter:description', content: frontmatter.description },
+          { name: 'twitter:card', content: 'summary_large_image' },
+          { name: 'twitter:site', content: '@alvarosabu' },
+          { name: 'twitter:creator', content: '@alvarosabu' },
+          { name: 'og:title', content: frontmatter.title },
+          { name: 'og:description', content: frontmatter.description },
+          { name: 'og:image', content: frontmatter.thumbnail },
+          { name: 'og:url', content: frontmatter.url },
+          { name: 'og:site_name', content: 'TresJS' },
+        ],
+      }}
+    />
     <title>{frontmatter.title}</title>
   </head>
   <body>
     <slot />
+    <style is:global>
+      :root {
+        --accent: 124, 58, 237;
+        --accent-gradient: linear-gradient(45deg, rgb(var(--accent)), #da62c4 30%, white 60%);
+      }
+      html {
+        font-family: system-ui, sans-serif;
+        background-color: #f6f6f6;
+      }
+      body {
+        margin: 0;
+      }
+      code {
+        font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono,
+          Courier New, monospace;
+      }
+    </style>
   </body>
 </html>
-<style is:global>
-  :root {
-    --accent: 124, 58, 237;
-    --accent-gradient: linear-gradient(45deg, rgb(var(--accent)), #da62c4 30%, white 60%);
-  }
-  html {
-    font-family: system-ui, sans-serif;
-    background-color: #f6f6f6;
-  }
-  body {
-    margin: 0;
-  }
-  code {
-    font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New,
-      monospace;
-  }
-</style>

+ 76 - 31
apps/playground/src/layouts/Layout.astro

@@ -1,42 +1,87 @@
 ---
-import Header from '../components/Header.astro';
+import { SEO } from 'astro-seo'
+
+import Header from '../components/Header.astro'
 
 export interface Props {
-	title: string;
+  title: string
 }
 
-const { title } = Astro.props;
+const { title } = Astro.props
 
+const meta = {
+  description: 'Playground for TresJS experiments for Vue',
+  thumbnail: 'https://pbs.twimg.com/media/FjtkgAlXwAIF7a_?format=png&name=4096x4096',
+  url: 'https://playground.tresjs.org/',
+}
 ---
 
 <!DOCTYPE html>
 <html lang="en">
-	<head>
-		<meta charset="UTF-8" />
-		<meta name="viewport" content="width=device-width" />
-		<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
-		<meta name="generator" content={Astro.generator} />
-		<title>{title}</title>
-	</head>
-	<body>
-		<Header title={title} visible={Astro.url.pathname === '/'} />
-		<slot />
-	</body>
+  <head>
+    <meta charset="UTF-8" />
+    <meta name="viewport" content="width=device-width" />
+    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
+    <meta name="generator" content={Astro.generator} />
+    <title>{title}</title>
+    <SEO
+      title={title}
+      description={meta.description}
+      openGraph={{
+        basic: {
+          title: title,
+          type: 'website',
+          image: meta.thumbnail,
+        },
+        image: {
+          alt: 'TresJS',
+        },
+      }}
+      twitter={{
+        creator: '@alvarosabu',
+      }}
+      extend={{
+        // extending the default link tags
+        link: [{ rel: 'icon', href: '/favicon.ico' }],
+        // extending the default meta tags
+        meta: [
+          {
+            name: 'twitter:image',
+            content: meta.thumbnail,
+          },
+          { name: 'twitter:title', content: title },
+          { name: 'twitter:description', content: meta.description },
+          { name: 'twitter:card', content: 'summary_large_image' },
+          { name: 'twitter:site', content: '@alvarosabu' },
+          { name: 'twitter:creator', content: '@alvarosabu' },
+          { name: 'og:title', content: title },
+          { name: 'og:description', content: meta.description },
+          { name: 'og:image', content: meta.thumbnail },
+          { name: 'og:url', content: meta.url },
+          { name: 'og:site_name', content: 'TresJS' },
+        ],
+      }}
+    />
+  </head>
+  <body>
+    <Header title={title} visible={Astro.url.pathname === '/'} />
+    <slot />
+    <style is:global>
+      :root {
+        --accent: 124, 58, 237;
+        --accent-gradient: linear-gradient(45deg, rgb(var(--accent)), #da62c4 30%, white 60%);
+      }
+      html {
+        font-family: system-ui, sans-serif;
+        background-color: #f6f6f6;
+      }
+      body {
+        margin: 0;
+      }
+      code {
+        font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono,
+          Courier New, monospace;
+      }
+    </style>
+  </body>
 </html>
-<style is:global>
-	:root {
-		--accent: 124, 58, 237;
-		--accent-gradient: linear-gradient(45deg, rgb(var(--accent)), #da62c4 30%, white 60%);
-	}
-	html {
-		font-family: system-ui, sans-serif;
-		background-color: #F6F6F6;
-	}
-	body {
-		margin: 0;
-	}
-	code {
-		font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,
-			Bitstream Vera Sans Mono, Courier New, monospace;
-	}
-</style>

+ 74 - 0
apps/playground/src/pages/vue/textures.mdx

@@ -0,0 +1,74 @@
+---
+layout: /@/layouts/ExperimentLayout.astro
+thumbnail: /textures.png
+title: Textures
+author: Alvarosabu
+description: A basic example of how to load textures using the useTexture composables and suspense
+tags: ['basic', 'useTexture', 'suspense']
+---
+
+import Textures from '/@/components/textures/Textures.vue'
+import TheInfo from '/@/components/TheInfo.astro'
+
+<Textures client:only />
+
+<TheInfo >
+# { frontmatter.title }
+
+Tutorial available [here](https://tresjs.org/examples/load-textures.html)
+
+```vue
+<script setup lang="ts">
+import { Ref, ref } from 'vue'
+
+import { useTexture, useRenderLoop, TresInstance } from '@tresjs/core'
+import { OrbitControls } from '@tresjs/cientos'
+
+const pbrTexture = await useTexture({
+  map: 'https://raw.githubusercontent.com/Tresjs/assets/main/textures/black-rock/Rock035_2K_Displacement.jpg',
+  displacementMap:
+    'https://raw.githubusercontent.com/Tresjs/assets/main/textures/black-rock/Rock035_2K_Displacement.jpg',
+  roughnessMap: 'https://raw.githubusercontent.com/Tresjs/assets/main/textures/black-rock/Rock035_2K_Roughness.jpg',
+  normalMap: 'https://raw.githubusercontent.com/Tresjs/assets/main/textures/black-rock/Rock035_2K_NormalGL.jpg',
+  ambientOcclusion:
+    'https://raw.githubusercontent.com/Tresjs/assets/main/textures/black-rock/Rock035_2K_AmbientOcclusion.jpg',
+})
+
+const sphereRef: Ref<TresInstance | null> = ref(null)
+
+const { resume, onLoop } = useRenderLoop()
+
+resume()
+
+onLoop(({ delta }) => {
+  // I will run at every frame ~ 60FPS (depending of your monitor)
+  if (sphereRef.value) {
+    sphereRef.value.rotation.y = delta
+  }
+})
+</script>
+
+<template>
+  <TresCanvas
+    clear-color="#82DBC5"
+    shadows
+    alpha
+    window-size
+    power-preference="high-performance"
+    preserve-drawing-buffer
+    physically-correct-lights
+  >
+    <OrbitControls />
+    <TresPerspectiveCamera :position="[1, 2, 5]" :fov="45" :aspect="1" :near="0.1" :far="1000" />
+    <TresScene>
+      <TresMesh ref="sphereRef" :scale="1" cast-shadow>
+        <TresSphereGeometry :args="[1, 100, 100]" />
+        <TresMeshStandardMaterial v-bind="pbrTexture" displacement-scale="0.2" />
+      </TresMesh>
+      <TresDirectionalLight :position="[0, 2, 4]" :intensity="2" cast-shadow />
+    </TresScene>
+  </TresCanvas>
+</template>
+```
+
+</TheInfo>

+ 6 - 0
pnpm-lock.yaml

@@ -55,6 +55,7 @@ importers:
       '@tresjs/cientos': workspace:^1.4.0
       '@tresjs/core': workspace:^1.5.0
       astro: ^1.9.2
+      astro-seo: ^0.7.0
       three: ^0.148.0
       unocss: ^0.48.0
       unocss-preset-daisy: ^1.2.0
@@ -64,6 +65,7 @@ importers:
       '@astrojs/mdx': 0.14.0
       '@astrojs/vue': 1.2.2_vue@3.2.45
       astro: 1.9.2
+      astro-seo: 0.7.0
       vue: 3.2.45
     devDependencies:
       '@iconify-json/carbon': 1.1.13
@@ -2935,6 +2937,10 @@ packages:
     hasBin: true
     dev: false
 
+  /astro-seo/0.7.0:
+    resolution: {integrity: sha512-G7zJUr4lfKLeqfWx2g5rfuBsOsIOfqxIOqErQfrMsMchDFfLFxNKAuW8yAo8hynJJwBvtGyS/vOXgGdMVVCFrA==}
+    dev: false
+
   /astro/1.9.2:
     resolution: {integrity: sha512-L+Ma0eR0Aa6QZg7RF0lEs+106Ye1/zukvtq3KtsYIogAojltlwllwU9X5CwMBzFwA55NxpNp4gSRh5US/xb+8Q==}
     engines: {node: ^14.18.0 || >=16.12.0, npm: '>=6.14.0'}