增加了 图片粒子化

This commit is contained in:
hawk86104 2025-01-07 19:54:29 +08:00
parent 9e2efc951b
commit f03f07b1ba
4 changed files with 169 additions and 1 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

View File

@ -0,0 +1,101 @@
<!--
* @Description:
* @Version: 1.668
* @Autor: 地虎降天龙
* @Date: 2025-01-07 15:43:55
* @LastEditors: 地虎降天龙
* @LastEditTime: 2025-01-07 19:51:22
-->
<template>
<TresPoints :position="[-8, 10, -2]" :scale="0.02">
<TresBufferGeometry :position="[positionArray, 3]" :color_list="[colorListArray, 3]" />
<TresShaderMaterial v-bind="smConfig" />
</TresPoints>
</template>
<script lang="ts" setup>
import { watch } from 'vue'
import * as THREE from 'three'
import { useTexture } from '@tresjs/core'
const props = defineProps({
zPos: { default: 1 },
useCustomColor: { default: false },
customColor: { default: '#ff0000' },
})
const pTexture = await useTexture(['./logo.png'])
const canvas = document.createElement('canvas')
const w = pTexture.image.width
const h = pTexture.image.height
canvas.width = w
canvas.height = h
const ctx = canvas.getContext('2d')
ctx?.drawImage(pTexture.image, 0, 0)
const data = ctx?.getImageData(0, 0, w, h).data
const info = []
const colorList = []
if (data) {
for (let y = 0; y < h; y++) {
for (let x = 0; x < w; x++) {
const pixelIndex = (y * w + x) * 4
if (data[pixelIndex + 3] > 0) {
const r = data[pixelIndex] / 255
const g = data[pixelIndex + 1] / 255
const b = data[pixelIndex + 2] / 255
const z = Math.random() * 100
info.push(x, -y, z)
colorList.push(r, g, b)
}
}
}
}
const positionArray = new Float32Array(info)
const colorListArray = new Float32Array(colorList)
const smConfig = {
uniforms: {
zPos: { value: props.zPos },
useCustomColor: { value: props.useCustomColor },
customColor: { value: new THREE.Color(props.customColor) },
},
vertexShader: `
attribute vec3 color_list;
varying vec3 vColor;
uniform float zPos;
void main() {
vec3 pos = position;
pos.z *= zPos;
vColor = color_list;
vec4 modelPosition = modelMatrix * vec4(pos, 1.0);
vec4 viewPosition = viewMatrix * modelPosition;
gl_PointSize = 0.001 * (1.0 - viewPosition.z);
gl_Position = projectionMatrix * viewPosition;
}`,
fragmentShader: `
varying vec3 vColor;
uniform bool useCustomColor;
uniform vec3 customColor;
void main() {
if(useCustomColor){
gl_FragColor = vec4(customColor, 1.0);
}else{
gl_FragColor = vec4(vColor, 1.0);
}
}`,
transparent: true,
depthTest: false,
blending: THREE.AdditiveBlending,
} as any
watch(
() => [props.zPos, props.useCustomColor, props.customColor],
([zPos, useCustomColor, customColor]) => {
smConfig.uniforms.zPos.value = zPos
smConfig.uniforms.useCustomColor.value = useCustomColor
smConfig.uniforms.customColor.value.set(customColor)
},
)
</script>

View File

@ -4,7 +4,7 @@
* @Autor: 地虎降天龙
* @Date: 2024-04-30 08:18:21
* @LastEditors: 地虎降天龙
* @LastEditTime: 2025-01-06 15:51:37
* @LastEditTime: 2025-01-07 15:52:38
*/
export default {
name: 'visualArts',
@ -84,5 +84,11 @@ export default {
title: '揭露动画效果',
referenceSource: { title: 'honbingitee', url: 'https://github.com/colindmg/r3f-image-reveal-effect' },
},
{
src: 'plugins/visualArts/preview/imgParticle.png',
type: 'img',
name: 'imgParticle',
title: '图片粒子化',
},
],
}

View File

@ -0,0 +1,61 @@
<!--
* @Description:
* @Version: 1.668
* @Autor: 地虎降天龙
* @Date: 2025-01-06 15:52:46
* @LastEditors: 地虎降天龙
* @LastEditTime: 2025-01-07 19:48:57
-->
<template>
<TresCanvas v-bind="state" window-size>
<TresPerspectiveCamera :position="[0, 3, 38]" :fov="45" :near="0.1" :far="1000" />
<OrbitControls />
<TresAmbientLight :intensity="0.5" />
<Suspense>
<imgParticleMesh v-bind="pcssConfig" />
</Suspense>
<Suspense>
<reflectorDUDV :position="[0, -6, 0]" v-bind="reflectorState" />
</Suspense>
</TresCanvas>
</template>
<script setup lang="ts">
import { reactive } from 'vue'
import { OrbitControls } from '@tresjs/cientos'
import { reflectorDUDV } from 'PLS/floor'
import { Pane } from 'tweakpane'
import imgParticleMesh from '../components/imgParticleMesh.vue'
const state = {
clearColor: '#050505',
antialias: false,
}
const reflectorState = {
reflectivity: 0.8,
showGridHelper: false,
scale: 6,
}
const pcssConfig = reactive({
zPos: 1,
useCustomColor: false,
customColor: '#ff0000',
})
const paneControl = new Pane({ title: '参数' })
paneControl.addBinding(pcssConfig, 'zPos', {
label: '厚度',
min: 0.5,
max: 10,
step: 0.5,
})
paneControl.addBinding(pcssConfig, 'useCustomColor', {
label: '使用自定义颜色',
})
paneControl.addBinding(pcssConfig, 'customColor', {
label: '自定义颜色',
})
</script>