tinyusdz
tinyusdz copied to clipboard
[Proposal] Spectral color support
USD itself does not support native spectral color type.
It'd be nice to have spectral color(and also other color value encoding(e.g. XYZ)) for physcally-based spectral rendering.
There are some directions to support spectral color
- Use namespace: Backward compatible way ⭐
- Introduce dedicated type for spectral color
- Define spectral color as customData or introduce SpectralColorAPI Prim API schema
- Use external file(e.g. JSON) and reference it
Backward compatible way(preferred way at the moment)
Use namespace(suffix) spectrum
and wavelength
.
color3f[] myred = (1.0, 0.0, 0.0) # Use this for existing RGB-based renderer and preview color for spectral renderer
float[] myred:spectrum = [0.1, 0.2, 0.8]
float[] myred:wavelength = [550, 600, 700]
default unit in wavelegnth is [nm]
(nanometer), since most computer graphics tool with spectral color support uses nanometer(e.g. PBRT).
On the contrary, most(?) optical software uses [um]
(micrometer) by default .
Unit can be specified in Stage metadatum or Attiribute's metadata
#usda 1.0
( wavelengthUnitPerNanometer = 1000 # for [um] )
float[] myred:wavelength = [0.55, 0.6, 0.7] ( wavelengthUnitPerNanometer = 1000 )
native support with new syntax
We can reuse TimeSamples syntax describe spectral value.
It'd be something like...
double spectral:myred = {550: 0.1, 600: 0.4, 700: 1.0}
double spectral:myred.timeSamples = {0: {550: 0.1, 600: 0.4, 700: 1.0}, 1: {...}}
Disadvantace: Need a custom support in DCC tool(e.g. Blender)
as CustomData
color3f myred = (1.0, 0.3, 0.1) ( customData = { dictionary spectral = { double[] wavelengths = [...], double[] values = [...] } } )
Advantage: its backward compatible. we can use native color3f value as an preview RGB color in spectral rendering. Disadvantace: A bit tricky
as new API Schema
def Material ( prepend apiSchemas = ["SpectralColorAPI"] ) {
double[] spectral:myred:wavelengths = [550, 600, 700]
double[] spectral:myred:values = [0.1, 0.4, 1.0]
color3f spectal:myred:displayColor = (1.0, 0.4, 0.1)
}
Advantage: its backward compatible. we can use :displayColor
suffix variable as an preview RGB color in spectral rendering.
Disadvantage: Still a bit tricky?
Use external file
def Material () {
asset spectral:myred:file = @blackbody.spd@
token spectral:myred:sourceColorSpace = "spectral"
}
Advantage: Simple
TODO
- [ ] Spectral texture map asset support(e.g. EXR multichannel), sequence of images(wavelength in its filename)
- EXR for spectral format: https://jcgt.org/published/0010/03/01/
- TIFF multichannel?
- [ ] Text wavelength data file format
- [x] CSV: This should be simple.
wavelength, value
per line - [ ] JSON
- [x] CSV: This should be simple.