Передача в векторе OnBeforeCompile Три js - PullRequest
0 голосов
/ 22 октября 2019

Я пытаюсь передать вектор в уже существующий фрагментный шейдер с тремя js с onBeforeCompile следующим образом:

var material = new THREE.MeshPhongMaterial({
            map: myLoadedTexture,
            shininess: 0,
            bumpMap: myBumpMap,
            bumpScale: 0.1,
            fog: true
        });

let myVector = new THREE.Vector3(1,0,0);

material.userData.myVector = { value: myVector };

material.onBeforeCompile = function (shader) {

     shader.uniforms.myVector = material.userData.myVector;

     shader.fragmentShader = 'uniform vec3 myVector;\n' + shader.fragmentShader;
     shader.fragmentShader = shader.fragmentShader.replace('#include <map_fragment>',
     `
     // some other code here

     // If I comment this out, the shader runs
     float result = dot(vNormal, myVector);


     `)
}

Я получаю следующую ошибку: TypeError: Cannot read property 'needsUpdate' of undefined, которая выглядит очень странно, так каквектор определен.

Есть подсказки?

1 Ответ

0 голосов
/ 22 октября 2019

Ваш код работает на меня. Я думаю, что ваша ошибка в другом месте.

function main() {
  const canvas = document.querySelector('#c');
  const renderer = new THREE.WebGLRenderer({canvas});

  const fov = 75;
  const aspect = 2;  // the canvas default
  const near = 0.1;
  const far = 5;
  const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
  camera.position.z = 2;

  const scene = new THREE.Scene();

  {
    const color = 0xFFFFFF;
    const intensity = 1;
    const light = new THREE.DirectionalLight(color, intensity);
    light.position.set(-1, 2, 4);
    scene.add(light);
  }

  const boxWidth = 1;
  const boxHeight = 1;
  const boxDepth = 1;
  const geometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth);

  const loader = new THREE.TextureLoader();
  const myLoadedTexture = loader.load('https://i.imgur.com/fqgm8uh.png');
  const myBumpMap = myLoadedTexture;

  var material = new THREE.MeshPhongMaterial({
              map: myLoadedTexture,
              shininess: 0,
              bumpMap: myBumpMap,
              bumpScale: 0.1,
              fog: true
          });

  let myVector = new THREE.Vector3(1,0,0);

  material.userData.myVector = { value: myVector };

  material.onBeforeCompile = function (shader) {

       shader.uniforms.myVector = material.userData.myVector;

       shader.fragmentShader = 'uniform vec3 myVector;\n' + shader.fragmentShader;
       shader.fragmentShader = shader.fragmentShader.replace('#include <map_fragment>',
       `
       // some other code here

       // If I comment this out, the shader runs
       float result = dot(vNormal, myVector);


       `)
  }  

  const cube = new THREE.Mesh(geometry, material);
  scene.add(cube);

  function render(time) {
    time *= 0.001;  // convert time to seconds

    cube.rotation.x = time;
    cube.rotation.y = time;

    renderer.render(scene, camera);

    requestAnimationFrame(render);
  }
  requestAnimationFrame(render);

}

main();
<canvas id="c"></canvas>
<script src="https://threejsfundamentals.org/threejs/resources/threejs/r108/build/three.min.js"></script>
...