THREE.js 使用 RawShaderMaterial 加载自定义着色器运行失败求助
代码错误点
- 着色器必填uniform变量
color、lightPosition未配置初始值,导致片元着色器无法正常计算输出颜色 - 存在无效对象引用:
cube本身就是THREE.Mesh实例,无需通过.mesh属性访问本身,cube.mesh.rotation会抛出JS异常中断渲染逻辑 - 你使用的
THREE.CubeGeometry已废弃,新版本Three.js中对应类名为THREE.BoxGeometry,可同步修改避免警告
修复后完整代码
function newCube(colour=0xffffff,height=1,width=height,depth=height){ const geometry = new THREE.BoxGeometry(height,depth,width); const material = new THREE.MeshBasicMaterial( {color: colour} ); return new THREE.Mesh( geometry, material ); } const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(60,window.innerWidth / window.innerHeight,1,10000); const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setClearColor(0xaaaaaa, 1); document.body.appendChild(renderer.domElement); const cube = newCube(0x220033,1); var material= new THREE.RawShaderMaterial({ "id": 5472, "name": "Fragmented", "fragmentShader": `precision highp float; precision highp int; uniform mat4 modelMatrix; uniform mat4 modelViewMatrix; uniform mat4 projectionMatrix; uniform mat4 viewMatrix; uniform mat3 normalMatrix; uniform vec3 cameraPosition; uniform float time; uniform vec3 color; uniform vec3 lightPosition; varying vec3 vPosition; varying vec3 vNormal; varying vec3 vColor; varying vec2 vUv; varying vec2 vUv2; void main() { vec3 worldPosition = ( modelMatrix * vec4( vPosition, 1.0 )).xyz; vec3 worldNormal = normalize( vec3( modelMatrix * vec4( vNormal, 0.0 ) ) ); vec3 lightVector = normalize( lightPosition - worldPosition ); float brightness = dot( worldNormal, lightVector ); // 避免背光面完全发黑可以取消下一行注释加环境光兜底 // brightness = max(brightness, 0.2); gl_FragColor = vec4( color * brightness, 1.0 ); }`, "vertexShader": `precision highp float; precision highp int; uniform mat4 modelMatrix; uniform mat4 modelViewMatrix; uniform mat4 projectionMatrix; uniform mat4 viewMatrix; uniform mat3 normalMatrix; uniform vec3 cameraPosition; uniform float time; uniform vec3 color; attribute vec3 position; attribute vec3 normal; attribute vec2 uv; attribute vec2 uv2; varying vec3 vPosition; varying vec3 vNormal; varying vec2 vUv; varying vec2 vUv2; void main() { vNormal = normal; vUv = uv; vUv2 = uv2; vPosition = position; gl_Position= projectionMatrix * modelViewMatrix * vec4( position+sin(position*time)/10., 1. ); }`, "uniforms": { "time": { "name": "time", "displayName": null, "type": "f", "glslType": "float", "useGridHelper": false, "useRange": false, "range": null, "isRandom": false, "randomRange": null, "useToggle": false, "toggle": null, "description": "", "value":0 }, "color": { "name": "color", "displayName": null, "type": "c", "glslType": "vec3", "useGridHelper": false, "useRange": false, "range": null, "isRandom": false, "randomRange": null, "useToggle": false, "toggle": null, "description": "Example light color", "value": new THREE.Color(0x9933ff) }, "lightPosition": { "name": "lightPosition", "displayName": null, "type": "v3", "glslType": "vec3", "useGridHelper": false, "useRange": false, "range": null, "isRandom": false, "randomRange": null, "useToggle": false, "toggle": null, "description": "", "value": new THREE.Vector3(5, 5, 5) } } }); scene.add(cube); cube.material=material; camera.position.z = 3; function render() { cube.material.uniforms.time.value+=0.1; renderer.render(scene, camera); cube.rotation.x += 0.05; cube.rotation.y -= 0.05; requestAnimationFrame(render); } render();
内容的提问来源于stack exchange,提问作者Agent Biscutt
相关产品推荐
相关产品推荐

