Анимированный декартовый каркас на Three.js

THREE.js r83

Я пытаюсь отобразить каркас сетки в декартовом стиле поверх моей модели, которую нужно анимировать (с помощью AnimationMixer). Я пробовал использовать подход EdgesGeometry / LineBasicMaterial / LineSegments, как показано ниже (из этот ответ):

var geo = new THREE.EdgesGeometry( mesh.geometry ); 
var mat = new THREE.LineBasicMaterial( { color: 0xffffff, linewidth: 2 } );
var wireframe = new THREE.LineSegments( geo, mat );
mesh.add( wireframe );

но если я чего-то не упускаю, не похоже, что это можно анимировать (нет атрибута morphTargets и т. д.).

Я переключился на использование собственного шейдера с использованием ShaderMaterial или RawShaderMaterial со следующими шейдерами (на основе https://github.com/rreusser/glsl-solid-wireframe/tree/master/cartesian):

// vertex shader
precision mediump float;
uniform mat4 projection, view;
attribute vec3 position;
attribute vec3 barycentric;
varying vec3 b;
varying vec3 p;

void main () {
    b = barycentric;
    p = position;
    gl_Position = projection * view * vec4(position, 1);
}

// fragment shader
precision mediump float;
    varying vec3 b;
    varying vec3 p;
    uniform float cartesianX, cartesianY, cartesianZ;
    uniform float width, feather;

    float gridFactor (float parameter, float width_0, float feather_0) {
      float w1 = width_0 - feather_0 * 0.5;
      float d = fwidth(parameter);
      float looped = 0.5 - abs(mod(parameter, 1.0) - 0.5);
      return smoothstep(d * w1, d * (w1 + feather_0), looped);
    }
    float gridFactor (vec2 parameter, float width_0, float feather_0) {
        float w1 = width_0 - feather_0 * 0.5;  vec2 d = fwidth(parameter);
        vec2 looped = 0.5 - abs(mod(parameter, 1.0) - 0.5);
        vec2 a2 = smoothstep(d * w1, d * (w1 + feather_0), looped);
        return min(a2.x, a2.y);
    }
    float gridFactor (vec3 parameter, float width_0, float feather_0) {
        float w1 = width_0 - feather_0 * 0.5;
        vec3 d = fwidth(parameter);
        vec3 looped = 0.5 - abs(mod(parameter, 1.0) - 0.5);
        vec3 a3 = smoothstep(d * w1, d * (w1 + feather_0), looped);
        return min(min(a3.x, a3.y), a3.z);
    }
    float gridFactor (vec4 parameter, float width_0, float feather_0) {
        float w1 = width_0 - feather_0 * 0.5;
        vec4 d = fwidth(parameter);
        vec4 looped = 0.5 - abs(mod(parameter, 1.0) - 0.5);
        vec4 a4 = smoothstep(d * w1, d * (w1 + feather_0), looped);
        return min(min(min(a4.x, a4.y), a4.z), a4.w);
    }
    float gridFactor (float parameter, float width_0) {
        float d = fwidth(parameter);
        float looped = 0.5 - abs(mod(parameter, 1.0) - 0.5);
        return smoothstep(d * (width_0 - 0.5), d * (width_0 + 0.5), looped);
    }
    float gridFactor (vec2 parameter, float width_0) {
        vec2 d = fwidth(parameter);
        vec2 looped = 0.5 - abs(mod(parameter, 1.0) - 0.5);
        vec2 a2 = smoothstep(d * (width_0 - 0.5), d * (width_0 + 0.5), looped);
        return min(a2.x, a2.y);
    }
    float gridFactor (vec3 parameter, float width_0) {
        vec3 d = fwidth(parameter);
        vec3 looped = 0.5 - abs(mod(parameter, 1.0) - 0.5);
        vec3 a3 = smoothstep(d * (width_0 - 0.5), d * (width_0 + 0.5), looped);
        return min(min(a3.x, a3.y), a3.z);
    }
    float gridFactor (vec4 parameter, float width_0) {
        vec4 d = fwidth(parameter);
        vec4 looped = 0.5 - abs(mod(parameter, 1.0) - 0.5);
        vec4 a4 = smoothstep(d * (width_0 - 0.5), d * (width_0 + 0.5), looped);
        return min(min(min(a4.x, a4.y), a4.z), a4.z);
    }

        void main () {
            float g = gridFactor( vec3( cartesianX > 0.0 ? p.x * cartesianX : 0.5, cartesianY > 0.0 ? p.y * cartesianY : 0.5, cartesianZ > 0.0 ? p.z * cartesianZ : 0.5 ), width, feather);
            gl_FragColor = vec4(mix(vec3(0), vec3(0.8), g), 1);
        }

А вот как определяется RawShaderMaterial:

new THREE.RawShaderMaterial({
                // uniforms: uniforms,
                derivatives: true,
                vertexShader: document.getElementById('vertexshader').textContent,
                fragmentShader: document.getElementById('fragmentshader').textContent,
                depthTest: false,
                side: THREE.DoubleSide,
                wireframe: true,
                lights: false,
                visible: true,
                color: 0x000000
            }))

Но при таком подходе ничего не отображается, хотя я получаю следующее предупреждение:

three.js:17014 THREE.WebGLProgram: gl.getProgramInfoLog() WARNING: Output of vertex shader 'b' not read by fragment shader

Я плохо разбираюсь в необработанном коде webgl, поэтому не уверен, насколько это важно.

Обобщить:

  1. У меня сложилось впечатление, что подход EdgesGeometry / LineBasicMaterial / LineSegments не может быть анимирован как есть, я ошибаюсь?

  2. Если это правда, я остаюсь с шейдерным подходом. Может ли кто-нибудь с большим опытом работы с webgl сказать мне, что здесь не так?

Обновлено: Похоже, что подход шейдера НЕ будет работать для меня, поскольку, похоже, мой шейдер должен будет иметь возможность обрабатывать анимацию, и я думаю, что это будет слишком сложно для меня в настоящее время. Итак, вернемся к первой части: есть ли способ заставить LineSegments анимировать с помощью AnimationMixer или, может быть, просто воспроизвести этот вид с помощью другой настройки?

Загляните на этот форум нить.

prisoner849 09.03.2018 23:20

В вашем шейдере много чего происходит. Один из способов отладки шейдеров - выводить цвет на любую трансформируемую сетку. С необработанным шейдером у вас есть больше движущихся частей, которые могут сломаться, например, ваши view и projection настроены правильно? По крайней мере, с ShaderMaterial вы можете рассчитывать на эти два (projectionMatrix и viewMatrix имеют 100% точность). Оттуда я отлаживал эти функции фрагментов одну за другой. Без них можно вывести плоский цвет и получить желаемую форму геометрии. Проверять. Далее, одна из этих функций, желаемые результаты? Проверять. Следующий...

pailhead 09.03.2018 23:27
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
2
289
0

Другие вопросы по теме