WebRTC и ThreeJS для создания текстуры матового металлаCube

Я пытаюсь применить THREE.ImageUtils.loadTextureCube() с помощью камеры реального времени к вращающемуся кубу.

До сих пор мне удавалось применить простую текстуру, используя мое видео, к MeshLambertMaterial :

var geometry = new THREE.CubeGeometry(100, 100, 100, 10, 10, 10);
videoTexture = new THREE.Texture( Video ); // var "Video" is my <video> element
var material = new THREE.MeshLambertMaterial({ map: videoTexture });
Cube = new THREE.Mesh(geometry, material);
Scene.add( Cube );

Это нормально, и вы можете увидеть результат на странице http://jmpp.fr/three-camera.

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

var videoSource = decodeURIComponent(Video.src);
var environment = THREE.ImageUtils.loadTextureCube([videoSource, // left
                                                    videoSource, // right
                                                    videoSource, // top
                                                    videoSource, // bottom
                                                    videoSource, // front
                                                    videoSource]); // back
var material = new THREE.MeshPhongMaterial({ envMap: environment });

... но выдает следующую ошибку:

blob:http://localhost/dad58cd1-1557-41dd-beed-dbfea4c340db 404 (Not Found) 

Я предполагаю, что loadTextureCube() пытается получить 6 параметров массива в виде изображения, но вместо этого, похоже, не ценит videoSource.

Я начинаю с трех и задаюсь вопросом, есть ли способ сделать это?

Спасибо, джмпп


person jmpp    schedule 03.12.2012    source источник


Ответы (3)


Есть два пути, которые я мог видеть. Во-первых, если вы просто хотите такое же изображение, но с некоторыми бликами/блестками, просто измените

var material = new THREE.MeshLambertMaterial({ map:texture});

to

var material = new THREE.MeshPhongMaterial({ 
         map: texture , 
         ambient: 0x030303, 
         specular: 0xffffff, 
         shininess: 90
});

и поиграйте с настройками окружающего, бликового и сияющего, чтобы найти то, что вам нравится.

Во-вторых, если вы действительно хотите добавить эффекты к самому видеоизображению, вы можете нарисовать изображение на холсте, манипулировать пикселями, а затем установить изображение текстуры для этого нового изображения. Это также можно сделать с помощью пользовательских шейдеров, избегая шага холста, но уже есть библиотеки для применения фильтров изображений к элементам, поэтому я бы придерживался этого. Это будет работать примерно так: вам понадобится холст для рисования <canvas id='testCanvas' width=256 height=256></canvas> Затем с помощью javascript

var ctx = document.getElementById('testCanvas').getContext('2d');
texture = new THREE.Texture();

// in the render loop
ctx.drawImage(Video,0,0);
var img = ctx.getImageData(0,0,c.width,c.height);
// do something with the img.data pixels, see 
// this article http://www.html5rocks.com/en/tutorials/canvas/imagefilters/
// then write it back to the texture
texture.image = img;

texture.needsUpdate = true

Обновлено!

На самом деле, вы можете сделать это как envMap, вам просто нужно заставить видео быть степенью 2 с одинаковой шириной/высотой. Видео передаются в Chrome как 640x480, поэтому вам все равно нужно рисовать холст, но только для обрезки/квадрата изображения. Итак, я заставил это работать:

 // In the access camera part
 var canvas = document.createElement('canvas')
     canvas.width = 512;
     canvas.height = 512;
 ctx = canvas.getContext('2d');   

 // In render loop 
 ctx.drawImage(Video,0,0, 512, 512);
 img = ctx.getImageData(0,0,512,512);
 // This part is a little different, but env maps have an array 
 // of images instead of just one
 cubeVideo.image = [img,img,img,img,img,img];
 if (Video.readyState === Video.HAVE_ENOUGH_DATA)
     cubeVideo.needsUpdate = true;
person Paul Kaplan    schedule 03.12.2012
comment
На самом деле я не хочу манипулировать пикселями изображения, но я хотел бы получить тот же эффект, что и этот: animateyourhtml5.appspot.com/part4-webgl/index.html (это самый последний пример справа), но с источником видео вместо JPG - person jmpp; 03.12.2012

Попробуй это:

var environment = new THREE.Texture( [ Video, Video, Video, Video, Video, Video ] );
var material = new THREE.MeshPhongMaterial({ envMap: environment });

// in animate()
environment.needsUpdate = true;
person mrdoob    schedule 03.12.2012
comment
это не сработало для меня, вы проверяли это или я что-то напутал? - person Paul Kaplan; 03.12.2012
comment
Я не проверял это. Но да, текстура, вероятно, должна быть pow2, как в вашем ответе. - person mrdoob; 03.12.2012
comment
Я просто получаю черный куб с этим :-/ Я также пробовал с Video.src, может быть, потому, что 6 параметров должны быть URL-адресами, как при использовании JPG? - person jmpp; 03.12.2012
comment
@mrdoob изучил это подробнее, и хром дает вам разрешение 640x480, и я не думаю, что вы можете изменить его, не рисуя его на холсте, так что да, сила 2 остановит такое простое решение. - person Paul Kaplan; 07.12.2012

Хорошо, теперь мне удалось получить блестящий эффект на кубе, используя материал Фонга:

videoTexture = new THREE.Texture( Video );
var material = new THREE.MeshPhongMaterial({
    map: videoTexture,
    ambient: 0x030303,
    specular: 0xc0c0c0,
    shininess: 25
});

Это выглядит не так уж и плохо.

Но похоже, что THREE.Texture([Video,Video,Video,Video,Video,Video]); не работает как envMap. Я все еще получаю черный куб.

person jmpp    schedule 03.12.2012
comment
подождите, это просто мой ответ. - person Paul Kaplan; 03.12.2012
comment
Ага, спасибо за это. Блестящий эффект выглядит очень круто. Но это не решает мою проблему с THREE.ImageUtils.loadTextureCube() :) - person jmpp; 03.12.2012
comment
хм, но ответ, который вы опубликовали, мой :( - person Paul Kaplan; 04.12.2012
comment
Мой плохой, я только что понял, что вы имеете в виду. В настоящее время я еще не освоился с системой ответов stackoverflow. Извините :/ - person jmpp; 04.12.2012