新增一个led shader

This commit is contained in:
kura 2025-01-15 12:00:36 +08:00
parent 5bcd94a3d0
commit 3f80854bbc

View File

@ -8,17 +8,22 @@
crossorigin="anonymous" crossorigin="anonymous"
></video> ></video>
<canvas id="canvas"></canvas> <canvas id="canvas"></canvas>
<button @click="handleClick">播放</button> <div class="play-button" v-show="!isPlaying" @click="handleClick">
<i class="play-icon"></i>
</div>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import * as THREE from "three"; import * as THREE from "three";
import { onMounted, onUnmounted } from "vue"; import { onMounted, onUnmounted, ref } from "vue";
const isPlaying = ref(false);
const handleClick = () => { const handleClick = () => {
const video = document.getElementById("video") as HTMLVideoElement; const video = document.getElementById("video") as HTMLVideoElement;
video.play(); video.play();
isPlaying.value = true;
}; };
// 创建场景和相机 // 创建场景和相机
@ -76,7 +81,7 @@ onMounted(async () => {
vec3 pos = position; vec3 pos = position;
// 基于位置和时间生成随机值 // 基于位置和时间生成随机值
float rand = random(pos.xy) * 2.0 - 1.0; float rand = random(pos.xy) * 1.01 - 0.01;
vRandom = rand; vRandom = rand;
// 计算打散效果 // 计算打散效果
@ -114,26 +119,46 @@ onMounted(async () => {
varying float vRandom; varying float vRandom;
uniform float time; uniform float time;
// 颜色调整辅助函数
vec3 adjustColor(vec3 color) {
// 增加对比度
vec3 contrast = (color - 0.5) * 1.4 + 0.5;
// 计算亮度
float luminance = dot(contrast, vec3(0.299, 0.587, 0.114));
// 增加饱和度
vec3 saturated = mix(vec3(luminance), contrast, 1.3);
// 稍微压暗高光
saturated = pow(saturated, vec3(1.1));
return saturated;
}
void main() { void main() {
// 减小马赛克大小 // 马赛克大小
float mosaicSize = 1000.0; float mosaicSize = 1000.0;
vec2 mosaicUv = floor(vUv * mosaicSize) / mosaicSize; vec2 mosaicUv = floor(vUv * mosaicSize) / mosaicSize;
// 减小抖动效果 // 减小抖动效果
float jitter = sin(time * 2.0 + vRandom * 6.28) * 0.000001; float jitter = sin(time * 2.0 + vRandom * 1.28) * 0.001;
mosaicUv += vec2(jitter); mosaicUv += vec2(jitter);
vec4 texColor = texture2D(mainTexture, mosaicUv); vec4 texColor = texture2D(mainTexture, mosaicUv);
// 调整颜色
vec3 adjustedColor = adjustColor(texColor.rgb);
// 调整扭曲和淡出效果 // 调整扭曲和淡出效果
float distortionFactor = 1.0 - vDist * 0.05; float distortionFactor = 1.0 - vDist * 0.005;
float alpha = 0.9 + 0.1 * sin(time * 2.0 + vRandom * 6.28); float alpha = 0.99 + 0.01 * sin(time * 2.0 + vRandom * 6.28);
// 边缘淡出效果 // 边缘淡出效果
float edgeFade = 1.0 - length(gl_PointCoord - vec2(0.5)) * 2.0; float edgeFade = 1.0 - length(gl_PointCoord - vec2(0.5)) * 2.0;
edgeFade = smoothstep(0.0, 0.5, edgeFade); edgeFade = smoothstep(0.0, 0.5, edgeFade);
gl_FragColor = vec4(texColor.rgb * distortionFactor, texColor.a * alpha * edgeFade); gl_FragColor = vec4(adjustedColor, texColor.a * alpha * edgeFade);
}`, }`,
uniforms: { uniforms: {
mainTexture: { value: videoTexture }, mainTexture: { value: videoTexture },
@ -185,6 +210,16 @@ onMounted(async () => {
renderer.setSize(width, height); renderer.setSize(width, height);
}); });
// 监听视频暂停事件
video.addEventListener("pause", () => {
isPlaying.value = false;
});
// 监听视频播放事件
video.addEventListener("play", () => {
isPlaying.value = true;
});
}); });
// 组件卸载时清理 // 组件卸载时清理
@ -202,4 +237,34 @@ canvas {
height: 100vh; height: 100vh;
display: block; display: block;
} }
.play-button {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 80px;
height: 80px;
background: rgba(0, 0, 0, 0.6);
border-radius: 50%;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s;
}
.play-button:hover {
background: rgba(0, 0, 0, 0.8);
transform: translate(-50%, -50%) scale(1.1);
}
.play-icon {
width: 0;
height: 0;
border-style: solid;
border-width: 20px 0 20px 30px;
border-color: transparent transparent transparent #ffffff;
margin-left: 8px;
}
</style> </style>