【问题标题】:threejs webgl shader cant compilethreejs webgl着色器无法编译
【发布时间】:2021-11-17 00:06:25
【问题描述】:

我是 webgl 的新手,目前正在学习着色器。我目前正在尝试在球体周围包裹纹理以提供地球图像,但在尝试这样做时遇到了问题,包括片段和顶点 glsl。

这是我当前面临的错误,当我尝试加载纹理时发生

three.module.js:17071 THREE.WebGLProgram: shader error:  0 35715 false gl.getProgramInfoLog Vertex shader is not compiled.

以下代码用于 main.js

import './style.css'
import * as THREE from 'three'
import * as dat from 'dat.gui'
import vertexShader from './vertex.glsl'
import fragmentShader from './fragment.glsl'

// Debug
const gui = new dat.GUI()

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

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

// Objects
const geometry = new THREE.SphereGeometry(5,50,50);

// Materials
const loader = new THREE.TextureLoader()


const material = new THREE.ShaderMaterial({
    vertexShader,
    fragmentShader,
    uniforms: {
        globeTexture: {
            value: loader.load('globe.jpg')
        }
    }
})

// material.color = new THREE.Color(0xff0000)
// const material = new THREE.MeshBasicMaterial( { map: texture } );

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

// Lights

const pointLight = new THREE.PointLight(0xffffff, 0.1)
pointLight.position.x = 2
pointLight.position.y = 3
pointLight.position.z = 4
scene.add(pointLight)

/**
 * 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)
camera.position.x = 0
camera.position.y = 0
camera.position.z = 20
scene.add(camera)

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

/**
 * Renderer
 */
const renderer = new THREE.WebGLRenderer({
    canvas: canvas,
    antialias: true
})
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 objects
    sphere.rotation.y = .5 * elapsedTime

    // Update Orbital Controls
    // controls.update()

    // Render
    renderer.render(scene, camera)

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

tick()

fragment.glsl 的代码 统一的 sampler2D globeTexture;

varying vec2 vertexUV; 

void main() {

    gl_FragColor = texture2D(globeTexture, vertexUV);
 ;
}

vertex.glsl

varying vec2 vertexUV;

void main(){
    
vertexUv = uv;

gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );

}

提前谢谢大家。

【问题讨论】:

  • vertex.glsluv 定义在哪里?
  • uv 可能是由 three.js 定义的,ShaderMaterial
  • 但是 globeTexture 没有在任何地方定义
  • 它在 fragcolour 中定义
  • @pailhead 定义在 fragcolour

标签: javascript three.js


【解决方案1】:

这里是固定代码:

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

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

// Objects
const geometry = new THREE.SphereGeometry(5, 50, 50);

// Materials
const loader = new THREE.TextureLoader();


const material = new THREE.ShaderMaterial({
  vertexShader: document.getElementById('vertexShader').textContent,
  fragmentShader: document.getElementById('fragmentShader').textContent,
  uniforms: {
    globeTexture: {
      value: loader.load('https://threejs.org/examples/textures/uv_grid_opengl.jpg')
    }
  }
})

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

// Lights

const pointLight = new THREE.PointLight(0xffffff, 0.1)
pointLight.position.x = 2
pointLight.position.y = 3
pointLight.position.z = 4
scene.add(pointLight)

/**
 * 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)
camera.position.x = 0
camera.position.y = 0
camera.position.z = 20
scene.add(camera)

/**
 * Renderer
 */
const renderer = new THREE.WebGLRenderer({
  canvas: canvas,
  antialias: true
})
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 objects
  sphere.rotation.y = .5 * elapsedTime

  // Render
  renderer.render(scene, camera)

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

tick()
body {
      margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three@0.134.0/build/three.js"></script>
<canvas class="webgl"></canvas>

<script id="vertexShader" type="x-shader/x-vertex">
varying vec2 vertexUV;

void main(){
    
    vertexUV = uv;

    gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );

}
 
</script>

<script id="fragmentShader" type="x-shader/x-fragment">
uniform sampler2D globeTexture;

varying vec2 vertexUV; 

void main() {

    gl_FragColor = texture2D(globeTexture, vertexUV);

}
 
</script>
  • 您没有定义制服globeTexture
  • 顶点着色器中有错字。应该是 vertexUV 而不是 vertexUv

【讨论】:

  • 谢谢兄弟,它可以工作,错过了类型vertexUV
  • 那么请接受/投票。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多