voxels
|
Страница в процессе перевода. |
#
MakieCore.voxels — Function
voxels(x, y, z, chunk::Array{<:Real, 3})
voxels(chunk::Array{<:Real, 3})
Строит блок вокселов с центром в точке 0. При необходимости расположение и масштаб фрагмента можно задать в виде диапазонов x, y и z. (Здесь учитываются только экстремумы. Вокселы всегда имеют одинаковый размер.)
На внутреннем уровне вокселы представлены 8-разрядными целыми числами без знака, при этом 0x00 — это всегда невидимый «воздушный» воксел. При передаче блока соответствующего типа эти значения задаются напрямую. Обратите внимание, что обработка цвета адаптирована для внутреннего представления и может происходить немного не так, как обычно.
Тип графика
Псевдоним типа графика для функции voxels — Voxels.
Примеры
Базовый пример
using GLMakie
# Аналогичен примеру для объема
r = LinRange(-1, 1, 100)
cube = [(x.^2 + y.^2 + z.^2) for x = r, y = r, z = r]
cube_with_holes = cube .* (cube .> 1.4)
# Для соответствия примеру объема с isovalue=1.7 и isorange=0.05 мы сопоставим все
# значения вне диапазона (1.65..1.75) с невидимыми воздушными блоками с is_air
f, a, p = voxels(-1..1, -1..1, -1..1, cube_with_holes, is_air = x -> !(1.65 <= x <= 1.75))
Атрибут gap
Атрибут gap позволяет задать размер промежутка между смежными вокселами. Он указывается в единицах размера воксела (при gap = 0), поэтому gap = 0 не создает промежутки, а gap = 1 уменьшает размер воксела до 0. Обратите внимание, что этот атрибут работает только при значениях gap > 0.01.
using GLMakie
chunk = reshape(collect(1:27), 3, 3, 3)
voxels(chunk, gap = 0.33)
Цвет и внутреннее представление
Вокселы представлены внутренним образом в виде Array{UInt8, 3} идентификаторов вокселов. В этом представлении идентификатор воксела 0x00 определяется как невидимый воздушный блок. Все остальные идентификаторы (0x01—0xff или 1—255) являются видимыми и получают свой цвет из различных цветовых атрибутов. Специально для plot.color идентификатор воксела выступает в качестве индекса в массиве цветов:
using GLMakie
chunk = UInt8[
1 0 2; 0 0 0; 3 0 4;;;
0 0 0; 0 0 0; 0 0 0;;;
5 0 6; 0 0 0; 7 0 8;;;
]
f, a, p = voxels(chunk, color = [:white, :red, :green, :blue, :black, :orange, :cyan, :magenta])
Цветовые карты
Со входами, отличными от UInt8, атрибуты цветовой карты (colormap, colorrange, highclip, lowclip и colorscale) работают как обычно, за исключением nan_color, который не применяется:
using GLMakie
chunk = reshape(collect(1:512), 8, 8, 8)
f, a, p = voxels(chunk,
colorrange = (65, 448), colorscale = log10,
lowclip = :red, highclip = :orange,
colormap = [:blue, :green]
)
Передаваемые напрямую идентификаторы вокселов (т. е. Array{UInt8, 3}) используются для индексирования вектора [lowclip; sampled_colormap; highclip]. Это означает, что идентификатор 1 соответствует lowclip, 2…254 — цветам цветовой карты, а 255 — highclip. В этом случае colorrangeи colorscale игнорируются.
Наложения текстур
Для наложения текстур нам нужно изображение, содержащее несколько текстур, которые должны быть наложены на вокселы. В качестве примера будем использовать Kenney’s Voxel Pack (воксельный пакет Kenney).
using GLMakie
using FileIO
texture = FileIO.load(Makie.assetpath("voxel_spritesheet.png"))
image(0..1, 0..1, texture, axis=(xlabel = "u", ylabel="v"))
Когда color является изображением и преобразование uv_transform определено, вокселы отображаются с наложенной текстурой. В данном случае генерируются uv-координаты (текстура), затем они преобразуются с помощью uv_transform и после этого используются для выборки изображения. Каждый воксел начинается с uv-диапазона 0…1, который можно отобразить с помощью debug_texture от Makie с преобразованием тождественности. Здесь пурпурный цвет соответствует (0, 0), синий — (1, 0), красный — (0, 1) и зеленый — (1, 1).
using GLMakie
using FileIO, LinearAlgebra
texture = FileIO.load(Makie.assetpath("debug_texture.png"))
voxels(ones(UInt8, 3,3,3), uv_transform = [I], color = texture)
Для наложения текстур мы хотим преобразовать uv-диапазон 0…1 в меньший, соответствующий текстурам на изображении. Для этого определим идентификатор uv_transform для каждого воксела, который включает перемещение и масштабирование.
using GLMakie
using FileIO
# загрузим лист спрайтов с текстурами 10 x 9
texture = FileIO.load(Makie.assetpath("voxel_spritesheet.png"))
# создадим отображение идентификатора воксела -> (перемещение, масштаб)
uvt = [(Point2f(x, y), Vec2f(1/10, 1/9))
for x in range(0.0, 1.0, length = 11)[1:end-1]
for y in range(0.0, 1.0, length = 10)[1:end-1]
]
# Определим, какие текстуры/uvs к каким вокселам применяются (0 — невидимый/воздушный блок)
chunk = UInt8[
1 0 2; 0 0 0; 3 0 4;;;
0 0 0; 0 0 0; 0 0 0;;;
5 0 6; 0 0 0; 7 0 9;;;
]
# строим
voxels(chunk, uv_transform = uvt, color = texture)
Наложение текстур также может быть выполнено для каждого воксела путем передачи Matrix uv-преобразований. Здесь первый индекс соответствует идентификатору воксела, а второй — стороне, следующей порядку: --x, --y, --z, +x, +y, +z.
using GLMakie
using FileIO
texture = FileIO.load(Makie.assetpath("voxel_spritesheet.png"))
# idx -> uv сопоставление LRBT для удобства. Обратите внимание на изменение порядка цикла.
uvs = [
(Point2f(x, y), Vec2f(1/10, 1/9))
for y in range(0.0, 1.0, length = 10)[1:end-1]
for x in range(0.0, 1.0, length = 11)[1:end-1]
]
# Создадим uvmap со сторонами (-x -y -z x y z) во втором измерении.
uvt = Matrix{Any}(undef, 5, 6)
uvt[1, :] = [uvs[9], uvs[9], uvs[8], uvs[9], uvs[9], uvs[8]] # 1 -> береза
uvt[2, :] = [uvs[11], uvs[11], uvs[10], uvs[11], uvs[11], uvs[10]] # 2 -> дуб
uvt[3, :] = [uvs[2], uvs[2], uvs[2], uvs[2], uvs[2], uvs[18]] # 3 -> верстак
uvt[4, :] = [uvs[1], uvs[1], uvs[1], uvs[1], uvs[1], uvs[1]] # 4 -> доска
uvt[5, :] = [uvs[75], uvs[75], uvs[76], uvs[75], uvs[75], uvs[62]] # 5 -> грязь/трава
chunk = UInt8[
1 0 1; 0 0 0; 1 0 5;;;
0 0 0; 0 0 0; 0 0 0;;;
2 0 2; 0 0 0; 3 0 4;;;
]
# сначала повернем координаты текстуры 0...1, потому что текстура повернута относительно того, что ожидает OpenGL
voxels(chunk, uv_transform = (uvt, :rotr90), color = texture)
Обратите внимание, что uv_transform допускает различные входные типы. Дополнительные сведения о них см. в описании ?Makie.uv_transform. В самом общем случае uv-преобразование представляет собой Makie.Mat{2, 3, Float32}, умноженное на Vec3f(uv..., 1). Синтаксис (translation, scale), который мы использовали выше, можно записать как Makie.Mat{2, 3, Float32}(1/10, 0, 0, 1/9, x, y).
Обновление вокселов
Воксельный график немного отличается от других типов графиков, что влияет на способ обновления его данных.
using GLMakie
chunk = Observable(ones(8,8,8))
f, a, p = voxels(chunk, colorrange = (0, 1))
chunk[] = rand(8,8,8)
f
Можно также обновить данные, содержащиеся в объекте графика. Однако при этом индексировать график нельзя, так как в данном случае будут возвращены преобразованные данные идентификатора воксела. Нужно индексировать p.args.
using GLMakie
f, a, p = voxels(ones(8,8,8), colorrange = (0, 1))
p.args[end][] = rand(8,8,8)
f
Оба эти решения приводят к полной замене входного массива (т. е. chunk), внутреннего представления (plot.converted[4]) и текстуры в GPU. Это может быть довольно медленным и затратным процессом, если требуется обновить только небольшую часть большого фрагмента. В этом случае следует обновить входные данные без запуска обновления (используя obs.val), а затем вызвать local_update(plot, is, js, ks) для обработки обновления:
using GLMakie
chunk = Observable(rand(64, 64, 64))
f, a, p = voxels(chunk, colorrange = (0, 1))
chunk.val[30:34, :, :] .= NaN # или p.args[end].val
Makie.local_update(p, 30:34, :, :)
f
Выбор вокселов
С помощью функции pick можно выбирать отдельные вокселы на воксельном графике. Возвращаемый индекс представляет собой плоский индекс в массиве, переданном voxels, то есть plt.args[end][][idx] вернет соответствующие данные. Здесь важно отметить, что возвращаемый индекс имеет внутреннее значение UInt32 и, следовательно, ограниченный диапазон. Очень большие воксельные графики (~4,3 млрд вокселов или 2048 x 2048 x 1024) могут достичь этого предела и вызвать целочисленное переполнение.
Атрибуты
alpha
Значение по умолчанию: 1.0
альфа-значение цветовой карты или атрибута цвета. Несколько альфа-значений, как в plot(alpha=0.2, color=(:red, 0.5), перемножаются.
backlight
Значение по умолчанию: 0.0
задает вес для расчета вторичного освещения с инвертированными нормалями.
clip_planes
Значение по умолчанию: automatic
плоскости отсечения позволяют выполнять отсечение в трехмерном пространстве. Здесь можно указать вектор из 8 плоскостей Plane3f, за которыми графики будут отсечены (т. е. станут невидимыми). По умолчанию плоскости отсечения наследуются от родительского графика или сцены. Чтобы удалить родительский объект clip_planes, передайте Plane3f[].
color
Значение по умолчанию: nothing
задает цвет для каждого идентификатора воксела, пропуская 0x00. Это означает, что воксел с идентификатором 1 получает plot.colors[1] и так далее до идентификатора 255. Можно также задать матрицу цветов, т. е. изображение для наложения текстуры.
colormap
Значение по умолчанию: @inherit colormap :viridis
задает цветовую карту, из которой производится выборка для числовых значений color. Также можно использовать PlotUtils.cgrad(...), Makie.Reverse(any_colormap) или любой символ из ColorBrewer или PlotUtils. Чтобы увидеть все доступные цветовые градиенты, можно вызвать Makie.available_gradients().
colorrange
Значение по умолчанию: automatic
значения, представляющие начальную и конечную точки colormap.
colorscale
Значение по умолчанию: identity
функция преобразования цвета. Может быть любой функцией, но с Colorbar хорошо работают только identity, log, log2, log10, sqrt, logit, Makie.pseudolog10 и Makie.Symlog10.
depth_shift
Значение по умолчанию: 0.0
корректирует значение глубины графика после всех остальных преобразований, т. е. в пространстве отсечения, где 0 <= depth <= 1. Применимо только к GLMakie и WGLMakie и может использоваться для настройки порядка отрисовки (настраиваемая перерисовка).
depthsorting
Значение по умолчанию: false
управляет порядком отрисовки вокселов. Если задано значение false, вокселы, расположенные ближе к зрителю, отрисовываются в первую очередь, что должно сокращать перерисовку и повышать производительность. Если задано значение true, вокселы отрисовываются от задних к передним, что обеспечивает правильный порядок для прозрачных вокселов.
diffuse
Значение по умолчанию: 1.0
определяет то, насколько сильно красный, зеленый и синий каналы реагируют на диффузное (рассеянное) освещение.
fxaa
Значение по умолчанию: true
определяет то, будет ли график отрисовываться с помощью fxaa (сглаживание, только GLMakie).
gap
Значение по умолчанию: 0.0
задает промежуток между соседними вокселами в единицах размера воксела. Чтобы этот атрибут действовал, значение должно быть больше 0.01.
inspectable
Значение по умолчанию: true
определяет, должен ли график проверяться с помощью DataInspector.
inspector_clear
Значение по умолчанию: automatic
задает функцию обратного вызова (inspector, plot) -> ... для очистки пользовательских индикаторов в DataInspector.
inspector_hover
Значение по умолчанию: automatic
задает функцию обратного вызова (inspector, plot, index) -> ..., которая заменяет методы show_data по умолчанию.
inspector_label
Значение по умолчанию: automatic
задает функцию обратного вызова (plot, index, position) -> string, которая заменяет метку по умолчанию, сгенерированную DataInspector.
interpolate
Значение по умолчанию: false
определяет то, производится ли выборка из текстурной карты с интерполяцией (сглаживание) или без нее (пикселизация).
is_air
Значение по умолчанию: x->begin #= /home/abogdanov/.julia/packages/MakieCore/EU17Y/src/basic_plots.jl:607 =# isnothing(x) || (ismissing(x) || isnan(x)) end
функция, которая управляет тем, какие значения во входных данных сопоставляются с невидимыми (воздушными) вокселами.
material
Значение по умолчанию: nothing
используемый только в RPRMakie атрибут для задания сложных материалов RadeonProRender. Внимание! Способ задания материала RPR может измениться, и другие бэкенды будут игнорировать этот атрибут.
model
Значение по умолчанию: automatic
задает модельную матрицу для графика. Переопределяет настройки, выполненные с помощью translate!, rotate! и scale!.
overdraw
Значение по умолчанию: false
определяет то, будет ли график отрисовываться поверх других графиков. В частности, это означает игнорирование проверок глубины в бэкендах GL.
shading
Значение по умолчанию: automatic
задает используемый алгоритм освещения. Возможные значения: NoShading (без освещения), FastShading (AmbientLight + PointLight) или MultiLightShading (несколько источников света, только для GLMakie). Обратите внимание, что это не влияет на RPRMakie.
space
Значение по умолчанию: :data
задает пространство преобразования для прямоугольника, охватывающего график. Возможные входные данные см. в описании Makie.spaces().
specular
Значение по умолчанию: 0.2
определяет то, насколько сильно объект отражает свет в красном, зеленом и синем каналах.
ssao
Значение по умолчанию: false
определяет то, будет ли график отрисовываться с использованием ssao (преграждение окружающего света в экранном пространстве). Обратите внимание, что это имеет смысл только для трехмерных графиков и применимо только с fxaa = true.
transparency
Значение по умолчанию: false
определяет то, как реализуется прозрачность графика. В GLMakie transparency = true приводит к использованию прозрачности, независимой от порядка.