Для отображение трехмерного пространства в браузере, с недавних пор, используют WebGL.
WebGL позволяет отображать такое пространство без дополнительных плагинов, используя видеокарту для вычислений. Это позволяет добиться высокой скорости выполнения кода и,
соответственно, высокого FPS (кадров в секунду).
Конечно, WebGL облегчает и разработку трехмерных приложений (не нужно самостоятельно
пересчитывать матрицы вершин объектов и просчитывать видимость граней), но для непосвященного пользователя и такой стиль
записи слишком сложен.
Например для создания куба придется написать что-то подобное:
Только малая часть программистов любят поработать рерайтером, чтобы сделать свой куб...
Поэтому упростит нам жизнь библиотека Three.js (скачать можно тут: архив three.js с офф. сайта)
Чтобы создать примитив в three.js достаточно написать:
С помощью примера earth, из библиотеки Three.js, сделаем вращающуюся землю:
Результат - 75 строк вместе с комментариями (меньше, чем создание куба в чистом WebGL) и выглядит неплохо.
Если у Вас работает WebGL, то можете посмотреть реализованный пример ниже:
Спасибо за внимание.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | function createCube(gl) { // Vertex Data var vertexBuffer; vertexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); var verts = [ // Front face −1.0, −1.0, 1.0, 1.0, −1.0, 1.0, 1.0, 1.0, 1.0, −1.0, 1.0, 1.0, // Back face −1.0, −1.0, −1.0, −1.0, 1.0, −1.0, 1.0, 1.0, −1.0, 1.0, −1.0, −1.0, // Top face −1.0, 1.0, −1.0, −1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, −1.0, // Bottom face −1.0, −1.0, −1.0, 1.0, −1.0, −1.0, 1.0, −1.0, 1.0, −1.0, −1.0, 1.0, // Right face 1.0, −1.0, −1.0, 1.0, 1.0, −1.0, 1.0, 1.0, 1.0, 1.0, −1.0, 1.0, // Left face −1.0, −1.0, −1.0, −1.0, −1.0, 1.0, −1.0, 1.0, 1.0, −1.0, 1.0, −1.0 ]; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verts), gl.STATIC_DRAW); // Color data var colorBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); var faceColors = [ [1.0, 0.0, 0.0, 1.0], // Front face [0.0, 1.0, 0.0, 1.0], // Back face [0.0, 0.0, 1.0, 1.0], // Top face [1.0, 1.0, 0.0, 1.0], // Bottom face [1.0, 0.0, 1.0, 1.0], // Right face [0.0, 1.0, 1.0, 1.0] // Left face ]; var vertexColors = []; for ( var i in faceColors) { var color = faceColors[i]; for ( var j=0; j < 4; j++) { vertexColors = vertexColors.concat(color); } } gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexColors), gl.STATIC_DRAW); // Index data (defines the triangles to be drawn) var cubeIndexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeIndexBuffer); var cubeIndices = [ 0, 1, 2, 0, 2, 3, // Front face 4, 5, 6, 4, 6, 7, // Back face 8, 9, 10, 8, 10, 11, // Top face 12, 13, 14, 12, 14, 15, // Bottom face 16, 17, 18, 16, 18, 19, // Right face 20, 21, 22, 20, 22, 23 // Left face ]; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeIndices), gl.STATIC_DRAW); var cube = {buffer:vertexBuffer, colorBuffer:colorBuffer, indices:cubeIndexBuffer, vertSize:3, nVerts:24, colorSize:4, nColors: 24, nIndices:36, primtype:gl.TRIANGLES}; return cube; } |
1 | var geometry = new THREE.SphereGeometry( 200, 20, 20 ); |
1 2 | < div id = "container" style = "min-height:300px;" ></ div > < script src = "/javascripts/three.js/build/three.min.js" ></ script > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | var container, camera, scene, renderer, group; var windowHalfX = $(container).width() / 2, windowHalfY = $(container).height() / 2; //запускает инициализацию init(); animate(); //Функция инициализирует сцену, //создает камеру и устанавливает режим отображения function init() { //получает контейнер для добавления канваса в него container = document.getElementById( 'container' ); //поворачивает наши 3D объекты, при наведении мыши container.onmousemove= function (event){ group.rotation.y+=event.movementX/30; group.rotation.x+=event.movementY/30; } //создаем камеру camera = new THREE.PerspectiveCamera( 60, $(container).width() / $(container).height(), 1, 2000 ); camera.position.z = 500; //создаем сцену, группу. добавляем группу в сцену scene = new THREE.Scene(); group = new THREE.Group(); scene.add( group ); //создаем загрузчик текстур var loader = new THREE.TextureLoader(); //грузим loader.load( '/images/news/101-earth.jpg' , /* тут колбек */ function ( texture ) { //вызывается при загрузке //создает примитив, материал var geometry = new THREE.SphereGeometry( 200, 20, 20 ); var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: 0.5 } ); //создает меш(поверхность) планеты по геометрии var mesh = new THREE.Mesh( geometry, material ); //добавляет объект в группу group.add( mesh ); } ); //получает канвас (хост) //т.е. место на чем будет рисовать var canvas = document.createElement( 'canvas' ); canvas.width = 128; canvas.height = 128; //создаем рисующий объект renderer = new THREE.WebGLRenderer(); //устанавливаем цвет фона renderer.setClearColor(0xeeeeee); //разрешение renderer.setPixelRatio(window.devicePixelRatio); //размеры рисуемого хоста renderer.setSize($(container).width(), $(container).height()); //добавляем в контейнер container.appendChild(renderer.domElement); } //отобразит анимацию модели, если она есть function animate() { requestAnimationFrame( animate ); render(); } //поворачивает модель планеты //вызывает перерисовку сцены function render() { //поворачиваем камеру camera.lookAt( scene.position ); //поворачиваем модель group.rotation.y -= 0.01; //отрисовываем renderer.render( scene, camera ); } |