You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Three.js中顶点着色器编译失败,请求排查原因

问题排查:Three.js顶点着色器编译错误('modelPosition'未声明)

问题描述

我是WebGL新手,尝试基于Three.js编写示例,已编写Setup脚本、顶点着色器和片元着色器代码,但控制台始终报错顶点着色器未编译,错误信息为'modelPosition'是未声明标识符。已打印顶点着色器内容,但仍无法解决,恳请提供排查提示。

相关代码

Setup脚本

import testVertexShader from './shaders/test/vertex.glsl'
import testFragmentShader from './shaders/test/fragment.glsl'
// Debug
const gui = new dat.GUI()

// Canvas
const canvas = document.querySelector('canvas.webgl')

// Scene
const scene = new THREE.Scene()

/**
 * Textures
 */
const textureLoader = new THREE.TextureLoader()
const dialTexture = textureLoader.load('/textures/textureD.png')

/**
 * Test mesh
 */
// Geometry
const geometry = new THREE.TorusGeometry(3, 1, 100, 100)


// Material
const material = new THREE.ShaderMaterial({
    vertexShader: testVertexShader,
    fragmentShader: testFragmentShader,
    uniforms:
    {
        uTime: { value: 0 },
        uTexture: { value: dialTexture }
    }
})

// Mesh
const mesh = new THREE.Mesh(geometry, material)
scene.add(mesh)

/**
 * Sizes
 */
const sizes = {
    width: window.innerWidth,
    height: window.innerHeight
}

window.addEventListener('resize', () =>
{
    // Update sizes
    sizes.width = window.innerWidth
    sizes.height = window.innerHeight

    // Update camera
    camera.aspect = sizes.width / sizes.height
    camera.updateProjectionMatrix()

    // Update renderer
    renderer.setSize(sizes.width, sizes.height)
    renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
})

/**
 * Camera
 */
// Base camera
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height, 0.1, 100)
scene.add(camera)

// Controls
const controls = new OrbitControls(camera, canvas)
controls.enableDamping = true

/**
 * Renderer
 */
const renderer = new THREE.WebGLRenderer({
    canvas: canvas
})
renderer.setSize(sizes.width, sizes.height)
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))

/**
 * Animate
 */
const clock = new THREE.Clock()

const tick = () =>
{
    const elapsedTime = clock.getElapsedTime()

    // Update material
    material.uniforms.uTime.value = elapsedTime

    // Update controls
    controls.update()

    // Render
    renderer.render(scene, camera)

    // Call tick again on the next frame
    window.requestAnimationFrame(tick)
}

tick();

原顶点着色器

varying vec2 vUv;
uniform float uTime;

void main()
{
    vUv = uv;

    gl_Position = projectionMatrix * modelPosition * vec4(position, 1.0);;
}

片元着色器

uniform float uTime;
uniform sampler2D uTexture;

varying vec2 vUv;


void main()
{
    vec4 color = texture2D(uTexture, vUv);
    gl_FragColor = color;
}

控制台错误信息

Three.module.js:19006 THREE.WebGLProgram: Shader Error 0 - VALIDATE_STATUS false

Program Info Log: Vertex shader is not compiled.

VERTEX

ERROR: 0:64: 'modelPosition' : undeclared identifier


  59: 
  60: void main()
  61: {
  62:     vUv = uv;
  63: 
> 64:     gl_Position = projectionMatrix * modelPosition * vec4(position, 1.0);;

解决方案

错误原因很直接:Three.js中用于表示模型变换的内置矩阵变量名是modelMatrix,而非你写的modelPosition。只需修改顶点着色器中的变量名即可解决编译错误,同时注意MVP矩阵的正确计算顺序(Model -> View -> Projection),并清理多余的分号:

修改后的顶点着色器

varying vec2 vUv;
uniform float uTime;

void main()
{
    vUv = uv;

    gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position, 1.0);
}

Three.js的ShaderMaterial会自动注入一系列内置的uniforms和attributes,比如modelMatrix、viewMatrix、projectionMatrix、position、uv等,无需额外声明即可使用,只要确保变量名拼写正确。

内容的提问来源于stack exchange,提问作者magui

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 02:52:53