我的 THREE.js RawShaderMaterial 不工作

My THREE.js RawShaderMaterial isn't Working

我在将其他人的着色器加载到 THREE.js 中时没有遇到任何问题,但我似乎 运行 在创建和 运行 自己的着色器时遇到了问题。 着色器在我用来创建它的网站上工作 (https://shaderfrog.com/app/view/5460),但在我尝试实现它时却没有。 我不确定这是 javascript、three.js 还是 GLSL 问题,所以非常感谢所有帮助。

这是我的js代码:

function newCube(colour=0xffffff,height=1,width=height,depth=height){
  const geometry = new THREE.CubeGeometry(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;\nprecision highp int;\n\nuniform mat4 modelMatrix;\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\nuniform mat4 viewMatrix;\nuniform mat3 normalMatrix;\nuniform vec3 cameraPosition;\nuniform float time;\nuniform vec3 color;\nuniform vec3 lightPosition;\nvarying vec3 vPosition;\nvarying vec3 vNormal;\nvarying vec3 vColor;\nvarying vec2 vUv;\nvarying vec2 vUv2;\n\nvoid main() {\n    vec3 worldPosition = ( modelMatrix * vec4( vPosition, 1.0 )).xyz;\n    vec3 worldNormal = normalize( vec3( modelMatrix * vec4( vNormal, 0.0 ) ) );\n    vec3 lightVector = normalize( lightPosition - worldPosition );\n    float brightness = dot( worldNormal, lightVector );\n    gl_FragColor = vec4( color * brightness, 1.0 );\n}",
  "vertexShader": "precision highp float;\nprecision highp int;\nuniform mat4 modelMatrix;\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\nuniform mat4 viewMatrix;\nuniform mat3 normalMatrix;\nuniform vec3 cameraPosition;\nuniform float time;\nuniform vec3 color;\nattribute vec3 position;\nattribute vec3 normal;\nattribute vec2 uv;\nattribute vec2 uv2;\nvarying vec3 vPosition;\nvarying vec3 vNormal;\nvarying vec2 vUv;\nvarying vec2 vUv2;\nvoid main() {\n    vNormal = normal;\n    vUv = uv;\n    vUv2 = uv2;\n    vPosition = position;\n    gl_Position= projectionMatrix * modelViewMatrix * vec4( position+sin(position*time)/10., 1. );\n}",
  "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"
    },
    "lightPosition": {
      "name": "lightPosition",
      "displayName": null,
      "type": "v3",
      "glslType": "vec3",
      "useGridHelper": false,
      "useRange": false,
      "range": null,
      "isRandom": false,
      "randomRange": null,
      "useToggle": false,
      "toggle": null,
      "description": ""
    }
  }
});
scene.add(cube);
cube.material=material;
camera.position.z = 3;

function render() {
  cube.material.uniforms.time.value+=0.1;
  renderer.render(scene, camera);
  cube.mesh.rotation.x += 0.05;
  cube.mesh.rotation.y -= 0.05;
  requestAnimationFrame(render);
}

render();

我修改了你的代码,所以至少它显示了一些东西:

body{
  overflow: hidden;
  margin: 0;
}
<script type="module">
import * as THREE from "https://cdn.skypack.dev/three@0.133";

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);
var geometry = new THREE.BoxGeometry();
var material= new THREE.RawShaderMaterial({
  "fragmentShader": "precision highp float;\nprecision highp int;\n\nuniform mat4 modelMatrix;\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\nuniform mat4 viewMatrix;\nuniform mat3 normalMatrix;\nuniform vec3 cameraPosition;\nuniform float time;\nuniform vec3 color;\nuniform vec3 lightPosition;\nvarying vec3 vPosition;\nvarying vec3 vNormal;\nvarying vec3 vColor;\nvarying vec2 vUv;\nvarying vec2 vUv2;\n\nvoid main() {\n    vec3 worldPosition = ( modelMatrix * vec4( vPosition, 1.0 )).xyz;\n    vec3 worldNormal = normalize( vec3( modelMatrix * vec4( vNormal, 0.0 ) ) );\n    vec3 lightVector = normalize( lightPosition - worldPosition );\n    float brightness = dot( worldNormal, lightVector );\n    gl_FragColor = vec4( color * brightness, 1.0 );\n}",
  "vertexShader": "precision highp float;\nprecision highp int;\nuniform mat4 modelMatrix;\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\nuniform mat4 viewMatrix;\nuniform mat3 normalMatrix;\nuniform vec3 cameraPosition;\nuniform float time;\nuniform vec3 color;\nattribute vec3 position;\nattribute vec3 normal;\nattribute vec2 uv;\nattribute vec2 uv2;\nvarying vec3 vPosition;\nvarying vec3 vNormal;\nvarying vec2 vUv;\nvarying vec2 vUv2;\nvoid main() {\n    vNormal = normal;\n    vUv = uv;\n    vUv2 = uv2;\n    vPosition = position;\n    gl_Position= projectionMatrix * modelViewMatrix * vec4( position+sin(position*time)/10., 1. );\n}",
  "uniforms": {
    "time": {
      "value":0
    },
    "color": {
      "value": new THREE.Color(0x320064)
    },
    "lightPosition": {
      "value": new THREE.Vector3().setScalar(5)
    }
  }
});
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);
camera.position.z = 3;

function render() {
  cube.material.uniforms.time.value+=0.1;
  renderer.render(scene, camera);
  cube.rotation.x += 0.01;
  cube.rotation.y -= 0.01;
  requestAnimationFrame(render);
}

render();
</script>