...

суббота, 14 июля 2018 г.

Аналитика воронки продаж

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

Поток новых клиентов не появляется из воздуха, его количество зависит от ваших маркетинговых усилий. Привлечение клиентов это корректный процессинг потенциальных клиентов со стадии контактов до стадии продаж. Входящие в когорты новые клиенты на самом деле финальный этап воронки продаж. Костяк этапов в воронке продаж выглядит так:

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


Ключевые этапы воронки продаж


  • Market — рынок ваших клиентов, которые в целом могут заинтересоваться вашим товаром или услугой. Определение вашего рынка это отдельная большая тема про позиционирование и маркетинговую стратегию. Правильный выбор рынка, ваше позиционирование, ваша цена, продукт и продвижение на нем в итоге определит кол-во ваших входящих клиентов. Обычно рынок не “считают” при оценки воронки продаж. Но я решил его упомянуть здесь, чтобы у нас осталась сквозная логика, откуда появляются потенциальные клиенты и что часто показатели воронки продаж определяются не тонкой настройкой ее параметров, а выбором правильного рынка.
  • Аудитория, до которой дотянулись (Reach) — потенциальные клиенты, кого вы охватили своими маркетинговыми коммуникациями и направили на следующие этапы воронки продаж.
  • Marketing Qualified Lead (MQL) — это потенциальные клиенты клиенты, которые с большей вероятностью станут вашими клиентами, по сравнению с клиентами, кто не имеет MQL статуса. В рамках анализа своего бизнеса вам нужно определить, какие характеристики и свойства потенциальных клиентов в большей степени помогают продажам и нацеливать ваш маркетинг на увеличение числа MQL. Именно на них стоит тратить наибольший объем усилий. С контактами MQL вы проводите маркетинговые взаимодействия, общаетесь усилия менеджеров или по средствам целенаправленной рекламы (ретаргетинг, например).
  • Sales Qualified Lead (SQL) — это этап воронке, на котором вы объединяете ваши данные о первичных контактах, дополнительные данные по вашей маркетинговой разведке и делаете заключение, кто из клиентов достиг стадии, которая с высокой вероятностью станет сделкой.
  • Продажа — это клиенты, кто в конечном итоге завершает все этапы воронки и становится клиентом, попадая в вашу новую когорту.

В этой воронке описаны ключевые этапы. На практике удобно добавить промежуточные этапы, для более детального контроля за процессом. Кроме этого вам нужно корректно определить ваши собственные критерии MQL и SQL. Отмечу так же, что этапов воронки обязательно является событие, в которое клиент может попасть 1 раз и с которого он может пойти в следующий шаг. Если у вас есть страница на сайте, куда клиент может зайти, а может и не зайти, и при этом она не ведет его к следующему этапу продажи, то не имеет особого смысла считать это действие этапов в воронке продаж. Воронка отслеживает движение в сторону продаж, а не просто карту движения и взаимодействия с вашими службами и сервисами.

Для примера, какой может быть воронка продаж для интернет магазина:


  1. Кол-во просмотров вне сайта (на внешних рекламных кампаниях) — Reach.
  2. Кол-во уникальных пользователей посетивших сайт c внешних рекламных кампаний.
  3. Просмотр страниц с товарами.
  4. Пополнение корзины — ваше определение MQL.
  5. Переход на страницу оплаты — ваше определение SQL.
  6. Оформление заказа (Продажа).

Т.к. Задача воронки — локализация проблем в этапах взаимодействия с потенциальным клиентом, то логично строить воронки по вашим канал взаимодействия, иначе вы можете получить сложную свалку событий и смешение факторов. Но стоит отметить, что целиком полагаться на воронки по каналам привлечения не всегда хорошая идея. Клиент скорее всего много раз натыкается на вашу рекламу, но если вы фиксируете только точку входа в воронку, которая заканчивается продажей, то вы рискуете переоценить или недооценить важность отдельного канала. Как пример, я мог увидеть 10 раз вашу рекламу в социальной сети, запомнить ее, затем загуглить и перейти прямиком на сайт. С точки зрения воронки по каналам выйдет, что социальная сеть никого не привела, а клиенты пришли из органического поиска. Но это, очевидно, не полная картина, вы необоснованно занижаете эффективность промежуточных взаимодействий. Эту проблему можно решать двумя подходами:


  1. Дешевле, менее точно: оцените, как изменения маркетинговых усилий в отдельном канале влияет на продажи во всех каналах. Из анализа этой чувствительности вы можете получить какие-то граничные оценки, насколько каналы взаимосвязаны между собой
  2. Дороже, более точно: научитесь “ловить” пользователя во всех его взаимодействия с вашей рекламой. Поставьте ему куку, когда он первый раз увидел рекламу, а дальше отмечайте, в каком рекламной материале вы увидели эту куку еще раз. Таким образом, когда этот клиент попадает на финальные стадии воронки продаж, вы будете иметь информацию о всех его взаимодействиях с рекламными каналами, а не только с последним.

Визуализация воронки продаж

Классика это таблица, в которой вы показываете, сколько % потенциальных клиентов добралось до следующего участка, и какая это доля из первичного потока. Важный нюанс, который вам надо решить — это каким образом выстраивать воронку по датам. Дело в том, что у вас есть несколько способов построить воронку:
1.По календарным датам событий — если сегодня на сайте было 10000 пользователей и 100 продаж, то эти цифры и пишем в воронку. Это не самый лучший подход, т.к. В этой случае мы смешивает когорты входящих потенциальных клиентов. По факту каждый календарный день у вас есть 10000 входящих, сколько-то в промежуточных стадиях и какие 100 продаж, которые на самом деле были принесены пользователями, кто пришел к вам за сколько дней до этого. Этой проблемы не будет, если ваш цикл продаж укладывается 1 день. И наоборот, в b2b сегменте это вообще полностью исказит картину, когда у вас могут проходить месяцы между контактов и продажей.
1.По дате контакта — в этом случае, вам нужно уметь ваш поток клиентов отслеживать на индивидуальном уровне и следить за проходом каждого клиента по этапам воронки продаж. Но зато вы получаете настоящую воронку, где причина (контакт) и следствие (продажа) действительно связаны и отображают реальную конверсию.

На практике бывает так, что только часть воронки у вас может быть построена по п.2. (обычно это получается с этапа регистрации/авторизации потенциального клиента, когда вы можете начать их различать между собой), а часть воронки будет построена по п.1. Ничего не поделаешь, придется смешивать и просто помнить о своей погрешности.

Отчет по воронке может быть таким

Получив воронку продаж и добавив наш анализ когорт, притоков и динамики клиентской базы мы получаем сквозную аналитику, которая может показать вам все этапы формирования клиентской базы и проблемы, которые у вас есть в этих процессах. Более того, теперь вы можете строить модели и составлять сценарии what if, оценивать, насколько вам надо увеличить показатели и на каком участке для достижения поставленных целей.

Эта 5 статья в цикле статей про анализ продукта. Другие статьи по этой теме:


  1. Top-Down approach. Экономика продукта. Gross Profit
  2. Экономика продукта. Анализ выручки
  3. Погружаемся в динамику клиентской базы: когортный анализ и анализ потоков
  4. Собираем когортный анализ/анализ потоков на примере Excel

Let's block ads! (Why?)

Techstars Startup Digest: 10 бесплатных ИТ-конференций, митапов и хакатонов в Москве

Настройка домашней среды для разработки (docker + gitlab + DNS)

Не смог придумать подходящее название для поста, поэтому кратко опишу, о чем будет идти речь.

У большинства из нас есть какие-нибудь мелкие личные поделки, которые не выходят за рамки наших домов. Кто-то хостит их на рабочем компьютере, кто-то — на Heroku, кто-то — на VPS, а у кого-то есть домашний сервер. На реддите даже есть сообщество r/homelab, в котором люди обсуждают разные железки и софт для т.н. домашней лаборатории.

Я не настолько увлечен этим вопросом, но у меня дома стоит Intel NUC, который проигрывает музыку с NAS с помощью MPD. Помимо MPD на нем крутятся мои мелкие поделки, которые помогают мне с ним работать: ныне мертвый бот для телеграма, HTTP API на синатре и корявенький фронтенд для него.

В посте я без особых подробностей (многих из которых сам не понимаю) опишу процесс установки DNS-сервера для работы с доменными именами для сервисов, схему одновременной работы нескольких сервисов с помощью Docker и установку Gitlab с CI. Ничего нового вы не узнаете, но вдруг кому-нибудь пригодится этот "гайд". К тому же я бы хотел услышать предложения по поводу того, как можно было бы сделать это проще/элегантнее/правильнее.

Изначально код моих сервисов лежал на битбакете/гитхабе и после создания докер-образов мне нужно было зайти под SSH и запустить пару скриптов, которые создавали/обновляли контейнеры с сервисами. Поймал себя на мысли, что вижу мелкий раздражающий баг в приложении, который я не исправляю только потому, что мне лень производить всю эту процедуру. Очевидно, что пора было автоматизировать все. Тут-то и пришла мысль установки Gitlab + CI.

Все контейнеры создавались с флагом --network=host для простоты — достаточно было использовать разные порты в приложениях. Однако с ростом количества сервисов запоминать, какое приложение какой порт использует. Да и вводить каждый раз IP-адрес с портом в браузере не очень красиво, поэтому прежде чем устанавливать гитлаб я решил разобраться с хостингом нескольких приложений на одном сервере.

Идея простая: настраиваем DNS, скармливаем его роутеру, устанавливаем Nginx и с помощью его конфигурации перенаправляем запросы на разные порты в зависимости от домена. Это же позволит не заморачиваться с портами при разработке, т.к. контейнеры начнут использовать --publish вместо --network=host.

При установке использовался этот гайд. В нем настройка производится для Ubuntu 16.04, у меня же Debian.

Дальнейшие действия производятся от пользователя root.

Первым делом устанавливаем bind9 и утилиты:

apt-get install -y bind9 bind9utils bind9-doc dnsutils

Далее нам нужно настроить доменную зону. Для этого добавляем в файл /etc/bind/named.conf.local следующее:

zone "nondv.home" IN { // Желаемое доменное имя
     type master;
     file "/etc/bind/fwd.nondv.home.db"; // Forward lookup file
     allow-update { none; }; // Since this is the primary DNS, it should be none.
};

Также в гайде добавляется конфигурация для reverse lookup, но, честно говоря, я не особо понимаю, для чего это нужно, поэтому не стал этого делать.

Теперь создаем файл /etc/bind/fwd.nondv.home.db:

$TTL    604800
@       IN      SOA     ns1.mydomain.home. root.mydomain.home. (
                             20         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL

;Name Server Information
        IN       NS     ns1.nondv.home.

;IP address of Name Server
ns1     IN       A      192.168.0.3

;A - Record HostName To Ip Address
nuc     IN       A      192.168.0.3
gitlab  IN       A      192.168.0.3
mpd     IN       A      192.168.0.3
@       IN       A      192.168.0.3

Далее перезапускаем bind9 и устанавливаем автозапуск:

systemctl restart bind9
systemctl enable bind9

Обратите внимание, что я использовал .home вместо .local. Это было сделано потому, что домен nondv.local не резолвился без поддоменов. Ну, точнее dig распознавал его нормально, но браузеры и curl — нет. Как мне объяснил коллега, это скорее всего связано с разным софтом вроде Bonjour (мой рабочий ноутбук с яблоком на крышке). В общем, с доменом .home подобных проблем быть не должно.

Собственно, это все. Я после этого добавил DNS как первичный в роутер и переподключился к нему (чтобы автоматически обновился файл /etc/resolve.conf).

Как я уже сказал, чтобы иметь возможность обращаться по HTTP на 80 порт ко всем сервисам одновременно, нам нужно настроить Nginx так, чтобы он проксировал запросы на разные порты в зависимости от домена.

Документация по образу nginx доступна на сайте Docker Hub.

Подготовим основной файл конфигурации /srv/nginx/nginx.conf:

user  nginx;
worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile        on;
    keepalive_timeout  65;
    server {
      listen 80;
      server_name nondv.home;
      rewrite ^/$ http://mpd.nondv.home redirect; # основной домен, на который будут пеправляться ненастроенные запросы
    }
    include /etc/nginx/conf.d/*.conf;
}

Далее настроим домены. Я покажу только один:

# /srv/nginx/conf.d/gitlab.conf
server {
  listen       80;
  server_name  gitlab.nondv.home;

  location / {
    proxy_pass http://127.0.0.1:3080;
  }
}

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

docker run --detach \
           --network host \
           --name nginx \
           --restart always \
           --volume /srv/nginx/nginx.conf:/etc/nginx/nginx.conf:ro \
           --volume /srv/nginx/conf.d:/etc/nginx/conf.d:ro \
           nginx:alpine

Вот и все, теперь HTTP запросы на 80 порт будут отлавливаться с помощью nginx и перенаправляться на нужный порт.

Здесь все просто по официальному руководству:

docker run --detach \
           --hostname gitlab.nondv.home \
           --publish 3080:80 --publish 3022:22 \
           --name gitlab \
           --restart always \
           --volume /srv/gitlab/config:/etc/gitlab:Z \
           --volume /srv/gitlab/logs:/var/log/gitlab:Z \
           --volume /srv/gitlab/data:/var/opt/gitlab:Z \
           gitlab/gitlab-ce:latest

Ждем, когда все настроится (поглядываем в docker logs -f gitlab) и после входим в контейнер (docker exec -it gitlab bash) для доп. настройки:

nano /etc/gitlab/gitlab.rb # or vim

# /etc/gitlab/gitlab.rb
external_url 'http://gitlab.nondv.home'
gitlab_rails['gitlab_shell_ssh_port'] = 3022
# /etc/gitlab/gitlab.rb

gitlab-ctl reconfigure

Для надежности можно перезапустить контейнер (docker container restart gitlab).


CI

Gitlab CI уже интегрирован, но ему нужен Gitlab Runner (документация).

Для этого я написал небольшой скрипт:

NAME="gitlab-runner$1"
echo $NAME
docker run -d --name $NAME --restart always \
           --network=host \
           -v /srv/gitlab-runner/config:/etc/gitlab-runner \
           -v /var/run/docker.sock:/var/run/docker.sock \
           gitlab/gitlab-runner:alpine

После создания раннера, нам нужно его зарегистирировать. Для этого заходим в гитлаб (через браузер), идем в Admin area → Overview → Runners. Там описана установка раннеров. Вкратце, вы просто выполняете:

docker exec -it gitlab-runner register

и отвечаете на вопросы.

Они запускаются по аналогии с гитлабом. Публикуете их на каком-нибудь порте и добавляете конфиг в nginx.

Теперь вы можете хостить ваши проекты на домашнем сервере и использовать мощь Gitlab CI для автоматизации сборки и публикации ваших проектов. Удобно ведь делать git push и не беспокоиться о запуске, верно?

Еще я бы рекомендовал настроить почту для гитлаба. Лично я использовал почтовый ящик на Яндексе. Документация.

Let's block ads! (Why?)

[Перевод] Создание мультяшного шейдера воды для веба. Часть 1

В своём туториале «Создание шейдеров» я в основном рассматривал фрагментные шейдеры, которых достаточно для реализации любых 2D-эффектов и примеров на ShaderToy. Но существует целая категория техник, требующих использования вершинных шейдеров. В этом туториале я расскажу о создании стилизованного мультяшного шейдера воды и познакомлю вас с вершинными шейдерами (vertex shaders). Также я расскажу о буфере глубин и о том, как использовать его для получения дополнительной информации о сцене и для создания линий морской пены.

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


Этот эффект состоит из следующих элементов:
  1. Просвечивающий меш воды с разбитыми на части (subdivided) полигонами и смещёнными вершинами для создания волн.
  2. Статичные линии воды на поверхности.
  3. Имитируемая плавучесть лодок.
  4. Динамические линии пены вокруг границ объектов в воде.
  5. Постобработка для создания искажений всего, что находится под водой.

В этом эффекте мне нравится то, что он затрагивает множество различных концепций компьютерной графики, поэтому позволит нам использовать идеи из предыдущих туториалов, а также развить техники, которые можно будет применить в новых эффектах.
В этом туториале я буду использовать PlayCanvas, просто потому что это удобная бесплатная web-IDE, но всё без проблем можно применить к любой другой среде работы с WebGL. В конце статьи будет представлена версия исходного кода для Three.js. Мы будем считать, что вы уже хорошо разбираетесь в фрагментных шейдерах и интерфейсе PlayCanvas. Освежить знания о шейдерах можно здесь, а познакомиться с PlayCanvas здесь.

Настройка среды


Цель этого раздела — настройка нашего проекта PlayCanvas и вставка в него нескольких объектов окружения, на которые будет влиять вода.

Если у вас нет аккаунта PlayCanvas, то зарегистрируйте его и создайте новый пустой проект (blank project). По умолчанию у вас в сцене должны быть пара объектов, камера и источник освещения.


Вставка моделей


Отличным ресурсом для поиска 3D-моделей для веба является проект Google Poly. Модель лодки я взял оттуда. Скачав и распаковав архив, вы найдёте в нём файлы .obj и .png.
  1. Перетащите оба файла в окно Assets проекта PlayCanvas.
  2. Выберите автоматически созданный материал и в качестве его диффузной карты укажите файл .png.


Теперь можно перетащить Tugboat.json в сцену и удалить объекты Box и Plane. Если лодка выглядит слишком маленькой, можно увеличить её масштаб (я поставил значение 50).

Аналогичным образом можно добавить в сцену любые другие модели.

Летающая по орбите камера


Для настройки летающей по орбите камеры мы скопируем скрипт из этого примера PlayCanvas. Перейдите по ссылке и нажмите на Editor, чтобы открыть проект.
  1. Скопируйте содержимое mouse-input.js и orbit-camera.js из этого проекта туториала в файлы с теми же названиями из вашего проекта.
  2. Добавьте к камере компонент Script.
  3. Прикрепите к камере два скрипта.

Подсказка: чтобы упорядочить проект, можно создавать в окне Assets папки. Я положил эти два скрипта камеры в папку Scripts/Camera/, свою модель в Models/, а материал в папку Materials/.

Теперь при запуске игры (кнопка запуска в верхней правой части окна сцены) вы должны увидеть лодку, которую можно осматривать камерой, перемещая её по орбите мышью.

Подразделение полигонов поверхности воды


Цель этого раздела — создание подразделённого меша, который будет использоваться в качестве поверхности воды.

Чтобы создать поверхность воды, мы адаптируем часть кода из туториала по генерации рельефа. Создайте новый файл скрипта Water.js. Откройте этот скрипт для редактирования и создайте новую функцию GeneratePlaneMesh, которая будет выглядеть так:

Water.prototype.GeneratePlaneMesh = function(options){
    // 1 - Задаём опции по умолчанию, если они не указаны
    if(options === undefined)
        options = {subdivisions:100, width:10, height:10};
    // 2 - Генерируем точки, UV и индексы 
    var positions = [];
    var uvs = [];
    var indices = [];
    var row, col;
    var normals;

    for (row = 0; row <= options.subdivisions; row++) {
        for (col = 0; col <= options.subdivisions; col++) {
            var position = new pc.Vec3((col * options.width) / options.subdivisions - (options.width / 2.0), 0, ((options.subdivisions - row) * options.height) / options.subdivisions - (options.height / 2.0));
            
            positions.push(position.x, position.y, position.z);
            
            uvs.push(col / options.subdivisions, 1.0 - row / options.subdivisions);
        }
    }

    for (row = 0; row < options.subdivisions; row++) {
        for (col = 0; col < options.subdivisions; col++) {
            indices.push(col + row * (options.subdivisions + 1));
            indices.push(col + 1 + row * (options.subdivisions + 1));
            indices.push(col + 1 + (row + 1) * (options.subdivisions + 1));

            indices.push(col + row * (options.subdivisions + 1));
            indices.push(col + 1 + (row + 1) * (options.subdivisions + 1));
            indices.push(col + (row + 1) * (options.subdivisions + 1));
        }
    }
    
    // Вычисляем нормали 
    normals = pc.calculateNormals(positions, indices);

    
    // Создаём саму модель
    var node = new pc.GraphNode();
    var material = new pc.StandardMaterial();
   
    // Создаём меш
    var mesh = pc.createMesh(this.app.graphicsDevice, positions, {
        normals: normals,
        uvs: uvs,
        indices: indices
    });

    var meshInstance = new pc.MeshInstance(node, mesh, material);
    
    // Добавляем его к этой сущности 
    var model = new pc.Model();
    model.graph = node;
    model.meshInstances.push(meshInstance);
    
    this.entity.addComponent('model');
    this.entity.model.model = model;
    this.entity.model.castShadows = false; // Мы не хотим, чтобы сама поверхность воды отбрасывала тень
};

Теперь мы можем вызвать её в функции initialize:
Water.prototype.initialize = function() {
    this.GeneratePlaneMesh({subdivisions:100, width:10, height:10});
};

Теперь при запуске игры вы должны видеть только плоскую поверхность. Но это не просто плоская поверхность, это меш, составленный из тысячи вершин. В качестве упражнения попробуйте сами в этом убедиться (это хороший повод изучить только что скопированный код).
Задача 1: сместите координату Y каждой вершины на случайную величину, чтобы плоскость выглядела как на рисунке ниже.


Волны


Цель этого раздела — назначение поверхности воды собственного материала и создание анимированных волн.

Чтобы получить нужные нам эффекты, нужно настроить собственный материал. В большинстве 3D-движков есть набор заранее готовых шейдеров для рендеринга объектов и способ их переопределения. Вот хорошая ссылка о том, как это делается в PlayCanvas.

Прикрепление шейдера


Давайте создадим новую функцию CreateWaterMaterial, задающую новый материал с изменённым шейдером, и возвращающую его:
Water.prototype.CreateWaterMaterial = function(){
    // Создаём новый пустой материал 
    var material = new pc.Material();
    // Имя нужно для того, чтобы проще находить его при отладке
    material.name = "DynamicWater_Material";
    
    // Создаём определение шейдера
    // и динамически задаём точность в зависимости от устройства.
    var gd = this.app.graphicsDevice;
    var fragmentShader = "precision " + gd.precision + " float;\n";
    fragmentShader = fragmentShader + this.fs.resource;
    
    var vertexShader = this.vs.resource;

    // Определение шейдера используется для создания нового шейдера.
    var shaderDefinition = {
        attributes: {           
            aPosition: pc.gfx.SEMANTIC_POSITION,
            aUv0: pc.SEMANTIC_TEXCOORD0,
        },
        vshader: vertexShader,
        fshader: fragmentShader
    };
    
    // Создаём шейдер из определения
    this.shader = new pc.Shader(gd, shaderDefinition);
    
    // Применяем шейдер к этому материалу 
    material.setShader(this.shader);
    
    return material;
};

Эта функция берёт код вершинного и фрагментного шейдера из атрибутов скрипта. Поэтому давайте определим их в верхней части файла (после строки pc.createScript):
Water.attributes.add('vs', {
    type: 'asset',
    assetType: 'shader',
    title: 'Vertex Shader'
});

Water.attributes.add('fs', {
    type: 'asset',
    assetType: 'shader',
    title: 'Fragment Shader'
});

Теперь мы можем создать эти файлы шейдера и прикрепить его к нашему скрипту. Вернитесь в редактор и создайте два файла шейдера: Water.frag и Water.vert. Прикрепите эти шейдеры к скрипту так, как показано на рисунке ниже.

Если новые атрибуты не отображаются в редакторе, то нажмите кнопку Parse, чтобы обновить скрипт.

Теперь вставьте этот базовый шейдер в Water.frag:

void main(void)
{
    vec4 color = vec4(0.0,0.0,1.0,0.5);
    gl_FragColor = color;
}

А этот — в Water.vert:
attribute vec3 aPosition;

uniform mat4 matrix_model;
uniform mat4 matrix_viewProjection;

void main(void)
{
    gl_Position = matrix_viewProjection * matrix_model * vec4(aPosition, 1.0);
}

Наконец, вернитесь в Water.js, чтобы он использовал вместо стандартного материала наш новый материал. То есть вместо:
var material = new pc.StandardMaterial();

вставьте:
var material = this.CreateWaterMaterial();

Теперь после запуска игры плоскость должна иметь синий цвет.

Горячая перезагрузка


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

Раскомментировав функцию swap в любом файле скрипта (например, в Water.js), мы включим горячую перезагрузку. Позже мы увидим, как пользоваться этим, чтобы сохранять состояние даже при обновлении кода в реальном времени. Но пока мы просто хотим заново применять шейдеры после внесения изменений. Перед запуском в WebGL шейдеры компилируются, поэтому для выполнения этого нам нужно заново создать наш материал.

Мы будем проверять, изменилось ли содержимое кода нашего шейдера, и если это так, создавать материал заново. Во-первых, сохраним текущие шейдеры в initialize:

// код initialize, вызываемый один раз для каждой сущности
Water.prototype.initialize = function() {
    this.GeneratePlaneMesh();
    
    // Сохранение текущих шейдеров
    this.savedVS = this.vs.resource;
    this.savedFS = this.fs.resource;
    
};

А в update мы проверяем, произошли ли какие-нибудь изменения:
// код update, вызываемый в каждом кадре
Water.prototype.update = function(dt) {
    
    if(this.savedFS != this.fs.resource || this.savedVS != this.vs.resource){
        // Создаём материал заново, чтобы можно было рекомпилировать шейдеры 
        var newMaterial = this.CreateWaterMaterial();
        // Применяем его к модели
        var model = this.entity.model.model;
        model.meshInstances[0].material = newMaterial;  
        
        // Сохраняем новые шейдеры
        this.savedVS = this.vs.resource;
        this.savedFS = this.fs.resource;
    }
    
};

Теперь, чтобы убедиться, что это работает, запустим игру и изменим цвет плоскости в Water.frag на более приятный синий. После сохранения файла он должен обновиться даже без перезагрузки и перезапуска! Вот цвет, который я выбрал:
vec4 color = vec4(0.0,0.7,1.0,0.5);

Вершинные шейдеры


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

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

Вершинный шейдер по умолчанию получает позицию в мире модели и возвращает её позицию на экране. Наша 3D-сцена задана в координатах x, y и z, но монитор — это ровная двухмерная плоскость, поэтому мы проецируем 3D-мир на 2D-экран. Таким проецированием занимаются матрицы вида, проекции и модели, поэтому мы не будем рассматривать его в этом туториале. Но если вы хотите понимать, что же конкретно происходит на каждом этапе, то вот очень хорошее руководство.

То есть эта строка:

gl_Position = matrix_viewProjection * matrix_model * vec4(aPosition, 1.0);

получает aPosition как позицию в 3D-мире конкретной вершины и преобразует её в gl_Position, то есть в конечную позицию на 2D-экране. Префикс «a» в aPosition обозначает, что это значение является атрибутом. Не забывайте, что переменная uniform — это значение, которое мы можем определить в ЦП и передавать шейдеру. Оно сохраняет одно и то же значение для всех пикселей/вершин. С другой стороны, значение атрибута получается из задаваемого ЦП массива. Вершинный шейдер вызывается для каждого значения этого массива атрибутов.

Можно увидеть, что эти атрибуты настраиваются в определении шейдера, которое мы задали в Water.js:

var shaderDefinition = {
    attributes: {           
        aPosition: pc.gfx.SEMANTIC_POSITION,
        aUv0: pc.SEMANTIC_TEXCOORD0,
    },
    vshader: vertexShader,
    fshader: fragmentShader
};

PlayCanvas берёт на себя работу по настройке и передаче массива позиций вершин для aPosition при передаче этого перечисления, но в общем случае мы можем передать вершинному шейдеру любой массив данных.

Перемещение вершин


Допустим, мы хотим сжать всю плоскость, умножив все значения x на 0,5. Нам нужно изменить aPosition или gl_Position?

Давайте сначала попробуем aPosition. Мы не можем изменять атрибут напрямую, но можем создать копию:

attribute vec3 aPosition;

uniform mat4 matrix_model;
uniform mat4 matrix_viewProjection;

void main(void)
{
    vec3 pos = aPosition;
    pos.x *= 0.5;
    
    gl_Position = matrix_viewProjection * matrix_model * vec4(pos, 1.0);    
}

Теперь плоскость должна больше напоминать прямоугольник. И в этом нет ничего странного. А что произойдёт, если вместо этого мы попробуем изменить gl_Position?
attribute vec3 aPosition;

uniform mat4 matrix_model;
uniform mat4 matrix_viewProjection;

void main(void)
{
    vec3 pos = aPosition;
    //pos.x *= 0.5;
    
    gl_Position = matrix_viewProjection * matrix_model * vec4(pos, 1.0);    
    gl_Position.x *= 0.5;
}

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

Так мы можем перемещать вершины, и при этом важно различать работу в мировом и экранном пространствах.

Задача 2: сможете ли вы переместить всю поверхность плоскости на несколько единиц вверх (вдоль оси Y) в вершинном шейдере, не искажая её форму?

Задача 3: я сказал, что gl_Position двухмерна, но gl_Position.z тоже существует. Можете ли вы выполнить проверки, чтобы понять, влияет ли это значение на что-нибудь, и если это так, то для чего оно используется?

Добавление времени


Последнее, что нам нужно, прежде чем начать создание подвижных волн — это uniform-переменная, которую можно использовать в качестве времени. Объявим uniform в вершинном шейдере:
uniform float uTime;

Теперь, чтобы передать её в шейдер, вернёмся в Water.js и в initialize определим переменную времени:
Water.prototype.initialize = function() {
    this.time = 0; ///// Сначала определяем здесь время
    
    this.GeneratePlaneMesh();
    
    // Сохраняем текущие шейдеры
    this.savedVS = this.vs.resource;
    this.savedFS = this.fs.resource;
};

Теперь для передачи переменной в шейдер мы используем material.setParameter. Для начала мы задаём исходное значение в конце функции CreateWaterMaterial:
// Создаём шейдер из определения
this.shader = new pc.Shader(gd, shaderDefinition);

////////////// Новая часть
material.setParameter('uTime',this.time);
this.material = material; // Сохраняем ссылку на этот материал
////////////////

// Применяем шейдер к этому материалу
material.setShader(this.shader);

return material;

Теперь в функции update мы можем выполнять приращение времени и получать доступ к материалу с помощью созданной для этого ссылки:
this.time += 0.1; 
this.material.setParameter('uTime',this.time);

Наконец в функции swap мы копируем старое значение времени, чтобы даже после изменения кода оно продолжало увеличиваться, не сбрасываясь на 0.
Water.prototype.swap = function(old) { 
    this.time = old.time;
};

Теперь всё готово. Запустите игру, чтобы убедиться, что нет никаких ошибок. Теперь давайте будем перемещать нашу плоскость с помощью функции времени в Water.vert:
pos.y += cos(uTime)

И наша плоскость должна начать двигаться вверх и вниз! Поскольку теперь у нас есть функция swap, то мы также можем обновлять Water.js без необходимости перезапуска. Чтобы убедиться, что это работает, попробуйте изменить инкремент времени.

Задача 4: сможете ли вы перемещать вершины так, чтобы они выглядели, как волны на рисунке ниже?


Подскажу, что я подробно рассматривал тему различных способов создания волн здесь. Статья относится к 2D, но математические вычисления применимы и к нашему случаю. Если вы просто хотите посмотреть решение, то вот gist.

Просвечиваемость


Цель этого раздела — создание просвечивающей поверхности воды.

Можно заметить, что цвет, возвращаемый в Water.frag, имеет значение альфа-канала 0.5, но поверхность всё равно остаётся непрозрачной. Во многих случаях прозрачность по-прежнему становится нерешённой проблемой в компьютерной графике. Малозатратным способом её решения является использование смешивания.

Обычно перед отрисовкой пикселя он проверяет значение в буфере глубин и сравнивает его с собственным значением глубины (его позицией по оси Z), чтобы определить, нужно ли перерисовывать текущий пиксель экрана, или отказаться от этого. Именно это позволяет рендерить сцену корректно без необходимости сортировки объектов сзади вперёд.

При смешивании вместо простого отказа от пикселя или перезаписи мы можем комбинировать цвет уже отрисованного пикселя (целевого) с пикселем, который мы собираемся отрисовать (источника). Список всех доступных в WebGL функций смешивания можно посмотреть здесь.

Чтобы альфа-канал работал в соответствии с нашими ожиданиями, мы хотим, чтобы комбинированный цвет результата был источником, умноженным на альфа-канал плюс целевым пикселем, умноженным на единицу минус альфа. Другими словами, если alpha = 0.4, то конечный цвет должен иметь значение:

finalColor = source * 0.4 + destination * 0.6;

В PlayCanvas именно эту операцию выполняет вариант pc.BLEND_NORMAL.

Чтобы включить его, достаточно просто задать свойство материала внутри CreateWaterMaterial:

material.blendType = pc.BLEND_NORMAL;

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

Мы можем устранить её, воспользовавшись вместо смешивания alpha to coverage — техникой мультисемплирования для получения прозрачности:
//material.blendType = pc.BLEND_NORMAL;
material.alphaToCoverage = true;

Но она доступна только в WebGL 2. В оставшейся части туториала я ради простоты буду использовать смешивание.

Подводим итог


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

В третьей (последней) части мы рассмотрим применение эффекта постобработки подводных искажений и рассмотрим идеи для дальнейшего усовершенствования.

Исходный код


Готовый проект PlayCanvas можно найти здесь. В нашем репозитории также есть порт проекта под Three.js.

Let's block ads! (Why?)

SUSE Linux вновь меняет владельца — почему?

В начале месяца британская компания Micro Focus объявила о продаже старейшей компании-разработчика дистрибутивов SUSE Linux за 2,5 млрд долларов. Обладателем SUSE стала шведская фондовая группа EQT, занимающаяся инвестициями в технологические компании.

Далее — почему заключили сделку, и как отреагировало сообщество.


/ фото Bernard DUPONT CC

Партнерское соглашение


Как отметили в компании, сделка с EQT является, по сути, партнерским соглашением с инвесторами. Они обладают внушительным опытом работы на рынке ПО, а их средства помогут SUSE стать полностью независимой компанией.

Планируется, что сделка будет окончательно закрыта в начале следующего года, когда акционеры Micro Focus уладят все формальности.

Представители SUSE пообещали, что компания продолжит держать курс на опенсорс и продвигать облачные решения. В частности, речь идет об облачной платформе OpenStack IaaS и платформе для работы с контейнерами приложений (CaaS), которые компания приобрела в прошлом году.

Мнение сообщества и участников сделки


В своем блоге SUSE отметили, что эта сделка — возможность ускорить развитие компании, так как инвестиции со стороны EQT предоставляют «опору для выпуска новых технологических решений на рынок». Однако в целом у компании дела уже идут неплохо: доход SUSE за последний квартал составил 164 млн долларов, при темпе роста в 13%. Представители EQT оценили уверенную позицию SUSE на рынке и нацелились на плодотворное сотрудничество с компанией.

Однако мнения ИТ-сообщества, касательно приобретения SUSE, разделились. Часть пользователей Reddit, например, обеспокоились тем, что EQT может волновать только прибыль, а не судьба самого Linux-проекта. Потому их беспокоит, как бы компания не начала развиваться в неправильном направлении, способному привести к её упадку.

Однако есть и положительное мнение. Часть резидентов Hacker News, например, понадеялась, что SUSE от этой сделки только выиграют, поскольку фондом EQT управляют люди, которые внесли значительный вклад в развитие Швеции. Сам фонд имеет большой опыт работы по развитию компаний — суммарно он вложил порядка 50 млрд долларов в более чем 200 организаций.

Краткая история [перепродаж] SUSE


Ранее SUSE уже покупали и продавали. Разработкой своего дистрибутива компания SUSE начала заниматься не сразу. Первое время она называлась S.u.S.E (от нем. Software und System-Entwicklung, что можно перевести как «Разработка ПО и систем») и выступала сервис-провайдером: выпускала пакеты ПО для Slackware и печатала мануалы по Linux.

В 1996 году компания выпустила первый дистрибутив S.u.S.E Linux 4.2. Номер релиза был выбран неспроста — он отсылает к ответу на «Главный вопрос жизни, вселенной и всего такого» из книги Дугласа Адамса «Автостопом по галактике».

Смысл отсылки немного ироничный: за 7,5 млн лет вычислений суперкомпьютер Deep Thought, разработанный сверхразумной расой, в ответ на «Главный вопрос...» выдал число 42. Этот ответ озадачил главных героев книги, поскольку им было не совсем понятно его значение, а некоторые разработчики начали использовать его в качестве «стартового номера» для релизов своих продуктов. Помимо S.u.S.E число 42 использовали разработчики программного пакета YaST: номер первого релиза был 0.42.


/ фото Tambako The Jaguar CC

После выпуска первого дистрибутива компания начала разрастаться и к 1997 году стала разработчиком самого крупного Linux-дистрибутива в Германии. В 1999 году компания начала работать и в Великобритании.

Далее началась «череда перепродаж». В 2004 году SUSE за 210 млн долларов приобрела компания Novell (при материальной поддержке со стороны IBM), которая известна своей сетевой ОС NetWare. Novell купили SUSE, чтобы предлагать своим клиентам enterprise-решения на базе SUSE Linux.

В 2005 году Novell создали openSUSE и стали вносить в платформу изменения, которые предлагало сообщество разработчиков. До этого над платформой работали только штатные программисты. За счет клиентской базы Novell решения SUSE распространились по всему миру.

Затем, в 2010 году, Novell не выдержали конкуренции на рынке и были вынуждены пойти на сделку: Attachmate при поддержке фондов Microsoft выкупили Novell вместе с SUSE за 2,2 млрд долларов. По завершению сделки Attachmate разделили линейку продуктов Novell на решения SUSE и все остальные. Аналитик из Gartner Эрл Перкинс (Earl Perkins) назвал эту сделку «концом эры конкуренции ключевых игроков рынка из 90-х», поскольку шансов на независимое существование у Novell и SUSE на тот момент не оставалось.

Вскоре после этого в 2014 году Attachmate вместе с Novell и SUSE за 1,2 млрд долларов объединились с британской компанией Micro Focus. Представители Micro Focus отметили, что это слияние было нацелено на получение выгоды для обеих компаний: за счет совместной работы они получили возможность предлагать своим корпоративным клиентам комплексные ИТ-решения и представлять больше продуктов на мировом рынке.

До недавнего времени SUSE функционировала как независимое подразделение Micro Focus. Теперь с помощью EQT у старейшей компании-разработчика Linux-дистрибутивов, возможно, появился шанс доказать Эрлу Перкинсу, что он был не прав. В SUSE надеются, что со временем они снова начнут работу как независимая компания.



P.S. О чем еще мы пишем в Первом блоге о корпоративном IaaS:
P.P.S. Несколько свежих материалов из нашего блога на Хабре:

Let's block ads! (Why?)

Другой papercraft

О бумажном макетировании бытуют два мифа. Согласно первому, оно является несерьёзным занятием. Но, здесь, как в любом виде искусства, возможны и детские каракули, и настоящие шедевры. Это наиболее логичный способ получать при минимуме затрат трёхмерные макеты, располагая лишь средствами двумерной печати, а то и обходясь без них, помочь плоским картинкам преодолеть оковы двух измерений и вырваться в третье. Второй же миф гласит, что там всё однобоко: транспорт да архитектура. А вот это действительно в значительной мере так. Но есть и другой papercraft, менее известный и более душевный...

Возможно, вам известны отличающиеся потрясающей детальностью миниатюрные копии аналоговых синтезаторов австралийца Дэна Макфарлина. Прямых реальных прототипов у них нет, это компиляции по принципу «если бы губы Никанора Ивановича да приставить к носу Ивана Кузьмича». Но стиль передан отлично.

В журнале «ЮТ для умелых рук», ставшем впоследствии «Левшой», публиковали развёртки моделей различных КА. Результат сборки может быть, например, таким:

Конечно, данное направление не забыто. Так, этот макет изображает МКС по состоянию на 2011 год.

IBN 5100 — тут нет опечатки. От своего реального неуклюжего, но красивого прототипа с похожим названием компьютер из игры «Врата; Штейна» отличается ещё и и чуть переделанной компоновкой: экран перемещён ближе к центру, нет боковых вентиляционных отверстий и др. Ну а вы можете изготовить макет этой своеобразной аллюзии на «Абибас».

Настольный терминал из Fallout нравится даже равнодушным и к жанру, и к такому дизайну, его так и хочется вытащить из виртуального пространства хотя бы в той степени, в какой Хоттабыч в старом фильме скопировал телефон. Что ж, возможно и такое.

Можете оставить так, а можете дополнить «кинескопом» и «шасси» с настоящими лампами…

… а затем и «отклоняющей системой».

И ещё одна модель, которой я завершу эту подборку — радиоприёмник Tesla 427A Poezia.

Тем, кто в прошлом столетии обращал внимание на маркировку электролитических конденсаторов, не придётся объяснять, что Маск тут ни при чём. До его рождения оставалось 9 лет.

Let's block ads! (Why?)

«Старый новый винил»: 20 материалов об истории и производстве проигрывателей и пластинок

Сегодня мы собрали для вас дайджест на «виниловую» тематику, в который вошли статьи из нашего блога «Мир Hi-Fi». Под катом материалы о том, как появились виниловые пластинки и как их производят, а также рекомендации для желающих начать свое знакомство с «вертушками».


Фото Best Picko / CC

Первое знакомство


  • Говорим о виниле: мифы, мнения и текущая ситуация. Это транскрипт подкаста «Звук» (прослушать аудио), в котором мы, вместе с экспертом Тимофеем Шиколенковым (timshick), говорим о ситуации с виниловыми проигрывателями и обсуждаем всевозможные мифы и мнения и рекомендации, связанные с темой винила. Разбираемся с тем, кого сегодня интересует винил, где его производят и продают.

  • Винил: притворись его знатоком. Статья понравится тем, кто хочет подробнее разобраться в технических нюансах работы виниловых проигрывателей и характеристиках пластинок. Здесь вы найдёте ответы на многие узкоспециальные вопросы, например: зачем нужна измерительная грампластинка, что такое поида и за счёт чего возникает пинч-эффект (pinch effect).

  • 100 вопросов о виниле: зачем нужен винил и с чего начинать. Если вы новичок в мире винила, эта серия вопросов и ответов написана, чтобы помочь вам сориентироваться. Где приобретать пластинки и на что обратить внимание при покупке на вторичном рынке? Чем современные переиздания пластинок отличаются от коллекционных вариантов? Статья поможет подойти к собранию фонотеки системно и со знанием дела.

История и философия винила


  • «Highway Hi-Fi»: с чего началась и чем закончилась история проигрывателей пластинок для автомобилей. Сегодня мы уже привыкли к возможности послушать музыку в машине, но для автолюбителей середины 50-х годов это было в новинку. Появление первых аудиопроигрывателей в моделях автомобилей Chrysler было уникальным событием, о котором писали в прессе. Подробнее о первых Highway Hi-Fi системах, принципе их работы, а также специально разработанном для них формате винила рассказываем в статье.

  • История винила. Неувядающий звук. Всеобщая диджитализация и цифровая звукозапись не повлияли на интерес к виниловым пластинкам, который продолжает возрастать с каждым годом. По данным доклада американской Ассоциации звукозаписывающих компаний, только в США за 2017 год было продано пластинок на сумму около $395 млн. Здесь мы расскажем, с чего начиналась история этого носителя и разберемся в разнообразии стандартов (размеров, материалов и принципов записи).

  • История аудиоаппаратуры класса High-End. Первая High-End аппаратура появилась еще в годы окончания Второй мировой войны. С тех пор устройства этого класса пережили несколько важных этапов развития техники. Подробнее о каждой исторической вехе рассказываем в статье.

  • Самые редкие и дорогие пластинки в мире. $300 тыс. — такую сумму отдал музыкант и основатель группы White Stripes за мастер-диск с синглом Элвиса Пресли. Говорим о самом первом выпущенном мастер-диске короля рок-н-ролла, редких альбомах на пластинках на 78 оборотов и других коллекционных записях. Из статьи вы узнаете, какую пластинку купил создатель Minecraft, у кого хранится уникальная запись группы The Quarrymen.

  • «Между винилом и кассетой»: история тефифона. Прототип этого необычного аудиогаджета был изобретён в 1930-х годах прошлого века в Германии и сперва использовался для военных целей. Одноименный проигрыватель имеет способ воспроизведения аналогичный винилу — с помощью звукоснимателя с иглой. Рассказываем об истории создания тефифона, его устройстве и назначении, а также расцвете формата и причинах падения его популярности.


Фото choo chin nian / CC

Как делают пластинки и проигрыватели


  • Священный Грааль винила: искусство мастеринга на половинной скорости. Лондонская студия звукозаписи «Эбби-Роуд» существует с 1931 года. На ней записывали свои альбомы такие культовые рок-группы, как U2, Keane, Pink Floyd и др. Именно рядом с этой студией на пешеходном переходе ливерпульская четвёрка сделала свое знаменитое фото. В статье инженер студии Майлз Шоуэлл знакомит нас со многими нюансами и деталями кропотливой работы по нарезке виниловых дисков и особенностях мастеринга пластинок на половинной скорости.

  • Репортаж с фабрики Ortofon: технологии, материалы и немного истории. Свой путь компания начинала с разработки техники для озвучивания кинофильмов. На аудиорынке она стала известна после изобретения одного из самых совершенных типов звукоснимателей в конце 1940-х. С тех пор Ortofon выпустили более трех сотен моделей картриджей. Эта статья — экскурсия по фабрике с рассказом об используемых технологиях. Во второй части этого материала инженеры Ortofon показывают весь сборочный процесс и делятся нюансами создания новых моделей: от идеи до серийного производства.

  • Перфекционизм Clearaudio. Как делают проигрыватели виниловых пластинок. За 40 лет компания Clearaudio выросла из небольшого семейного бизнеса звукового инженера Питера Зухи во всемирно известный бренд виниловых проигрывателей. Предлагаем заглянуть на производство и в офис немецкой компании и познакомиться с ней подробнее. Первая часть экскурсии посвящена этапам сборки виниловых проигрывателей и заготовкам деталей для будущих устройств. Во второй части вы узнаете, как изготавливаются и собираются тонармы и как тестируют детали проигрывателя.

  • Возвращение эпохи винила. Меломан Марк Рейни открыл неподалёку от Портленда — города, известного своей независимой музыкальной сценой, — фабрику по производству виниловых пластинок Cascade Record Pressing. В статье он и другие представители индустрии делятся своими мыслями о будущем винила, проблемах, с которыми приходится сталкиваться производствам (поиск независимых лейблов, устаревшее оборудование и др.) и обсуждают почему от увеличения спроса на пластинки может пострадать их качество.

  • Как делают виниловые пластинки, или новая LP-столица мира. Первый сингл группы The Beatles в США был выпущен в городе Нэшвил на самой крупной фабрике по производству пластинок — United Record Pressing. Мы покажем, как работает круглосуточное производство винила и расскажем сколько времени занимает «печать» партии дисков. Обсудим как врождённый консерватизм Нэшвила и его связь с кантри-музыкой влияет на успех фабрики и почему «винил будет жить», несмотря на развитие высоких технологий.

  • Как работает крупнейшая фабрика виниловых пластинок. Ещё один материал о нюансах производства и продажи виниловых пластинок, но теперь уже в Европе. В небольшой чешской деревне Лоденице работает крупнейшая фабрика пластинок GZ Media. Генеральный директор фабрики рассказывает, как разработка собственных прессов и внедрение новых технологий помогает им выполнять заказы быстрее других, а также как устроена работа на фабрике. Также вы узнаете, как пластинки упаковываются и поставляются музыкальным магазинам.

  • Роберто Виго: «Мастер-лента — чистейший источник аналогового звучания». Студия Analogy Records «пишет» на магнитную ленту артистов разных музыкальных жанров: джаз, поп, фолк и др. В этом интервью её основатель, музыкальный энтузиаст и звукоинженер Роберт Виго делится историей своего бренда, тонкостями записи на ленту и преимуществами мастеровой записи по сравнению с копией.

Винил и другие форматы


  • Что такое HD-винил и действительно ли он так хорош. Австрийская компания Rebeat Innovation объявила HD-пластинки будущим виниловой звукозаписи и недавно привлекла $4,8 млн инвестиций на их производство. Первую партию компания пообещала выпустить в 2019 году. Чем новая технология отличается от традиционной? В чём её преимущества и недостатки? Как она повлияет на жизнь пластинок и их стоимость? Рассуждаем об этом в статье.

  • Битва за формат: бобина vs кассета vs винил vs CD vs HiRes. Компания ММС, производящая звуковое оборудование и мультимедиа, устроила «битву» между пятью форматами аудиозаписи. В сравнительном прослушивании участие мог принять любой желающий. Посетителям предложили угадать на слух, какой из форматов звучит, опираясь на характерные особенности воспроизведения. О результатах эксперимента читайте в нашем материале.

  • Гибкие пластинки — универсальный носитель, который вернулся из прошлого. Расскажем об истории этого звукового носителя — от подпольных записей рок-н-ролла на рентгеновских снимках («музыка на костях») до пластинок с записями звёзд эстрады в ежемесячном журнале «Кругозор». Приведём примеры использования гибкого формата в России и за рубежом и поговорим, с чего началось его массовое производство.

  • Может ли современное издание пластинки оказаться лучше первопресса?. Один из 30 самых продаваемых альбомов в истории музыки — Brothers In Arms британской рок-группы Dire Straits был выпущен в 1985 году и разошёлся тиражом около 30 млн копий. Мы сравнили первопресс популярного альбома с переизданием. Может ли современное переиздание сравниться с оригинальным первым прессингом по звучанию? Как на него повлиял полностью цифровой мастеринг первого издания? В статье отвечаем на эти вопросы и делимся результатами.

  • Оцифровка винила: «ЗА» И «ПРОТИВ». В статье разбираем все тонкости перевода виниловых записей в цифру: какую роль играет аудиокарта, с какими программами нужно работать для редактирования записи и почему нельзя обойтись без фонокорректора. Cравним между собой звучание релизов, изданных на компакт-дисках, SACD, и оцифрованных с винила.

  • Почему CD могут звучать лучше виниловых пластинок. Вопросу противостояния этих двух форматов посвящена не одна словесная битва на аудиофорумах. Статья повествует о положительных и отрицательных моментах в использовании обоих форматов. Поговорим о причинах того, почему виниловая пластинка не всегда звучит лучше, чем CD и наоборот.

  • Как оцифровывать виниловые пластинки. Ещё один «двухтомный» материал, посвященный оцифровке виниловых записей. В этой части подробно останавливаемся на каждом этапе и разбираем узкие места — на что обращать внимание при тестовых прогонах системы и какой софт выбрать. Во второй части поговорим про реставрацию записи (инструментах аудиоредактора, приемах нарезки треков и др.) и дадим советы по удалению дефектов (щелчков, шипения и др.) .



Дополнительное чтение: несколько постов из нашей Академии Винила:

Let's block ads! (Why?)

[Перевод] «Песчаные дюны» Плутона состоят не из песка – это гранулы замёрзшего метана

В июле 2015 года межпланетная станция "Новые горизонты" вошла в историю, совершив первый пролёт мимо Плутона. В процессе пролёта зонд собрал горы данных о поверхности Плутона, его составе, атмосфере и системе спутников. Он также подарил нам захватывающие снимки «сердца» Плутона, его замёрзших равнин, горных гряд и загадочной "колючей равнины".

Эти странные особенности впервые продемонстрировали, как сильно отличается поверхность Плутона от Земли и других планет внутренней Солнечной системы. Забавно, что они также показали, насколько этот далёкий мир похож на Землю. К примеру, в новом исследовании команда учёных, обрабатывавших изображения, полученные с «Новых горизонтов», заметила «дюны» на поверхности Плутона, напоминающие песчаные дюны Земли.
Исследование назвали «Дюны на Плутоне», и недавно опубликовали в журнале Science. Им руководил Мэтью Телфер, преподаватель физической географии из Плимутского университета, и участвовали геологи Эрик Партели из Кёльнского университета и Джани Радебаух из Университета Бригама Янга.


Мелкие пятна на равнине Спутника распознали как поперечные дюны, из-за их перпендикулярности к тёмным «ветровым полосам»

Им помогали члены Центра Карла Сагана из института SETI, Исследовательского центра Эймса НАСА, Обсерватории Лоуэлла, Юго-западного исследовательского института, Национальной обсерватории оптической астрономии, Массачусетского технологического института, Лаборатории прикладной физики Университета Джонса Хопкинса и многих других университетов.

Дюны на Земле формируются из песка, сдуваемого ветром, создающим повторяющиеся гребни в пустыне или вдоль пляжей. Такие же явления наблюдаются вдоль рек и аллювиальных равнин, где вода со временем оставляет минеральные отложения. Во всех этих случаях дюны появляются из-за переноса твёрдых частиц в движущейся среде (в воздухе или воде). За пределами Земли такие явления наблюдались на Марсе, Титане и даже на комете Чурюмова-Герасименко.

Однако, при изучении изображений, полученных с зонда «Новые горизонты», Телфер с коллегами отметили сходные образования на равнине Спутника на Плутоне. Этот регион, составляющий западную долю области Томбо, имеющей форму сердца, по сути, представляет собой массивный резервуар льда. Исследователи уже отмечали, что его поверхность вроде бы состоит из неправильных многоугольников, разграниченных впадинами, что может служить признаком наличия конвективных ячеек.

Как доктор Телфер объяснил нам по почте:

«Уже в первые дни мы заметили особенности, напоминающие дюны, но с течением времени и с получением всё большего количества изображений, большая их часть становилась всё менее и менее убедительной. Однако одна область становилась всё более убедительной с каждым проходом. Именно о ней мы и сообщаем».

Ещё одна интересная особенность – тёмные потоки длиной в несколько километров, выровненные в одном направлении. Настолько же интересными были и обнаруженные командой Телфера особенности – они выглядели, как дюны, идущие перпендикулярно ветровым полосам. Это говорило о том, что дюны являются поперечными – такими, которые возникают из-за длительных ветров в пустыне.


Изображения с зонда «Новые горизонты» демонстрируют узоры на поверхности Плутона, которые считаются дюнами.

Чтобы определить правдоподобность такой гипотезы, исследователи построили модели, учитывающие тип частиц, из которых могли бы состоять эти дюны. Они заключили, что гранулы, подверженные переносу типичными ветрами, могли бы состоять из метанового или азотного льда. Затем они смоделировали физику ветров Плутона, которые должны дуть сильнее, спускаясь с горных склонов, окружающих равнину Спутника.

Однако они также определили, что ветра на Плутоне не могли быть достаточно сильными для того, чтобы самостоятельно передвигать эти частицы. В этом процессе играет большую роль возгонка – когда поверхностный лёд переходит из твёрдой фазы в газообразную при нагреве солнечным светом. Такой процесс обеспечил бы действующую вертикально вверх силу, необходимую для подъёма частиц с места, после чего ветра Плутона смогли бы уже переносить их и разбрасывать по поверхности.

Как пояснил Тефлер, этот вывод стал возможным благодаря огромной поддержке, полученной его командой, большую часть которой обеспечили команда геологии, геофизики и получения изображений миссии «Новые горизонты»:

«Проведя пространственный анализ, убедивший нас в том, что это реально могут быть дюны, мы получили великолепную возможность поработать вместе с Эриком Партели из Кёльна; он продемонстрировал нам на своих моделях, что такие дюны должны формироваться, только если гранулы сначала поднимутся в воздух. Команда „Новых горизонтов“ нам очень помогла, указав на то, что смешанные азотные и метановые льды должны вздымать гранулы метанового льда вверх в процессе возгонки льдов».


Сравнение особенностей дюн на Плутоне, Земле и Марсе

Это исследование продемонстрировало не только то, чем Плутон, один из самых удалённых объектов Солнечной системы, похож на Землю, но и то, насколько активна его поверхность. «Это демонстрирует нам не только то, что поверхность Плутона влияет на его атмосферу, но и обратный эффект, — сказал Телфер. – Мы обнаружили весьма динамичную поверхность планеты, так далеко расположенной в Солнечной системе».

Кроме этого, понимание того, как дюны могут формироваться в условиях Плутона, поможет учёным интерпретировать сходные особенности, которые они находят и в других местах Солнечной системы. К примеру, НАСА в следующем десятилетии планирует отправку миссии на Титан, чтобы изучить множество его интересных поверхностных особенностей, среди которых есть и дюны. Также множество миссий отправляется на изучение Красной планеты до тех пор, пока туда не полетят люди где-нибудь в 2030-х.

Знания о том, как появлялись эти образования, помогут нам понять динамику планеты, и ответить на более глубокие вопросы о процессах, происходящих на её поверхности.

Let's block ads! (Why?)

Исследование: хедж-фонды под управлением женщин демонстрируют более высокие результаты

Изображение: Unsplash

Согласно данным исследования Hedge Fund Research, Inc., результаты хедж-фондов под управлением женщин, в среднем, на 20% превосходят показатели по отрасли за последние десять лет.

Женский индекс эффективности обогнал рынок


Вопросы возможностей и положения женщин в современном обществе привлекают все больше внимания. Forbes, Тhe Times, Financial Times за последние 3 года выпустили несколько материалов, в которых сравнили индексы HFRX и HFRI Women, оценивающие эффективность хедж-фондов под управлением женщин, с аналогичными общеотраслевыми показателями.

Сравнение индексов показало, что вопреки стереотипам, «женские» хедж-фонды оказались на высоте. По итогам 2017 года показатель HFRX Woman почти вдвое превысил средний результат: 11% против 6% за тот же период. По индексу HFRI женщины также обогнали мужчин на 0,9%. Статистика за три, пять, десять лет подтверждает высокие показатели женщин-финансистов на рынке.

Источник: KPMG

Пол не определяет способности к инвестированию


Глядя на приведенные цифры можно подумать, что женщины просто лучше предрасположены к такой работе: проявляют большую осторожность или внимательность к деталям. Неоднократно процитированное СМИ исследование ученых Northeastern U. D’Amore-McKim School of Business, проведенное в 2015 году, опровергает такое предположение.

Ученые сравнивали фонды, управляемые только женщинами, только мужчинами и менеджерами обоих полов, опираясь на значения коэффициента Шарпа (отношения возврата портфеля к портфельному риску) в каждой группе. Ощутимых различий между инвестиционными стратегиями групп замечено не было.

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

Плюсы жесткой конкуренции


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

В поддержку женщин, участвующих в такой конкурентной борьбе, выступают не только исследователи, но и сами участницы рынка. В 2001 году был создан благотворительный фонд 100 Women in Finance, занимающийся поддержкой, трудоустройством и обучением женщин-инвесторов. Активность СМИ и общественных организаций направляется на повышение видимости женщин в «мужском» мире финансов.

Нельзя сказать что женщины совсем не получают предложений на рынке труда. Например, в конце 2017 года один из крупнейших хедж-фондов мира, Bridgewater Assotiates, нанял для анализа торговых стратегий самую успешную женщину в турнирном покере Ванессу Селбст. В конечном итоге, целью хедж-фондов является не найм специалистов определенного пола, а максимизация прибыли.

Другие материалы по теме финансов и фондового рынка от ITI Capital:


Let's block ads! (Why?)

Что грозит Burger King

Для тех, кто еще не читал новости о том, как Burger King в своем мобильном приложении интегрировал нежелательное программное обеспечение AppSee, публикую краткую информацию:
  • AppSee — это, malware-сервис, который можно интегрировать в мобильное приложение и получить видеозапись экрана для какой-то там аналитики
  • Как видно из перехваченного видео — данные передаются без какой-либо обработки, а уже в самом AppSee видео обрабатывается и данные держателей карт (ДДК) закрашиваются черными квадратами, как они утверждают
  • Представители Burger King заняли позицию, что они ничего не нарушают, так как данные от AppSee им уже приходят после обработки и они не видят в них ДДК, как они утверждают

Даже если поверить, что оба утверждения верные, то все равно Burger King своими действиями нарушает стандарт безопасности отправку видео файла на AppSee: нельзя передавать с номером карты (PAN) дату истечения и имя владельца. Про телефон я вообще молчу. Это прямое нарушение PCI DSS в частности и здравого смысла вообще. Обычный MITM в публичном WiFi организовать утечку ДДК, а номер телефона — вообще легчайший способ получить дубликат sim карты в любом отделении с помощью имени владельца и базовых навыков графического редактора.

Сама компания Burger King прошла проверку стандартам, а значит попадает под все карательные меры, а именно:

  1. Крупные денежные штрафы
  2. Повторные аудиты QSA
  3. Понижение уровня сертификации

В заключение хочу добавить, что такие стандарты как GDPR или 152-ФЗ, к которым апеллируют, действуют на определенных геополитических областях, в то время как PCI DSS — это международный стандарт платежных систем и нарушать его нельзя нигде.

Let's block ads! (Why?)

Не Долиной единой

Представьте, что вы — российская IT-компания, которая хочет открыть свой офис в Америке и выйти на американский рынок. Какая первая локация приходит в голову? Кремниевая долина! Считается, что она просто создана для этого.

Но насколько это справедливо? Основатель Macroscop Артем Разумков посетил 11 технологических хабов в различных частях США, и теперь по ряду причин мы ставим под сомнение, что Кремниевая долина – идеальное место для любой IT-компании.


фото с сайта apalych.com

Все дороги ведут в Долину…?

Подавляющее большинство великих IT-компаний, которые сразу приходят на ум (Google, Apple, Facebook, Uber), находятся в Кремниевой долине. Значит, практика подтверждает, что Долина – это то место, где эффективно развиваются IT-компании? А исключений из этого не так уж много, и, видимо, поэтому туда так все стремятся.

Действительно, Кремниевая долина — это уникальная экосистема! Если вы делаете IT-стартап, то именно в Долине найдете самое большое количество различного капитала: венчурные фонды, бизнес-ангелы и т.д. Нигде больше нет такой концентрации! Если нужны инструменты для роста, то опять же больше всего их здесь: акселераторы, технологические центры и т.д. И что отмечают практически все — это скорость работы. В Кремниевой долине сложились какие-то уникальные правила игры, и все происходит очень быстро. Пожалуй, здесь самый быстрый процесс работы над IT-продуктами и темп роста IT-компаний.

Стало быть, если IT-компания выбирает место, где «приземлиться» в США, все указывает на Кремниевую долину? Многие именно так и делают. Когда у российской компании с командой разработки в России появляется задача выйти на американский рынок, исходя из всего вышесказанного, вопрос, где это делать, даже не встает. «Конечно, Кремниевая долина!» — говорят все (почти все).

Но давайте приглядимся

Пусть, есть IT-компания из России, продукты которой продаются в десятках стран мира, но не в Америке. Компания делает B2B-продукт, продает его дистрибьюторам и системным интеграторам и хочет выйти на рынок США. Попробуем понять, насколько ей подходит Кремниевая долина.
Продавать планируется дистрибьюторам и интеграторам, которые, предположим, располагаются в разных точках США. Соответственно, если открывать офис продаж в Кремниевой долине, формировать команду, которая будет там находиться, по телефону вести переговоры с потенциальными партнерами и покупателями и иногда выезжать на личные переговоры, что получаем?

1. Высокие расходы на содержание команды.
Людям надо платить зарплату, которая позволит им жить в Долине. А жить в Калифорнии и, в особенности, в Кремниевой долине – отнюдь не дешево. Снять маленькую комнату в Сан-Франциско стоит от 1700$/мес. Снять квартиру – от 2300$/мес. Стоимость жизни в Кремниевой долине очень высока (одна из самых высоких в Америке, примерно раза в 3-4 выше, чем посередине американского континента), и зарплаты у людей должны быть соответствующими. Формируя в Долине команду продаж, будьте готовы платить ей в разы больше.

2. Разница во времени.
Насколько расположение офиса продаж в Кремниевой долине удобно с точки зрения часовых поясов? Долина расположена на западном побережье, и разница во времени, например, с Нью-Йорком, составляет 3 часа. То есть когда вы ведете переговоры в 14 часов по местному времени, в Нью-Йорке и на восточном побережье уже 17ч, и рабочий день заканчивается. Коммуницируя из Долины, не очень удобно захватывать другие американские регионы.

3. Логистика.
Насколько Кремниевая долина является хорошим транспортным хабом? Откровенно говоря, это одно из самых слабых мест Сан-Франциско. Авиарейсов немного и часто, чтобы куда-то добраться, надо делать дополнительные стыковки. И чтобы долететь, например, до восточного побережья, надо потратить 6 часов. А это совсем немало.

Положение воздушных судов над американским континентом, сервис Flightradar24

Но хоть в Сан-Франциско с рейсами все не очень здорово, есть одно преимущество, которое может перевесить все логистические минусы: в аэропорту есть специальная комната для занятий йогой.

Так что справедливость 3 пункта оставляем на ваше усмотрение :)

Итак, формируя команду продаж в Кремниевой долине, получаем команду в самом дорогом месте (и содержать ее там дорого), которая имеет большие ограничения по возможностям телефонных (и других) коммуникаций с другими частями Америки из-за разницы часовых поясов, которой при всем этом летать на переговоры долго и неудобно.
Учитывая все это возникает впечатление, совершенно противоположное первому.

Вдобавок ко всему, «блага» Долины в виде капитала, акселераторов, технологических центров, уникальной среды талантов в области разработки вам не пригодятся. Они не будут работать на вас. И выходит, все, что получаем – дорогая команда, которая находятся в дорогом месте и продает в другие бедные штаты, да еще и с ограничениями во времени и очень неудобной транспортной логистикой.

Исключения, конечно, есть. Существуют примеры, когда разместить в Долине команду продаж будет самым правильным решением. Самый очевидный – когда вы продаете в саму Калифорнию и саму Кремниевую долину. Правильно работать там, куда продаешь, плюс это дешевле всего с точки зрения логистики – не надо тратить лишние деньги на переезды и перелеты.
А если речь идет о продажах по всей Америке, то размещать команду именно в Долине будет странным решением.

Совсем другое дело, когда компания там основана. В Долине очень благодатная почва для роста стартапов. Посмотрите на те великие IT-компании, которые вспоминались в самом начале: и Google, и Facebook были основаны в Кремниевой долине. Ядром таких компаний является разработка. И центр принятия решений должен находиться там, где находится разработка. В то же время, эти компании открывают офисы продаж в разных точках Америки и мира, и именно из соображений экономии. Кстати, великих IT-компаний, основанных за пределами долины тоже хватает. Например, Microsoft и Amazon из Сиэтла.

Резюмируя: экономически и логистически оправдано находиться в Долине тем компаниям, которые в нее же продают. Либо компаниям, у которых есть какие-то специфические необходимости там быть. Все остальное – просто дань моде или желание жить конкретно в этом месте кого-то из основателей компании, но не какие-то объективные бизнес-причины.

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

Куда податься?

Увидев ситуацию своими глазами и осознав все это, Артем посетили большинство технологических хабов в США, чтобы понять, какое место тогда подходит лучше Долины. И вот некоторые мысли относительно этого.

Так или иначе, для прочих технологических мест Кремниевая долина – это своего рода икона, и каждое из них старается в той или иной степени быть на нее похожим. Даже неформальные названия перекликаются: в Лос-Анжелесе — Silicon Beach, в Портленде — Silicon Forest, в Филадельфии – Great Valley.

Одной из альтернатив Долины, избавленной от обозначенных выше недостатков, представляется Чикаго. Это очень большой и очень недорогой город, он находится в центре континента и является отличным транспортным хабом. Вдобавок Чикаго хорош, если хочется попробовать отладить продажи – благодаря своему размеру, в нем есть покупатели практически на все. Поэтому можно отвалидировать процессы и проверить модель продаж.

Многие российские компании выбирают Нью-Йорк. Он находится на восточном побережье, а, значит, разница во времени с Россией не так велика, это огромный город и огромный транспортный хаб. Но наряду с Кремниевой долиной является одним из самых дорогих мест в Америке. Зато в Нью-Йорке есть варианты снижения затрат: не обязательно жить на Манхеттене, можно жить в менее дорогом Бруклине или Нью-Джерси, меняя понижение стоимости на свое время, которое вы проведете в дороге. А транспорт в Нью-Йорке – это отдельная история. Складывается впечатление, что можно быстро доехать из Джерси-Сити до Манхеттена (всего около 10 км), но на практике на это уходит иногда чуть ли не час. До Бруклина ходит метро, но метро в Нью-Йорке – это отдельная песня, в нем нередко образуются пробки из поездов. Но для людей, которые готовы поменять свое время на экономию, окрестности Нью-Йорка могут стать хорошим решением.

Города отличаются не только стоимостью жизни и часовыми поясами, но и неким бизнес-менталитетом: западное побережье (Калифорния, Кремниевая долина) – это образ рискованного, в какой-то степени бесшабашного подхода к ведению дел, центр рисков, инноваций и безумных идей; восточное (Нью-Йорк) -консервативный, более взвешенный и строгий, это финансовый центр, где люди в галстуках принимают серьезные решения по классическим моделям. Это тоже можно учитывать. И выбрать Нью-Йорк, если у вас стартап в области финансов и он требует консервативных денег. Или Долину, если хочется привлечь какие-то «безбашенные» инвестиции.

Кремниевая долина уникальна!

И это мы не ставим под сомнение. Но выбирая место, например, для офиса продаж, нужно понимать, откуда вам будет максимально удобно продавать туда, куда вы нецеливаетесь. Если продавать планируется по всей стране, надо найти место:

• где все удобно с точки зрения часовых поясов (а это, желательно, где-то посередине континента, чтобы максимально эффективно вести переговоры с западом и с востоком);
• откуда можно долететь в любую точку быстро (и это тоже посередине континента);
• где есть достаточное количество специалистов соответствующего уровня для вашей команды;
• где затраты (на оплату труда, на аренду офиса и пр.), будут приемлемы.

Но это все определяется уже после того, как вы поняли, кому продаете, где все эти люди находятся, и как к ним добраться. Конечно, если покупатели находятся в каком-то конкретном штате, то и открыть офис стоит там. Но если рассматривать всю Америку, то лучше руководствоваться обозначенными выше принципами.

Не надо думать, что Кремниевая долина – это универсальное место, которое подходит всем. Ищите свое место под свои конкретные условия.

Let's block ads! (Why?)

Unity3D: как узнать степень освещения точки сцены?

Приветствую!

Я знаю, и вы в глубине души знаете, чего не хватает вашим карточным играм или играм «три в ряд». Системы скрытности!

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

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

Способ 1: коллайдеры


Простой и не особо ресурсоёмкий способ.

К каждому источнику освещения добавляем по сферическому коллайдеру. Делаем его триггером. Выставляем размеры примерно равными радиусу света.

Остальное — ясно, как тень. Пишем простенький скрипт, где в OnTriggerEnter() размещаем активацию расчета освещенности (чтобы источники света не работали «вхолостую», когда игрока рядом нет).

Сам расчет освещенности будет расположен в Update(). По сути, это обычный Physics.Raycast(). Если попадает в игрока — игрок в зоне света. Если не попадает — значит, игрок за препятствиями и, значит, в тени.

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

Пример

В точке 1 освещенность близка к максимальной. В точке 2 освещенность минимальна — между светом и точкой препятствие. В точке 3 освещенность средняя.

И это не всё! Можно добавить триггер-коллайдеров в различные «зоны теней», где игрок должен прятаться. В лучших традициях Manhunt. Аналогичным образом можно помечать коллайдером светлые зоны, имитируя, например, свет прожектора.

Преимущества:


  • Легко настроить Point light'ы.
  • Довольно экономен в плане ресурсов, если не спамить источники света.

Недостатки:


  • Тяжело настраиваются Spot light и Directional light. Если для первого достаточно отпозиционировать коллайдер в области света (чтобы повышать видимость игрока при входе), то второй представляется настоящим ужасом. Нужно либо размещать коллайдеры у каждой тени (чтобы снижать видимость игрока при входе), либо постоянно проверять с помощью Physics.Raycast() между игроком и «солнцем» — находится тот под лучами или в тени.
  • Большое количество коллайдеров захламляет сцену, усложняя физику.
  • Необходимо аккуратно работать с пересекающимися источниками света.
  • Динамичный свет (перемещающийся или меняющий интенсивность) нужно отдельно дописывать через скрипты.

Способ 2: RenderTexture


Что мы тут делаем? По сути — получаем «скриншот» с камеры, причем необязательно с камеры основной. А затем анализируем цвет скриншота, чтобы узнать, насколько яркий свет падает на предмет.

Для начала нам нужен объект, с которого мы будем «читать» свет. Создаем обычную сферу или плоскость, делаем маленькой (scale 0.1), размещаем вплотную к полу, делаем белой, убираем коллайдер:

Скрытый текст


Добавляем камеру (обязательно убираем audio listener и проверяем, что не стоит таг MainCamera). Привязываем её к нашему объекту. Ставим её чуть выше, направляем вниз. Выставляем в настройках не основной дисплей. Делать ли её ортографической — это на ваш вкус.

Под конец позиционируем её так, чтобы она смотрела на наш объект и только на него.

Скрытый текст


Под конец настраиваем Culling mask основной и вторичных камер, чтобы основная не отображала наши «световые» объекты, а вторичные видели только их, не захламляясь ничем прочим.

И тут начинается самое интересное. Привязываем к камере скрипт:

public Camera cam; // наша камера
RenderTexture tex;
Texture2D _tex;

void Start () {
        // Создаем изображение для "скриншота". 
        // Да, он всего в один пиксель размером - больше не надо.
        // Depth лучше на 0 не ставить - появляются различные баги.
        tex = new RenderTexture (1, 1, 8); 
        // RenderTexture "читать" нельзя, 
        // поэтому создаем текстуру, в которую его переводим.
        _tex = new Texture2D (1, 1, TextureFormat.RGB24, false);
}

void Update () {
        // назначаем текстуру "скриншота" камере
        cam.targetTexture = tex; 
        cam.Render ();
        // делаем полученный скриншот активным
        RenderTexture.active = tex;
        // записываем в Texture2D
        _tex.ReadPixels (new Rect (0, 0, 1, 1), 0, 0); 
        _tex.Apply ();
        Color col = _tex.GetPixel (0, 0);
        float vis = (col.r + col.g + col.b) / 3;
}

На выходе получаем float vis, который, по сути, является числовой репрезентацией уровня освещения, падающего на наш объект. Если источник близко — предмет белый — vis равен 1. Если темно — предмет черный — vis равен ~0.

Нам не нужно проделывать вышеуказанную операцию каждый фрейм, так что встраиваем небольшой секундный таймер:

float interval = 0;
void Update ()
{
        interval += Time.deltaTime;
        if (interval < 1)
                return;
        interval = 0;
        // наш код
}

Далее мы всю нашу систему привязываем к игроку, чтобы она передвигалась вместе с ним. И наша переменная vis автоматически выдает освещенность вокруг игрока!

Данную систему можно использовать не только в связке с игроком. Можно разместить её где угодно и как угодно, создавая своеобразные датчики света. Как правило для их реализации имеются более эффективные пути, но всегда приятно иметь альтернативы?

Преимущества очевидны, поговорим о недостатках.

Недостатки


  • Каждый «детектор света» (если их больше одного) требует отдельной камеры.
  • Texture2D.ReadPixels() — ну крайне медленная. Даже если проделывать её раз в секунду, а не каждый фрейм, даже если разбить функции записи и чтения текстур на разные фреймы, все равно бывают пролагивания в 40-110ms.
  • Эта система не учитывает некоторые редкие случаи. Например, на персонажа светят фонариком. Персонаж хорошо освещен, но свет падает на него и за ним, а не вниз, соответственно, наш детектор света показывает низкий уровень освещенности. Решить проблему можно, например, размещая детектор не у пола, а на уровне груди персонажа. Тогда нужно ставить две камеры с противоположных сторон, чтобы читать свет с любой стороны. Что замедлит систему ещё вдвое.

Let's block ads! (Why?)