diff --git a/dev/obs/obs_codegen/__init__.py b/dev/obs/obs_codegen/__init__.py deleted file mode 100644 index e574996..0000000 --- a/dev/obs/obs_codegen/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import c diff --git a/dev/obs/obs_codegen/__main__.py b/dev/obs/obs_codegen/__main__.py deleted file mode 100644 index 1c5933e..0000000 --- a/dev/obs/obs_codegen/__main__.py +++ /dev/null @@ -1,199 +0,0 @@ -import logging -import colour -import argparse - -from obs_codegen.entitities import Whitepoint -from obs_codegen.entitities import Cat -from obs_codegen.entitities import AssemblyColorspace -from obs_codegen.entitities import ColorspaceGamut -from obs_codegen.entitities import TransferFunction -from obs_codegen.hlsl.generator import HlslGenerator -from obs_codegen.lua.generator import LuaGenerator - -logger = logging.getLogger(__name__) - - -def generate(language: str): - - illuminant1931: dict = colour.CCS_ILLUMINANTS["CIE 1931 2 Degree Standard Observer"] - - transfer_function_power_2_2 = TransferFunction("Power 2.2") - transfer_function_sRGB_EOTF = TransferFunction("sRGB EOTF") - transfer_function_BT709 = TransferFunction("BT.709") - transfer_function_DCIP3 = TransferFunction("DCI-P3") - transfer_function_Display_P3 = TransferFunction("Display P3") - transfer_function_Adobe_RGB_1998 = TransferFunction("Adobe RGB 1998") - transfer_function_BT2020 = TransferFunction("BT.2020") - - transfer_function_list = [ - transfer_function_power_2_2, - transfer_function_sRGB_EOTF, - transfer_function_BT709, - transfer_function_DCIP3, - transfer_function_Display_P3, - transfer_function_Adobe_RGB_1998, - transfer_function_BT2020, - ] - - # fmt: off - colorspace_gamut_sRGB = ColorspaceGamut.fromColourColorspaceName("sRGB") - colorspace_gamut_DCIP3 = ColorspaceGamut.fromColourColorspaceName("DCI-P3") - colorspace_gamut_Display_P3 = ColorspaceGamut.fromColourColorspaceName("Display P3") - colorspace_gamut_Adobe_RGB_1998 = ColorspaceGamut.fromColourColorspaceName("Adobe RGB (1998)") - colorspace_gamut_ITUR_BT_2020 = ColorspaceGamut.fromColourColorspaceName("ITU-R BT.2020") - colorspace_gamut_list = [ - colorspace_gamut_sRGB, - colorspace_gamut_DCIP3, - colorspace_gamut_Display_P3, - colorspace_gamut_Adobe_RGB_1998, - colorspace_gamut_ITUR_BT_2020, - ] - # fmt: on - - whitepoint_D60 = Whitepoint("D60", illuminant1931["D60"]) - whitepoint_D65 = Whitepoint("D65", illuminant1931["D65"]) - whitepoint_DCIP3 = Whitepoint("DCI-P3", illuminant1931["DCI-P3"]) - whitepoint_list = [whitepoint_D60, whitepoint_D65, whitepoint_DCIP3] - - assembly_colorspace_Passthrough = AssemblyColorspace( - "Passthrough", - None, - None, - None, - ) - assembly_colorspace_sRGB_Display_EOTF = AssemblyColorspace( - "sRGB Display (EOTF)", - colorspace_gamut_sRGB, - whitepoint_D65, - transfer_function_sRGB_EOTF, - ) - assembly_colorspace_sRGB_Display_2_2 = AssemblyColorspace( - "sRGB Display (2.2)", - colorspace_gamut_sRGB, - whitepoint_D65, - transfer_function_power_2_2, - ) - assembly_colorspace_sRGB_Linear = AssemblyColorspace( - "sRGB Linear", - colorspace_gamut_sRGB, - whitepoint_D65, - None, - ) - assembly_colorspace_BT_709_Display_2_4 = AssemblyColorspace( - "BT.709 Display (2.4)", - colorspace_gamut_sRGB, - whitepoint_D65, - transfer_function_BT709, - ) - assembly_colorspace_DCIP3_Display_2_6 = AssemblyColorspace( - "DCI-P3 Display (2.6)", - colorspace_gamut_DCIP3, - whitepoint_DCIP3, - transfer_function_DCIP3, - ) - assembly_colorspace_DCIP3_D65_Display_2_6 = AssemblyColorspace( - "DCI-P3 D65 Display (2.6)", - colorspace_gamut_DCIP3, - whitepoint_D65, - transfer_function_DCIP3, - ) - assembly_colorspace_DCIP3_D60_Display_2_6 = AssemblyColorspace( - "DCI-P3 D60 Display (2.6)", - colorspace_gamut_DCIP3, - whitepoint_D60, - transfer_function_DCIP3, - ) - assembly_colorspace_Apple_Display_P3 = AssemblyColorspace( - "Apple Display P3", - colorspace_gamut_Display_P3, - whitepoint_DCIP3, - transfer_function_Display_P3, - ) - assembly_colorspace_Adobe_RGB_1998_Display = AssemblyColorspace( - "Adobe RGB 1998 Display", - colorspace_gamut_Adobe_RGB_1998, - whitepoint_D65, - transfer_function_Adobe_RGB_1998, - ) - assembly_colorspace_BT_2020_Display_OETF = AssemblyColorspace( - "BT.2020 Display (OETF)", - colorspace_gamut_ITUR_BT_2020, - whitepoint_D65, - transfer_function_BT2020, - ) - assembly_colorspace_BT_2020_Linear = AssemblyColorspace( - "BT.2020 Linear", - colorspace_gamut_ITUR_BT_2020, - whitepoint_D65, - None, - ) - assembly_colorspace_DCIP3_Linear = AssemblyColorspace( - "DCI-P3 Linear", - colorspace_gamut_DCIP3, - whitepoint_DCIP3, - None, - ) - assembly_colorspace_list = [ - assembly_colorspace_Passthrough, - assembly_colorspace_sRGB_Display_EOTF, - assembly_colorspace_sRGB_Display_2_2, - assembly_colorspace_sRGB_Linear, - assembly_colorspace_BT_709_Display_2_4, - assembly_colorspace_DCIP3_Display_2_6, - assembly_colorspace_DCIP3_D65_Display_2_6, - assembly_colorspace_DCIP3_D60_Display_2_6, - assembly_colorspace_Apple_Display_P3, - assembly_colorspace_Adobe_RGB_1998_Display, - assembly_colorspace_BT_2020_Display_OETF, - assembly_colorspace_BT_2020_Linear, - assembly_colorspace_DCIP3_Linear, - ] - - generator_kwargs = { - "colorspaces_gamut": colorspace_gamut_list, - "whitepoints": whitepoint_list, - "cats": [ - Cat("XYZ Scaling"), - Cat("Bradford"), - Cat("CAT02"), - Cat("Von Kries"), - ], - "colorspaces_assemblies": assembly_colorspace_list, - "transfer_functions": transfer_function_list, - } - - if language == "hlsl": - - generator_hlsl = HlslGenerator(**generator_kwargs) - print(generator_hlsl.generateCode()) - - elif language == "lua": - - generator_lua = LuaGenerator(**generator_kwargs) - print(generator_lua.generateCode()) - - else: - raise ValueError(f"Unsupported {language=}") - - return - - -def cli(): - - parser = argparse.ArgumentParser( - description="OBS code generator. Just print in console." - ) - parser.add_argument( - "language", - choices=["hlsl", "lua"], - help="For which language shoudl teh code be generated", - ) - args = parser.parse_args() - language: str = args.language.lower() - - generate(language=language) - - -if __name__ == "__main__": - - cli() diff --git a/dev/obs/obs_codegen/hlsl/__init__.py b/dev/obs/obs_codegen/hlsl/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/dev/obs/obs_codegen/lua/__init__.py b/dev/obs/obs_codegen/lua/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/obs/README.md b/obs/README.md index 7e9a586..dd73351 100644 --- a/obs/README.md +++ b/obs/README.md @@ -2,26 +2,31 @@ Implementation of AgX for [OBS](https://obsproject.com/) as a script. -![screenshot of OBS interface while in the Filters section](doc/img/obs-main.png) +This is mainly intended to be applied on live camera feeds as this would not have +many benefits applied on desktop capture. -This is mainly intended to be applied on live camera feeds as this would have not much benefit -to apply this on desktop captures. +![screenshot of OBS interface while in the Filters section](doc/img/obs-main.png) -![screenshot of obs interface while camera is pointing at various colored objects like legos](doc/img/obs-c922-default.jpg) -![screenshot of obs interface while camera is pointing at various colored objects like legos](doc/img/obs-c922-agx.jpg) -> bottom image has the AgX filter applied in OBS, top is default rendering -- standard C922 webcam +| default rendering | with AgX filter | +|-----------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------| +| ![screenshot of obs interface while camera is pointing at various colored objects like legos](doc/img/obs-c922-default.jpg) | ![screenshot of obs interface while camera is pointing at various colored objects like legos](doc/img/obs-c922-agx.jpg) | +> video device is a "standard" Logitech C922 webcam # Requirements -- This has been developed on OBS 28.1.2 for Windows but should work for lower version -and other operating systems. +- This has been developed on OBS `28.1.2` for Windows but should work for lower +versions, and other operating systems. - Nothing more than the content of this directory. # Installation -Put the **whole** content of the [obs-script](obs-script) directory anywhere you want. +[Download](https://github.com/MrLixm/AgXc/archive/refs/heads/main.zip) this whole +GitHub repository. + +Put the **whole** content of the [obs/obs-script](obs-script) directory +anywhere you want on your system (you DON'T need the `src/` or the `doc/` directory). 1. Open OBS 2. In the top menu > Tools > Scripts @@ -39,21 +44,22 @@ All done ! You can now configure it. ![screenshot of OBS interface while in the Filters section](doc/img/obs-filter-options.png) -> **Note** Reminder that AgX being a display transform it should be placed at the -> very end of the image processing chain. (so at the bottom in OBS) +> ![NOTE] +> Reminder that AgX being a display transform it should be placed at +> **the very end** of the image processing chain (= at the bottom in OBS). The camera/video-source and your lighting setup will affect how much you need -to tweak the paramaters. There is no setup that work for all cases (but once -configured for your camera/usual lighting, you will not need to touch it anymore) +to tweak the parameters. There is no setup that work for all cases, but once +configured for your camera/usual lighting, you should not need to touch it anymore. -## Recommended +## Recommended Options I recommend to always start by : -- boosting the Grading Exposure by +1.0 stop. +- boosting the `Grading Exposure` by +1.0 stop. - boosting `Highligh Gain` by 2.0 -## Available +## Available Options ### Input Colorspace @@ -65,20 +71,20 @@ Passthrough means no decoding is applied. Target colorspace encoding. Must correspond to your monitor calibration. -> **Note** You can request adding new colorspace by opening an issue ! +> ![NOTE] +> You can request adding new colorspace by opening an issue on GitHub ! ### DRT Pick the DRT to use. Technically here we could include other DRT than AgX. But for now only None and AgX are available. -None means you can use all the options like grading, input colorspace, ... but -you will get a look similar to the usual broken imagery workflow. +`None` will not apply AgX but still allow you to use the grading options. ### Pre-Grading/... -Adjust imagery look in a Linear space, before AgX is applied. +Adjust imagery look in a linear space, before AgX is applied. ### Grading/Exposure @@ -108,7 +114,7 @@ See above. Grading modifications applied after AgX on display encoded data. This will introduce skews, clipping and other artefacts. -Recommended to change small values if used. +Not recommended to use or with very small values. ### Debug/Use OCIO Log Transform @@ -120,6 +126,7 @@ Does not create any change visually. Not originally included in the first AgX version but should be in the future. Restore chroma and avoid having to use Punchy saturation. +Might bring back some hue skews so better left off. ### Debug/CAT Method diff --git a/obs/doc/DEV.md b/obs/doc/DEV.md index 1b8eae4..eb2480f 100644 --- a/obs/doc/DEV.md +++ b/obs/doc/DEV.md @@ -4,16 +4,14 @@ - `AgX.lua` : direct interface with OBS used for building the GUI - `AgX.hlsl` : GPU shader with the actual AgX code. -- `colorspace.hlsl` : side-module imported in `AgX.hlsl` +- `colorspace.hlsl` : side-library imported in `AgX.hlsl` + - this is actually the public interface of the `colorscience/` "package". +- `colorscience/` library of hlsl modules for color manipulation. some of the modules +are code-generated and not intended to be edited directly. Directly editable modules are : + - `math.hlsl` + - `cctf.hlsl` -An important point is that part of the code in `colorspace.hlsl` is "procedurally" -generated from python code. - -To keep scalability on such a pontentatilly big dataset and reduce human mistakes, -a good part of the code is generated in python. - -This can be found in [{root}/dev/obs/obs_codegen](../../dev/obs/obs_codegen) -package. More details below. +The "procedurally" generated code can be found in the [../src/](../src) directory. # Add a new colorspace. @@ -21,20 +19,19 @@ package. More details below. You will need : -1. Modify the `/dev/obs/obs_codegen/__main__.py` by adding the new colorspace. -This is done by adding a new instance of `AssemblyColorspace`. - -2. Generate the HLSL code by running `python -m obs_codegen hlsl` -3. Copy the code generated in `colorspace.hlsl` (using the `//region` `//endregion` comment as marks) -4. Generate the LUA code `python -m obs_codegen lua` -5. Copy the code generated in `AgX.lua` where it "seems" to belong. -(for now just adding entries to the properties dropdown) +1. Modify the `../src/scripts/build-colorspace_core.hlsl.py` by adding the new colorspace. + 1. This is done by adding a new instance of `AssemblyColorspace`. +2. Run the script, this will automatically take care of the hlsl code. +3. You will need to manually update the LUA code : + 1. copy the lua code generated and print in the console to `AgX.lua` where it "seems" to belong. + (for now just adding entries to the properties dropdown) ## Case 2 : whole new colorspace Similar to Case 1 but : -- the step 1. is more complex : you also have to add a new Gamut/TransferFunction/Whitepoint +- the step 1.1 is more complex : you also have to add a new Gamut/TransferFunction/Whitepoint instance if needed. -- After step 3 you migth need to manually add the corresponding cctf function -(the name is generated automatically but you have to manually create it) +- If you added a new `TransferFunction` you will need to manually write its +hlsl code in the `colorscience/cctf.hlsl` module. Note the name of the function +can be found in `cctf-auto.hlsl` after running the build script. diff --git a/obs/obs-script/AgX.lua b/obs/obs-script/AgX.lua index 7fca189..abc8768 100644 --- a/obs/obs-script/AgX.lua +++ b/obs/obs-script/AgX.lua @@ -9,7 +9,7 @@ tutorial for learning the basics. ]] obs = obslua -local __version__ = "1.1.0" +local __version__ = "1.2.0" -- dependencies : local hlsl_shader_file_path = script_path() .. 'AgX.hlsl' @@ -18,7 +18,7 @@ local agx_lut_file_path = script_path() .. 'AgX-default_contrast.lut.png' function script_description() return ([[
- AgX is a display rendering transform to improve image formation. + AgX is a display rendering transform to improve imagery rendering.
Visit https://github.com/MrLixm/AgXc
@@ -126,6 +126,15 @@ source_info.get_properties = function(data)
obs.obs_property_list_add_int(propInputColorspace, "BT.2020 Display (OETF)", 10)
obs.obs_property_list_add_int(propInputColorspace, "BT.2020 Linear", 11)
obs.obs_property_list_add_int(propInputColorspace, "DCI-P3 Linear", 12)
+ obs.obs_property_list_add_int(propInputColorspace, "Cinema Gamut (Canon)", 13)
+ obs.obs_property_list_add_int(propInputColorspace, "F-Gamut FLog (Fujifilm)", 14)
+ obs.obs_property_list_add_int(propInputColorspace, "F-Gamut FLog2 (Fujifilm)", 15)
+ obs.obs_property_list_add_int(propInputColorspace, "N-Gamut (Nikon)", 16)
+ obs.obs_property_list_add_int(propInputColorspace, "S-Gamut (Sony)", 17)
+ obs.obs_property_list_add_int(propInputColorspace, "S-Gamut2 (Sony)", 18)
+ obs.obs_property_list_add_int(propInputColorspace, "S-Gamut3 (Sony)", 19)
+ obs.obs_property_list_add_int(propInputColorspace, "S-Gamut3.Cine (Sony)", 20)
+ obs.obs_property_list_add_int(propInputColorspace, "V-Gamut (Panasonic)", 21)
local propOutputColorspace = obs.obs_properties_add_list(masterProperty, "OUTPUT_COLORSPACE", "Output Colorspace", obs.OBS_COMBO_TYPE_LIST, obs.OBS_COMBO_FORMAT_INT) -- In which colorspace is encoded the input.
obs.obs_property_list_add_int(propOutputColorspace, "Passthrough", 0)
@@ -141,6 +150,15 @@ source_info.get_properties = function(data)
obs.obs_property_list_add_int(propOutputColorspace, "BT.2020 Display (OETF)", 10)
obs.obs_property_list_add_int(propOutputColorspace, "BT.2020 Linear", 11)
obs.obs_property_list_add_int(propOutputColorspace, "DCI-P3 Linear", 12)
+ obs.obs_property_list_add_int(propOutputColorspace, "Cinema Gamut (Canon)", 13)
+ obs.obs_property_list_add_int(propOutputColorspace, "F-Gamut FLog (Fujifilm)", 14)
+ obs.obs_property_list_add_int(propOutputColorspace, "F-Gamut FLog2 (Fujifilm)", 15)
+ obs.obs_property_list_add_int(propOutputColorspace, "N-Gamut (Nikon)", 16)
+ obs.obs_property_list_add_int(propOutputColorspace, "S-Gamut (Sony)", 17)
+ obs.obs_property_list_add_int(propOutputColorspace, "S-Gamut2 (Sony)", 18)
+ obs.obs_property_list_add_int(propOutputColorspace, "S-Gamut3 (Sony)", 19)
+ obs.obs_property_list_add_int(propOutputColorspace, "S-Gamut3.Cine (Sony)", 20)
+ obs.obs_property_list_add_int(propOutputColorspace, "V-Gamut (Panasonic)", 21)
local propDrt = obs.obs_properties_add_list(masterProperty, "DRT", "DRT", obs.OBS_COMBO_TYPE_LIST, obs.OBS_COMBO_FORMAT_INT)
obs.obs_property_list_add_int(propDrt, "None", 0)
diff --git a/obs/obs-script/colorscience/cat.hlsl b/obs/obs-script/colorscience/cat.hlsl
new file mode 100644
index 0000000..f652901
--- /dev/null
+++ b/obs/obs-script/colorscience/cat.hlsl
@@ -0,0 +1,163 @@
+// code generated by automatic build; do not manually edit
+/* --------------------------------------------------------------------------------
+Chromatic Adaptation Transforms
+-------------------------------------------------------------------------------- */
+
+#define matrix_cat_XYZ_Scaling_D60_to_D65 float3x3(\
+ 0.997749312, 0.0, 0.0,\
+ 0.0, 1.0, 0.0,\
+ 0.0, 0.0, 1.079011464\
+)
+#define matrix_cat_XYZ_Scaling_D60_to_DCIP3 float3x3(\
+ 0.939100313, 0.0, 0.0,\
+ 0.0, 1.0, 0.0,\
+ 0.0, 0.0, 0.945611705\
+)
+#define matrix_cat_XYZ_Scaling_D65_to_D60 float3x3(\
+ 1.002255765, 0.0, 0.0,\
+ 0.0, 1.0, 0.0,\
+ 0.0, 0.0, 0.926774212\
+)
+#define matrix_cat_XYZ_Scaling_D65_to_DCIP3 float3x3(\
+ 0.941218703, 0.0, 0.0,\
+ 0.0, 1.0, 0.0,\
+ 0.0, 0.0, 0.876368543\
+)
+#define matrix_cat_XYZ_Scaling_DCIP3_to_D60 float3x3(\
+ 1.064848969, 0.0, 0.0,\
+ 0.0, 1.0, 0.0,\
+ 0.0, 0.0, 1.05751652\
+)
+#define matrix_cat_XYZ_Scaling_DCIP3_to_D65 float3x3(\
+ 1.062452326, 0.0, 0.0,\
+ 0.0, 1.0, 0.0,\
+ 0.0, 0.0, 1.141072449\
+)
+#define matrix_cat_Bradford_D60_to_D65 float3x3(\
+ 0.987323904, -0.006062169, 0.015845876,\
+ -0.007531959, 1.001832321, 0.005293338,\
+ 0.00305302, -0.005064257, 1.081147527\
+)
+#define matrix_cat_Bradford_D60_to_DCIP3 float3x3(\
+ 0.964265012, -0.021300233, -0.002647012,\
+ -0.033122492, 1.030598686, 0.000944999,\
+ -0.003057139, 0.006720893, 0.941838177\
+)
+#define matrix_cat_Bradford_D65_to_D60 float3x3(\
+ 1.012931026, 0.006054132, -0.0148757,\
+ 0.007630325, 0.998191932, -0.004999018,\
+ -0.002824644, 0.004658585, 0.924961741\
+)
+#define matrix_cat_Bradford_D65_to_DCIP3 float3x3(\
+ 0.976578897, -0.015436265, -0.016686022,\
+ -0.025689666, 1.028539168, -0.003785174,\
+ -0.005705746, 0.011077866, 0.871176159\
+)
+#define matrix_cat_Bradford_DCIP3_to_D60 float3x3(\
+ 1.037804611, 0.021430283, 0.002895221,\
+ 0.033351213, 0.971004834, -0.00088053,\
+ 0.003130647, -0.006859463, 1.061769201\
+)
+#define matrix_cat_Bradford_DCIP3_to_D65 float3x3(\
+ 1.024496728, 0.015163541, 0.019688522,\
+ 0.025612193, 0.972586306, 0.004716352,\
+ 0.006384231, -0.012268083, 1.147942445\
+)
+#define matrix_cat_CAT02_D60_to_D65 float3x3(\
+ 0.988317991, -0.007816256, 0.016645551,\
+ -0.00564353, 0.998686699, 0.00662762,\
+ 0.00035077, 0.001116791, 1.077573915\
+)
+#define matrix_cat_CAT02_D60_to_DCIP3 float3x3(\
+ 0.979655622, -0.035093475, -0.003506859,\
+ -0.024670911, 1.024631944, -0.001120007,\
+ 0.000239512, -0.000975875, 0.946352523\
+)
+#define matrix_cat_CAT02_D65_to_D60 float3x3(\
+ 1.011870978, 0.007936977, -0.015679437,\
+ 0.005720259, 1.001366784, -0.00624727,\
+ -0.000335311, -0.001040394, 0.928022164\
+)
+#define matrix_cat_CAT02_D65_to_DCIP3 float3x3(\
+ 0.991085525, -0.027362287, -0.018395654,\
+ -0.019102244, 1.025837747, -0.007053718,\
+ -8.0549e-05, -0.001959887, 0.878238458\
+)
+#define matrix_cat_CAT02_DCIP3_to_D60 float3x3(\
+ 1.021647216, 0.034994893, 0.003827292,\
+ 0.024598791, 0.976803896, 0.001247201,\
+ -0.000233203, 0.00099842, 1.056688999\
+)
+#define matrix_cat_CAT02_DCIP3_to_D65 float3x3(\
+ 1.009516172, 0.026967753, 0.021362003,\
+ 0.018799243, 0.97533018, 0.008227297,\
+ 0.000134542, 0.002179032, 1.138663236\
+)
+#define matrix_cat_Von_Kries_D60_to_D65 float3x3(\
+ 0.995663132, -0.014998519, 0.016829124,\
+ -0.001647481, 1.001234102, 0.000332195,\
+ 0.0, 0.0, 1.079011464\
+)
+#define matrix_cat_Von_Kries_D60_to_DCIP3 float3x3(\
+ 0.9888443, -0.038575341, -0.0087295,\
+ -0.004237228, 1.003172521, 0.000855893,\
+ 0.0, 0.0, 0.945611705\
+)
+#define matrix_cat_Von_Kries_D65_to_D60 float3x3(\
+ 1.004380654, 0.015045655, -0.015669755,\
+ 0.001652658, 0.998792176, -0.000333274,\
+ 0.0, 0.0, 0.926774212\
+)
+#define matrix_cat_Von_Kries_D65_to_DCIP3 float3x3(\
+ 0.993112333, -0.023650939, -0.023572367,\
+ -0.002597888, 1.001897113, 0.000525285,\
+ 0.0, 0.0, 0.876368543\
+)
+#define matrix_cat_Von_Kries_DCIP3_to_D60 float3x3(\
+ 1.011448214, 0.038893569, 0.009302073,\
+ 0.004272183, 0.997001792, -0.000862968,\
+ 0.0, 0.0, 1.05751652\
+)
+#define matrix_cat_Von_Kries_DCIP3_to_D65 float3x3(\
+ 1.00699762, 0.023771342, 0.027071751,\
+ 0.002611113, 0.998168118, -0.000528057,\
+ 0.0, 0.0, 1.141072449\
+)
+
+uniform int catid_XYZ_Scaling = 0;
+uniform int catid_Bradford = 1;
+uniform int catid_CAT02 = 2;
+uniform int catid_Von_Kries = 3;
+
+uniform int whitepointid_D60 = 0;
+uniform int whitepointid_D65 = 1;
+uniform int whitepointid_DCIP3 = 2;
+
+
+float3x3 get_chromatic_adaptation_transform_matrix(int cat_id, int whitepoint_source, int whitepoint_target){
+ if (cat_id == 0 && whitepoint_source == 0 && whitepoint_target == 1) return matrix_cat_XYZ_Scaling_D60_to_D65;
+ if (cat_id == 0 && whitepoint_source == 0 && whitepoint_target == 2) return matrix_cat_XYZ_Scaling_D60_to_DCIP3;
+ if (cat_id == 0 && whitepoint_source == 1 && whitepoint_target == 0) return matrix_cat_XYZ_Scaling_D65_to_D60;
+ if (cat_id == 0 && whitepoint_source == 1 && whitepoint_target == 2) return matrix_cat_XYZ_Scaling_D65_to_DCIP3;
+ if (cat_id == 0 && whitepoint_source == 2 && whitepoint_target == 0) return matrix_cat_XYZ_Scaling_DCIP3_to_D60;
+ if (cat_id == 0 && whitepoint_source == 2 && whitepoint_target == 1) return matrix_cat_XYZ_Scaling_DCIP3_to_D65;
+ if (cat_id == 1 && whitepoint_source == 0 && whitepoint_target == 1) return matrix_cat_Bradford_D60_to_D65;
+ if (cat_id == 1 && whitepoint_source == 0 && whitepoint_target == 2) return matrix_cat_Bradford_D60_to_DCIP3;
+ if (cat_id == 1 && whitepoint_source == 1 && whitepoint_target == 0) return matrix_cat_Bradford_D65_to_D60;
+ if (cat_id == 1 && whitepoint_source == 1 && whitepoint_target == 2) return matrix_cat_Bradford_D65_to_DCIP3;
+ if (cat_id == 1 && whitepoint_source == 2 && whitepoint_target == 0) return matrix_cat_Bradford_DCIP3_to_D60;
+ if (cat_id == 1 && whitepoint_source == 2 && whitepoint_target == 1) return matrix_cat_Bradford_DCIP3_to_D65;
+ if (cat_id == 2 && whitepoint_source == 0 && whitepoint_target == 1) return matrix_cat_CAT02_D60_to_D65;
+ if (cat_id == 2 && whitepoint_source == 0 && whitepoint_target == 2) return matrix_cat_CAT02_D60_to_DCIP3;
+ if (cat_id == 2 && whitepoint_source == 1 && whitepoint_target == 0) return matrix_cat_CAT02_D65_to_D60;
+ if (cat_id == 2 && whitepoint_source == 1 && whitepoint_target == 2) return matrix_cat_CAT02_D65_to_DCIP3;
+ if (cat_id == 2 && whitepoint_source == 2 && whitepoint_target == 0) return matrix_cat_CAT02_DCIP3_to_D60;
+ if (cat_id == 2 && whitepoint_source == 2 && whitepoint_target == 1) return matrix_cat_CAT02_DCIP3_to_D65;
+ if (cat_id == 3 && whitepoint_source == 0 && whitepoint_target == 1) return matrix_cat_Von_Kries_D60_to_D65;
+ if (cat_id == 3 && whitepoint_source == 0 && whitepoint_target == 2) return matrix_cat_Von_Kries_D60_to_DCIP3;
+ if (cat_id == 3 && whitepoint_source == 1 && whitepoint_target == 0) return matrix_cat_Von_Kries_D65_to_D60;
+ if (cat_id == 3 && whitepoint_source == 1 && whitepoint_target == 2) return matrix_cat_Von_Kries_D65_to_DCIP3;
+ if (cat_id == 3 && whitepoint_source == 2 && whitepoint_target == 0) return matrix_cat_Von_Kries_DCIP3_to_D60;
+ if (cat_id == 3 && whitepoint_source == 2 && whitepoint_target == 1) return matrix_cat_Von_Kries_DCIP3_to_D65;
+ return matrix_identity_3x3;
+}
\ No newline at end of file
diff --git a/obs/obs-script/colorscience/cctf-auto.hlsl b/obs/obs-script/colorscience/cctf-auto.hlsl
new file mode 100644
index 0000000..14d10db
--- /dev/null
+++ b/obs/obs-script/colorscience/cctf-auto.hlsl
@@ -0,0 +1,53 @@
+// code generated by automatic build; do not manually edit
+
+uniform int cctf_id_Power_2_2 = 0; // Power 2.2
+uniform int cctf_id_sRGB_EOTF = 1; // sRGB EOTF
+uniform int cctf_id_BT_709 = 2; // BT.709
+uniform int cctf_id_DCIP3 = 3; // DCI-P3
+uniform int cctf_id_Display_P3 = 4; // Display P3
+uniform int cctf_id_Adobe_RGB_1998 = 5; // Adobe RGB 1998
+uniform int cctf_id_BT_2020 = 6; // BT.2020
+uniform int cctf_id_FLog = 7; // FLog
+uniform int cctf_id_FLog2 = 8; // FLog2
+uniform int cctf_id_NLog = 9; // NLog
+uniform int cctf_id_SLog = 10; // SLog
+uniform int cctf_id_SLog2 = 11; // SLog2
+uniform int cctf_id_SLog3 = 12; // SLog3
+uniform int cctf_id_VLog = 13; // VLog
+
+
+float3 apply_cctf_decoding(float3 color, int cctf_id){
+ if (cctf_id == cctf_id_Power_2_2 ) return cctf_decoding_Power_2_2(color);
+ if (cctf_id == cctf_id_sRGB_EOTF ) return cctf_decoding_sRGB_EOTF(color);
+ if (cctf_id == cctf_id_BT_709 ) return cctf_decoding_BT_709(color);
+ if (cctf_id == cctf_id_DCIP3 ) return cctf_decoding_DCIP3(color);
+ if (cctf_id == cctf_id_Display_P3 ) return cctf_decoding_Display_P3(color);
+ if (cctf_id == cctf_id_Adobe_RGB_1998 ) return cctf_decoding_Adobe_RGB_1998(color);
+ if (cctf_id == cctf_id_BT_2020 ) return cctf_decoding_BT_2020(color);
+ if (cctf_id == cctf_id_FLog ) return cctf_decoding_FLog(color);
+ if (cctf_id == cctf_id_FLog2 ) return cctf_decoding_FLog2(color);
+ if (cctf_id == cctf_id_NLog ) return cctf_decoding_NLog(color);
+ if (cctf_id == cctf_id_SLog ) return cctf_decoding_SLog(color);
+ if (cctf_id == cctf_id_SLog2 ) return cctf_decoding_SLog2(color);
+ if (cctf_id == cctf_id_SLog3 ) return cctf_decoding_SLog3(color);
+ if (cctf_id == cctf_id_VLog ) return cctf_decoding_VLog(color);
+ return color;
+}
+
+float3 apply_cctf_encoding(float3 color, int cctf_id){
+ if (cctf_id == cctf_id_Power_2_2 ) return cctf_encoding_Power_2_2(color);
+ if (cctf_id == cctf_id_sRGB_EOTF ) return cctf_encoding_sRGB_EOTF(color);
+ if (cctf_id == cctf_id_BT_709 ) return cctf_encoding_BT_709(color);
+ if (cctf_id == cctf_id_DCIP3 ) return cctf_encoding_DCIP3(color);
+ if (cctf_id == cctf_id_Display_P3 ) return cctf_encoding_Display_P3(color);
+ if (cctf_id == cctf_id_Adobe_RGB_1998 ) return cctf_encoding_Adobe_RGB_1998(color);
+ if (cctf_id == cctf_id_BT_2020 ) return cctf_encoding_BT_2020(color);
+ if (cctf_id == cctf_id_FLog ) return cctf_encoding_FLog(color);
+ if (cctf_id == cctf_id_FLog2 ) return cctf_encoding_FLog2(color);
+ if (cctf_id == cctf_id_NLog ) return cctf_encoding_NLog(color);
+ if (cctf_id == cctf_id_SLog ) return cctf_encoding_SLog(color);
+ if (cctf_id == cctf_id_SLog2 ) return cctf_encoding_SLog2(color);
+ if (cctf_id == cctf_id_SLog3 ) return cctf_encoding_SLog3(color);
+ if (cctf_id == cctf_id_VLog ) return cctf_encoding_VLog(color);
+ return color;
+}
\ No newline at end of file
diff --git a/obs/obs-script/colorscience/cctf.hlsl b/obs/obs-script/colorscience/cctf.hlsl
new file mode 100644
index 0000000..e7a9a76
--- /dev/null
+++ b/obs/obs-script/colorscience/cctf.hlsl
@@ -0,0 +1,288 @@
+/* --------------------------------------------------------------------------------
+Transfer functions
+
+References
+----------
+
+All data without explicit reference can assumed to be extracted/generated from `colour-science` python library.
+
+- [1] https://github.com/sobotka/AgX-S2O3/blob/main/AgX.py
+- [2] https://github.com/colour-science/colour/blob/develop/colour/models/rgb/transfer_functions/srgb.py#L99
+- [3] https://dl.fujifilm-x.com/support/lut/F-Log_DataSheet_E_Ver.1.0.pdf
+- [4] https://dl.fujifilm-x.com/support/lut/F-Log2_DataSheet_E_Ver.1.0.pdf
+- [5] https://github.com/colour-science/colour/blob/develop/colour/models/rgb/transfer_functions/fujifilm_f_log.py
+- [6] http://download.nikonimglib.com/archive3/hDCmK00m9JDI03RPruD74xpoU905/N-Log_Specification_(En)01.pdf
+- [7] https://github.com/colour-science/colour/blob/develop/colour/models/rgb/transfer_functions/sony.py
+- [8] https://drive.google.com/file/d/1Q1RYri6BaxtYYxX0D4zVD6lAmbwmgikc/view
+- [9] https://pro-av.panasonic.net/en/cinema_camera_varicam_eva/support/pdf/VARICAM_V-Log_V-Gamut.pdf
+-------------------------------------------------------------------------------- */
+
+float3 cctf_log2_normalized_from_open_domain(float3 color, float minimum_ev, float maximum_ev)
+/*
+ Output log domain encoded data.
+
+ Similar to OCIO lg2 AllocationTransform.
+
+ --ref[1]
+*/
+{
+ float in_midgrey = 0.18;
+
+ // remove negative before log transform
+ color = max(0.0, color);
+ // avoid infinite issue with log -- ref[1]
+ color = (color < 0.00003051757) ? (0.00001525878 + color) : (color);
+ color = clamp(
+ log2(color / in_midgrey),
+ float3(minimum_ev, minimum_ev, minimum_ev),
+ float3(maximum_ev,maximum_ev,maximum_ev)
+ );
+ float total_exposure = maximum_ev - minimum_ev;
+
+ return (color - minimum_ev) / total_exposure;
+}
+
+// exactly the same as above but I let it for reference
+float3 cctf_log2_ocio_transform(float3 color)
+/*
+ Output log domain encoded data.
+
+ Copy of OCIO lg2 AllocationTransform with the AgX Log values.
+
+ :param color: rgba linear color data
+*/
+{
+ // remove negative before log transform
+ color = max(0.0, color);
+ color = (color < 0.00003051757) ? (log2(0.00001525878 + color * 0.5)) : (log2(color));
+
+ // obtained via m = ocio.MatrixTransform.Fit(oldMin=[-12.47393, -12.47393, -12.47393, 0.0], oldMax=[4.026069, 4.026069, 4.026069, 1.0])
+ float3x3 fitMatrix = float3x3(
+ 0.060606064279155415, 0.0, 0.0,
+ 0.0, 0.060606064279155415, 0.0,
+ 0.0, 0.0, 0.060606064279155415
+ );
+ // obtained via same as above
+ float fitMatrixOffset = 0.7559958033936851;
+ color = mul(fitMatrix, color);
+ color += fitMatrixOffset.xxx;
+
+ return color;
+}
+
+float3 cctf_decoding_sRGB_EOTF(float3 color){
+ // ref[2]
+ return (color <= 0.04045) ? (color / 12.92) : (powsafe((color + 0.055) / 1.055, 2.4));
+}
+float3 cctf_encoding_sRGB_EOTF(float3 color){
+ // ref[2]
+ return (color <= 0.0031308) ? (color * 12.92) : (1.055 * powsafe(color, 1/2.4) - 0.055);
+}
+
+float3 cctf_decoding_Power_2_2(float3 color){return powsafe(color, 2.2);}
+float3 cctf_encoding_Power_2_2(float3 color){return powsafe(color, 1/2.2);}
+
+float3 cctf_decoding_BT_709(float3 color){return powsafe(color, 2.4);}
+float3 cctf_encoding_BT_709(float3 color){return powsafe(color, 1/2.4);}
+
+float3 cctf_decoding_DCIP3(float3 color){return powsafe(color, 2.6);}
+float3 cctf_encoding_DCIP3(float3 color){return powsafe(color, 1/2.6);}
+
+float3 cctf_encoding_BT_2020(float3 color){
+ return (color < 0.0181) ? color * 4.5 : 1.0993 * powsafe(color, 0.45) - (1.0993 - 1);
+}
+float3 cctf_decoding_BT_2020(float3 color){
+ return (color < cctf_encoding_BT_2020(0.0181)) ? color / 4.5 : powsafe((color + (1.0993 - 1)) / 1.0993, 1 / 0.45) ;
+}
+
+float3 cctf_decoding_Display_P3(float3 color){return cctf_decoding_sRGB_EOTF(color);}
+float3 cctf_encoding_Display_P3(float3 color){return cctf_encoding_sRGB_EOTF(color);}
+
+float3 cctf_decoding_Adobe_RGB_1998(float3 color){return powsafe(color, 2.19921875);}
+float3 cctf_encoding_Adobe_RGB_1998(float3 color){return powsafe(color, 1/2.19921875);}
+
+
+struct _FLogConstants {
+ float a;
+ float b;
+ float c;
+ float d;
+ float e;
+ float f;
+ float cut1;
+ float cut2;
+};
+// ref[3]
+_FLogConstants FLogConstants(){
+ _FLogConstants output;
+ output.a = 0.555556;
+ output.b = 0.009468;
+ output.c = 0.344676;
+ output.d = 0.790453;
+ output.e = 8.735631;
+ output.f = 0.092864;
+ output.cut1 = 0.00089;
+ output.cut2 = 0.10053777522386;
+ return output;
+}
+// ref[4]
+_FLogConstants FLog2Constants(){
+ _FLogConstants output;
+ output.a = 5.555556;
+ output.b = 0.064829;
+ output.c = 0.245281;
+ output.d = 0.384316;
+ output.e = 8.799461;
+ output.f = 0.092864;
+ output.cut1 = 0.000889;
+ output.cut2 = 0.100686685370811;
+ return output;
+}
+
+// ref[3][4][5]
+float3 _cctf_decoding_FLog(float3 color, _FLogConstants flconst){
+ return color < flconst.cut2 ?
+ (color - flconst.f) / flconst.e :
+ pow(10.0, ((color - flconst.d) / flconst.c)) / flconst.a - flconst.b / flconst.a;
+}
+float3 _cctf_encoding_FLog(float3 color, _FLogConstants flconst){
+ return color < flconst.cut1 ?
+ flconst.e * color + flconst.f :
+ flconst.c * log10(flconst.a * color + flconst.b) + flconst.d;
+}
+
+float3 cctf_decoding_FLog(float3 color){return _cctf_decoding_FLog(color, FLogConstants());}
+float3 cctf_encoding_FLog(float3 color){return _cctf_encoding_FLog(color, FLogConstants());}
+
+float3 cctf_decoding_FLog2(float3 color){return _cctf_decoding_FLog(color, FLog2Constants());}
+float3 cctf_encoding_FLog2(float3 color){return _cctf_encoding_FLog(color, FLog2Constants());}
+
+struct _NLogConstants {
+ float a;
+ float b;
+ float c;
+ float d;
+ float cut1;
+ float cut2;
+};
+// ref[6]
+_NLogConstants NLogConstants(){
+ _NLogConstants output;
+ output.a = 650.0/1023.0;
+ output.b = 0.0075;
+ output.c = 150.0/1023.0;
+ output.d = 619.0/1023.0;
+ output.cut1 = 0.328;
+ output.cut2 = 452.0/1023.0;
+ return output;
+}
+// ref[6]
+float3 cctf_decoding_NLog(float3 color){
+ _NLogConstants nlconst = NLogConstants();
+ return color < nlconst.cut2 ?
+ powsafe(color/nlconst.a, 3.0) - nlconst.b:
+ exp((color - nlconst.d) / nlconst.c);
+}
+float3 cctf_encoding_NLog(float3 color){
+ _NLogConstants nlconst = NLogConstants();
+ return color < nlconst.cut1 ?
+ nlconst.a * powsafe(color + nlconst.b, 1.0/3.0):
+ nlconst.c * log(color) + nlconst.d;
+}
+
+struct _SLogConstants {
+ float a;
+ float b;
+ float c;
+ float d;
+ float e;
+ float f;
+ float g;
+ float h;
+};
+// ref[7][8]
+_SLogConstants SLogConstants(){
+ _SLogConstants output;
+ output.a = 0.432699;
+ output.b = 0.616596;
+ output.c = 0.030001222851889303;
+ output.d = 3.53881278538813;
+ output.e = 0.03;
+ output.f = 155.0;
+ output.g = 219.0;
+ output.h = 0.037584;
+ return output;
+}
+// ref[7]
+float3 cctf_encoding_SLog(float3 color){
+ _SLogConstants slconst = SLogConstants();
+ // convert from reflection to IRE
+ float3 outcolor = color / 0.9;
+ outcolor = color >= 0.0 ?
+ (slconst.a * log10(outcolor + slconst.h) + slconst.b) + slconst.e:
+ outcolor * 5.0 + slconst.c;
+ // asume bitdepth=10 and out_normalised_code_value=True compared to colour
+ return convert_cctf_full_to_legal(outcolor);
+
+}
+float3 cctf_decoding_SLog(float3 color){
+ _SLogConstants slconst = SLogConstants();
+ // asume bitdepth=10 and in_normalised_code_value=True compared to colour
+ float3 outcolor = convert_cctf_legal_to_full(color);
+ outcolor = color >= cctf_encoding_SLog(0.0) ?
+ pow(10.0, (color - slconst.b - slconst.e) / slconst.a) - slconst.h:
+ (color - slconst.c) / 5.0;
+ // convert IRE to reflection
+ return outcolor * 0.9;
+
+}
+
+float3 cctf_decoding_SLog2(float3 color){return 219.0 * cctf_decoding_SLog(color) / 155.0;}
+float3 cctf_encoding_SLog2(float3 color){return cctf_encoding_SLog(color * 155.0 / 219.0);}
+
+
+// ref[7]
+float3 cctf_decoding_SLog3(float3 color){
+ float slconst_a = 0.01125000;
+ float slconst_b = 171.2102946929;
+ return color >= slconst_b / 1023.0 ?
+ pow(10.0, (color * 1023.0 - 420.0) / 261.5) * (0.18 + 0.01) - 0.01:
+ (color * 1023.0 - 95.0) * slconst_a / (slconst_b - 95.0);
+}
+float3 cctf_encoding_SLog3(float3 color){
+ float slconst_a = 0.01125000;
+ float slconst_b = 171.2102946929;
+ return color >= slconst_a ?
+ (420.0 + log10((color + 0.01) / (0.18 + 0.01)) * 261.5) / 1023.0:
+ (color * (slconst_b - 95.0) / slconst_a + 95.0) / 1023.0;
+}
+
+struct _VLogConstants {
+ float b;
+ float c;
+ float d;
+ float cut1;
+ float cut2;
+};
+// ref[9]
+_VLogConstants VLogConstants(){
+ _VLogConstants output;
+ output.b = 0.00873;
+ output.c = 0.241514;
+ output.d = 0.598206;
+ output.cut1 = 0.01;
+ output.cut2 = 0.181;
+ return output;
+}
+float3 cctf_decoding_VLog(float3 color){
+ _VLogConstants vlconst = VLogConstants();
+ return color < vlconst.cut2 ?
+ (color - 0.125) / 5.6:
+ pow(10.0, (color - vlconst.d) / vlconst.c) - vlconst.b;
+}
+float3 cctf_encoding_VLog(float3 color){
+ _VLogConstants vlconst = VLogConstants();
+ return color < vlconst.cut1 ?
+ 5.6 * color + 0.125:
+ vlconst.c * log10(color + vlconst.b) + vlconst.d;
+}
diff --git a/obs/obs-script/colorscience/colorspace.hlsl b/obs/obs-script/colorscience/colorspace.hlsl
new file mode 100644
index 0000000..8d06e6f
--- /dev/null
+++ b/obs/obs-script/colorscience/colorspace.hlsl
@@ -0,0 +1,150 @@
+// code generated by automatic build; do not manually edit
+/* --------------------------------------------------------------------------------
+Colorspaces
+-------------------------------------------------------------------------------- */
+
+struct Colorspace{
+ int gamut_id;
+ int whitepoint_id;
+ int cctf_id;
+};
+
+uniform int colorspaceid_Passthrough = 0;
+uniform int colorspaceid_sRGB_Display_EOTF = 1;
+uniform int colorspaceid_sRGB_Display_2_2 = 2;
+uniform int colorspaceid_sRGB_Linear = 3;
+uniform int colorspaceid_BT_709_Display_2_4 = 4;
+uniform int colorspaceid_DCIP3_Display_2_6 = 5;
+uniform int colorspaceid_DCIP3_D65_Display_2_6 = 6;
+uniform int colorspaceid_DCIP3_D60_Display_2_6 = 7;
+uniform int colorspaceid_Apple_Display_P3 = 8;
+uniform int colorspaceid_Adobe_RGB_1998_Display = 9;
+uniform int colorspaceid_BT_2020_Display_OETF = 10;
+uniform int colorspaceid_BT_2020_Linear = 11;
+uniform int colorspaceid_DCIP3_Linear = 12;
+uniform int colorspaceid_Cinema_Gamut_Canon = 13;
+uniform int colorspaceid_FGamut_FLog_Fujifilm = 14;
+uniform int colorspaceid_FGamut_FLog2_Fujifilm = 15;
+uniform int colorspaceid_NGamut_Nikon = 16;
+uniform int colorspaceid_SGamut_Sony = 17;
+uniform int colorspaceid_SGamut2_Sony = 18;
+uniform int colorspaceid_SGamut3_Sony = 19;
+uniform int colorspaceid_SGamut3_Cine_Sony = 20;
+uniform int colorspaceid_VGamut_Panasonic = 21;
+
+Colorspace getColorspaceFromId(int colorspace_id){
+
+ Colorspace colorspace;
+
+ if (colorspace_id == colorspaceid_Passthrough){
+ colorspace.gamut_id = -1;
+ colorspace.whitepoint_id = -1;
+ colorspace.cctf_id = -1;
+ };
+ if (colorspace_id == colorspaceid_sRGB_Display_EOTF){
+ colorspace.gamut_id = gamutid_sRGB;
+ colorspace.whitepoint_id = whitepointid_D65;
+ colorspace.cctf_id = cctf_id_sRGB_EOTF;
+ };
+ if (colorspace_id == colorspaceid_sRGB_Display_2_2){
+ colorspace.gamut_id = gamutid_sRGB;
+ colorspace.whitepoint_id = whitepointid_D65;
+ colorspace.cctf_id = cctf_id_Power_2_2;
+ };
+ if (colorspace_id == colorspaceid_sRGB_Linear){
+ colorspace.gamut_id = gamutid_sRGB;
+ colorspace.whitepoint_id = whitepointid_D65;
+ colorspace.cctf_id = -1;
+ };
+ if (colorspace_id == colorspaceid_BT_709_Display_2_4){
+ colorspace.gamut_id = gamutid_sRGB;
+ colorspace.whitepoint_id = whitepointid_D65;
+ colorspace.cctf_id = cctf_id_BT_709;
+ };
+ if (colorspace_id == colorspaceid_DCIP3_Display_2_6){
+ colorspace.gamut_id = gamutid_DCIP3;
+ colorspace.whitepoint_id = whitepointid_DCIP3;
+ colorspace.cctf_id = cctf_id_DCIP3;
+ };
+ if (colorspace_id == colorspaceid_DCIP3_D65_Display_2_6){
+ colorspace.gamut_id = gamutid_DCIP3;
+ colorspace.whitepoint_id = whitepointid_D65;
+ colorspace.cctf_id = cctf_id_DCIP3;
+ };
+ if (colorspace_id == colorspaceid_DCIP3_D60_Display_2_6){
+ colorspace.gamut_id = gamutid_DCIP3;
+ colorspace.whitepoint_id = whitepointid_D60;
+ colorspace.cctf_id = cctf_id_DCIP3;
+ };
+ if (colorspace_id == colorspaceid_Apple_Display_P3){
+ colorspace.gamut_id = gamutid_Display_P3;
+ colorspace.whitepoint_id = whitepointid_DCIP3;
+ colorspace.cctf_id = cctf_id_Display_P3;
+ };
+ if (colorspace_id == colorspaceid_Adobe_RGB_1998_Display){
+ colorspace.gamut_id = gamutid_Adobe_RGB_1998;
+ colorspace.whitepoint_id = whitepointid_D65;
+ colorspace.cctf_id = cctf_id_Adobe_RGB_1998;
+ };
+ if (colorspace_id == colorspaceid_BT_2020_Display_OETF){
+ colorspace.gamut_id = gamutid_ITUR_BT_2020;
+ colorspace.whitepoint_id = whitepointid_D65;
+ colorspace.cctf_id = cctf_id_BT_2020;
+ };
+ if (colorspace_id == colorspaceid_BT_2020_Linear){
+ colorspace.gamut_id = gamutid_ITUR_BT_2020;
+ colorspace.whitepoint_id = whitepointid_D65;
+ colorspace.cctf_id = -1;
+ };
+ if (colorspace_id == colorspaceid_DCIP3_Linear){
+ colorspace.gamut_id = gamutid_DCIP3;
+ colorspace.whitepoint_id = whitepointid_DCIP3;
+ colorspace.cctf_id = -1;
+ };
+ if (colorspace_id == colorspaceid_Cinema_Gamut_Canon){
+ colorspace.gamut_id = gamutid_Cinema_Gamut;
+ colorspace.whitepoint_id = whitepointid_D65;
+ colorspace.cctf_id = -1;
+ };
+ if (colorspace_id == colorspaceid_FGamut_FLog_Fujifilm){
+ colorspace.gamut_id = gamutid_ITUR_BT_2020;
+ colorspace.whitepoint_id = whitepointid_D65;
+ colorspace.cctf_id = cctf_id_FLog;
+ };
+ if (colorspace_id == colorspaceid_FGamut_FLog2_Fujifilm){
+ colorspace.gamut_id = gamutid_ITUR_BT_2020;
+ colorspace.whitepoint_id = whitepointid_D65;
+ colorspace.cctf_id = cctf_id_FLog2;
+ };
+ if (colorspace_id == colorspaceid_NGamut_Nikon){
+ colorspace.gamut_id = gamutid_ITUR_BT_2020;
+ colorspace.whitepoint_id = whitepointid_D65;
+ colorspace.cctf_id = cctf_id_NLog;
+ };
+ if (colorspace_id == colorspaceid_SGamut_Sony){
+ colorspace.gamut_id = gamutid_SGamut;
+ colorspace.whitepoint_id = whitepointid_D65;
+ colorspace.cctf_id = cctf_id_SLog;
+ };
+ if (colorspace_id == colorspaceid_SGamut2_Sony){
+ colorspace.gamut_id = gamutid_SGamut;
+ colorspace.whitepoint_id = whitepointid_D65;
+ colorspace.cctf_id = cctf_id_SLog2;
+ };
+ if (colorspace_id == colorspaceid_SGamut3_Sony){
+ colorspace.gamut_id = gamutid_SGamut;
+ colorspace.whitepoint_id = whitepointid_D65;
+ colorspace.cctf_id = cctf_id_SLog3;
+ };
+ if (colorspace_id == colorspaceid_SGamut3_Cine_Sony){
+ colorspace.gamut_id = gamutid_SGamut3_Cine;
+ colorspace.whitepoint_id = whitepointid_D65;
+ colorspace.cctf_id = cctf_id_SLog3;
+ };
+ if (colorspace_id == colorspaceid_VGamut_Panasonic){
+ colorspace.gamut_id = gamutid_VGamut;
+ colorspace.whitepoint_id = whitepointid_D65;
+ colorspace.cctf_id = cctf_id_VLog;
+ };
+ return colorspace;
+}
\ No newline at end of file
diff --git a/obs/obs-script/colorscience/gamut.hlsl b/obs/obs-script/colorscience/gamut.hlsl
new file mode 100644
index 0000000..3ff663e
--- /dev/null
+++ b/obs/obs-script/colorscience/gamut.hlsl
@@ -0,0 +1,150 @@
+// code generated by automatic build; do not manually edit
+/* --------------------------------------------------------------------------------
+Matrices
+-------------------------------------------------------------------------------- */
+
+// sRGB
+#define matrix_sRGB_to_XYZ float3x3(\
+ 0.4124, 0.3576, 0.1805,\
+ 0.2126, 0.7152, 0.0722,\
+ 0.0193, 0.1192, 0.9505\
+)
+#define matrix_sRGB_from_XYZ float3x3(\
+ 3.2406, -1.5372, -0.4986,\
+ -0.9689, 1.8758, 0.0415,\
+ 0.0557, -0.204, 1.057\
+)
+
+// DCI-P3
+#define matrix_DCIP3_to_XYZ float3x3(\
+ 0.445169816, 0.277134409, 0.17228267,\
+ 0.209491678, 0.721595254, 0.068913068,\
+ -0.0, 0.04706056, 0.907355394\
+)
+#define matrix_DCIP3_from_XYZ float3x3(\
+ 2.72539403, -1.018003006, -0.440163195,\
+ -0.795168026, 1.689732055, 0.022647191,\
+ 0.041241891, -0.087639019, 1.100929379\
+)
+
+// Display P3
+#define matrix_Display_P3_to_XYZ float3x3(\
+ 0.486570949, 0.265667693, 0.198217285,\
+ 0.228974564, 0.691738522, 0.079286914,\
+ -0.0, 0.045113382, 1.043944369\
+)
+#define matrix_Display_P3_from_XYZ float3x3(\
+ 2.493496912, -0.931383618, -0.402710784,\
+ -0.82948897, 1.76266406, 0.023624686,\
+ 0.03584583, -0.076172389, 0.956884524\
+)
+
+// Adobe RGB (1998)
+#define matrix_Adobe_RGB_1998_to_XYZ float3x3(\
+ 0.57667, 0.18556, 0.18823,\
+ 0.29734, 0.62736, 0.07529,\
+ 0.02703, 0.07069, 0.99134\
+)
+#define matrix_Adobe_RGB_1998_from_XYZ float3x3(\
+ 2.04159, -0.56501, -0.34473,\
+ -0.96924, 1.87597, 0.04156,\
+ 0.01344, -0.11836, 1.01517\
+)
+
+// ITU-R BT.2020
+#define matrix_ITUR_BT_2020_to_XYZ float3x3(\
+ 0.636958048, 0.144616904, 0.168880975,\
+ 0.262700212, 0.677998072, 0.059301716,\
+ 0.0, 0.028072693, 1.060985058\
+)
+#define matrix_ITUR_BT_2020_from_XYZ float3x3(\
+ 1.716651188, -0.355670784, -0.253366281,\
+ -0.666684352, 1.616481237, 0.015768546,\
+ 0.017639857, -0.042770613, 0.942103121\
+)
+
+// Cinema Gamut
+#define matrix_Cinema_Gamut_to_XYZ float3x3(\
+ 0.716049647, 0.129683478, 0.104722803,\
+ 0.261261358, 0.869642146, -0.130903503,\
+ -0.009676347, -0.236481636, 1.335215733\
+)
+#define matrix_Cinema_Gamut_from_XYZ float3x3(\
+ 1.489818275, -0.260895902, -0.142426522,\
+ -0.458166574, 1.261627783, 0.159623632,\
+ -0.070349668, 0.221557667, 0.776181604\
+)
+
+// S-Gamut
+#define matrix_SGamut_to_XYZ float3x3(\
+ 0.706482713, 0.12880105, 0.115172164,\
+ 0.270979671, 0.786606411, -0.057586082,\
+ -0.009677845, 0.004600038, 1.094135559\
+)
+#define matrix_SGamut_from_XYZ float3x3(\
+ 1.507399899, -0.245822137, -0.171611681,\
+ -0.518151727, 1.355391241, 0.125878668,\
+ 0.015511698, -0.007872771, 0.911916366\
+)
+
+// S-Gamut3.Cine
+#define matrix_SGamut3_Cine_to_XYZ float3x3(\
+ 0.599083921, 0.248925516, 0.10244649,\
+ 0.21507582, 0.885068502, -0.100144322,\
+ -0.03206585, -0.027658391, 1.148781991\
+)
+#define matrix_SGamut3_Cine_from_XYZ float3x3(\
+ 1.846778969, -0.525986123, -0.210545211,\
+ -0.444153263, 1.259442903, 0.149399973,\
+ 0.040855421, 0.015640889, 0.868207249\
+)
+
+// V-Gamut
+#define matrix_VGamut_to_XYZ float3x3(\
+ 0.679644, 0.152211, 0.1186,\
+ 0.260686, 0.774894, -0.03558,\
+ -0.00931, -0.004612, 1.10298\
+)
+#define matrix_VGamut_from_XYZ float3x3(\
+ 1.589012, -0.313204, -0.180965,\
+ -0.534053, 1.396011, 0.102458,\
+ 0.011179, 0.003194, 0.905535\
+)
+
+
+uniform int gamutid_sRGB = 0;
+uniform int gamutid_DCIP3 = 1;
+uniform int gamutid_Display_P3 = 2;
+uniform int gamutid_Adobe_RGB_1998 = 3;
+uniform int gamutid_ITUR_BT_2020 = 4;
+uniform int gamutid_Cinema_Gamut = 5;
+uniform int gamutid_SGamut = 6;
+uniform int gamutid_SGamut3_Cine = 7;
+uniform int gamutid_VGamut = 8;
+
+
+float3x3 get_gamut_matrix_to_XYZ(int gamutid){
+ if (gamutid == gamutid_sRGB ) return matrix_sRGB_to_XYZ;
+ if (gamutid == gamutid_DCIP3 ) return matrix_DCIP3_to_XYZ;
+ if (gamutid == gamutid_Display_P3 ) return matrix_Display_P3_to_XYZ;
+ if (gamutid == gamutid_Adobe_RGB_1998 ) return matrix_Adobe_RGB_1998_to_XYZ;
+ if (gamutid == gamutid_ITUR_BT_2020 ) return matrix_ITUR_BT_2020_to_XYZ;
+ if (gamutid == gamutid_Cinema_Gamut ) return matrix_Cinema_Gamut_to_XYZ;
+ if (gamutid == gamutid_SGamut ) return matrix_SGamut_to_XYZ;
+ if (gamutid == gamutid_SGamut3_Cine ) return matrix_SGamut3_Cine_to_XYZ;
+ if (gamutid == gamutid_VGamut ) return matrix_VGamut_to_XYZ;
+ return matrix_identity_3x3;
+}
+
+float3x3 get_gamut_matrix_from_XYZ(int gamutid){
+ if (gamutid == gamutid_sRGB ) return matrix_sRGB_from_XYZ;
+ if (gamutid == gamutid_DCIP3 ) return matrix_DCIP3_from_XYZ;
+ if (gamutid == gamutid_Display_P3 ) return matrix_Display_P3_from_XYZ;
+ if (gamutid == gamutid_Adobe_RGB_1998 ) return matrix_Adobe_RGB_1998_from_XYZ;
+ if (gamutid == gamutid_ITUR_BT_2020 ) return matrix_ITUR_BT_2020_from_XYZ;
+ if (gamutid == gamutid_Cinema_Gamut ) return matrix_Cinema_Gamut_from_XYZ;
+ if (gamutid == gamutid_SGamut ) return matrix_SGamut_from_XYZ;
+ if (gamutid == gamutid_SGamut3_Cine ) return matrix_SGamut3_Cine_from_XYZ;
+ if (gamutid == gamutid_VGamut ) return matrix_VGamut_from_XYZ;
+ return matrix_identity_3x3;
+}
\ No newline at end of file
diff --git a/obs/obs-script/colorscience/math.hlsl b/obs/obs-script/colorscience/math.hlsl
new file mode 100644
index 0000000..9b9e6ad
--- /dev/null
+++ b/obs/obs-script/colorscience/math.hlsl
@@ -0,0 +1,66 @@
+/*
+References
+----------
+
+- [1] https://github.com/ampas/aces-dev/blob/master/transforms/ctl/lib/ACESlib.Utilities_Color.ctl#L492
+- [2] https://github.com/colour-science/colour/blob/develop/colour/models/rgb/transfer_functions/common.py
+*/
+#define matrix_identity_3x3 float3x3(\
+ 1.0, 0.0, 0.0,\
+ 0.0, 1.0, 0.0,\
+ 0.0, 0.0, 1.0\
+)
+
+#define luma_coefs_bt709 float3(0.2126, 0.7152, 0.0722)
+
+float3 powsafe(float3 color, float power){
+ // pow() but safe for NaNs/negatives
+ return pow(abs(color), power) * sign(color);
+}
+
+float3 apply_matrix(float3 color, float3x3 inputMatrix){
+ // seems you can't just use mul() with OBS, and we have to split per component like that :
+ float r = dot(color, inputMatrix[0]);
+ float g = dot(color, inputMatrix[1]);
+ float b = dot(color, inputMatrix[2]);
+ return float3(r, g, b);
+}
+
+float get_luminance(float3 image){
+ // Return approximative perceptive luminance of the image.
+ return dot(image, luma_coefs_bt709);
+}
+
+float3 saturation(float3 color, float saturationAmount){
+ /*
+
+ Increase color saturation of the given color data.
+
+ :param color: expected sRGB primaries input
+ :oaram saturationAmount: expected 0-1 range with 1=neutral, 0=no saturation.
+
+ -- ref[1]
+ */
+ float luma = get_luminance(color);
+ return lerp(luma, color, saturationAmount);
+}
+
+float3 convert_cctf_full_to_legal(float3 color){
+ // ref[2] but we assume bitdepth=10, in_int=False, out_int=False
+ float bitdepth = 10.0;
+ float MV = pow(2.0, bitdepth) - 1.0;
+ float B = 64.0;
+ float W = 940.0;
+ float3 CV_legal = (W - B) * color + B;
+ return CV_legal / MV;
+}
+
+float3 convert_cctf_legal_to_full(float3 color){
+ // ref[2] but we assume bitdepth=10, in_int=False, out_int=False
+ float bitdepth = 10.0;
+ float MV = pow(2.0, bitdepth) - 1.0;
+ float B = 64.0;
+ float W = 940.0;
+ float3 CV_full = color * MV;
+ return (CV_full - B) / (W - B);
+}
\ No newline at end of file
diff --git a/obs/obs-script/colorspace.hlsl b/obs/obs-script/colorspace.hlsl
index b2489e2..07ef37d 100644
--- a/obs/obs-script/colorspace.hlsl
+++ b/obs/obs-script/colorspace.hlsl
@@ -6,532 +6,17 @@ References
----------
All data without explicit reference can assumed to be extracted/generated from `colour-science` python library.
-
-- [1] https://github.com/sobotka/AgX-S2O3/blob/main/AgX.py
-- [2] https://github.com/colour-science/colour/blob/develop/colour/models/rgb/transfer_functions/srgb.py#L99
-- [3] https://github.com/colour-science/colour/blob/develop/colour/models/rgb/transfer_functions/st_2084.py
-- [4] https://github.com/ampas/aces-dev/blob/master/transforms/ctl/lib/ACESlib.Utilities_Color.ctl#L492
-- [5] https://github.com/ampas/aces-dev/blob/master/transforms/ctl/lib/ACESlib.ODT_Common.ctl#L42
*/
-
uniform int CAT_METHOD = 0; // See Chromatic Adapatation transform section for availables ids
+#include "colorscience/math.hlsl"
+#include "colorscience/cctf.hlsl"
+#include "colorscience/cctf-auto.hlsl"
+#include "colorscience/cat.hlsl"
+#include "colorscience/gamut.hlsl"
+#include "colorscience/colorspace.hlsl"
-#define luma_coefs_bt709 float3(0.2126, 0.7152, 0.0722)
-
-#define matrix_identity_3x3 float3x3(\
- 1.0, 0.0, 0.0,\
- 0.0, 1.0, 0.0,\
- 0.0, 0.0, 1.0\
-)
-
-float3 powsafe(float3 color, float power){
- // pow() but safe for NaNs/negatives
- return pow(abs(color), power) * sign(color);
-}
-
-float3 apply_matrix(float3 color, float3x3 inputMatrix){
- // seems you can't just use mul() with OBS, and we have to split per component like that :
- float r = dot(color, inputMatrix[0]);
- float g = dot(color, inputMatrix[1]);
- float b = dot(color, inputMatrix[2]);
- return float3(r, g, b);
-}
-
-float get_luminance(float3 image){
- // Return approximative perceptive luminance of the image.
- return dot(image, luma_coefs_bt709);
-}
-
-float3 saturation(float3 color, float saturationAmount){
- /*
-
- Increase color saturation of the given color data.
-
- :param color: expected sRGB primaries input
- :oaram saturationAmount: expected 0-1 range with 1=neutral, 0=no saturation.
-
- -- ref[2] [4]
- */
- float luma = get_luminance(color);
- return lerp(luma, color, saturationAmount);
-}
-
-/* --------------------------------------------------------------------------------
-Transfer functions
--------------------------------------------------------------------------------- */
-
-float3 cctf_log2_normalized_from_open_domain(float3 color, float minimum_ev, float maximum_ev)
-/*
- Output log domain encoded data.
-
- Similar to OCIO lg2 AllocationTransform.
-
- ref[1]
-*/
-{
- float in_midgrey = 0.18;
-
- // remove negative before log transform
- color = max(0.0, color);
- // avoid infinite issue with log -- ref[1]
- color = (color < 0.00003051757) ? (0.00001525878 + color) : (color);
- color = clamp(
- log2(color / in_midgrey),
- float3(minimum_ev, minimum_ev, minimum_ev),
- float3(maximum_ev,maximum_ev,maximum_ev)
- );
- float total_exposure = maximum_ev - minimum_ev;
-
- return (color - minimum_ev) / total_exposure;
-}
-
-// exactly the same as above but I let it for reference
-float3 cctf_log2_ocio_transform(float3 color)
-/*
- Output log domain encoded data.
-
- Copy of OCIO lg2 AllocationTransform with the AgX Log values.
-
- :param color: rgba linear color data
-*/
-{
- // remove negative before log transform
- color = max(0.0, color);
- color = (color < 0.00003051757) ? (log2(0.00001525878 + color * 0.5)) : (log2(color));
-
- // obtained via m = ocio.MatrixTransform.Fit(oldMin=[-12.47393, -12.47393, -12.47393, 0.0], oldMax=[4.026069, 4.026069, 4.026069, 1.0])
- float3x3 fitMatrix = float3x3(
- 0.060606064279155415, 0.0, 0.0,
- 0.0, 0.060606064279155415, 0.0,
- 0.0, 0.0, 0.060606064279155415
- );
- // obtained via same as above
- float fitMatrixOffset = 0.7559958033936851;
- color = mul(fitMatrix, color);
- color += fitMatrixOffset.xxx;
-
- return color;
-}
-
-float3 cctf_decoding_sRGB_EOTF(float3 color){
- // ref[2]
- return (color <= 0.04045) ? (color / 12.92) : (powsafe((color + 0.055) / 1.055, 2.4));
-}
-
-float3 cctf_encoding_sRGB_EOTF(float3 color){
- // ref[2]
- return (color <= 0.0031308) ? (color * 12.92) : (1.055 * powsafe(color, 1/2.4) - 0.055);
-}
-
-float3 cctf_decoding_Power_2_2(float3 color){return powsafe(color, 2.2);}
-
-float3 cctf_encoding_Power_2_2(float3 color){return powsafe(color, 1/2.2);}
-
-float3 cctf_decoding_BT_709(float3 color){return powsafe(color, 2.4);}
-
-float3 cctf_encoding_BT_709(float3 color){return powsafe(color, 1/2.4);}
-
-float3 cctf_decoding_DCIP3(float3 color){return powsafe(color, 2.6);}
-
-float3 cctf_encoding_DCIP3(float3 color){return powsafe(color, 1/2.6);}
-
-float3 cctf_encoding_BT_2020(float3 color){return (color < 0.0181) ? color * 4.5 : 1.0993 * powsafe(color, 0.45) - (1.0993 - 1);}
-
-float3 cctf_decoding_BT_2020(float3 color){return (color < cctf_encoding_BT_2020(0.0181)) ? color / 4.5 : powsafe((color + (1.0993 - 1)) / 1.0993, 1 / 0.45) ;}
-
-float3 cctf_decoding_Display_P3(float3 color){return cctf_decoding_sRGB_EOTF(color);}
-
-float3 cctf_encoding_Display_P3(float3 color){return cctf_encoding_sRGB_EOTF(color);}
-
-float3 cctf_decoding_Adobe_RGB_1998(float3 color){return powsafe(color, 2.19921875);}
-
-float3 cctf_encoding_Adobe_RGB_1998(float3 color){return powsafe(color, 1/2.19921875);}
-
-
-// region WARNING code is procedurally generated
-
-uniform int cctf_id_Power_2_2 = 0; // Power 2.2
-uniform int cctf_id_sRGB_EOTF = 1; // sRGB EOTF
-uniform int cctf_id_BT_709 = 2; // BT.709
-uniform int cctf_id_DCIP3 = 3; // DCI-P3
-uniform int cctf_id_Display_P3 = 4; // Display P3
-uniform int cctf_id_Adobe_RGB_1998 = 5; // Adobe RGB 1998
-uniform int cctf_id_BT_2020 = 6; // BT.2020
-
-
-float3 apply_cctf_decoding(float3 color, int cctf_id){
- if (cctf_id == cctf_id_Power_2_2 ) return cctf_decoding_Power_2_2(color);
- if (cctf_id == cctf_id_sRGB_EOTF ) return cctf_decoding_sRGB_EOTF(color);
- if (cctf_id == cctf_id_BT_709 ) return cctf_decoding_BT_709(color);
- if (cctf_id == cctf_id_DCIP3 ) return cctf_decoding_DCIP3(color);
- if (cctf_id == cctf_id_Display_P3 ) return cctf_decoding_Display_P3(color);
- if (cctf_id == cctf_id_Adobe_RGB_1998 ) return cctf_decoding_Adobe_RGB_1998(color);
- if (cctf_id == cctf_id_BT_2020 ) return cctf_decoding_BT_2020(color);
- return color;
-}
-
-float3 apply_cctf_encoding(float3 color, int cctf_id){
- if (cctf_id == cctf_id_Power_2_2 ) return cctf_encoding_Power_2_2(color);
- if (cctf_id == cctf_id_sRGB_EOTF ) return cctf_encoding_sRGB_EOTF(color);
- if (cctf_id == cctf_id_BT_709 ) return cctf_encoding_BT_709(color);
- if (cctf_id == cctf_id_DCIP3 ) return cctf_encoding_DCIP3(color);
- if (cctf_id == cctf_id_Display_P3 ) return cctf_encoding_Display_P3(color);
- if (cctf_id == cctf_id_Adobe_RGB_1998 ) return cctf_encoding_Adobe_RGB_1998(color);
- if (cctf_id == cctf_id_BT_2020 ) return cctf_encoding_BT_2020(color);
- return color;
-}
-
-/* --------------------------------------------------------------------------------
-Chromatic Adaptation Transforms
--------------------------------------------------------------------------------- */
-
-#define matrix_cat_XYZ_Scaling_D60_to_D65 float3x3(\
- 0.997749312, 0.0, 0.0,\
- 0.0, 1.0, 0.0,\
- 0.0, 0.0, 1.079011464\
-)
-#define matrix_cat_XYZ_Scaling_D60_to_DCIP3 float3x3(\
- 0.939100313, 0.0, 0.0,\
- 0.0, 1.0, 0.0,\
- 0.0, 0.0, 0.945611705\
-)
-#define matrix_cat_XYZ_Scaling_D65_to_D60 float3x3(\
- 1.002255765, 0.0, 0.0,\
- 0.0, 1.0, 0.0,\
- 0.0, 0.0, 0.926774212\
-)
-#define matrix_cat_XYZ_Scaling_D65_to_DCIP3 float3x3(\
- 0.941218703, 0.0, 0.0,\
- 0.0, 1.0, 0.0,\
- 0.0, 0.0, 0.876368543\
-)
-#define matrix_cat_XYZ_Scaling_DCIP3_to_D60 float3x3(\
- 1.064848969, 0.0, 0.0,\
- 0.0, 1.0, 0.0,\
- 0.0, 0.0, 1.05751652\
-)
-#define matrix_cat_XYZ_Scaling_DCIP3_to_D65 float3x3(\
- 1.062452326, 0.0, 0.0,\
- 0.0, 1.0, 0.0,\
- 0.0, 0.0, 1.141072449\
-)
-#define matrix_cat_Bradford_D60_to_D65 float3x3(\
- 0.987323904, -0.006062169, 0.015845876,\
- -0.007531959, 1.001832321, 0.005293338,\
- 0.00305302, -0.005064257, 1.081147527\
-)
-#define matrix_cat_Bradford_D60_to_DCIP3 float3x3(\
- 0.964265012, -0.021300233, -0.002647012,\
- -0.033122492, 1.030598686, 0.000944999,\
- -0.003057139, 0.006720893, 0.941838177\
-)
-#define matrix_cat_Bradford_D65_to_D60 float3x3(\
- 1.012931026, 0.006054132, -0.0148757,\
- 0.007630325, 0.998191932, -0.004999018,\
- -0.002824644, 0.004658585, 0.924961741\
-)
-#define matrix_cat_Bradford_D65_to_DCIP3 float3x3(\
- 0.976578897, -0.015436265, -0.016686022,\
- -0.025689666, 1.028539168, -0.003785174,\
- -0.005705746, 0.011077866, 0.871176159\
-)
-#define matrix_cat_Bradford_DCIP3_to_D60 float3x3(\
- 1.037804611, 0.021430283, 0.002895221,\
- 0.033351213, 0.971004834, -0.00088053,\
- 0.003130647, -0.006859463, 1.061769201\
-)
-#define matrix_cat_Bradford_DCIP3_to_D65 float3x3(\
- 1.024496728, 0.015163541, 0.019688522,\
- 0.025612193, 0.972586306, 0.004716352,\
- 0.006384231, -0.012268083, 1.147942445\
-)
-#define matrix_cat_CAT02_D60_to_D65 float3x3(\
- 0.988317991, -0.007816256, 0.016645551,\
- -0.00564353, 0.998686699, 0.00662762,\
- 0.00035077, 0.001116791, 1.077573915\
-)
-#define matrix_cat_CAT02_D60_to_DCIP3 float3x3(\
- 0.979655622, -0.035093475, -0.003506859,\
- -0.024670911, 1.024631944, -0.001120007,\
- 0.000239512, -0.000975875, 0.946352523\
-)
-#define matrix_cat_CAT02_D65_to_D60 float3x3(\
- 1.011870978, 0.007936977, -0.015679437,\
- 0.005720259, 1.001366784, -0.00624727,\
- -0.000335311, -0.001040394, 0.928022164\
-)
-#define matrix_cat_CAT02_D65_to_DCIP3 float3x3(\
- 0.991085525, -0.027362287, -0.018395654,\
- -0.019102244, 1.025837747, -0.007053718,\
- -8.0549e-05, -0.001959887, 0.878238458\
-)
-#define matrix_cat_CAT02_DCIP3_to_D60 float3x3(\
- 1.021647216, 0.034994893, 0.003827292,\
- 0.024598791, 0.976803896, 0.001247201,\
- -0.000233203, 0.00099842, 1.056688999\
-)
-#define matrix_cat_CAT02_DCIP3_to_D65 float3x3(\
- 1.009516172, 0.026967753, 0.021362003,\
- 0.018799243, 0.97533018, 0.008227297,\
- 0.000134542, 0.002179032, 1.138663236\
-)
-#define matrix_cat_Von_Kries_D60_to_D65 float3x3(\
- 0.995663132, -0.014998519, 0.016829124,\
- -0.001647481, 1.001234102, 0.000332195,\
- 0.0, 0.0, 1.079011464\
-)
-#define matrix_cat_Von_Kries_D60_to_DCIP3 float3x3(\
- 0.9888443, -0.038575341, -0.0087295,\
- -0.004237228, 1.003172521, 0.000855893,\
- 0.0, 0.0, 0.945611705\
-)
-#define matrix_cat_Von_Kries_D65_to_D60 float3x3(\
- 1.004380654, 0.015045655, -0.015669755,\
- 0.001652658, 0.998792176, -0.000333274,\
- 0.0, 0.0, 0.926774212\
-)
-#define matrix_cat_Von_Kries_D65_to_DCIP3 float3x3(\
- 0.993112333, -0.023650939, -0.023572367,\
- -0.002597888, 1.001897113, 0.000525285,\
- 0.0, 0.0, 0.876368543\
-)
-#define matrix_cat_Von_Kries_DCIP3_to_D60 float3x3(\
- 1.011448214, 0.038893569, 0.009302073,\
- 0.004272183, 0.997001792, -0.000862968,\
- 0.0, 0.0, 1.05751652\
-)
-#define matrix_cat_Von_Kries_DCIP3_to_D65 float3x3(\
- 1.00699762, 0.023771342, 0.027071751,\
- 0.002611113, 0.998168118, -0.000528057,\
- 0.0, 0.0, 1.141072449\
-)
-
-uniform int catid_XYZ_Scaling = 0;
-uniform int catid_Bradford = 1;
-uniform int catid_CAT02 = 2;
-uniform int catid_Von_Kries = 3;
-
-uniform int whitepointid_D60 = 0;
-uniform int whitepointid_D65 = 1;
-uniform int whitepointid_DCIP3 = 2;
-
-
-float3x3 get_chromatic_adaptation_transform_matrix(int cat_id, int whitepoint_source, int whitepoint_target){
- if (cat_id == 0 && whitepoint_source == 0 && whitepoint_target == 1) return matrix_cat_XYZ_Scaling_D60_to_D65;
- if (cat_id == 0 && whitepoint_source == 0 && whitepoint_target == 2) return matrix_cat_XYZ_Scaling_D60_to_DCIP3;
- if (cat_id == 0 && whitepoint_source == 1 && whitepoint_target == 0) return matrix_cat_XYZ_Scaling_D65_to_D60;
- if (cat_id == 0 && whitepoint_source == 1 && whitepoint_target == 2) return matrix_cat_XYZ_Scaling_D65_to_DCIP3;
- if (cat_id == 0 && whitepoint_source == 2 && whitepoint_target == 0) return matrix_cat_XYZ_Scaling_DCIP3_to_D60;
- if (cat_id == 0 && whitepoint_source == 2 && whitepoint_target == 1) return matrix_cat_XYZ_Scaling_DCIP3_to_D65;
- if (cat_id == 1 && whitepoint_source == 0 && whitepoint_target == 1) return matrix_cat_Bradford_D60_to_D65;
- if (cat_id == 1 && whitepoint_source == 0 && whitepoint_target == 2) return matrix_cat_Bradford_D60_to_DCIP3;
- if (cat_id == 1 && whitepoint_source == 1 && whitepoint_target == 0) return matrix_cat_Bradford_D65_to_D60;
- if (cat_id == 1 && whitepoint_source == 1 && whitepoint_target == 2) return matrix_cat_Bradford_D65_to_DCIP3;
- if (cat_id == 1 && whitepoint_source == 2 && whitepoint_target == 0) return matrix_cat_Bradford_DCIP3_to_D60;
- if (cat_id == 1 && whitepoint_source == 2 && whitepoint_target == 1) return matrix_cat_Bradford_DCIP3_to_D65;
- if (cat_id == 2 && whitepoint_source == 0 && whitepoint_target == 1) return matrix_cat_CAT02_D60_to_D65;
- if (cat_id == 2 && whitepoint_source == 0 && whitepoint_target == 2) return matrix_cat_CAT02_D60_to_DCIP3;
- if (cat_id == 2 && whitepoint_source == 1 && whitepoint_target == 0) return matrix_cat_CAT02_D65_to_D60;
- if (cat_id == 2 && whitepoint_source == 1 && whitepoint_target == 2) return matrix_cat_CAT02_D65_to_DCIP3;
- if (cat_id == 2 && whitepoint_source == 2 && whitepoint_target == 0) return matrix_cat_CAT02_DCIP3_to_D60;
- if (cat_id == 2 && whitepoint_source == 2 && whitepoint_target == 1) return matrix_cat_CAT02_DCIP3_to_D65;
- if (cat_id == 3 && whitepoint_source == 0 && whitepoint_target == 1) return matrix_cat_Von_Kries_D60_to_D65;
- if (cat_id == 3 && whitepoint_source == 0 && whitepoint_target == 2) return matrix_cat_Von_Kries_D60_to_DCIP3;
- if (cat_id == 3 && whitepoint_source == 1 && whitepoint_target == 0) return matrix_cat_Von_Kries_D65_to_D60;
- if (cat_id == 3 && whitepoint_source == 1 && whitepoint_target == 2) return matrix_cat_Von_Kries_D65_to_DCIP3;
- if (cat_id == 3 && whitepoint_source == 2 && whitepoint_target == 0) return matrix_cat_Von_Kries_DCIP3_to_D60;
- if (cat_id == 3 && whitepoint_source == 2 && whitepoint_target == 1) return matrix_cat_Von_Kries_DCIP3_to_D65;
- return matrix_identity_3x3;
-}
-
-/* --------------------------------------------------------------------------------
-Matrices
--------------------------------------------------------------------------------- */
-
-// sRGB
-#define matrix_sRGB_to_XYZ float3x3(\
- 0.4124, 0.3576, 0.1805,\
- 0.2126, 0.7152, 0.0722,\
- 0.0193, 0.1192, 0.9505\
-)
-#define matrix_sRGB_from_XYZ float3x3(\
- 3.2406, -1.5372, -0.4986,\
- -0.9689, 1.8758, 0.0415,\
- 0.0557, -0.204, 1.057\
-)
-
-// DCI-P3
-#define matrix_DCIP3_to_XYZ float3x3(\
- 0.445169816, 0.277134409, 0.17228267,\
- 0.209491678, 0.721595254, 0.068913068,\
- -0.0, 0.04706056, 0.907355394\
-)
-#define matrix_DCIP3_from_XYZ float3x3(\
- 2.72539403, -1.018003006, -0.440163195,\
- -0.795168026, 1.689732055, 0.022647191,\
- 0.041241891, -0.087639019, 1.100929379\
-)
-
-// Display P3
-#define matrix_Display_P3_to_XYZ float3x3(\
- 0.486570949, 0.265667693, 0.198217285,\
- 0.228974564, 0.691738522, 0.079286914,\
- -0.0, 0.045113382, 1.043944369\
-)
-#define matrix_Display_P3_from_XYZ float3x3(\
- 2.493496912, -0.931383618, -0.402710784,\
- -0.82948897, 1.76266406, 0.023624686,\
- 0.03584583, -0.076172389, 0.956884524\
-)
-
-// Adobe RGB (1998)
-#define matrix_Adobe_RGB_1998_to_XYZ float3x3(\
- 0.57667, 0.18556, 0.18823,\
- 0.29734, 0.62736, 0.07529,\
- 0.02703, 0.07069, 0.99134\
-)
-#define matrix_Adobe_RGB_1998_from_XYZ float3x3(\
- 2.04159, -0.56501, -0.34473,\
- -0.96924, 1.87597, 0.04156,\
- 0.01344, -0.11836, 1.01517\
-)
-
-// ITU-R BT.2020
-#define matrix_ITUR_BT_2020_to_XYZ float3x3(\
- 0.636958048, 0.144616904, 0.168880975,\
- 0.262700212, 0.677998072, 0.059301716,\
- 0.0, 0.028072693, 1.060985058\
-)
-#define matrix_ITUR_BT_2020_from_XYZ float3x3(\
- 1.716651188, -0.355670784, -0.253366281,\
- -0.666684352, 1.616481237, 0.015768546,\
- 0.017639857, -0.042770613, 0.942103121\
-)
-
-
-uniform int gamutid_sRGB = 0;
-uniform int gamutid_DCIP3 = 1;
-uniform int gamutid_Display_P3 = 2;
-uniform int gamutid_Adobe_RGB_1998 = 3;
-uniform int gamutid_ITUR_BT_2020 = 4;
-
-
-float3x3 get_gamut_matrix_to_XYZ(int gamutid){
- if (gamutid == gamutid_sRGB ) return matrix_sRGB_to_XYZ;
- if (gamutid == gamutid_DCIP3 ) return matrix_DCIP3_to_XYZ;
- if (gamutid == gamutid_Display_P3 ) return matrix_Display_P3_to_XYZ;
- if (gamutid == gamutid_Adobe_RGB_1998 ) return matrix_Adobe_RGB_1998_to_XYZ;
- if (gamutid == gamutid_ITUR_BT_2020 ) return matrix_ITUR_BT_2020_to_XYZ;
- return matrix_identity_3x3;
-}
-
-float3x3 get_gamut_matrix_from_XYZ(int gamutid){
- if (gamutid == gamutid_sRGB ) return matrix_sRGB_from_XYZ;
- if (gamutid == gamutid_DCIP3 ) return matrix_DCIP3_from_XYZ;
- if (gamutid == gamutid_Display_P3 ) return matrix_Display_P3_from_XYZ;
- if (gamutid == gamutid_Adobe_RGB_1998 ) return matrix_Adobe_RGB_1998_from_XYZ;
- if (gamutid == gamutid_ITUR_BT_2020 ) return matrix_ITUR_BT_2020_from_XYZ;
- return matrix_identity_3x3;
-}
-
-/* --------------------------------------------------------------------------------
-Colorspaces
--------------------------------------------------------------------------------- */
-
-struct Colorspace{
- int gamut_id;
- int whitepoint_id;
- int cctf_id;
-};
-
-uniform int colorspaceid_Passthrough = 0;
-uniform int colorspaceid_sRGB_Display_EOTF = 1;
-uniform int colorspaceid_sRGB_Display_2_2 = 2;
-uniform int colorspaceid_sRGB_Linear = 3;
-uniform int colorspaceid_BT_709_Display_2_4 = 4;
-uniform int colorspaceid_DCIP3_Display_2_6 = 5;
-uniform int colorspaceid_DCIP3_D65_Display_2_6 = 6;
-uniform int colorspaceid_DCIP3_D60_Display_2_6 = 7;
-uniform int colorspaceid_Apple_Display_P3 = 8;
-uniform int colorspaceid_Adobe_RGB_1998_Display = 9;
-uniform int colorspaceid_BT_2020_Display_OETF = 10;
-uniform int colorspaceid_BT_2020_Linear = 11;
-uniform int colorspaceid_DCIP3_Linear = 12;
-
-Colorspace getColorspaceFromId(int colorspace_id){
-
- Colorspace colorspace;
-
- if (colorspace_id == colorspaceid_Passthrough){
- colorspace.gamut_id = -1;
- colorspace.whitepoint_id = -1;
- colorspace.cctf_id = -1;
- };
- if (colorspace_id == colorspaceid_sRGB_Display_EOTF){
- colorspace.gamut_id = gamutid_sRGB;
- colorspace.whitepoint_id = whitepointid_D65;
- colorspace.cctf_id = cctf_id_sRGB_EOTF;
- };
- if (colorspace_id == colorspaceid_sRGB_Display_2_2){
- colorspace.gamut_id = gamutid_sRGB;
- colorspace.whitepoint_id = whitepointid_D65;
- colorspace.cctf_id = cctf_id_Power_2_2;
- };
- if (colorspace_id == colorspaceid_sRGB_Linear){
- colorspace.gamut_id = gamutid_sRGB;
- colorspace.whitepoint_id = whitepointid_D65;
- colorspace.cctf_id = -1;
- };
- if (colorspace_id == colorspaceid_BT_709_Display_2_4){
- colorspace.gamut_id = gamutid_sRGB;
- colorspace.whitepoint_id = whitepointid_D65;
- colorspace.cctf_id = cctf_id_BT_709;
- };
- if (colorspace_id == colorspaceid_DCIP3_Display_2_6){
- colorspace.gamut_id = gamutid_DCIP3;
- colorspace.whitepoint_id = whitepointid_DCIP3;
- colorspace.cctf_id = cctf_id_DCIP3;
- };
- if (colorspace_id == colorspaceid_DCIP3_D65_Display_2_6){
- colorspace.gamut_id = gamutid_DCIP3;
- colorspace.whitepoint_id = whitepointid_D65;
- colorspace.cctf_id = cctf_id_DCIP3;
- };
- if (colorspace_id == colorspaceid_DCIP3_D60_Display_2_6){
- colorspace.gamut_id = gamutid_DCIP3;
- colorspace.whitepoint_id = whitepointid_D60;
- colorspace.cctf_id = cctf_id_DCIP3;
- };
- if (colorspace_id == colorspaceid_Apple_Display_P3){
- colorspace.gamut_id = gamutid_Display_P3;
- colorspace.whitepoint_id = whitepointid_DCIP3;
- colorspace.cctf_id = cctf_id_Display_P3;
- };
- if (colorspace_id == colorspaceid_Adobe_RGB_1998_Display){
- colorspace.gamut_id = gamutid_Adobe_RGB_1998;
- colorspace.whitepoint_id = whitepointid_D65;
- colorspace.cctf_id = cctf_id_Adobe_RGB_1998;
- };
- if (colorspace_id == colorspaceid_BT_2020_Display_OETF){
- colorspace.gamut_id = gamutid_ITUR_BT_2020;
- colorspace.whitepoint_id = whitepointid_D65;
- colorspace.cctf_id = cctf_id_BT_2020;
- };
- if (colorspace_id == colorspaceid_BT_2020_Linear){
- colorspace.gamut_id = gamutid_ITUR_BT_2020;
- colorspace.whitepoint_id = whitepointid_D65;
- colorspace.cctf_id = -1;
- };
- if (colorspace_id == colorspaceid_DCIP3_Linear){
- colorspace.gamut_id = gamutid_DCIP3;
- colorspace.whitepoint_id = whitepointid_DCIP3;
- colorspace.cctf_id = -1;
- };
- return colorspace;
-}
-// endregion
float3 convertColorspaceToColorspace(float3 color, int sourceColorspaceId, int targetColorspaceId){
@@ -549,7 +34,14 @@ float3 convertColorspaceToColorspace(float3 color, int sourceColorspaceId, int t
// apply Chromatic adaptation transform if any
if (source_colorspace.whitepoint_id != target_colorspace.whitepoint_id && (source_colorspace.whitepoint_id != -1) && (target_colorspace.whitepoint_id != -1)){
- color = apply_matrix(color, get_chromatic_adaptation_transform_matrix(CAT_METHOD, source_colorspace.whitepoint_id, target_colorspace.whitepoint_id));
+ color = apply_matrix(
+ color,
+ get_chromatic_adaptation_transform_matrix(
+ CAT_METHOD,
+ source_colorspace.whitepoint_id,
+ target_colorspace.whitepoint_id
+ )
+ );
}
if (source_colorspace.gamut_id != target_colorspace.gamut_id && (source_colorspace.gamut_id != -1) && (target_colorspace.gamut_id != -1)){
diff --git a/obs/src/python/obs_codegen/__init__.py b/obs/src/python/obs_codegen/__init__.py
new file mode 100644
index 0000000..bea400b
--- /dev/null
+++ b/obs/src/python/obs_codegen/__init__.py
@@ -0,0 +1,9 @@
+from . import c
+from .generators import BaseGenerator
+from .generators import LuaGenerator
+from .generators import HlslGenerator
+from ._colorcomponents import Whitepoint
+from ._colorcomponents import Cat
+from ._colorcomponents import AssemblyColorspace
+from ._colorcomponents import ColorspaceGamut
+from ._colorcomponents import TransferFunction
diff --git a/dev/obs/obs_codegen/entitities.py b/obs/src/python/obs_codegen/_colorcomponents.py
similarity index 100%
rename from dev/obs/obs_codegen/entitities.py
rename to obs/src/python/obs_codegen/_colorcomponents.py
diff --git a/dev/obs/obs_codegen/c.py b/obs/src/python/obs_codegen/c.py
similarity index 100%
rename from dev/obs/obs_codegen/c.py
rename to obs/src/python/obs_codegen/c.py
diff --git a/obs/src/python/obs_codegen/generators/__init__.py b/obs/src/python/obs_codegen/generators/__init__.py
new file mode 100644
index 0000000..8f43914
--- /dev/null
+++ b/obs/src/python/obs_codegen/generators/__init__.py
@@ -0,0 +1,3 @@
+from ._base import BaseGenerator
+from ._lua import LuaGenerator
+from ._hlsl import HlslGenerator
diff --git a/dev/obs/obs_codegen/generator.py b/obs/src/python/obs_codegen/generators/_base.py
similarity index 69%
rename from dev/obs/obs_codegen/generator.py
rename to obs/src/python/obs_codegen/generators/_base.py
index f506f45..cee65f0 100644
--- a/dev/obs/obs_codegen/generator.py
+++ b/obs/src/python/obs_codegen/generators/_base.py
@@ -4,11 +4,11 @@
import logging
from abc import abstractmethod
-from .entitities import Whitepoint
-from .entitities import Cat
-from .entitities import AssemblyColorspace
-from .entitities import ColorspaceGamut
-from .entitities import TransferFunction
+from obs_codegen._colorcomponents import Whitepoint
+from obs_codegen._colorcomponents import Cat
+from obs_codegen._colorcomponents import AssemblyColorspace
+from obs_codegen._colorcomponents import ColorspaceGamut
+from obs_codegen._colorcomponents import TransferFunction
logger = logging.getLogger(__name__)
diff --git a/dev/obs/obs_codegen/hlsl/generator.py b/obs/src/python/obs_codegen/generators/_hlsl.py
similarity index 91%
rename from dev/obs/obs_codegen/hlsl/generator.py
rename to obs/src/python/obs_codegen/generators/_hlsl.py
index a32095f..f808f1c 100644
--- a/dev/obs/obs_codegen/hlsl/generator.py
+++ b/obs/src/python/obs_codegen/generators/_hlsl.py
@@ -5,19 +5,18 @@
import colour
from obs_codegen.c import HLSL_INDENT as INDENT
-from obs_codegen.generator import BaseGenerator
-from obs_codegen.entitities import Whitepoint
-from obs_codegen.entitities import Cat
-from obs_codegen.entitities import ColorspaceGamut
-from .util import convert3x3MatrixToHlslStr
-from .util import generateCommentHeader
+from obs_codegen.generators import BaseGenerator
+from obs_codegen._colorcomponents import Whitepoint
+from obs_codegen._colorcomponents import Cat
+from obs_codegen._colorcomponents import ColorspaceGamut
+from obs_codegen.hlsl_utils import convert3x3MatrixToHlslStr
+from obs_codegen.hlsl_utils import generateCommentHeader
logger = logging.getLogger(__name__)
@dataclasses.dataclass
class HlslVariable:
-
name: str
definition: str
@@ -27,7 +26,6 @@ def processCat(
whitepoint_target: Whitepoint,
cat: Cat,
) -> HlslVariable:
-
matrix_cat = colour.adaptation.matrix_chromatic_adaptation_VonKries(
colour.xy_to_XYZ(whitepoint_source.coordinates),
colour.xy_to_XYZ(whitepoint_target.coordinates),
@@ -67,10 +65,10 @@ def generateCode(self) -> str:
Returns:
valid HLSL code snippet
"""
- str_cctf = self._generateTransferFunctionBlock()
- str_matrices = self._generateMatricesBlock()
- str_cat = self._generateCatBlock()
- str_colorspace = self._generateColorspacesBlock()
+ str_cctf = self.generateTransferFunctionBlock()
+ str_matrices = self.generateMatricesBlock()
+ str_cat = self.generateCatBlock()
+ str_colorspace = self.generateColorspacesBlock()
return (
"// region WARNING code is procedurally generated\n"
@@ -78,22 +76,18 @@ def generateCode(self) -> str:
"// endregion\n"
)
- def _generateTransferFunctionBlock(self) -> str:
-
+ def generateTransferFunctionBlock(self) -> str:
out_str = ""
out_str += "\n"
for transfer_function in self.transfer_functions:
-
out_str += f"uniform int {transfer_function.id_variable_name} = {transfer_function.id}; // {transfer_function.name}\n"
for cctf_mode in ["decoding", "encoding"]:
-
out_str += "\n\n"
out_str += f"float3 apply_cctf_{cctf_mode}(float3 color, int cctf_id){{\n"
for transfer_function in self.transfer_functions:
-
skip = not transfer_function.has_decoding and cctf_mode == "decoding"
if skip:
continue
@@ -113,13 +107,11 @@ def _generateTransferFunctionBlock(self) -> str:
return out_str
- def _generateMatricesBlock(self) -> str:
-
+ def generateMatricesBlock(self) -> str:
out_str = generateCommentHeader("Matrices")
out_str += "\n"
for colorspace in self.colorspaces_gamut:
-
out_str += processColorspaceMatrix(colorspace) + "\n"
out_str += "\n"
@@ -128,7 +120,6 @@ def _generateMatricesBlock(self) -> str:
out_str += f"uniform int {colorspace.id_variable_name} = {colorspace.id};\n"
for gamut_direction in ["to_XYZ", "from_XYZ"]:
-
out_str += "\n\n"
out_str += f"float3x3 get_gamut_matrix_{gamut_direction}(int gamutid){{\n"
@@ -143,8 +134,7 @@ def _generateMatricesBlock(self) -> str:
return out_str
- def _generateCatBlock(self) -> str:
-
+ def generateCatBlock(self) -> str:
out_str = generateCommentHeader("Chromatic Adaptation Transforms")
out_str += "\n"
@@ -155,9 +145,7 @@ def _generateCatBlock(self) -> str:
cat_variable_dict = dict()
for cat in self.cats:
-
for whitepoint_combinaison in whitepoint_combinaison_list:
-
whitepoint_source = whitepoint_combinaison[0]
whitepoint_target = whitepoint_combinaison[1]
@@ -196,8 +184,7 @@ def _generateCatBlock(self) -> str:
return out_str
- def _generateColorspacesBlock(self) -> str:
-
+ def generateColorspacesBlock(self) -> str:
out_str = generateCommentHeader("Colorspaces")
out_str += "\n"
@@ -210,7 +197,6 @@ def _generateColorspacesBlock(self) -> str:
out_str += "};\n\n"
for assembly_colorspace in self.colorspaces_assemblies:
-
out_str += f"uniform int {assembly_colorspace.id_variable_name} = {assembly_colorspace.id};\n"
out_str += "\n"
@@ -219,7 +205,6 @@ def _generateColorspacesBlock(self) -> str:
out_str += f"\n{INDENT}Colorspace colorspace;\n\n"
for assembly_colorspace in self.colorspaces_assemblies:
-
out_str += INDENT
out_str += (
f"if (colorspace_id == {assembly_colorspace.id_variable_name}){{\n"
diff --git a/dev/obs/obs_codegen/lua/generator.py b/obs/src/python/obs_codegen/generators/_lua.py
similarity index 95%
rename from dev/obs/obs_codegen/lua/generator.py
rename to obs/src/python/obs_codegen/generators/_lua.py
index 0ac363b..05a1630 100644
--- a/dev/obs/obs_codegen/lua/generator.py
+++ b/obs/src/python/obs_codegen/generators/_lua.py
@@ -2,7 +2,7 @@
import logging
from obs_codegen.c import LUA_IDENT as INDENT
-from obs_codegen.generator import BaseGenerator
+from obs_codegen.generators import BaseGenerator
logger = logging.getLogger(__name__)
@@ -23,25 +23,21 @@ def generateCode(self) -> str:
return f"{str_props}"
def _generatePropertyList(self) -> str:
-
out_str = ""
for colorspace in self.colorspaces_assemblies:
-
out_str += INDENT
out_str += f'obs.obs_property_list_add_int(propOutputColorspace, "{colorspace.name}", {colorspace.id})\n'
out_str += "\n----------\n"
for colorspace in self.colorspaces_assemblies:
-
out_str += INDENT
out_str += f'obs.obs_property_list_add_int(propInputColorspace, "{colorspace.name}", {colorspace.id})\n'
out_str += "\n----------\n"
for cat in self.cats:
-
out_str += INDENT
out_str += f'obs.obs_property_list_add_int(propCatMethod, "{cat.name}", {cat.id})\n'
diff --git a/dev/obs/obs_codegen/hlsl/util.py b/obs/src/python/obs_codegen/hlsl_utils.py
similarity index 100%
rename from dev/obs/obs_codegen/hlsl/util.py
rename to obs/src/python/obs_codegen/hlsl_utils.py
diff --git a/dev/obs/obs_codegen/util.py b/obs/src/python/obs_codegen/util.py
similarity index 100%
rename from dev/obs/obs_codegen/util.py
rename to obs/src/python/obs_codegen/util.py
diff --git a/obs/src/scripts/build-colorspace_core.hlsl.py b/obs/src/scripts/build-colorspace_core.hlsl.py
new file mode 100644
index 0000000..47d7b7b
--- /dev/null
+++ b/obs/src/scripts/build-colorspace_core.hlsl.py
@@ -0,0 +1,329 @@
+import dataclasses
+import logging
+import sys
+from pathlib import Path
+from typing import Type
+from typing import TypeVar
+
+import colour
+
+from obs_codegen import Whitepoint
+from obs_codegen import Cat
+from obs_codegen import AssemblyColorspace
+from obs_codegen import ColorspaceGamut
+from obs_codegen import TransferFunction
+from obs_codegen import BaseGenerator
+from obs_codegen import HlslGenerator
+from obs_codegen import LuaGenerator
+
+LOGGER = logging.getLogger(__name__)
+
+
+BaseGeneratorType = TypeVar("BaseGeneratorType", bound=BaseGenerator)
+
+
+@dataclasses.dataclass
+class ColorManagementConfig:
+ colorspaces_gamut: list[ColorspaceGamut]
+ whitepoints: list[Whitepoint]
+ cats: list[Cat]
+ colorspaces_assemblies: list[AssemblyColorspace]
+ transfer_functions: list[TransferFunction]
+
+ def use_with_generator(
+ self, generator_class: Type[BaseGeneratorType]
+ ) -> BaseGeneratorType:
+ instance = generator_class(
+ colorspaces_gamut=self.colorspaces_gamut,
+ whitepoints=self.whitepoints,
+ cats=self.cats,
+ colorspaces_assemblies=self.colorspaces_assemblies,
+ transfer_functions=self.transfer_functions,
+ )
+ return instance
+
+
+def get_config():
+ illuminant1931: dict = colour.CCS_ILLUMINANTS["CIE 1931 2 Degree Standard Observer"]
+
+ transfer_function_power_2_2 = TransferFunction("Power 2.2")
+ transfer_function_sRGB_EOTF = TransferFunction("sRGB EOTF")
+ transfer_function_BT709 = TransferFunction("BT.709")
+ transfer_function_DCIP3 = TransferFunction("DCI-P3")
+ transfer_function_Display_P3 = TransferFunction("Display P3")
+ transfer_function_Adobe_RGB_1998 = TransferFunction("Adobe RGB 1998")
+ transfer_function_BT2020 = TransferFunction("BT.2020")
+ transfer_function_FLog = TransferFunction("FLog")
+ transfer_function_FLog2 = TransferFunction("FLog2")
+ transfer_function_NLog = TransferFunction("NLog")
+ transfer_function_SLog = TransferFunction("SLog")
+ transfer_function_SLog2 = TransferFunction("SLog2")
+ transfer_function_SLog3 = TransferFunction("SLog3")
+ transfer_function_VLog = TransferFunction("VLog")
+
+ transfer_function_list = [
+ transfer_function_power_2_2,
+ transfer_function_sRGB_EOTF,
+ transfer_function_BT709,
+ transfer_function_DCIP3,
+ transfer_function_Display_P3,
+ transfer_function_Adobe_RGB_1998,
+ transfer_function_BT2020,
+ transfer_function_FLog,
+ transfer_function_FLog2,
+ transfer_function_NLog,
+ transfer_function_SLog,
+ transfer_function_SLog2,
+ transfer_function_SLog3,
+ transfer_function_VLog,
+ ]
+
+ # fmt: off
+ colorspace_gamut_sRGB = ColorspaceGamut.fromColourColorspaceName("sRGB")
+ colorspace_gamut_DCIP3 = ColorspaceGamut.fromColourColorspaceName("DCI-P3")
+ colorspace_gamut_Display_P3 = ColorspaceGamut.fromColourColorspaceName("Display P3")
+ colorspace_gamut_Adobe_RGB_1998 = ColorspaceGamut.fromColourColorspaceName("Adobe RGB (1998)")
+ colorspace_gamut_ITUR_BT_2020 = ColorspaceGamut.fromColourColorspaceName("ITU-R BT.2020")
+ colorspace_gamut_Cinema_Gamut = ColorspaceGamut.fromColourColorspaceName("Cinema Gamut")
+ colorspace_gamut_S_Gamut = ColorspaceGamut.fromColourColorspaceName("S-Gamut")
+ colorspace_gamut_S_Gamut3_Cine = ColorspaceGamut.fromColourColorspaceName("S-Gamut3.Cine")
+ colorspace_gamut_V_Gamut = ColorspaceGamut.fromColourColorspaceName("V-Gamut")
+ colorspace_gamut_list = [
+ colorspace_gamut_sRGB,
+ colorspace_gamut_DCIP3,
+ colorspace_gamut_Display_P3,
+ colorspace_gamut_Adobe_RGB_1998,
+ colorspace_gamut_ITUR_BT_2020,
+ colorspace_gamut_Cinema_Gamut,
+ colorspace_gamut_S_Gamut,
+ colorspace_gamut_S_Gamut3_Cine,
+ colorspace_gamut_V_Gamut,
+ ]
+ # fmt: on
+
+ whitepoint_D60 = Whitepoint("D60", illuminant1931["D60"])
+ whitepoint_D65 = Whitepoint("D65", illuminant1931["D65"])
+ whitepoint_DCIP3 = Whitepoint("DCI-P3", illuminant1931["DCI-P3"])
+ whitepoint_list = [whitepoint_D60, whitepoint_D65, whitepoint_DCIP3]
+
+ assembly_colorspace_Passthrough = AssemblyColorspace(
+ "Passthrough",
+ None,
+ None,
+ None,
+ )
+ assembly_colorspace_sRGB_Display_EOTF = AssemblyColorspace(
+ "sRGB Display (EOTF)",
+ colorspace_gamut_sRGB,
+ whitepoint_D65,
+ transfer_function_sRGB_EOTF,
+ )
+ assembly_colorspace_sRGB_Display_2_2 = AssemblyColorspace(
+ "sRGB Display (2.2)",
+ colorspace_gamut_sRGB,
+ whitepoint_D65,
+ transfer_function_power_2_2,
+ )
+ assembly_colorspace_sRGB_Linear = AssemblyColorspace(
+ "sRGB Linear",
+ colorspace_gamut_sRGB,
+ whitepoint_D65,
+ None,
+ )
+ assembly_colorspace_BT_709_Display_2_4 = AssemblyColorspace(
+ "BT.709 Display (2.4)",
+ colorspace_gamut_sRGB,
+ whitepoint_D65,
+ transfer_function_BT709,
+ )
+ assembly_colorspace_DCIP3_Display_2_6 = AssemblyColorspace(
+ "DCI-P3 Display (2.6)",
+ colorspace_gamut_DCIP3,
+ whitepoint_DCIP3,
+ transfer_function_DCIP3,
+ )
+ assembly_colorspace_DCIP3_D65_Display_2_6 = AssemblyColorspace(
+ "DCI-P3 D65 Display (2.6)",
+ colorspace_gamut_DCIP3,
+ whitepoint_D65,
+ transfer_function_DCIP3,
+ )
+ assembly_colorspace_DCIP3_D60_Display_2_6 = AssemblyColorspace(
+ "DCI-P3 D60 Display (2.6)",
+ colorspace_gamut_DCIP3,
+ whitepoint_D60,
+ transfer_function_DCIP3,
+ )
+ assembly_colorspace_Apple_Display_P3 = AssemblyColorspace(
+ "Apple Display P3",
+ colorspace_gamut_Display_P3,
+ whitepoint_DCIP3,
+ transfer_function_Display_P3,
+ )
+ assembly_colorspace_Adobe_RGB_1998_Display = AssemblyColorspace(
+ "Adobe RGB 1998 Display",
+ colorspace_gamut_Adobe_RGB_1998,
+ whitepoint_D65,
+ transfer_function_Adobe_RGB_1998,
+ )
+ assembly_colorspace_BT_2020_Display_OETF = AssemblyColorspace(
+ "BT.2020 Display (OETF)",
+ colorspace_gamut_ITUR_BT_2020,
+ whitepoint_D65,
+ transfer_function_BT2020,
+ )
+ assembly_colorspace_BT_2020_Linear = AssemblyColorspace(
+ "BT.2020 Linear",
+ colorspace_gamut_ITUR_BT_2020,
+ whitepoint_D65,
+ None,
+ )
+ assembly_colorspace_DCIP3_Linear = AssemblyColorspace(
+ "DCI-P3 Linear",
+ colorspace_gamut_DCIP3,
+ whitepoint_DCIP3,
+ None,
+ )
+ assembly_colorspace_Cinema_Gamut = AssemblyColorspace(
+ "Cinema Gamut (Canon)",
+ colorspace_gamut_Cinema_Gamut,
+ whitepoint_D65,
+ None,
+ )
+ assembly_colorspace_F_Gamut_FLog = AssemblyColorspace(
+ "F-Gamut FLog (Fujifilm)",
+ colorspace_gamut_ITUR_BT_2020,
+ whitepoint_D65,
+ transfer_function_FLog,
+ )
+ assembly_colorspace_F_Gamut_FLog2 = AssemblyColorspace(
+ "F-Gamut FLog2 (Fujifilm)",
+ colorspace_gamut_ITUR_BT_2020,
+ whitepoint_D65,
+ transfer_function_FLog2,
+ )
+ assembly_colorspace_N_Gamut = AssemblyColorspace(
+ "N-Gamut (Nikon)",
+ colorspace_gamut_ITUR_BT_2020,
+ whitepoint_D65,
+ transfer_function_NLog,
+ )
+ assembly_colorspace_S_Gamut = AssemblyColorspace(
+ "S-Gamut (Sony)",
+ colorspace_gamut_S_Gamut,
+ whitepoint_D65,
+ transfer_function_SLog,
+ )
+ assembly_colorspace_S_Gamut2 = AssemblyColorspace(
+ "S-Gamut2 (Sony)",
+ colorspace_gamut_S_Gamut,
+ whitepoint_D65,
+ transfer_function_SLog2,
+ )
+ assembly_colorspace_S_Gamut3 = AssemblyColorspace(
+ "S-Gamut3 (Sony)",
+ colorspace_gamut_S_Gamut,
+ whitepoint_D65,
+ transfer_function_SLog3,
+ )
+ assembly_colorspace_S_Gamut3_Cine = AssemblyColorspace(
+ "S-Gamut3.Cine (Sony)",
+ colorspace_gamut_S_Gamut3_Cine,
+ whitepoint_D65,
+ transfer_function_SLog3,
+ )
+ assembly_colorspace_V_Gamut = AssemblyColorspace(
+ "V-Gamut (Panasonic)",
+ colorspace_gamut_V_Gamut,
+ whitepoint_D65,
+ transfer_function_VLog,
+ )
+ assembly_colorspace_list = [
+ assembly_colorspace_Passthrough,
+ assembly_colorspace_sRGB_Display_EOTF,
+ assembly_colorspace_sRGB_Display_2_2,
+ assembly_colorspace_sRGB_Linear,
+ assembly_colorspace_BT_709_Display_2_4,
+ assembly_colorspace_DCIP3_Display_2_6,
+ assembly_colorspace_DCIP3_D65_Display_2_6,
+ assembly_colorspace_DCIP3_D60_Display_2_6,
+ assembly_colorspace_Apple_Display_P3,
+ assembly_colorspace_Adobe_RGB_1998_Display,
+ assembly_colorspace_BT_2020_Display_OETF,
+ assembly_colorspace_BT_2020_Linear,
+ assembly_colorspace_DCIP3_Linear,
+ assembly_colorspace_Cinema_Gamut,
+ assembly_colorspace_F_Gamut_FLog,
+ assembly_colorspace_F_Gamut_FLog2,
+ assembly_colorspace_N_Gamut,
+ assembly_colorspace_S_Gamut,
+ assembly_colorspace_S_Gamut2,
+ assembly_colorspace_S_Gamut3,
+ assembly_colorspace_S_Gamut3_Cine,
+ assembly_colorspace_V_Gamut,
+ ]
+
+ config = ColorManagementConfig(
+ colorspaces_gamut=colorspace_gamut_list,
+ whitepoints=whitepoint_list,
+ cats=[
+ Cat("XYZ Scaling"),
+ Cat("Bradford"),
+ Cat("CAT02"),
+ Cat("Von Kries"),
+ ],
+ colorspaces_assemblies=assembly_colorspace_list,
+ transfer_functions=transfer_function_list,
+ )
+ return config
+
+
+class BuildPaths:
+ root = Path(__file__).parent.parent.parent / "obs-script"
+ assert root.exists()
+
+ hlsl_colorscience_root = root / "colorscience"
+ assert hlsl_colorscience_root.exists()
+
+ hlsl_colorscience_cctfa = hlsl_colorscience_root / "cctf-auto.hlsl"
+ hlsl_colorscience_colorspace = hlsl_colorscience_root / "colorspace.hlsl"
+ hlsl_colorscience_gamut = hlsl_colorscience_root / "gamut.hlsl"
+ hlsl_colorscience_cat = hlsl_colorscience_root / "cat.hlsl"
+
+
+def build():
+ LOGGER.info("started build.")
+
+ colormanagement_config = get_config()
+
+ generator_hlsl = colormanagement_config.use_with_generator(HlslGenerator)
+
+ hlsl_code_mapping = {
+ BuildPaths.hlsl_colorscience_cctfa: generator_hlsl.generateTransferFunctionBlock(),
+ BuildPaths.hlsl_colorscience_cat: generator_hlsl.generateCatBlock(),
+ BuildPaths.hlsl_colorscience_gamut: generator_hlsl.generateMatricesBlock(),
+ BuildPaths.hlsl_colorscience_colorspace: generator_hlsl.generateColorspacesBlock(),
+ }
+
+ for target_path, hlsl_code in hlsl_code_mapping.items():
+ hlsl_code = (
+ "// code generated by automatic build; do not manually edit\n" + hlsl_code
+ )
+ LOGGER.info(f"writting <{target_path}> ...")
+ target_path.write_text(hlsl_code)
+
+ LOGGER.info("generating lua code ...")
+ generator_lua = colormanagement_config.use_with_generator(LuaGenerator)
+ lua_code = generator_lua.generateCode()
+ print(lua_code)
+ LOGGER.info("finished build.")
+
+
+if __name__ == "__main__":
+ logging.basicConfig(
+ level=logging.DEBUG,
+ format="{levelname: <7} | {asctime} [{name}] {message}",
+ style="{",
+ stream=sys.stdout,
+ )
+ build()
diff --git a/pyproject.toml b/pyproject.toml
index 05395f0..490b51e 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,13 +1,13 @@
[tool.poetry]
name = "AgXc"
-version = "0.5.3"
+version = "0.6.0"
description = "Fork of Troy.S AgX, a display rendering transform available via OCIO and more."
authors = ["Liam Collod