Нарисуйте для него (нее) праздничный 3D-торт с помощью Three.js

внешний интерфейс JavaScript three.js
Нарисуйте для него (нее) праздничный 3D-торт с помощью Three.js

Как фронтенд-инженер, который весь день занимается пользовательским интерфейсом, хотите ли вы удивить его или ее кодом на его или ее день рождения?

С тем же успехом вы можете использовать Three.js, чтобы сделать 3D-торт для ta, который одновременно романтичен и демонстрирует очарование вашей технологии.

В этой статье мы научимся рисовать торт с помощью Three.js.

Кодовый адрес:GitHub.com/кварк глюон P…

Основание, связанное с Three.js

Three.js управляет всеми объектами через сцену сцены, а добавленные на сцену объекты также можно разделить на группы:

const scene = new THREE.Scene();

scene.add(xxx);

const group = new THREE.Group();
group.add(yyy);
group.add(zzz);

scene.add(group);

Если вы хотите визуализировать все объекты в сцене, вам нужно указать камеру, а затем использовать средство визуализации для визуализации.Если есть эффект анимации, используйте requestAnimationFrame для непрерывной визуализации кадр за кадром.

const renderer = new THREE.WebGLRenderer();

 function render() {        
    renderer.render(scene, camera);
    requestAnimationFrame(render);
 }
 render();

Камера камеры разделена на перспективную камеру PerspectiveCamera, которая смотрит из точки, и ортогональную камеру OrthographicCamera, которая проецируется с поверхности.

Характеристики перспективной камеры в том, что она почти большая и далеко маленькая, а ортогональная - нет, это параллельная проекция, и размер неизменен.

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

  • Точечный свет: излучает свет из точки, как лампочка.
  • параллельный свет: параллельный свет
  • Окружающий свет: равномерно освещает везде
  • Прожектор: источник света для сценических прожекторов.

В 3D-сцене существует много видов объектов, например, плоскость, которая всегда обращена к камере, — это спрайт (мы делаем"Цветочный дождь"эффект) и объект, состоящий из треугольников, называемый сеткой.

Чаще используется сетка, она представляет собой геометрию, состоящую из треугольников, и также может быть отображена на каждой поверхности. Итак, есть два параметра: Geometry и Material.

Например, цилиндр — это Mesh, при его создании укажите геометрию цилиндра CylinderBufferGeometry и материал каждой грани.

const 圆柱几何体 = new THREE.CylinderBufferGeometry(上圆半径, 下圆半径, 高度, 侧面分段数量);

const 侧面材质 = new THREE.MeshBasicMaterial({map: 纹理图片});
const 上面材质 = new THREE.MeshBasicMaterial({color: 'red'});
const 下面材质 = new THREE.MeshBasicMaterial({color: 'red'});

const 圆柱 = new THREE.Mesh(圆柱几何体, [侧面材质, 上面材质, 下面材质]);

MeshBasicMaterial — это базовый материал, вы можете указать цвет по цвету или указать текстуру изображения текстуры по карте.

Среди различных мешей особенным является текст, который использует TextGeometry, и текст необходимо загружать из xxx.typeface.json.

И этот файл json можно преобразовать с помощью файла шрифта ttf. использоватьttf на этот сайт typeface.jsonПриходи и уходи:

Затем может отображаться текст:

const fontLoader = new THREE.FontLoader();

fontLoader.load('./font/xxx.typeface.json', function (font) {
    var textGeometry = new THREE.TextGeometry('文字', 参数);
    const textMaterial = [
        new THREE.MeshBasicMaterial({color: '字体颜色'}),
        new THREE.MeshBasicMaterial({color: '侧面颜色'}),
    ];

    const text = new THREE.Mesh(textGeometry, textMaterial);
});

Это основы Three.js, которые мы будем использовать, и краткое изложение:

Three.js управляет различными объектами через сцену, а также объекты можно группировать.

Общие объекты включают Mesh и Sprite.Sprite — это плоскость, которая всегда обращена к камере, а Mesh — это трехмерный объект, состоящий из треугольников. Сетка Чтобы указать геометрию Геометрия и материал Материал, обычно используемый материал может быть картой цвета или текстуры. Текст TextGeometry является особенным и требует файла typeface.json, который можно преобразовать с помощью ttf.

После того, как объекты в сцене готовы, вам также необходимо установить источник света Light и камеру Camera.Камера в основном включает в себя перспективную камеру, которая смотрит из точки, и ортогональную камеру, которая проецируется из плоскости.После этого она может рендерером. Объедините requestAnimationFrame для рендеринга кадр за кадром.

Изучив азы, мы официально приступили к рисованию тортов.

Нарисуйте 3D торт

Торт на самом деле состоит из 4 цилиндров плюс текст.Каждый цилиндр имеет разное положение.Боковая, верхняя и нижняя стороны цилиндра наклеены с разными текстурами, что и является тортом.

Сначала приготовим текстуру торта:

Используйте загрузчик текстур TextureLoader для их загрузки:

const cakeTexture1 = new THREE.TextureLoader().load('img/cake1.png');
const cakeTexture2 = new THREE.TextureLoader().load('img/cake2.png');
const cakeTexture3 = new THREE.TextureLoader().load(`img/cake3.png`);
const cakeTexture4 = new THREE.TextureLoader().load('img/cake4.png');

Затем создайте материал для текстурной карты:

const cakeMaterail1 = new THREE.MeshBasicMaterial({map: cakeTexture1});
const cakeMaterail2 = new THREE.MeshBasicMaterial({map: cakeTexture2});
const cakeMaterail3 = new THREE.MeshBasicMaterial({map: cakeTexture3});
const cakeMaterail4 = new THREE.MeshBasicMaterial({map: cakeTexture4}); 

В дополнение к материалу текстурной карты подготовьте материал, состоящий из цветов:

const pinkMaterial = new THREE.MeshBasicMaterial({color: 'pink'});

Затем создайте 4 цилиндрических объекта (Mesh) с разными материалами текстуры и цвета:

const cakeGeometry1 = new THREE.CylinderBufferGeometry(100, 100, 70, 40);
const cakePart1 = new THREE.Mesh(cakeGeometry1, [cakeMaterail1, pinkMaterial, pinkMaterial]);

Параметры цилиндрической геометрии CylinderBufferGeometry — радиус верхней окружности, радиус нижней окружности, высота и количество делений на стороне.

Радиус круга выше остается прежним, так что это цилиндр. Количество боковых разделений установлено на 40, что более плавно.

Затем установите смещение, а затем вы можете добавить его в группу торта.

Точно так же создаем четыре цилиндра, задаем разные размеры и положения и вставляем разные изображения:

const cakeGeometry1 = new THREE.CylinderBufferGeometry(100, 100, 70, 40);
const cakePart1 = new THREE.Mesh(cakeGeometry1, [cakeMaterail1, pinkMaterial, pinkMaterial]);
cakePart1.translateY(45)

const cakeGeometry2 = new THREE.CylinderBufferGeometry(120, 120, 70, 40);
const cakePart2 = new THREE.Mesh(cakeGeometry2,[cakeMaterail3, pinkMaterial, pinkMaterial]);
cakePart2.translateY(-25)

const cakeGeometry3 = new THREE.CylinderBufferGeometry(140, 140, 60, 40);
const cakePart3 = new THREE.Mesh(cakeGeometry3, [cakeMaterail2, pinkMaterial, pinkMaterial]);
cakePart3.translateY(-90)

const cakeGeometry4 = new THREE.CylinderBufferGeometry(160, 160, 10, 40);
const cakePart4 = new THREE.Mesh(cakeGeometry4, [cakeMaterail4, cakeMaterail4, cakeMaterail4]);
cakePart4.translateY(-120)

cake.add(cakePart1)
cake.add(cakePart2)
cake.add(cakePart3)
cake.add(cakePart4)

Если вы не уверены в положении координат, вы можете добавить в сцену вспомогательный инструмент координат AxisHelper. Параметр - длина оси.

const axisHelper = new THREE.AxisHelper(2500);
scene.add(axisHelper);

Затем идет текстовая часть, которую нужно преобразовать в файл typeface.json через файл шрифта ttf, затем загрузить с помощью fontLoader, а затем создать соответствующий Mesh:

fontLoader.load('./font/guang.typeface.json', function (font) {
    var textGeometry = new THREE.TextGeometry('光光', {
        font: font,
        size: 30,
        height: 5,
        bevelEnabled: true,
        bevelSize: 10,
    });
    const textMaterial = ['white', 'red'].map(color => new THREE.MeshBasicMaterial({color}));

    const text = new THREE.Mesh(textGeometry, textMaterial);
    text.translateY(90)
    text.translateX(-45)

    cake.add(text); 
});

В параметрах TextGeometry нужно задать размер шрифта с размером, если толщина по высоте, а край изогнут bevelEnabled, размер и поверхность bevelSize.

Эффект, который мы здесь имеем, заключается в включении поверхности.

После того, как нарисованы 4 цилиндра и нарисован текст, даже если торт нарисован, после установки источника света и камеры его можно визуализировать с помощью Renderer.

Источник света использует окружающий свет из-за равномерного освещения:

const light = new THREE.AmbientLight(0xCCCCCC);
scene.add(light);

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

const width = window.innerWidth;
const height = window.innerHeight;
//窗口宽高比
const k = width / height;
//三维场景显示范围的高度
const s = 200;

const camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);

camera.position.set(0, 100, 500)
camera.lookAt(scene.position);

Параметры орфографической камеры - трехмерное поле зрения, слева, справа, вверх, вниз, далеко и близко.Высоту указываем 200, а затем вычисляем ширину по соотношению сторон окна. Для дальнего и ближнего можно установить относительно большой диапазон.

Затем вы можете использовать Renderer для рендеринга. Прикрепите отрендеренный холст к корпусу.

const renderer = new THREE.WebGLRenderer();

renderer.setSize(width, height);
//设置背景颜色
renderer.setClearColor(0xFFFFFF, 1);
document.body.appendChild(renderer.domElement);

function render() {        
    renderer.render(scene, camera);

    cake.rotation.y += 0.005;

    requestAnimationFrame(render)
}
render()

Перед каждым кадром рендера также делается автоматический поворот вокруг оси Y.

Для поддержки ручного вращения это можно сделать напрямую с помощью OrbitControls, контроллера орбиты Three.js.

const controls = new THREE.OrbitControls(camera);

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

После создания каждой части пирога в сцене, установки источника света, камеры, покадрового рендеринга с помощью средства визуализации и добавления контроллера дорожки, который использует мышь для изменения угла обзора, 3D-торт готов.

Давайте посмотрим на эффект:

Кодовый адрес:GitHub.com/кварк глюон P…

Полный код:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>生日蛋糕</title>
    <style>
        body {
            margin: 0;
            overflow: hidden;
        }
    </style>
    <script src="./js/three.js"></script>
    <script src="./js/OrbitControls.js"></script>
</head>
<body>
<script>
    const width = window.innerWidth;
    const height = window.innerHeight;
    //窗口宽高比
    const k = width / height;
    //三维场景显示范围的宽度
    const s = 200;

    const camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);

    const fontLoader = new THREE.FontLoader();

    const scene = new THREE.Scene();

    const cake = new THREE.Group();

    const renderer = new THREE.WebGLRenderer();


    function create() {
        renderer.setSize(width, height);
        //设置背景颜色
        renderer.setClearColor(0xFFFFFF, 1);
        document.body.appendChild(renderer.domElement);

        camera.position.set(0, 100, 500)
        camera.lookAt(scene.position);

        const light = new THREE.AmbientLight(0xCCCCCC);
        scene.add(light);

        const axisHelper = new THREE.AxisHelper(2500);
        scene.add(axisHelper);

        const cakeTexture1 = new THREE.TextureLoader().load('img/cake1.png');
        const cakeTexture2 = new THREE.TextureLoader().load('img/cake2.png');
        const cakeTexture3 = new THREE.TextureLoader().load(`img/cake3.png`);
        const cakeTexture4 = new THREE.TextureLoader().load('img/cake4.png');

        const cakeMaterail1 = new THREE.MeshBasicMaterial({map: cakeTexture1});
        const cakeMaterail2 = new THREE.MeshBasicMaterial({map: cakeTexture2});
        const cakeMaterail3 = new THREE.MeshBasicMaterial({map: cakeTexture3});
        const cakeMaterail4 = new THREE.MeshBasicMaterial({map: cakeTexture4}); 

        const pinkMaterial = new THREE.MeshBasicMaterial({color: 'pink'});

        const cakeGeometry1 = new THREE.CylinderBufferGeometry(100, 100, 70, 40);
        const cakePart1 = new THREE.Mesh(cakeGeometry1, [cakeMaterail1, pinkMaterial, pinkMaterial]);
        cakePart1.translateY(45)
 
        const cakeGeometry2 = new THREE.CylinderBufferGeometry(120, 120, 70, 40);
        const cakePart2 = new THREE.Mesh(cakeGeometry2,[cakeMaterail3, pinkMaterial, pinkMaterial]);
        cakePart2.translateY(-25)

        const cakeGeometry3 = new THREE.CylinderBufferGeometry(140, 140, 60, 40);
        const cakePart3 = new THREE.Mesh(cakeGeometry3, [cakeMaterail2, pinkMaterial, pinkMaterial]);
        cakePart3.translateY(-90)

        const cakeGeometry4 = new THREE.CylinderBufferGeometry(160, 160, 10, 40);
        const cakePart4 = new THREE.Mesh(cakeGeometry4, [cakeMaterail4, cakeMaterail4, cakeMaterail4]);
        cakePart4.translateY(-120)

        cake.add(cakePart1)
        cake.add(cakePart2)
        cake.add(cakePart3)
        cake.add(cakePart4)

        fontLoader.load('./font/guang.typeface.json', function (font) {
            var textGeometry = new THREE.TextGeometry('光光', {
                font: font,
                size: 30,
                height: 5,
                bevelEnabled: true,
                bevelSize: 10,
            });
            const textMaterial = ['white', 'red'].map(color => new THREE.MeshBasicMaterial({color}));

            const text = new THREE.Mesh(textGeometry, textMaterial);
            text.translateY(90)
            text.translateX(-45)
            cake.add(text); 
        });

        scene.add(cake);
    }


    function render() {        
        renderer.render(scene, camera);

        cake.rotation.y += 0.005;

        requestAnimationFrame(render)
    }

    create()
    render()

    const controls = new THREE.OrbitControls(camera);
</script>
</body>
</html>

Суммировать

В этой статье мы используем Three.js для достижения эффекта 3D-торта.

Прежде всего, мы изучили основы Three.js: управлять объектами через Scene, объекты можно группировать, объекты включают Mesh, Sprite и т. д. Mesh — это 3D-объект, состоящий из треугольников, и Geometry и Material должны быть указаны соответственно. Материалы могут быть текстурными картами или цветами. Сетку текста необходимо преобразовать из ttf в typeface.json, и этот json можно загрузить для отображения текста.

После того, как объект создан, необходимо настроить камеру, освещение и т. д., а затем рендерить кадр за кадром через рендерер.

При отладке вы также можете добавить вспомогательный инструмент системы координат AxisHelper для помощи в разработке.

Затем реализуем 3D-торт:

Он рисуется 4 цилиндрами + текст.Цилиндры используют разные материалы текстурной карты, устанавливают разные позиции, а затем образуют группу тортов.

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

В его (ее) день рождения в следующий раз попробуйте с помощью Three.js нарисовать ему (ей) торт, может быть, будет другой урожай.