From f26dd70d8cc7994bc3f9b1304f3e2fd0c18a0041 Mon Sep 17 00:00:00 2001 From: Francesco Michelini Date: Thu, 19 Oct 2023 16:22:47 +0200 Subject: [PATCH 1/9] Add `CustomShaderMaterial` wrapper --- package.json | 1 + .../materials/CustomShaderMaterialDemo.vue | 54 +++++++++++++ playground/src/router/routes/materials.ts | 7 +- pnpm-lock.yaml | 75 ++++++++++++++++++- .../materials/customShaderMaterial/index.vue | 17 +++++ .../customShaderMaterial/material.ts | 35 +++++++++ src/core/materials/index.ts | 3 +- 7 files changed, 189 insertions(+), 3 deletions(-) create mode 100644 playground/src/pages/materials/CustomShaderMaterialDemo.vue create mode 100644 src/core/materials/customShaderMaterial/index.vue create mode 100644 src/core/materials/customShaderMaterial/material.ts diff --git a/package.json b/package.json index 2cef6af6..3c9f9537 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,7 @@ "camera-controls": "^2.7.2", "stats-gl": "^1.0.5", "stats.js": "^0.17.0", + "three-custom-shader-material": "^5.4.0", "three-stdlib": "^2.27.3" }, "devDependencies": { diff --git a/playground/src/pages/materials/CustomShaderMaterialDemo.vue b/playground/src/pages/materials/CustomShaderMaterialDemo.vue new file mode 100644 index 00000000..37791e89 --- /dev/null +++ b/playground/src/pages/materials/CustomShaderMaterialDemo.vue @@ -0,0 +1,54 @@ + + + diff --git a/playground/src/router/routes/materials.ts b/playground/src/router/routes/materials.ts index c2a4eb92..12c5f78c 100644 --- a/playground/src/router/routes/materials.ts +++ b/playground/src/router/routes/materials.ts @@ -9,4 +9,9 @@ export const materialsRoutes = [ name: 'GlassMaterial', component: () => import('../../pages/materials/GlassMaterialDemo.vue'), }, -] \ No newline at end of file + { + path: '/materials/custom-shader-material', + name: 'CustomShaderMaterial', + component: () => import('../../pages/materials/CustomShaderMaterialDemo.vue'), + }, +] diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c423d782..41d4aa90 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,6 +23,9 @@ importers: stats.js: specifier: ^0.17.0 version: 0.17.0 + three-custom-shader-material: + specifier: ^5.4.0 + version: 5.4.0(three@0.157.0) three-stdlib: specifier: ^2.27.3 version: 2.27.3(three@0.157.0) @@ -2572,6 +2575,10 @@ packages: meow: 12.1.1 dev: true + /core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + dev: false + /cosmiconfig@8.3.6(typescript@5.2.2): resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} engines: {node: '>=14'} @@ -3736,6 +3743,20 @@ packages: slash: 4.0.0 dev: true + /glsl-token-functions@1.0.1: + resolution: {integrity: sha512-EigGhp1g+aUVeUNY7H1o5tL/bnwIB3/FcRREPr2E7Du+/UDXN24hDkaZ3e4aWHDjHr9lJ6YHXMISkwhUYg9UOg==} + dev: false + + /glsl-token-string@1.0.1: + resolution: {integrity: sha512-1mtQ47Uxd47wrovl+T6RshKGkRRCYWhnELmkEcUAPALWGTFe2XZpH3r45XAwL2B6v+l0KNsCnoaZCSnhzKEksg==} + dev: false + + /glsl-tokenizer@2.1.5: + resolution: {integrity: sha512-XSZEJ/i4dmz3Pmbnpsy3cKh7cotvFlBiZnDOwnj/05EwNp2XrhQ4XKJxT7/pDt4kp4YcpRSKz8eTV7S+mwV6MA==} + dependencies: + through2: 0.6.5 + dev: false + /gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} dependencies: @@ -3981,7 +4002,6 @@ packages: /inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - dev: true /ini@1.3.8: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} @@ -4317,6 +4337,10 @@ packages: engines: {node: '>=12'} dev: true + /isarray@0.0.1: + resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} + dev: false + /isarray@2.0.5: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} dev: true @@ -4836,6 +4860,11 @@ packages: boolbase: 1.0.0 dev: true + /object-hash@3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + dev: false + /object-inspect@1.13.0: resolution: {integrity: sha512-HQ4J+ic8hKrgIt3mqk6cVOVrW2ozL4KdvHlqpBv9vDYWx9ysAgENAdvy4FoGF+KFdhR7nQTNm5J0ctAeOwn+3g==} dev: true @@ -5332,6 +5361,15 @@ packages: type-fest: 4.4.0 dev: true + /readable-stream@1.0.34: + resolution: {integrity: sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==} + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 0.0.1 + string_decoder: 0.10.31 + dev: false + /readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} @@ -5838,6 +5876,10 @@ packages: es-abstract: 1.22.2 dev: true + /string_decoder@0.10.31: + resolution: {integrity: sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==} + dev: false + /string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} dependencies: @@ -5941,6 +5983,25 @@ packages: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} dev: true + /three-custom-shader-material@5.4.0(three@0.157.0): + resolution: {integrity: sha512-Yn1lFlKOk3Vul3npEGAmbbFUZ5S2+yjPgM2XqJEZEYRSUUH2vk+WVYrtTB6Bcq15wa7hLUXAKoctAvbRmBmbYA==} + peerDependencies: + '@react-three/fiber': '>=8.0' + react: '>=18.0' + three: '>=0.154' + peerDependenciesMeta: + '@react-three/fiber': + optional: true + react: + optional: true + dependencies: + glsl-token-functions: 1.0.1 + glsl-token-string: 1.0.1 + glsl-tokenizer: 2.1.5 + object-hash: 3.0.0 + three: 0.157.0 + dev: false + /three-stdlib@2.27.3(three@0.157.0): resolution: {integrity: sha512-HA3LDEGnrbahOMGMk4HTfCClr/oKQnwvnvNR2gOMytvHg7nk8SIiABl/qgol2xDVp/Lf7MEbeq5ZjzjajuZxpw==} peerDependencies: @@ -5958,6 +6019,13 @@ packages: /three@0.157.0: resolution: {integrity: sha512-CeAwQrf4x3z0/e+MC4F+nXLW5t0gh3pw+L6CCBqpHvOq3bGYIgRYub7Pv0j/9wR+d++OiEglyZzWyuSYbwWGOA==} + /through2@0.6.5: + resolution: {integrity: sha512-RkK/CCESdTKQZHdmKICijdKKsCRVHs5KsLZ6pACAmF/1GPUQhonHSXWNERctxEp7RmvjdNbZTL5z9V7nSCXKcg==} + dependencies: + readable-stream: 1.0.34 + xtend: 4.0.2 + dev: false + /through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} dev: true @@ -6712,6 +6780,11 @@ packages: engines: {node: '>=12'} dev: true + /xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + dev: false + /y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} diff --git a/src/core/materials/customShaderMaterial/index.vue b/src/core/materials/customShaderMaterial/index.vue new file mode 100644 index 00000000..665d5869 --- /dev/null +++ b/src/core/materials/customShaderMaterial/index.vue @@ -0,0 +1,17 @@ + + + diff --git a/src/core/materials/customShaderMaterial/material.ts b/src/core/materials/customShaderMaterial/material.ts new file mode 100644 index 00000000..27a38b04 --- /dev/null +++ b/src/core/materials/customShaderMaterial/material.ts @@ -0,0 +1,35 @@ +import type { Material } from 'three' +import { MeshBasicMaterial } from 'three' +import CustomShaderMaterial from 'three-custom-shader-material/vanilla' + +interface Props { + baseMaterial: Material + vertexShader?: string + fragmentShader?: string + silent?: boolean + uniforms?: { [uniform: string]: any } + flatShading?: boolean + color?: string | number +} + +export class CustomShaderMaterialImpl extends CustomShaderMaterial { + baseMaterial: Material + vertexShader?: string + fragmentShader?: string + silent?: boolean + uniforms?: { [uniform: string]: any } + flatShading?: boolean + color?: string | number + + constructor(props: Props = { baseMaterial: new MeshBasicMaterial() }) { + super(props) + + this.baseMaterial = props.baseMaterial + this.vertexShader = props.vertexShader + this.fragmentShader = props.fragmentShader + this.silent = props.silent + this.uniforms = props.uniforms + this.flatShading = props.flatShading + this.color = props.color + } +} diff --git a/src/core/materials/index.ts b/src/core/materials/index.ts index ecabbc99..9a9fc728 100644 --- a/src/core/materials/index.ts +++ b/src/core/materials/index.ts @@ -1,4 +1,5 @@ import MeshWobbleMaterial from './meshWobbleMaterial/index.vue' import MeshGlassMaterial from './meshGlassMaterial/index.vue' +import CustomShaderMaterial from './customShaderMaterial/index.vue' -export { MeshWobbleMaterial, MeshGlassMaterial } +export { MeshWobbleMaterial, MeshGlassMaterial, CustomShaderMaterial } From 14812d96da923895247ae3e3c8c1796e4f3490f3 Mon Sep 17 00:00:00 2001 From: alvarosabu Date: Tue, 24 Oct 2023 17:09:14 +0200 Subject: [PATCH 2/9] fix: pass props as arg to custom shader, remove extra class --- .../materials/CustomShaderMaterialDemo.vue | 11 +++--- .../materials/customShaderMaterial/index.vue | 26 +++++++++++--- .../customShaderMaterial/material.ts | 35 ------------------- 3 files changed, 29 insertions(+), 43 deletions(-) delete mode 100644 src/core/materials/customShaderMaterial/material.ts diff --git a/playground/src/pages/materials/CustomShaderMaterialDemo.vue b/playground/src/pages/materials/CustomShaderMaterialDemo.vue index 37791e89..2b375e31 100644 --- a/playground/src/pages/materials/CustomShaderMaterialDemo.vue +++ b/playground/src/pages/materials/CustomShaderMaterialDemo.vue @@ -1,5 +1,6 @@ diff --git a/src/core/materials/customShaderMaterial/material.ts b/src/core/materials/customShaderMaterial/material.ts deleted file mode 100644 index 27a38b04..00000000 --- a/src/core/materials/customShaderMaterial/material.ts +++ /dev/null @@ -1,35 +0,0 @@ -import type { Material } from 'three' -import { MeshBasicMaterial } from 'three' -import CustomShaderMaterial from 'three-custom-shader-material/vanilla' - -interface Props { - baseMaterial: Material - vertexShader?: string - fragmentShader?: string - silent?: boolean - uniforms?: { [uniform: string]: any } - flatShading?: boolean - color?: string | number -} - -export class CustomShaderMaterialImpl extends CustomShaderMaterial { - baseMaterial: Material - vertexShader?: string - fragmentShader?: string - silent?: boolean - uniforms?: { [uniform: string]: any } - flatShading?: boolean - color?: string | number - - constructor(props: Props = { baseMaterial: new MeshBasicMaterial() }) { - super(props) - - this.baseMaterial = props.baseMaterial - this.vertexShader = props.vertexShader - this.fragmentShader = props.fragmentShader - this.silent = props.silent - this.uniforms = props.uniforms - this.flatShading = props.flatShading - this.color = props.color - } -} From 3cecf5608f077d1ef56189ebb9f5939c54fd200a Mon Sep 17 00:00:00 2001 From: alvarosabu Date: Tue, 24 Oct 2023 17:09:41 +0200 Subject: [PATCH 3/9] chore: remove unused import --- src/core/materials/customShaderMaterial/index.vue | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/core/materials/customShaderMaterial/index.vue b/src/core/materials/customShaderMaterial/index.vue index d45cf1b0..197efa6e 100644 --- a/src/core/materials/customShaderMaterial/index.vue +++ b/src/core/materials/customShaderMaterial/index.vue @@ -2,8 +2,6 @@ import { shallowRef } from 'vue' import { useTresContext } from '@tresjs/core' -/* import { CustomShaderMaterialImpl as CustomShaderMaterial } from './material' - */ import CustomShaderMaterial from 'three-custom-shader-material/vanilla' import type { Material } from 'three' From cfff85980e8dead3c4b180f7040a37e8ce40f5b0 Mon Sep 17 00:00:00 2001 From: Francesco Michelini Date: Wed, 25 Oct 2023 17:03:50 +0200 Subject: [PATCH 4/9] Update demo --- .../materials/CustomShaderMaterialDemo.vue | 37 ++++++++++++++----- .../materials/customShaderMaterial/index.vue | 5 +-- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/playground/src/pages/materials/CustomShaderMaterialDemo.vue b/playground/src/pages/materials/CustomShaderMaterialDemo.vue index 2b375e31..c0eeab1f 100644 --- a/playground/src/pages/materials/CustomShaderMaterialDemo.vue +++ b/playground/src/pages/materials/CustomShaderMaterialDemo.vue @@ -17,20 +17,39 @@ const gl = { const materialProps = { baseMaterial: MeshBasicMaterial, - color: '#ffff00', + fragmentShader: ` + varying float vWobble; + + void main() { + csm_FragColor = mix(vec4(1.0, 1.0, 0.0, 1.0), vec4(1.0, 0.0, 1.0, 1.0), vWobble); + } + `, + vertexShader: ` + uniform float u_Time; + uniform float u_WobbleSpeed; + uniform float u_WobbleAmplitude; + + varying float vWobble; + + void main() { + float wobble = (sin(csm_Position.z * 7.0 + u_Time * u_WobbleSpeed) * 0.5 + 0.5); + csm_Position *= 1.0 + wobble * u_WobbleAmplitude; + + vWobble = wobble; + } + `, + uniforms: { + u_Time: { value: 0 }, + u_WobbleSpeed: { value: 3 }, + u_WobbleAmplitude: { value: 0.3 }, + }, } onMounted(async () => { await nextTick() onLoop(({ elapsed }) => { - /* console.log( - materialRef.value.value.userData.tres__name, - materialRef.value.value.color, - ) */ - - meshRef.value.rotation.x = elapsed / 7 - meshRef.value.rotation.y = elapsed / 2 + materialProps.uniforms.u_Time.value = elapsed }) }) @@ -49,7 +68,7 @@ onMounted(async () => { v-bind="materialProps" /> - + diff --git a/src/core/materials/customShaderMaterial/index.vue b/src/core/materials/customShaderMaterial/index.vue index 197efa6e..dd43268b 100644 --- a/src/core/materials/customShaderMaterial/index.vue +++ b/src/core/materials/customShaderMaterial/index.vue @@ -3,16 +3,13 @@ import { shallowRef } from 'vue' import { useTresContext } from '@tresjs/core' import CustomShaderMaterial from 'three-custom-shader-material/vanilla' -import type { Material } from 'three' interface CustomShaderMaterialProps { - baseMaterial: Material + baseMaterial: Function vertexShader?: string fragmentShader?: string silent?: boolean uniforms?: { [uniform: string]: any } - flatShading?: boolean - color?: string | number } const props = defineProps() From c4413c145337be08b16f878cf26ad9c6a964c23b Mon Sep 17 00:00:00 2001 From: Francesco Michelini Date: Wed, 25 Oct 2023 17:35:26 +0200 Subject: [PATCH 5/9] Add control panel --- .../materials/CustomShaderMaterialDemo.vue | 49 +++++++++++++++---- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/playground/src/pages/materials/CustomShaderMaterialDemo.vue b/playground/src/pages/materials/CustomShaderMaterialDemo.vue index c0eeab1f..d3482592 100644 --- a/playground/src/pages/materials/CustomShaderMaterialDemo.vue +++ b/playground/src/pages/materials/CustomShaderMaterialDemo.vue @@ -1,7 +1,6 @@