/
versus2
/
Versus
Обзор
Документация
Войти
/
versus2
/
Versus
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/index.html
452 строки
31 KB
Alexander Starov
Add Web GL
07 сен 2025, 16:07
07 сен 2025, 16:07
9890ddc
Код
Авторство
О чём код?
<!DOCTYPE html> <html lang="ru"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Versus Engine</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"> <link href="css/app.css" rel="stylesheet"> <link href="css/style.css" rel="stylesheet"> <script type="importmap"> { "imports": { "three": "https://unpkg.com/three@0.164.1/build/three.module.js", "three/examples/jsm/": "https://unpkg.com/three@0.164.1/examples/jsm/" } } </script> </head> <body> <div class="vs-container d-flex flex-column"> <div class="vs-topbar vs-fade-up"> <div class="d-flex align-items-center gap-4 w-100"> <div class="d-flex align-items-center"> <div class="vs-logo me-2">V</div> <div> <div class="vs-app-title">Versus</div> <div class="vs-app-sub" style="margin-right: 10px;">3D Game Builder — Прототип</div> </div> </div> <div class="d-flex gap-2"> <div class="dropdown"> <button style="margin-right: 10px;" class="vs-btn dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false"> <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M4 1.5H9.5L14 6V14.5H4V1.5Z" stroke="currentColor" stroke-linejoin="round"></path><path d="M9 1.5V6H14" stroke="currentColor" stroke-linejoin="round"></path></svg> Файл </button> <ul class="dropdown-menu"> <li><a class="dropdown-item" href="#" id="load-model-btn">Загрузить модель (.glb, .gltf)</a></li> <li><a class="dropdown-item" href="#" id="load-hdri-btn">Загрузить окружение (.hdr)</a></li> <li><a class="dropdown-item" href="#">Новый</a></li> <li><a class="dropdown-item" href="#">Открыть</a></li> <li><a class="dropdown-item" href="#">Сохранить как</a></li> <li><a class="dropdown-item" href="#">Собрать</a></li> <li><hr class="dropdown-divider"></li> <li><a class="dropdown-item" href="#">Выйти</a></li> </ul> </div> <button style="margin-right: 10px;" class="vs-btn" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Назад (Ctrl+Z)"> <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M3.5 7.5H10.5C12.1569 7.5 13.5 8.84315 13.5 10.5V10.5C13.5 12.1569 12.1569 13.5 10.5 13.5H9.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M6 5L3.5 7.5L6 10" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path></svg> Назад </button> <button style="margin-right: 10px;" class="vs-btn" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Повторить (Ctrl+Y)"> <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M12.5 7.5H5.5C3.84315 7.5 2.5 8.84315 2.5 10.5V10.5C2.5 12.1569 3.84315 13.5 5.5 13.5H6.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M10 5L12.5 7.5L10 10" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path></svg> Повторить </button> <button style="margin-right: 10px;" class="vs-btn" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Открыть доступ к проекту"> <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M11 6.5L13.5 4L11 1.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M4.5 12.5H10C11.3807 12.5 12.5 11.3807 12.5 10V4" stroke="currentColor" stroke-linecap="round"></path><path d="M12 14.5H3.5C2.94772 14.5 2.5 14.0523 2.5 13.5V3.5C2.5 2.94772 2.94772 2.5 3.5 2.5H7" stroke="currentColor" stroke-linecap="round"></path></svg> Открыть доступ </button> <input type="file" id="model-loader-input" style="display: none;" accept=".glb, .gltf"> <input type="file" id="hdri-loader-input" style="display: none;" accept=".hdr"> </div> <div class="ms-auto d-flex align-items-center"> <span data-bs-toggle="tooltip" data-bs-placement="bottom" title="Закрыть проект"> </span> </div> </div> </div> <div class="row flex-grow-1 g-3"> <div class="col-md-3 col-lg-2 vs-sidebar-col"> <div class="vs-sidebar vs-fade-up"> <div class="d-flex gap-2"> <div class="dropdown"> <button class="vs-btn dropdown-toggle" type="button" id="add-object-btn" data-bs-toggle="dropdown" aria-expanded="false" title="Добавить объект"> <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M8 3.5V12.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M3.5 8H12.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path></svg> </button> <ul class="dropdown-menu"> <li><h6 class="dropdown-header">Примитивы</h6></li> <li><a class="dropdown-item add-primitive-btn" href="#" data-primitive-type="cube">Куб</a></li> <li><a class="dropdown-item add-primitive-btn" href="#" data-primitive-type="sphere">Сфера</a></li> <li><a class="dropdown-item add-primitive-btn" href="#" data-primitive-type="plane">Плоскость</a></li> <li><hr class="dropdown-divider"></li> <li><h6 class="dropdown-header">Освещение</h6></li> <li><a class="dropdown-item add-light-btn" href="#" data-light-type="directional">Направленный свет</a></li> <li><a class="dropdown-item add-light-btn" href="#" data-light-type="point">Точечный свет</a></li> </ul> </div> <input class="vs-input" style="margin-right: 20px;" placeholder="Поиск..."> </div> <div class="vs-section-title" style="margin-top: 20px;" >Объекты сцены</div> <div class="vs-tree"> </div> <div class="mt-auto"> <div class="vs-muted" style="font-size:12px">Autosave: 2m ago</div> </div> </div> </div> <div class="col-md-6 col-lg-8"> <div class="vs-viewport-panel vs-fade-up h-100"> <div class="d-flex gap-3"> <div class="vs-play-toggle mx-auto"> <button class="vs-btn active" style="margin-right: 10px;"> <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M4.5 2.5L12.5 8L4.5 13.5V2.5Z" stroke="currentColor" stroke-linejoin="round"></path></svg> Запуск </button> <button class="vs-btn" style="margin-right: 10px;"> <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M5.5 2.5L11.5 5.5L8.5 8.5L5.5 13.5L2.5 10.5L5.5 2.5Z" stroke="currentColor" stroke-linejoin="round"></path><path d="M10.5 13.5L13.5 10.5L8.5 8.5" stroke="currentColor" stroke-linejoin="round"></path></svg> Ноды </button> </div> </div> <div id="viewport-container" class="vs-viewport-canvas" tabindex="0"> <div class="vs-viewport-tools"> <button class="vs-btn" style="margin-top: 10px;" data-bs-toggle="tooltip" data-bs-placement="right" title="Move Tool (W)"> <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M8 1.5V14.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M1.5 8H14.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M10 3.5L8 1.5L6 3.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M10 12.5L8 14.5L6 12.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M12.5 6L14.5 8L12.5 10" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M3.5 6L1.5 8L3.5 10" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path></svg> </button> <button class="vs-btn" style="margin-top: 10px;" data-bs-toggle="tooltip" data-bs-placement="right" title="Rotate Tool (E)"> <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M12.5 6.00004C13.1905 7.15243 13.5 8.5434 13.5 10C13.5 12.9261 11.2394 15 8.5 15C5.99201 15 3.86433 13.2124 3.5638 10.8" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M10.5 6H12.5V8" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path></svg> </button> <button class="vs-btn" style="margin-top: 10px;" data-bs-toggle="tooltip" data-bs-placement="right" title="Scale Tool (R)"> <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M3.5 12.5V3.5H12.5V12.5H3.5Z" stroke="currentColor" stroke-linejoin="round"></path><path d="M1.5 1.5H5.5" stroke="currentColor" stroke-linecap="round"></path><path d="M1.5 1.5V5.5" stroke="currentColor" stroke-linecap="round"></path><path d="M14.5 1.5H10.5" stroke="currentColor" stroke-linecap="round"></path><path d="M14.5 1.5V5.5" stroke="currentColor" stroke-linecap="round"></path><path d="M1.5 14.5H5.5" stroke="currentColor" stroke-linecap="round"></path><path d="M1.5 14.5V10.5" stroke="currentColor" stroke-linecap="round"></path><path d="M14.5 14.5H10.5" stroke="currentColor" stroke-linecap="round"></path><path d="M14.5 14.5V10.5" stroke="currentColor" stroke-linecap="round"></path></svg> </button> </div> </div> </div> </div> <div class="col-md-3 col-lg-2 vs-inspector-col"> <div class="vs-inspector vs-fade-up"> <ul class="nav nav-tabs"> <li class="nav-item"> <a class="nav-link active" data-bs-toggle="tab" href="#inspector-tab">Инспектор</a> </li> <li class="nav-item"> <a class="nav-link" data-bs-toggle="tab" href="#world-tab">Мир</a> </li> </ul> <div class="tab-content flex-grow-1 pt-3"> <div class="tab-pane fade show active" id="inspector-tab"> <div class="accordion" id="inspectorAccordion"> <div class="accordion-item" id="transform-accordion-item"> <h2 class="accordion-header"> <button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseTransform"> Трансформация </button> </h2> <div id="collapseTransform" class="accordion-collapse collapse show" data-bs-parent="#inspectorAccordion"> <div class="accordion-body"> </div> </div> </div> <div class="accordion-item" id="material-accordion-item"> <h2 class="accordion-header"> <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseMaterial"> Материал </button> </h2> <div id="collapseMaterial" class="accordion-collapse collapse" data-bs-parent="#inspectorAccordion"> <div class="accordion-body"> </div> </div> </div> <div class="accordion-item" id="light-accordion-item" style="display: none;"> <h2 class="accordion-header"> <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseLight"> Источник света </button> </h2> <div id="collapseLight" class="accordion-collapse collapse" data-bs-parent="#inspectorAccordion"> <div class="accordion-body"> <div class="vs-prop"> <label for="light-color">Цвет</label> <input type="color" id="light-color-input" class="vs-input" value="#ffffff"> </div> <div class="vs-prop"> <label for="light-intensity">Интенсивность</label> <div class="d-flex align-items-center gap-2"> <input type="range" id="light-intensity-slider" class="vs-input flex-grow-1" min="0" max="10" step="0.05" value="1"> <input type="number" id="light-intensity-number" class="vs-input" style="max-width: 60px;" min="0" max="10" step="0.1" value="1"> </div> </div> <div class="vs-prop"> <div class="form-check"> <input class="form-check-input" type="checkbox" value="" id="light-shadow-check"> <label class="form-check-label" for="light-shadow-check"> Создавать тени </label> </div> </div> </div> </div> </div> </div> </div> <div class="tab-pane fade" id="world-tab"> <div class="accordion" id="worldAccordion"> <div class="accordion-item"> <h2 class="accordion-header"><button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseIbl">Окружение (IBL)</button></h2> <div id="collapseIbl" class="accordion-collapse collapse show" data-bs-parent="#worldAccordion"> <div class="accordion-body"> <div class="vs-prop"> <label>Интенсивность</label> <input type="range" id="ibl-intensity-slider" class="vs-input" min="0" max="3" step="0.01" value="0.3"> </div> <div class="vs-prop"> <label>Размытие фона</label> <input type="range" id="bg-blur-slider" class="vs-input" min="0" max="1" step="0.01" value="0.2"> </div> </div> </div> </div> <div class="accordion-item"> <h2 class="accordion-header"><button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseSkybox">Небо</button></h2> <div id="collapseSkybox" class="accordion-collapse collapse show" data-bs-parent="#worldAccordion"> <div class="accordion-body"> <div class="vs-prop"> <label>Режим</label> <select id="skybox-mode-select" class="vs-input"> <option value="hdri">HDRI</option> <option value="color">Цвет</option> <option value="gradient">Градиент</option> </select> </div> <div class="vs-prop"> <label for="skybox-color-input">Цвет неба</label> <input type="color" id="skybox-color-input" class="vs-input" value="#1e2127"> </div> <div class="vs-prop"> <label for="skybox-gradient-top-input">Цвет градиента (верх)</label> <input type="color" id="skybox-gradient-top-input" class="vs-input" value="#1e2127"> </div> <div class="vs-prop"> <label for="skybox-gradient-bottom-input">Цвет градиента (низ)</label> <input type="color" id="skybox-gradient-bottom-input" class="vs-input" value="#2a2f36"> </div> </div> </div> </div> <div class="accordion-item"> <h2 class="accordion-header"><button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseSun">Солнце</button></h2> <div id="collapseSun" class="accordion-collapse collapse show" data-bs-parent="#worldAccordion"> <div class="accordion-body"> <div class="vs-prop"> <label>X</label> <input type="range" id="sun-x-slider" class="vs-input" min="-50" max="50" step="0.1" value="15"> </div> <div class="vs-prop"> <label>Y</label> <input type="range" id="sun-y-slider" class="vs-input" min="-50" max="50" step="0.1" value="20"> </div> <div class="vs-prop"> <label>Z</label> <input type="range" id="sun-z-slider" class="vs-input" min="-50" max="50" step="0.1" value="10"> </div> <div class="vs-prop"> <label>Интенсивность</label> <input type="range" id="sun-intensity-slider" class="vs-input" min="0" max="5" step="0.01" value="1.2"> </div> <div class="vs-prop"> <div class="form-check"> <input class="form-check-input" type="checkbox" id="sun-shadow-check" checked> <label class="form-check-label" for="sun-shadow-check"> Создавать тени </label> </div> </div> </div> </div> </div> <div class="accordion-item"> <h2 class="accordion-header"><button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseClouds">Облака</button></h2> <div id="collapseClouds" class="accordion-collapse collapse show" data-bs-parent="#worldAccordion"> <div class="accordion-body"> <div class="vs-prop"> <label>Включить</label> <div class="form-check form-switch ms-auto"> <input class="form-check-input" type="checkbox" id="cloud-enabled-check" checked> </div> </div> <div class="vs-prop"> <label>Скорость</label> <input type="range" id="cloud-speed-slider" class="vs-input" min="0" max="0.1" step="0.001" value="0.01"> </div> <div class="vs-prop"> <label>Плотность</label> <input type="range" id="cloud-density-slider" class="vs-input" min="0" max="1" step="0.01" value="0.5"> </div> <div class="vs-prop"> <label>Поглощение</label> <input type="range" id="cloud-absorption-slider" class="vs-input" min="0" max="1" step="0.01" value="0.2"> </div> <div class="vs-prop"> <label>Поглощение света</label> <input type="range" id="cloud-light-absorption-slider" class="vs-input" min="0" max="1" step="0.01" value="0.5"> </div> <div class="vs-prop"> <label>Мин. высота</label> <input type="range" id="cloud-min-height-slider" class="vs-input" min="0" max="1000" step="10" value="200"> </div> <div class="vs-prop"> <label>Макс. высота</label> <input type="range" id="cloud-max-height-slider" class="vs-input" min="0" max="1000" step="10" value="400"> </div> <div class="vs-prop"> <label>Масштаб шума</label> <input type="range" id="cloud-noise-scale-slider" class="vs-input" min="0" max="0.1" step="0.001" value="0.02"> </div> <div class="vs-prop"> <label>Влияние деталей</label> <input type="range" id="cloud-detail-influence-slider" class="vs-input" min="0" max="1" step="0.01" value="0.5"> </div> </div> </div> </div> <div class="accordion-item"> <h2 class="accordion-header"><button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapsePostProcessing">Постобработка</button></h2> <div id="collapsePostProcessing" class="accordion-collapse collapse show" data-bs-parent="#worldAccordion"> <div class="accordion-body"> <div class="vs-prop"> <label>Сила виньетки</label> <input type="range" id="vignette-strength-slider" class="vs-input" min="0" max="2" step="0.01" value="0.5"> </div> <div class="vs-prop"> <label>Хроматическая аберрация</label> <input type="range" id="chromatic-aberation-amount-slider" class="vs-input" min="0" max="0.1" step="0.001" value="0.0"> </div> </div> </div> </div> <div class="accordion-item"> <h2 class="accordion-header"><button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseBloom">Glow (Bloom)</button></h2> <div id="collapseBloom" class="accordion-collapse collapse show" data-bs-parent="#worldAccordion"> <div class="accordion-body"> <div class="vs-prop"> <label>Порог</label> <input type="range" id="bloom-threshold-slider" class="vs-input" min="0" max="2" step="0.01" value="0.85"> </div> <div class="vs-prop"> <label>Сила</label> <input type="range" id="bloom-strength-slider" class="vs-input" min="0" max="3" step="0.01" value="0.5"> </div> <div class="vs-prop"> <label>Радиус</label> <input type="range" id="bloom-radius-slider" class="vs-input" min="0" max="2" step="0.01" value="0.2"> </div> </div> </div> </div> <div class="accordion-item"> <h2 class="accordion-header"><button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseFog">Туман</button></h2> <div id="collapseFog" class="accordion-collapse collapse show" data-bs-parent="#worldAccordion"> <div class="accordion-body"> <div class="vs-prop"> <label for="fog-color">Цвет тумана</label> <input type="color" id="fog-color-input" class="vs-input" value="#282c34"> </div> <div class="vs-prop"> <label for="fog-density">Плотность тумана</label> <input type="range" id="fog-density-slider" class="vs-input" min="0" max="0.1" step="0.001" value="0"> </div> </div> </div> </div> <div class="accordion-item"> <h2 class="accordion-header"><button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOutline">Обводка</button></h2> <div id="collapseOutline" class="accordion-collapse collapse show" data-bs-parent="#worldAccordion"> <div class="accordion-body"> <div class="vs-prop"> <label>Включить</label> <div class="form-check form-switch ms-auto"> <input class="form-check-input" type="checkbox" id="outline-enabled-check" checked> </div> </div> <div class="vs-prop"> <label>Толщина</label> <input type="range" id="outline-thickness-slider" class="vs-input" min="0" max="10" step="0.1" value="3"> </div> <div class="vs-prop"> <label for="outline-color-input">Цвет</label> <input type="color" id="outline-color-input" class="vs-input" value="#74c0fc"> </div> </div> </div> </div> <div class="accordion-item"> <h2 class="accordion-header"><button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseLensflare">Блик от линзы</button></h2> <div id="collapseLensflare" class="accordion-collapse collapse show" data-bs-parent="#worldAccordion"> <div class="accordion-body"> <div class="vs-prop"> <label>Включить</label> <div class="form-check form-switch ms-auto"> <input class="form-check-input" type="checkbox" id="lensflare-enabled-check" checked> </div> </div> <div class="vs-prop"> <label>Интенсивность</label> <input type="range" id="lensflare-intensity-slider" class="vs-input" min="0" max="1" step="0.01" value="0.75"> </div> </div> </div> </div> <div class="accordion-item"> <h2 class="accordion-header"><button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseGround">Пол</button></h2> <div id="collapseGround" class="accordion-collapse collapse show" data-bs-parent="#worldAccordion"> <div class="accordion-body"> <div class="vs-prop"> <label>Включить</label> <div class="form-check form-switch ms-auto"> <input class="form-check-input" type="checkbox" id="floor-enabled-check" checked> </div> </div> </div> </div> </div> <div class="vs-prop"> <label class="vs-check-label"> <input type="checkbox" id="bloom-enabled-check" class="vs-check"> Свечение (Bloom) </label> </div> </div> </div> </div> </div> </div> </div> <div class="vs-bottom-panel vs-fade-up"> <div class="vs-assets"> <div class="d-flex flex-column gap-2"> <div class="vs-section-title">Assets</div> <div class="d-flex gap-2"> <div class="vs-asset-item">Cube</div> <div class="vs-asset-item">Sphere</div> <div class="vs-asset-item">Plane</div> <div class="vs-asset-item">Light</div> </div> </div> </div> </div> </div> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script> <script type="module" src="js/renderer.js"></script> </body> </html>