Контур сложной формы

Скажем, у меня есть этот символ, и я хочу, чтобы пользователь мог его выбрать, поэтому, когда он выбран, я хочу показать схему вокруг него.

enter image description hereenter image description here

символ - объект3D с некоторыми сетками. Я попытался клонировать и установить задний материал, но он НЕ работал, проблема заключалась в том, что каждый куб в форме визуализировался с обратной стороны отдельно, поэтому контур был неправильным.

Мне нужно создать еще одну сетку для контура, есть ли более простой способ?

Ответ 1

То, что написал @spassvolgel, верно;

Я подозреваю, что нужно сделать что-то вроде этого: 1. Сначала нужно отрисовать фон 2. Затем на отдельном прозрачном слое модель персонажа с плоским цветом, немного больше оригинала, 3. На другом прозрачном слой персонажа с его обычным материалом/текстурой 4. Наконец, слой персонажа должен идти поверх слоя с контуром, и их вместе нужно поместить в bg

Вы просто создаете несколько сцен и комбинируете их с последовательными проходами рендеринга:

renderer.autoClear = false;
. . . 

renderer.render(scene, camera); // the entire scene
renderer.clearDepth();
renderer.render(scene2, camera); // just the selected item, larger, in a flat color
renderer.render(scene3, camera); // the selected item again

Вот скрипка, реализованная с помощью выбора GPU, но ее можно легко реализовать с помощью более знакомого Raycaster:

Скрипка: http://jsfiddle.net/Tcb3z/

Screenshot of selected item outlined

three.js.r.66

Ответ 2

Общее решение, применимое к геометрии любой сложности, может заключаться в применении шейдера фрагментов через ShaderMaterial class в three.js. Не уверен, что такое уровень вашего опыта, но если вам это нужно, вы можете найти введение в шейдеры здесь.

Хороший пример, где шейдеры используются для выделения геометрий, можно найти здесь. В своем вершинном шейдере они вычисляют нормаль для вершины и параметр, используемый для выражения интенсивности эффекта свечения:

uniform vec3 viewVector;
uniform float c;
uniform float p;
varying float intensity;
void main() 
{
    vec3 vNormal = normalize( normalMatrix * normal );
    vec3 vNormel = normalize( normalMatrix * viewVector );
    intensity = pow( c - dot(vNormal, vNormel), p );

    gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}

Эти параметры передаются в шейдер фрагмента, где они используются для изменения значений цвета пикселей, окружающих геометрию:

uniform vec3 glowColor;
varying float intensity;
void main() 
{
    vec3 glow = glowColor * intensity;
    gl_FragColor = vec4( glow, 1.0 );
}

Ответ 4

Я еще не нашел ответа, но я хотел продемонстрировать, что происходит, когда я создаю несколько сеток, и помещаю другую сетку за каждую из этих сеток с помощью

side: THREE.BackSide  

http://jsfiddle.net/GwS9c/8/

как вы можете видеть, это не желаемый эффект. Я бы хотел, чтобы чистый план позади ВСЕХ трех сеток, которые не перекрываются. Мой уровень программирования шейдеров действительно не существует, но в большинстве онлайн-ресурсов люди говорят, что используют этот подход для клонирования сеток.

Ответ 5

Вы можете получить хорошие результаты путем рендеринга вашего выделенного объекта (объектов) в текстуру, которая (в идеале) соответствует размеру целевого кадрового буфера, затем рендеринг четырехугольника размером с кадровый буфер с использованием этой текстуры и смазывание фрагментного шейдера или преобразование другого изображения. У меня есть пример здесь, который использует сырые WebGL, но вы можете сделать пользовательский ShaderMaterial без особых проблем.