Освещение не обновляется при использовании пользовательских ShaderMaterial и InstancedBufferGeometry - PullRequest
0 голосов
/ 25 октября 2019

Я сделал сцену, используя InstancedBufferGeometry , созданный из модели gltf, и используя spritesheet для создания множества объектов с одинаковой формой, но другой текстурой. Это почти успешно, но свет не обновляется при его вращении. (Я поместил 20 экземпляров объектов прямо перед скрипкой)

(изображение) описание того, что происходит

Я думаю, что освещение работает и просто не обновляется, потому что всекубов имеет светлое лицо и темное лицо.

Когда я добавляю один и тот же объект с помощью gltf.scene (прямоугольник справа от скрипки), все работает нормально. Освещение обновляется по мере его вращения.

Это моя материальная часть кода. Я улучшил существующий материал Ламберта, используя onBeforeCompile для InstancedBufferGeometry, используя spritesheet.
Spritesheet разделен на 4x4 фрагмента, поэтому я установил пользовательский параметр vUvScale в 1/4 и использовал часть текстуры, указав координаты для атрибута vUvOffsets.

const material = new THREE.MeshLambertMaterial({map: new THREE.TextureLoader().load('https://rawcdn.githack.com/maemaemae3/threejs_instancing_light_test/4a73876e64ff257aaed6222935bbcb537a74eac8/models/boxSprite.png')});

material.onBeforeCompile = function( shader ) {
    const vert_insert_transform = "#include <project_vertex>"
    const vert_insert_vUvOffset = "#include <fog_vertex>";
    const frag_insert_map_pars  = "#include <map_pars_fragment>"
    const frag_insert_map       = "#include <map_fragment>"
    const vert_chunk_instance   = `
attribute vec3 translation;
attribute vec4 orientation;
attribute vec3 scale;

attribute vec2 vUvOffsets;
varying vec2 v_vUvOffsets;
uniform float vUvScale;
`;
    const vert_chunk_vUvOffset = THREE.ShaderChunk.fog_vertex + `
v_vUvOffsets = vUvOffsets;
`
    const vert_chunk_transform  = `
transformed *= scale;
vec3 vcV = cross(orientation.xyz, transformed);
transformed = vcV * (2.0 * orientation.w) + (cross(orientation.xyz, vcV) * 2.0 + transformed);
vec4 mvPosition = modelViewMatrix * vec4(translation + transformed, 1.0);
gl_Position = projectionMatrix * mvPosition;
`
    const frag_chunk_map_pars = `
#ifdef USE_MAP
uniform sampler2D map;
uniform float vUvScale;
varying vec2 v_vUvOffsets;
#endif
`
    const frag_chunk_map = `
#ifdef USE_MAP
vec4 texelColor = texture2D( map, (vUv * vUvScale) + (v_vUvOffsets * vUvScale) );

texelColor = mapTexelToLinear( texelColor );
diffuseColor *= texelColor;
#endif
`
    shader.vertexShader = vert_chunk_instance + shader.vertexShader;
    shader.vertexShader = shader.vertexShader.replace(vert_insert_vUvOffset, vert_chunk_vUvOffset);
    shader.vertexShader = shader.vertexShader.replace(vert_insert_transform, vert_chunk_transform);
    shader.fragmentShader = shader.fragmentShader.replace(frag_insert_map_pars, frag_chunk_map_pars);
    shader.fragmentShader = shader.fragmentShader.replace(frag_insert_map, frag_chunk_map);

    shader.uniforms.vUvScale = { value: 1 / 4 }
};

моя скрипка: https://jsfiddle.net/maemaemae3/v51jL27c/35/

Обновление (12 ноября 2019 г.) : я обновил свой код и написал соответствующую часть кода здесьслишком. (Извините за то, что не знаете правила, что вопрос просто поставить ссылку - это плохо)

...