新增一个led shader
This commit is contained in:
parent
5bcd94a3d0
commit
3f80854bbc
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user