Войти
ПрограммированиеФорумГрафика

Unity3D: в чем реальная польза от использования fixed в шейдерах?

#0
14:22, 1 июля 2018

Привет всем.
Знаю, что от размера используемой переменной зависит результат операций и вообще, если брать шейдеры, итоговый цвет. По идее так должно быть.
Я экспериментировал с переменными, делал шейдер и использовал в нем то float4, то fixed4, например:

fixed4 frag(..){..
fixed4 color = tex2D(...
return color;
}

float4 frag(..){..
float4 color = tex2D(...
return color;
}

Но так и не смог добиться разницы в цвете. Да и вообще разницы не заметно, что странно.
Читал что-то про типы на сайте NVidia, там говорилось еще что скорость операций над fixed4 вроде быстрее (хотя графическому процессору, как я понимаю, хоть float4, хоть fixed4 хоть float100 подавай, думаю главное чтобы в конвеер влезло).
Так в чем же разница? Или все же разница в цвете есть, но малозаметная?

Еще хотелось бы узнать что все же значат скобки "{}" в:

_MainTex ("Albedo (RGB)", 2D) = "white" {}
Писал и без них, тоже работает.


#1
17:49, 1 июля 2018

Для цвета это не будет давать видимого эффекта если ты только не работаешь с чем то вроде HDR (хотя не сильно). В документации unity написано что fixed в основном приемлем для мобильных устройств. Но это понятие движка unity, а не конечного шейдера.
Ну и само понятие fixed и float разные, одно с фиксированной точкой другое с плавающей. Для операций с цветом вполне адекватно использовать fixed, поскольку сам источник (прежде всего текстуры) в этом виде формата. А также fixed имеет большую битность на канал чем 8 бит. Поэтому считать из текстуры (32 битный) цвет в fixed4 (44 битный) более чем достаточно.

Даже для "high dynamic range colors" (HDR) рекомендуют использовать half, а это 16 бит на канал. То есть float для цвета это перебор. Для PC я думаю ты разницы в производительности не разглядишь, это все зависит от разрядности расчетов самого процессора, если он 32 битный то работа с меньшим количеством битов в редких случаях наоборот может замедлить работу, но чаще всего не на много быстрее. Поэтому разницу в скорости надо смотреть на конечном 16 битном устройстве.

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

Alerr
> Писал и без них, тоже работает.
Просто догадка по синтаксису, как пустой массив, унаследовано от старой формы записи ранних версий.

#2
8:34, 2 июля 2018

Alerr, https://docs.unity3d.com/Manual/SL-DataTypesAndPrecision.html

#3
12:53, 2 июля 2018

Нужно учитывать что приведение типов внутри шейдера между fixed, half и float ресурсоемкое. И часто может нивелировать "оптимизацию". Нужно стараться дабы операции производились между одинаковыми типами - тогда будет прирост в производительности

#4
14:35, 2 июля 2018

Durane
> Нужно учитывать что приведение типов внутри шейдера между fixed, half и float ресурсоемкое.
На сколько ресурсоемкое, больше такта?

#5
15:35, 2 июля 2018

Durane
> Нужно учитывать что приведение типов внутри шейдера между fixed, half и float
> ресурсоемкое
fixed может и да, а в чем ресурсоемкость half <-> float?

#6
0:29, 3 июля 2018

Eugene
Я бы сказал так. Поскольку операции деления, умножения, сложения и тд. нет имеют возможности совершать действия между разными типами данных, то для приведения к одному типу понадобиться дополнительная операция.
Ну а для приведения как целое<->целое так и плавающее<->плавающее так же как и плавающее<->целое приходиться грубо говоря один такт для видюшки (конечно тут еще от железа и разрядности зависит). Только на FPU преобразование типов долго, в основном из за использование памяти.

Только вот все это меркнет по сравнению с тем сколько жрет сама операция обращения к текстурам.

А вот что Unity пишут в документации по ссылке выше:

Одним из осложнений использования float/ half/ fixed типа данных является то, что графические процессоры ПК всегда отличаются высокой точностью. То есть, для всех ПК (Windows / Mac / Linux) графических процессоров, это не имеет значения , пишите ли вы float, half или fixed типы данных в ваших шейдерах. Они всегда вычисляют все в полной 32-битной точности с плавающей точкой.

То есть для PC, как я уже писал, можно не заморачиваться. И в этом случае реальной разницы нет ни какой, даже в преобразовании типов это не даст ни какой просадки. Кроме плавающее<->целое поскольку типы будут уже разные.
Хотя странно что числа с фиксированным форматом точки считаются как плавающие, это же по факту масштабированные целочисленные. При том что DX и GL предоставляют такое огромное разнообразие типов вплоть до dooble, на чем Unity решили сэкономить.

#7
3:30, 3 июля 2018

кхм... что касаемо glsl то там давно нет разницы между точностью флоат.
указание "precision точность float" на быстродействие не влияет (на теперешнем железе. Всевозможные могилки меня не интересуют). А вот во времена нв30 (hvec4 тогда было) разница была....

#8
9:15, 3 июля 2018

Кстати, все современные GPU ведут просчеты во float, потому сложно тестировать. Потому только на устройстве можно посмотреть хватает ли точности. И новое поколение OpenGL ES 3 и Metal также оперируют с fixed и half как с float.

Eugene
> fixed может и да, а в чем ресурсоемкость half <-> float?
float,half,fixed - 32,16,11 бит соответственно. Любые операции между разными типами - приведение типа

#9
13:24, 3 июля 2018
Рекурсивная фрактальная бесконечность алгоритма с постоянным повторением одного и того же достигнута..
#10
19:01, 3 июля 2018

точность float на мобилках убогая, делал multiband blending, пришлось все на инты переписывать.

#11
23:29, 3 июля 2018

MAMOHT-92
> делал multiband blending
не дорого для мобил? :)

#12
6:09, 4 июля 2018

Durane

Кстати, все современные GPU ведут просчеты во float, потому сложно тестировать.
Потому только на устройстве можно посмотреть хватает ли точности.
И новое поколение OpenGL ES 3 и Metal также оперируют с fixed и half как с float.

Следует отметить, что на десктопе ввели отдельное новое понятия для 16-битного float в шейдере,
имеющее отличный от half и precision qualifiers (OpenGL ES) синтаксис:
https://www.khronos.org/registry/OpenGL/extensions/AMD/AMD_gpu_sh… alf_float.txt
https://github.com/Microsoft/DirectXShaderCompiler/wiki/16-Bit-Scalar-Types

16-битные флоаты поддерживаются не везде, например их поддержку добавили в видеокарты VEGA от AMD,
обеспечивая теоретически в два раза больше вычислений относительно 32-битных флоатов - говорят, что полезно для алгоритмов машинного обучения.

Это касательно железа и шейдеров - про юнити ничего не знаю, думаю они эти штучки тоже будут поддерживать в будущем (если ещё не поддерживают).

ПрограммированиеФорумГрафика

Тема в архиве.