GLSL顶点置换着色器仅单顶点生效问题求助(Three.js 0.171.0)
排查Three.js 0.171.0顶点置换着色器仅单个顶点生效问题
问题概述
- 重构十年前基于旧版Three.js的GLSL顶点置换着色器,适配Three.js 0.171.0版本
- 已修复视频纹理加载顺序等问题,但顶点置换仅作用于单个顶点,预期效果是根据视频纹理像素亮度值将置换映射到整个几何体尺寸上
旧版GLSL顶点着色器代码
// 旧版顶点着色器示例 varying vec2 vUv; uniform sampler2D videoTexture; void main() { vUv = uv; vec4 texColor = texture2D(videoTexture, vUv); float displacement = texColor.r * 5.0; vec3 newPosition = position + normal * displacement; gl_Position = projectionMatrix * modelViewMatrix * vec4(newPosition, 1.0); }
新版GLSL顶点着色器代码
// 新版顶点着色器(当前出现问题的版本) varying vec2 vUv; uniform sampler2D videoTexture; void main() { vUv = uv; vec4 texColor = texture(videoTexture, vUv); float displacement = texColor.r * 5.0; vec3 newPosition = position + normal * displacement; gl_Position = projectionMatrix * modelViewMatrix * vec4(newPosition, 1.0); }
Three.js实现代码片段
// 几何体与材质初始化示例 const geometry = new THREE.PlaneGeometry(10, 10, 32, 32); const video = document.getElementById('video'); const videoTexture = new THREE.VideoTexture(video); videoTexture.colorSpace = THREE.SRGBColorSpace; const shaderMaterial = new THREE.ShaderMaterial({ vertexShader: document.getElementById('vertexShader').textContent, fragmentShader: document.getElementById('fragmentShader').textContent, uniforms: { videoTexture: { value: videoTexture } }, side: THREE.DoubleSide }); const mesh = new THREE.Mesh(geometry, shaderMaterial); scene.add(mesh); // 视频加载与播放逻辑 video.addEventListener('loadedmetadata', () => { video.play(); });
排查方向建议
- UV坐标验证:检查几何体的UV映射是否正确。新版Three.js中部分几何体(如PlaneGeometry)的UV生成逻辑可能与旧版不同,可在片元着色器中输出
vUv的RGB值(如gl_FragColor = vec4(vUv, 0.0, 1.0)),直观查看UV是否覆盖整个几何体。 - 纹理采样点检查:确认所有顶点使用的UV坐标是否唯一且分布合理。若所有顶点采样同一纹理坐标,会导致置换效果仅集中在单个顶点。
- 顶点属性传递:确保着色器中声明的
attribute vec3 position、attribute vec2 uv与Three.js几何体的内置属性匹配,新版Three.js对顶点属性的命名规范严格,避免自定义属性未正确绑定。 - 内置变量适配:旧版着色器可能使用了已废弃的内置变量(如
gl_Vertex),需全部替换为新版标准的attribute变量。 - 纹理状态确认:在片元着色器中输出视频纹理的颜色,验证纹理是否正常传递给着色器,排除因纹理未加载或更新导致的采样异常。
内容的提问来源于stack exchange,提问作者steveblue
相关产品推荐
相关产品推荐

