1000 порошка! Используйте Three.js, чтобы сделать эксклюзивную 3D-медаль 🥇

внешний интерфейс three.js
1000 порошка! Используйте Three.js, чтобы сделать эксклюзивную 3D-медаль 🥇

«Это первый день моего участия в первом испытании обновлений 2022 года. Подробную информацию о мероприятии см.:Вызов первого обновления 2022 г.".

задний план

сломанная защита😭! внезапно обнаружилSegmentFaultКоличество фанатов на платформе зашкалило1000теперь это мои три блог-платформыНаггетс, Парк блогов, SegmentFaultПервый фанатский прорыв1000Да, поэтому я разработал и разработал эту страницу, чтобы отметить это. Спасибо вам большое за ваше внимание🙏, в будущем я больше сосредоточусь на сортировке и обмене фронтенд-знаниями и буду писать больше качественных статей. (Надеюсь, другие платформы тоже скоро превысят тысячу😂)

В этой статье используетсяReact + Three.jsСтек технологий для достижения прорыва для фанатов1000из3DПамятная страница содержит основные точки знаний, в том числе:Three.jsналичие источника света,DirectionLightПараллельный свет,HemisphereLightполусферический источник света,AmbientLightОкружающий свет, генерация материала медали, знание текстуры,MeshPhysicalMaterialфизический материал,TWEENанимация объектива,CSSФейерверк анимация и др.

Эффект

Реализуйте диаграмму эффекта как статью👆 Banner图Как показано, страница состоит из медали с моей личной информацией.🥇,1000+ FollowersСостав модели, вы можете просмотреть его в режиме реального времени по следующей ссылке🤣.

👀онлайн просмотр:дракон IR.GitHub.IO/3/#/ извращенец…

выполнить

Представить ресурсы

Сначала введите библиотеки, необходимые для функции разработки, гдеFBXLoaderдля добавления в1000+модель шрифта,OrbitControlsуправление треком объектива,TWEENдля создания анимации движения,StatsИспользуется для просмотра производительности во время разработки.

import * as THREE from "three";
import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { TWEEN } from "three/examples/jsm/libs/tween.module.min.js";
import Stats from "three/examples/jsm/libs/stats.module";

инициализация сцены

Эта часть контента в основном используется для инициализации сцены и параметров.Для подробного объяснения вы можете перейти по ссылке в конце статьи, чтобы прочитать мою предыдущую статью, и я не буду повторяться в этой статье.

container = document.getElementById('container');
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
renderer.shadowMap.needsUpdate = true;
container.appendChild(renderer.domElement);
// 场景
scene = new THREE.Scene();
// 给场景设置好看的背景
scene.background = new THREE.TextureLoader().load(backgroundTexture);
// 摄像机
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 0, 0);
camera.lookAt(new THREE.Vector3(0, 0, 0));
// 控制器
controls = new OrbitControls(camera, renderer.domElement);
controls.target.set(0, 0, 0);
controls.enableDamping = true;
controls.enableZoom = false;
controls.enablePan = false;
controls.rotateSpeed = .2;

📌Для достижения лучшего визуального эффектаOrbitControlsМасштабирование отключено, панорамирование отключено и установлена ​​уменьшенная скорость вращения по умолчанию

световой эффект

Для имитации реальной физической сцены в этом примере используется3种источник света.

// 直射光
const cubeGeometry = new THREE.BoxGeometry(0.001, 0.001, 0.001);
const cubeMaterial = new THREE.MeshLambertMaterial({ color: 0xffffff });
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.position.set(0, 0, 0);
light = new THREE.DirectionalLight(0xffffff, 1);
light.intensity = 1;
light.position.set(18, 20, 60);
light.castShadow = true;
light.target = cube;
light.shadow.mapSize.width = 512 * 12;
light.shadow.mapSize.height = 512 * 12;
light.shadow.camera.top = 80;
light.shadow.camera.bottom = -80;
light.shadow.camera.left = -80;
light.shadow.camera.right = 80;
scene.add(light);
// 半球光
const ambientLight = new THREE.AmbientLight(0xffffff);
ambientLight.intensity = .8;
scene.add(ambientLight);
// 环境光
const hemisphereLight = new THREE.HemisphereLight(0xffffff, 0xfffc00);
hemisphereLight.intensity = .3;
scene.add(hemisphereLight);

💡Источник света предоставлен Three.js

Three.jsБиблиотека предоставляет список источников света, каждый из которых имеет определенное поведение и предназначение. К таким источникам света относятся:

название источника света описывать
AmbientLightокружающий свет Это базовый свет, цвет которого добавляется к текущему цвету всей сцены и всех объектов.
PointLightточечный свет Точка в пространстве, излучающая свет во всех направлениях
SpotLightточечный источник света Этот источник света имеет эффект прожектора, похожий на настольную лампу, люстру на потолке или фонарик.
DirectionLightПараллельный свет Также известен как бесконечный свет. Можно видеть, что световые лучи от такого источника света параллельны. Например, солнечный свет
HemishpereLightполусферический свет Это специальный источник света, который можно использовать для создания более естественного наружного освещения, имитирующего блестящие поверхности и тускло освещенное небо.
AreaLightПлощадь источника света Используйте этот источник света, чтобы указать плоскость, из которой излучается свет, а не точку в пространстве.
LensFlareотблеск от линз Это не источник света, а черезLensFlareМожет добавлять эффекты бликов к источникам света в сцене.

💡THREE.DirectionLight параллельный свет

THREE.DirectionLightЕго можно увидеть как свет издалека, все испускаемые им лучи параллельны друг другу. Примером направленного света являетсяСолнечный свет. Вся площадь, освещенная направленным светом, получает одинаковую интенсивность света.

Конструктор:

new THREE.DirectionLight(color);

Описание недвижимости:

  • position: положение источника света в сцене.
  • target:Цель. Его наведение важно. использоватьtargetсвойства, вы можете направлять источники света на определенные объекты или места в сцене. Это свойство требуетTHREE.Object3Dобъект.
  • intensity: Яркость источника света, значение по умолчанию:1.
  • castShadow: проекция, если установленоtrue, источник света будет генерировать тени.
  • onlyShadow: Только тени, если для этого свойства установлено значениеtrue, источник света генерирует только тени и не добавляет света в сцену.
  • shadow.camera.near: Ближняя точка проекции, указывающая расстояние от источника света, где начинает генерироваться тень.
  • shadow.camera.far: дальняя точка проекции, указывающая, в каком положении от источника света могут создаваться тени.
  • shadow.camera.left: Проецирование левой границы.
  • shadow.camera.right: Проецирование правой границы.
  • shadow.camera.top: Проецирование верхней границы.
  • shadow.camera.bottom: Проецирование нижней границы.
  • shadow.map.widthа такжеshadow.map.height: Ширина карты теней и высота карты теней. Определяет, сколько пикселей используется для создания теней. Увеличьте это значение, если тени имеют неровные края или не выглядят гладкими. Нельзя изменить после рендеринга сцены. Значения по умолчанию для обоих:512.

💡THREE.HemisphereLight Источник света Hemisphere

Используя полусферический источник света, вы можете создатьБлиже к эффекту света природы.

Конструктор:

new THREE.HeimsphereLight(groundColor, color, intensity);

Описание недвижимости:

  • groundColor: Цвет света, излучаемого землей.
  • Color: Цвет света, испускаемый из неба.
  • intensity: Интенсивность освещенного облучения.

💡THREE.AmbientLight Окружающий свет

при созданииTHREE.AmbientLight, цвет применяется глобально. Источник света не имеет определенного направления источника, инет теней.

Конструктор:

new THREE.AmbientLight(color);

Рекомендации:

  • обычно нетTHREE.AmbientLightКак единственный источник света в сцене, так как он окрашивает все объекты сцены в один и тот же цвет.
  • Используйте другие источники света, такие какTHREE.SpotLightилиTHREE.DirectionLightпри использовании его, чтобы смягчить тени или добавить дополнительный цвет в сцену.
  • из-заTHREE.AmbientLightИсточники света не нужно позиционировать, они применяются глобально, поэтому просто назначьте цвет и добавьте его в сцену.

Добавьте сетку и землю

Сетка добавлена ​​для удобства разработки, и можно настроить соответствующее взаимное расположение модели.В этом примере цель сохранения сетки - сделать страницу более3D景深效果. Основание из прозрачного материала должно показать тень модели.

// 网格
const grid = new THREE.GridHelper(200, 200, 0xffffff, 0xffffff);
grid.position.set(0, -30, -50);
grid.material.transparent = true;
grid.material.opacity = 0.1;
scene.add(grid);
// 创建地面,透明材质显示阴影
var planeGeometry = new THREE.PlaneGeometry(200, 200);
var planeMaterial = new THREE.ShadowMaterial({ opacity: .5 });
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.rotation.x = -0.5 * Math.PI;
plane.position.set(0, -30, -50);
plane.receiveShadow = true;
scene.add(plane);

Создать медаль

Из-за нехватки времени в этом примере модели медали напрямую используетсяThree.jsВстроенная модель базового кубаTHREE.BoxGeometryдля достижения вы также можете использовать другие кубики, такие как сферы, бусины и т. д., или даже использоватьBlenderи другое профессиональное программное обеспечение для моделирования, чтобы создать вашу любимую форму медали. (ps: Лично я считаю куб тоже очень красивым😂)

💡Создание материала пользовательского интерфейса медали

🥇Верхние, нижние и боковые текстуры медалей:

Чтобы создать золотую текстуру, используйте в этом примере👇материальную карту, чтобы сгенерироватьСлепое твердое золото 24КЭффект🤑.

🥇Изготовление текстуры лицевой и оборотной стороны медали:

Текстуры, используемые на передней и задней части медалиSegmentFaultСкриншот отдельного центра страницы, для большего металлического эффекта я использовал👆Карта текстуры металла выше добавляетбордюр с закругленными углами.

Как создать закругленную металлическую рамку в Photoshop: добавить металлический слой над снимком экрана.->Используйте инструмент выделения, чтобы выделить содержимое, которое необходимо удалить.->Нажмите, чтобы выбрать->Нажмите, чтобы изменить->Нажмите, чтобы сгладить->Введите подходящий размер филе->удалить выделение->Соединить слои->Готово и экспортировать картинку.

Окончательные карты материалов передней и задней части выглядят следующим образом.👇Как показано на рисунке ниже, для ясности яPhotoshopтакже изменил картинку в对比度а также饱和度, и добавилSegmentFaultизLogoВерхняя.

🥇Имеет текстурирование передней и задней части медали.:

чтобы генерироватьрельефная текстура, нужно добавить в модельюридическая карта. использовать👆Карты материалов передней и задней части, созданные выше, можно использовать онлайн-инструменты для автоматического создания карт нормалей. При генерации его можно скорректировать по мере необходимостиStrength,Level,Blurи другие параметры для точной настройки стиля, а также предварительный просмотр в режиме реального времени. После настройки нажмитеDownloadПросто скачайте его.

🚪Портал онлайн-инструмента создания правовой карты:NormalMap-Online

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

Используя сгенерированные выше активы, теперь приступайте к построению модели медали. Использование спереди и сзадиличные информационные материалы, другие поверхности используютМеталл Материал. Затем повторите все грани, чтобы настроитьМеталличностьа такжеШероховатостьстиль.

let segmentMap = new THREE.MeshPhysicalMaterial({map: new THREE.TextureLoader().load(segmentTexture), normalMap: new THREE.TextureLoader().load(normalMapTexture) });
let metalMap = new THREE.MeshPhysicalMaterial({map: new THREE.TextureLoader().load(metalTexture)});
// 创建纹理数组
const boxMaps = [metalMap, metalMap, metalMap, metalMap, segmentMap, segmentMap];
// 💡 立方体长宽高比例需要和贴图的大小比例一致,厚度可以随便定
box = new THREE.Mesh(new THREE.BoxGeometry(297, 456, 12), boxMaps);
box.material.map(item => {
  // 材质样式调整
  item.metalness = .5;
  item.roughness = .4;
  item.refractionRatio = 1;
  return item;
});
box.scale.set(0.085, 0.085, 0.085);
box.position.set(-22, 2, 0);
box.castShadow = true;
meshes.push(box);
scene.add(box);

👆над4Визуализации, в свою очередь, соответствуют:

  • 图1: Создать без текстурыBoxGeometry, просто белый куб.
  • 图2: куб добавлен材质贴图,В настоящее времянет эффекта удара.
  • 图3: куб добавлен法相贴图,В настоящее времяСоздайте эффект выпуклости.
  • 图4: регулирует текстуру куба.金属度,粗糙程度а также反射率, более реалистично.

💡Текстуры в Three.js

тип текстуры
  • map: Карта материалов
  • normalMap: нормальная карта
  • bumpMap: Рельефная карта
  • envMap: Карта окружающей среды
  • specularMap: Зеркальная карта
  • lightMap: карта освещения
Принцип текстуры

Через загрузчик карт текстурTextureLoader()Перейдите к созданию нового объекта текстуры, а затем вызовите внутреннююload()метод для загрузки изображения, которое вернет объект текстуры, который можно использовать в качестве цветовой карты материала модели.mapЗначение свойства, свойство палитры материалаmapКогда установлено, модель захватывает значения пикселей из карты текстуры.

💡MeshPhysicalMaterial физический материал

MeshPhysicalMaterialклассPBRФизические материалы, которые могут лучше имитировать расчеты освещения по сравнению с сетчатыми материалами с высоким освещением.MeshPhongMaterialЭффект рендеринга более реалистичен.

Если вы хотите показать продукт, для более реалистичного отображения материала лучший выбор, если игра для лучшего эффекта отображения может быть выбранаPBRматериалMeshPhysicalMaterial, вместо зеркального материалаMeshPhongMaterial.

специальные свойства
  • .metalnessСвойство металличности: указывает, насколько материал похож на металл. Неметаллические материалы, такие как дерево или камень, используют0.0, использование металла1.0Середина без (обычно).По умолчанию0.5. 0.0прибыть1.0Значения между ними можно использовать для вида ржавого металла. Если также предоставляется карта шероховатости.metalnessMap, то оба значения перемножаются.
  • .roughnessСвойство Roughness: указывает на шероховатость материала.0.0представляет собой гладкое зеркальное отражение,1.0Указывает на полное диффузное отражение.0.5, если также предоставляется карта шероховатости.roughnessMap, два значения перемножаются.
  • .metalnessMapКарта металличности: синий канал текстуры используется для изменения металличности материала.
  • .roughnessMapКарта шероховатости: зеленый канал текстуры используется для изменения шероховатости материала.

📌Обратите внимание, что при использовании физических материалов обычно необходимо установить карту среды..envMap.

Загрузите более 1000 текстовых моделей

1000+Модель используемого шрифтаTHREE.LoadingManagerа такжеFBXLoaderнагрузка. Подробный метод использования не будет повторяться в этой статье, вы можете перейти по ссылке в конце статьи, чтобы просмотреть другие мои статьи, в которых есть подробные описания.😁

const manager = new THREE.LoadingManager();
manager.onProgress = async(url, loaded, total) => {
  if (Math.floor(loaded / total * 100) === 100) {
    // 设置加载进度
    _this.setState({ loadingProcess: Math.floor(loaded / total * 100) });
    // 加载镜头移动补间动画
    Animations.animateCamera(camera, controls, { x: 0, y: 4, z: 60 }, { x: 0, y: 0, z: 0 }, 3600, () => {});
  } else {
    _this.setState({ loadingProcess: Math.floor(loaded / total * 100) });
  }
};
const fbxLoader = new FBXLoader(manager);
fbxLoader.load(textModel, mesh => {
  mesh.traverse(child => {
    if (child.isMesh) {
      // 生成阴影
      child.castShadow = true;
      // 样式调整
      child.material.metalness = 1;
      child.material.roughness = .2;
      meshes.push(mesh);
    }
  });
  mesh.position.set(16, -4, 0);
  mesh.rotation.x = Math.PI / 2
  mesh.scale.set(.08, .08, .08);
  scene.add(mesh);
});

промежуточная анимация

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

animateCamera: (camera, controls, newP, newT, time = 2000, callBack) => {
  var tween = new TWEEN.Tween({
    x1: camera.position.x, // 相机x
    y1: camera.position.y, // 相机y
    z1: camera.position.z, // 相机z
    x2: controls.target.x, // 控制点的中心点x
    y2: controls.target.y, // 控制点的中心点y
    z2: controls.target.z, // 控制点的中心点z
  });
  tween.to({
    x1: newP.x,
    y1: newP.y,
    z1: newP.z,
    x2: newT.x,
    y2: newT.y,
    z2: newT.z,
  }, time);
  tween.onUpdate(function (object) {
    camera.position.x = object.x1;
    camera.position.y = object.y1;
    camera.position.z = object.z1;
    controls.target.x = object.x2;
    controls.target.y = object.y2;
    controls.target.z = object.z2;
    controls.update();
  });
  tween.onComplete(function () {
    controls.enabled = true;
    callBack();
  });
  tween.easing(TWEEN.Easing.Cubic.InOut);
  tween.start();
}

обновление анимации

Наконец, не забудьтеrequestAnimationFrameОбновите сцены, отслеживайте контроллеры,TWEEN, а вращение модели🌍Ждать.

// 监听页面缩放,更新相机和渲染
function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
  stats && stats.update();
  controls && controls.update();
  TWEEN && TWEEN.update();
  // 奖牌模型自转
  box && (box.rotation.y += .04);
}

фейерверк анимация

Наконец, поbox-shadowи простоCSSАнимация, добавить на страницу🎉Цветущий эффект, чтобы создать🎅Праздничная атмосфера!

<div className="firework_1"></div>
<div className="firework_2"></div>
<!-- ... -->
<div className="firework_10"></div>

Стиль анимации:

[class^=firework_] {
  position: absolute;
  width: 0.1rem;
  height: 0.1rem;
  border-radius: 50%;
  transform: scale(8)
}
.firework_1 {
  animation: firework_lg 2s both infinite;
  animation-delay: 0.3s;
  top: 5%;
  left: 5%;
}
@keyframes firework_lg {
  0%, 100% {
    opacity: 0;
  }
  10%, 70% {
    opacity: 1;
  }
  100% {
    box-shadow: -0.9rem 0rem 0 #fff, 0.9rem 0rem 0 #fff, 0rem -0.9rem 0 #fff, 0rem 0.9rem 0 #fff, 0.63rem -0.63rem 0 #fff, 0.63rem 0.63rem 0 #fff, -0.63rem -0.63rem 0 #fff, -0.63rem 0.63rem 0 #fff;
  }
}

Осознайте эффект:

🔗полный кодGitHub.com/дракон ИК/3…

Суммировать

Основные точки знаний, затронутые в этой статье, включают:

  • Three.jsпредоставленный источник света
  • THREE.DirectionLightПараллельный свет
  • THREE.HemisphereLightПолусферический источник света
  • THREE.AmbientLightокружающий свет
  • медальUIгенерация материала
  • Three.jsтекстуры в
  • MeshPhysicalMaterialфизический материал
  • TWEENАнимация кадра
  • CSSфейерверк анимация

Хотите узнать об инициализации сцены, освещении, тенях и многом другомThree.jsДля получения соответствующих знаний вы можете прочитать другие мои статьи. Если вы считаете, что статья полезна для вас, не забудьте一键三连 👍.

приложение