├── .gitignore ├── LICENSE ├── README.md ├── blink ├── EnvironmentBlur.blink ├── EnvironmentTransform.blink ├── LUTApply.blink ├── LUTApply1D.blink ├── LUTInvert.blink ├── LUTRecover.blink ├── LUTRecover1D.blink ├── LUTRecoverMerge.blink ├── LineIntegral.blink └── scripts │ ├── FilmicTonemappingLut.lut │ ├── FilmicTonemappingLut.tga │ ├── LUTApply.nk │ ├── LUTApply1D.nk │ ├── LUTApply1D_example.lut │ ├── LUTApply_exampleGrade.3dl │ ├── LUTApply_grade.jpg │ ├── LUTApply_identity.jpg │ ├── LUTApply_screenshot.png │ ├── LUTInverse.nk │ ├── LUTInverse_exampleGrade.3dl │ ├── LUTInverse_exampleGrade.jpg │ ├── LUTInverse_identity.jpg │ ├── LUTInverse_inverseGrade.3dl │ ├── LUTInverse_inverseGrade.jpg │ ├── LUTInverse_screenshot.png │ ├── LUTRecover.nk │ ├── LUTRecover1D.nk │ ├── LUTRecoverMerge.nk │ ├── LUTRecoverMerge_recoveredGrade1.3dl │ ├── LUTRecoverMerge_recoveredGrade1.jpg │ ├── LUTRecoverMerge_recoveredGrade2.3dl │ ├── LUTRecoverMerge_recoveredGrade2.jpg │ ├── LUTRecoverMerge_recoveredGrade3.3dl │ ├── LUTRecoverMerge_recoveredGrade3.jpg │ ├── LUTRecover_comparisonGradedImage.jpg │ ├── LUTRecover_gradedImage.jpg │ ├── LUTRecover_identity.jpg │ ├── LUTRecover_rawImage.jpg │ ├── LUTRecover_recoveredGrade.3dl │ ├── LUTRecover_recoveredGrade.jpg │ ├── LUTRecover_screenshot.png │ └── LUTRecover_screenshot2.png ├── hdr ├── README.md ├── curves │ └── thetas.spi1d └── python │ └── mkhdr.py ├── layerlab ├── README.md └── merl-conversion.py ├── lightStage └── mayaLightStageImport.py ├── nuke ├── README.md ├── gizmos │ ├── ColorMatrixPlus.gizmo │ ├── SpectralToRGB.gizmo │ └── SpectralToXYZ.gizmo └── python │ ├── nuke_matrix_transfer.py │ └── spectral_to_xyz.py ├── opencv ├── README.md ├── findOpticalFlow.py └── recoverCameraResponse.py └── touchDesigner ├── README.md ├── scripts ├── nuke_lookup3d_Capture.JPG ├── ramp3d_32_fp.tiff ├── ramp3d_64_fp.tiff ├── touchDesigner_lookup3d_common_parameters_Capture.JPG └── touchDesigner_lookup3d_pixelShader_parameter_Capture.JPG └── touchDesigner_lookup_3d.glsl.txt /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | *.egg-info/ 23 | .installed.cfg 24 | *.egg 25 | 26 | # PyInstaller 27 | # Usually these files are written by a python script from a template 28 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 29 | *.manifest 30 | *.spec 31 | 32 | # Installer logs 33 | pip-log.txt 34 | pip-delete-this-directory.txt 35 | 36 | # Unit test / coverage reports 37 | htmlcov/ 38 | .tox/ 39 | .coverage 40 | .coverage.* 41 | .cache 42 | nosetests.xml 43 | coverage.xml 44 | *,cover 45 | 46 | # Translations 47 | *.mo 48 | *.pot 49 | 50 | # Django stuff: 51 | *.log 52 | 53 | # Sphinx documentation 54 | docs/_build/ 55 | 56 | # PyBuilder 57 | target/ 58 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014-2015 Haarm-Pieter Duiker 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # general 2 | Repo for smaller bits and pieces of code. 3 | -------------------------------------------------------------------------------- /blink/EnvironmentBlur.blink: -------------------------------------------------------------------------------- 1 | // 2 | // A kernel that will blur Spherical environment maps 3 | // 4 | 5 | // 6 | // Functions specific to spherical panoramas 7 | // 8 | float3 spherical_tex2dir(float2 tc) 9 | { 10 | float theta, gamma, u, v; 11 | float3 dir; 12 | 13 | u = tc.x*2 - 1; 14 | v = tc.y*2 - 1; 15 | 16 | theta = u*3.14159; 17 | gamma = v*3.14159f/2.f; 18 | 19 | dir.z = cos(theta)*cos(gamma); 20 | dir.y = sin(gamma); 21 | dir.x = sin(theta)*cos(gamma); 22 | 23 | return dir; 24 | } 25 | 26 | float spherical_solidAngle(int y, int width, int height) 27 | { 28 | float u = (2.f*3.14159f)/width; 29 | float v = sin(float(y+0.5)/height*3.14159f)*(3.14159f/height); 30 | return u*v; 31 | } 32 | 33 | // 34 | // Add the same functions for other panorama types to support those types 35 | // 36 | 37 | // 38 | // kernel 39 | // 40 | kernel EnvironmentBlurKernel : public ImageComputationKernel 41 | { 42 | Image src; 43 | Image dst; 44 | 45 | param: 46 | float phongExponent; 47 | 48 | void define() { 49 | defineParam(phongExponent, "phongExponent", 1.f); 50 | } 51 | 52 | void process(int2 pos) { 53 | SampleType(src) valueSum(0); 54 | ValueType(src) filterSum(0); 55 | 56 | ValueType(src) filter, u, v; 57 | 58 | float3 centerDir, filterDir; 59 | 60 | // The direction for the current pixel 61 | u = float(pos.x + 0.5f)/src.bounds.width(); 62 | v = float(pos.y + 0.5f)/src.bounds.height(); 63 | centerDir = spherical_tex2dir( float2(u, v) ); 64 | 65 | // Would be nice to have a min and max range on the parameter definition 66 | // Not there now, so we just make sure the value doesn't go below 1 67 | // 1 = Lambertian Diffuse 68 | float exponent = max(phongExponent, 1.f); 69 | 70 | //Iterate over the src image rows 71 | for(int j = 0; j < src.bounds.height(); j++) { 72 | 73 | // solid angle is the same for all pixels in a row 74 | float dsa = spherical_solidAngle(j, src.bounds.width(), src.bounds.height()); 75 | 76 | //Iterate over the src image columns 77 | for(int i = 0; i < src.bounds.width(); i++) { 78 | 79 | // The direction for the pixel to be filtered 80 | u = float(i + 0.5f)/src.bounds.width(); 81 | v = float(j + 0.5f)/src.bounds.height(); 82 | filterDir = spherical_tex2dir( float2(u, v) ); 83 | 84 | //Get the filter value 85 | ValueType(src) filterVal = pow(max(dot(centerDir, filterDir), 0.f), exponent)*dsa; 86 | 87 | //Multiply the src value by the corresponding filter weight and accumulate 88 | valueSum += filterVal * src(i, j); 89 | 90 | //Update the filter sum with the current filter value 91 | filterSum += filterVal; 92 | } 93 | } 94 | 95 | //Normalise the value sum, avoiding division by zero 96 | if (filterSum != 0) 97 | valueSum /= filterSum; 98 | 99 | dst() = valueSum; 100 | } 101 | }; 102 | -------------------------------------------------------------------------------- /blink/EnvironmentTransform.blink: -------------------------------------------------------------------------------- 1 | // 2 | // A kernel that will transform between environment map / panorama formats 3 | // 4 | 5 | // The panorama types numbers are 6 | // 0 = Spherical / Lat long map 7 | // 1 = Angular / Angular Map 360 8 | // 2 = Chrome Ball / Mirror Ball 9 | // 3 = Fisheye / 180 degrees fisheye lens 10 | // 4 = Cubic (single image) 11 | 12 | #define M_PI 3.14159265358979323846f 13 | 14 | // acos workaround 15 | // bug reported in email from Mads Lund, madshlund@gmail.com to nuke-users on 2014/06/16 16 | float acosWorkaround(float x) 17 | { 18 | return M_PI/2.f - asin(x); 19 | } 20 | 21 | // 22 | // Functions specific to spherical panoramas 23 | // 24 | float3 spherical_tex2dir(float2 tc) 25 | { 26 | float theta, gamma, u, v; 27 | float3 dir; 28 | 29 | u = tc.x*2.f - 1.f; 30 | v = tc.y*2.f - 1.f; 31 | 32 | theta = u*M_PI; 33 | gamma = v*M_PI/2.f; 34 | 35 | dir.z = cos(theta)*cos(gamma); 36 | dir.y = sin(gamma); 37 | dir.x = sin(theta)*cos(gamma); 38 | 39 | return dir; 40 | } 41 | 42 | float2 spherical_dir2tex(float3 dir) 43 | { 44 | float2 tc; 45 | float theta, gamma; 46 | 47 | gamma = asin(dir.y); 48 | theta = atan2(dir.x, dir.z); 49 | 50 | tc.x = (float)(theta/M_PI); 51 | tc.y = (float)(gamma/(M_PI/2.f)); 52 | 53 | tc = (tc + 1.f)/2.f; 54 | 55 | return tc; 56 | } 57 | 58 | float spherical_solidAngle(int y, int width, int height) 59 | { 60 | float u = (2.f*M_PI)/width; 61 | float v = sin(float(y+0.5)/height*M_PI)*(M_PI/height); 62 | return u*v; 63 | } 64 | 65 | // 66 | // Functions specific to angular panoramas 67 | // 68 | float3 angular_tex2dir(float2 tc) 69 | { 70 | float3 dir; 71 | float theta, gamma; 72 | 73 | tc = tc*2.f - 1.f; 74 | 75 | if( sqrt(tc.x*tc.x + tc.y*tc.y) > 1.f ) 76 | return float3(0.f); 77 | 78 | theta = M_PI*sqrt(tc.x*tc.x + tc.y*tc.y); 79 | gamma = atan2(tc.y, tc.x); 80 | 81 | dir.x = cos(gamma)*sin(theta); 82 | dir.y = sin(gamma)*sin(theta); 83 | dir.z = cos(theta); 84 | 85 | return dir; 86 | } 87 | 88 | float2 angular_dir2tex(float3 dir) 89 | { 90 | float2 tc; 91 | float theta, gamma; 92 | 93 | // using workaround for acos bug 94 | theta = acosWorkaround(dir.z); 95 | gamma = atan2(dir.y, dir.x); 96 | 97 | tc.x = cos(gamma)*theta/M_PI; 98 | tc.y = sin(gamma)*theta/M_PI; 99 | 100 | tc = (tc + 1.f)/2.f; 101 | 102 | return tc; 103 | } 104 | 105 | // 106 | // Functions specific to chrome balls panoramas 107 | // 108 | float3 ball_tex2dir(float2 tc) 109 | { 110 | float3 dir; 111 | float theta, gamma; 112 | 113 | tc = tc*2.f - 1.f; 114 | 115 | if( sqrt(tc.x*tc.x + tc.y*tc.y) > 1.f ) 116 | return float3(0.f); 117 | 118 | theta = asin(sqrt(tc.x*tc.x + tc.y*tc.y)); 119 | gamma = atan2(tc.y, tc.x); 120 | 121 | dir.x = cos(gamma)*sin(2*theta); 122 | dir.y = sin(gamma)*sin(2*theta); 123 | dir.z = cos(2*theta); 124 | 125 | return dir; 126 | } 127 | 128 | float2 ball_dir2tex(float3 dir) 129 | { 130 | float2 tc; 131 | float theta, gamma; 132 | 133 | theta = 0.5f*acosWorkaround(dir.z); 134 | gamma = atan2(dir.y, dir.x); 135 | 136 | tc.x = cos(gamma)*sin(theta); 137 | tc.y = sin(gamma)*sin(theta); 138 | 139 | tc = (tc + 1.f)/2.f; 140 | 141 | return tc; 142 | } 143 | 144 | 145 | // 146 | // Functions specific to Fisheye 180 panoramas 147 | // 148 | float3 fisheye_tex2dir(float2 tc) 149 | { 150 | float3 dir; 151 | float theta, gamma; 152 | 153 | tc = tc*2.f - 1.f; 154 | 155 | if( sqrt(tc.x*tc.x + tc.y*tc.y) > 1.f ) 156 | return float3(0.f); 157 | 158 | theta = M_PI/2.f*sqrt(tc.x*tc.x + tc.y*tc.y); 159 | gamma = atan2(tc.y,tc.x); 160 | 161 | dir.x = cos(gamma)*sin(theta); 162 | dir.y = sin(gamma)*sin(theta); 163 | dir.z = cos(theta); 164 | 165 | return dir; 166 | } 167 | 168 | float2 fisheye_dir2tex(float3 dir) 169 | { 170 | float2 tc; 171 | float theta, gamma; 172 | 173 | if( dir.z < 0.f ) 174 | return float2(0.f); 175 | 176 | theta = acosWorkaround(dir.z); 177 | gamma = atan2(dir.y, dir.x); 178 | 179 | tc.x = cos(gamma)*theta/M_PI*2.f; 180 | tc.y = sin(gamma)*theta/M_PI*2.f; 181 | 182 | tc = (tc + 1.f)/2.f; 183 | 184 | return tc; 185 | } 186 | 187 | // 188 | // Functions specific to cubic panoramas 189 | // 190 | float2 cubic_dir2tex(float3 dir) 191 | { 192 | float2 tc; 193 | float theta, gamma; 194 | 195 | theta = atan2(dir.x, -dir.z); 196 | gamma = asin(dir.y); 197 | 198 | const float quarterPi = (float)M_PI/4.f; 199 | 200 | float rotationOffset; 201 | float textureOffset; 202 | float textureXScale; 203 | float textureYScale; 204 | 205 | rotationOffset = 0.f; 206 | textureOffset = 0.f; 207 | textureXScale = 1.f; 208 | textureYScale = 1.f; 209 | 210 | // -Z 211 | if( ( theta >= -quarterPi && theta < quarterPi ) ) 212 | { 213 | rotationOffset = 0.f; 214 | textureOffset = 0.f; 215 | 216 | textureXScale = -1.f; 217 | } 218 | 219 | // +X 220 | else if( ( theta >= quarterPi && theta < 3.f*quarterPi ) || 221 | ( theta >= -7.f*quarterPi && theta < -5.f*quarterPi ) ) 222 | { 223 | if( theta >= quarterPi && theta < 3.f*quarterPi ) 224 | { 225 | rotationOffset = 2.f; 226 | textureOffset = 4.f; 227 | } 228 | else 229 | { 230 | rotationOffset = -6.f; 231 | textureOffset = 4.f; 232 | } 233 | 234 | textureXScale = -1.f; 235 | } 236 | 237 | // +Z 238 | else if( ( theta >= 3.f*quarterPi && theta < 5.f*quarterPi ) || 239 | ( theta >= -5.f*quarterPi && theta < -3.f*quarterPi ) ) 240 | { 241 | if( theta >= 3.f*quarterPi && theta < 5.f*quarterPi ) 242 | { 243 | rotationOffset = 4.f; 244 | textureOffset = 1.f; 245 | } 246 | else 247 | { 248 | rotationOffset = -4.f; 249 | textureOffset = 1.f; 250 | } 251 | 252 | textureXScale = -1.f; 253 | } 254 | 255 | // -X 256 | else if( ( theta >= 5.f*quarterPi && theta < 7.f*quarterPi ) || 257 | ( theta >= -3.f*quarterPi && theta < -1.f*quarterPi ) ) 258 | { 259 | if( theta >= 5.f*quarterPi && theta < 7.f*quarterPi ) 260 | { 261 | rotationOffset = 6.f; 262 | textureOffset = 5.f; 263 | } 264 | else 265 | { 266 | rotationOffset = -2.f; 267 | textureOffset = 5.f; 268 | } 269 | 270 | textureXScale = -1.f; 271 | } 272 | 273 | theta = theta - rotationOffset*quarterPi; 274 | 275 | float u, v, w, h; 276 | h = cos(gamma); 277 | u = sin(theta) * h; 278 | v = sin(gamma); 279 | w = cos(theta) * h; 280 | 281 | tc.x = u/w; 282 | tc.y = v/w; 283 | 284 | // -Y 285 | if( tc.y <= -1.f ) 286 | { 287 | //float otc = tc.y; 288 | theta = atan2(dir.x, -dir.y); 289 | gamma = asin(+dir.z); 290 | 291 | h = cos(gamma); 292 | u = sin(theta) * h; 293 | v = sin(gamma); 294 | w = cos(theta) * h; 295 | 296 | tc.x = u/w; 297 | tc.y = v/w; 298 | 299 | textureXScale = 1.f; 300 | textureOffset = 2.f; 301 | 302 | //tc.y = otc; 303 | tc.y = clamp(tc.y, -0.999f, 0.999f); 304 | } 305 | 306 | // +Y 307 | if( tc.y >= 1.f ) 308 | { 309 | theta = atan2(dir.x, dir.y); 310 | gamma = asin(-dir.z); 311 | 312 | h = cos(gamma); 313 | u = sin(theta) * h; 314 | v = sin(gamma); 315 | w = cos(theta) * h; 316 | 317 | tc.x = u/w; 318 | tc.y = v/w; 319 | 320 | textureXScale = 1.f; 321 | textureOffset = 3.f; 322 | 323 | tc.y = clamp(tc.y, -0.999f, 0.999f); 324 | } 325 | 326 | tc.x = clamp(tc.x, -1.f, 1.f); 327 | tc.y = clamp(tc.y, -1.f, 1.f); 328 | 329 | tc.x *= textureXScale; 330 | tc.y *= textureYScale; 331 | 332 | tc = (tc + 1.f)/2.f; 333 | tc = clamp(tc, float2(0.f), float2(1.f)); 334 | tc.y += textureOffset; 335 | tc.y /= 6.f; 336 | 337 | return tc; 338 | } 339 | 340 | float3 cubic_tex2dir(float2 tc) 341 | { 342 | float3 dir; 343 | 344 | float os = 1.f/6.f; 345 | 346 | // -X 347 | if( tc.y > (1.f-os) ) 348 | { 349 | tc.y *= 6.f; 350 | tc.y -= 5.f; 351 | 352 | tc = clamp(tc, float2(0.f), float2(1.f)); 353 | tc = tc*2.f - 1.f; 354 | 355 | float3 udir = float3(-1.f, tc.y, tc.x); 356 | dir = udir/sqrt(udir.x*udir.x + udir.y*udir.y + udir.z*udir.z); 357 | 358 | } 359 | 360 | // +X 361 | else if( tc.y > (1.f-2*os) ) 362 | { 363 | tc.y *= 6.f; 364 | tc.y -= 4.f; 365 | 366 | tc = clamp(tc, float2(0.f), float2(1.f)); 367 | tc = tc*2.f - 1.f; 368 | 369 | float3 udir = float3( 1.f, tc.y, -tc.x); 370 | dir = udir/sqrt(udir.x*udir.x + udir.y*udir.y + udir.z*udir.z); 371 | } 372 | 373 | // +Y 374 | else if( tc.y > (1.f-3*os) ) 375 | { 376 | tc.y *= 6.f; 377 | tc.y -= 3.f; 378 | 379 | tc = clamp(tc, float2(0.f), float2(1.f)); 380 | tc = tc*2.f - 1.f; 381 | 382 | float3 udir = float3( tc.x, 1.f, -tc.y); 383 | dir = udir/sqrt(udir.x*udir.x + udir.y*udir.y + udir.z*udir.z); 384 | } 385 | 386 | // -Y 387 | else if( tc.y > (1.f-4*os) ) 388 | { 389 | tc.y *= 6.f; 390 | tc.y -= 2.f; 391 | 392 | tc = clamp(tc, float2(0.f), float2(1.f)); 393 | tc = tc*2.f - 1.f; 394 | 395 | float3 udir = float3( tc.x, -1.f, tc.y); 396 | dir = udir/sqrt(udir.x*udir.x + udir.y*udir.y + udir.z*udir.z); 397 | } 398 | 399 | // +Z 400 | else if( tc.y > (1.f-5*os) ) 401 | { 402 | tc.y *= 6.f; 403 | tc.y -= 1.f; 404 | 405 | tc = clamp(tc, float2(0.f), float2(1.f)); 406 | tc = tc*2.f - 1.f; 407 | 408 | float3 udir = float3( tc.x, tc.y, 1.f); 409 | dir = udir/sqrt(udir.x*udir.x + udir.y*udir.y + udir.z*udir.z); 410 | } 411 | 412 | // -Z 413 | else // if( tc.y < 6*os ) 414 | { 415 | tc.y *= 6.f; 416 | tc.y -= 0.f; 417 | 418 | tc = clamp(tc, float2(0.f), float2(1.f)); 419 | tc = tc*2.f - 1.f; 420 | 421 | float3 udir = float3(-tc.x, tc.y, -1.f); 422 | dir = udir/sqrt(udir.x*udir.x + udir.y*udir.y + udir.z*udir.z); 423 | } 424 | 425 | return dir; 426 | } 427 | 428 | 429 | // 430 | // Add the same functions for other panorama types to support those types 431 | // 432 | 433 | // 434 | // kernel 435 | // 436 | kernel EnvironmentTransformKernel : public ImageComputationKernel 437 | { 438 | Image src; 439 | Image dst; 440 | 441 | param: 442 | int panoramaInput; 443 | int panoramaOutput; 444 | int sampling; 445 | 446 | void define() { 447 | defineParam(panoramaInput, "panoramaInput", 0); 448 | defineParam(panoramaOutput, "panoramaOutput", 1); 449 | defineParam(sampling, "sampling", 1); 450 | } 451 | 452 | void process(int2 pos) { 453 | SampleType(src) valueSum(0); 454 | 455 | SampleType(src) filterSum(0); 456 | ValueType(src) filter; 457 | 458 | float u, v; 459 | 460 | // Have to sample at least once 461 | int os = max(1, sampling); 462 | 463 | float filterVal = 1.f/float(os*os); 464 | 465 | // 466 | // Oversampling loop 467 | // 468 | // No oversampling option 469 | //int osx = 0; 470 | //int osy = 0; 471 | 472 | for(int osx = 0; osx < os; osx++) 473 | { 474 | for(int osy = 0; osy < os; osy++) 475 | { 476 | // 477 | // Compute the direction for the output pixel 478 | // 479 | float3 outputDir; 480 | 481 | // Using the src width and height because there seems to be some 482 | // issue if you choose a different output format 483 | // Once those are fixed, this should use dst.bounds width and height 484 | u = float(pos.x + (1.f/(2.f*os)) + (1.f/os)*osx)/(src.bounds.width()); 485 | v = float(pos.y + (1.f/(2.f*os)) + (1.f/os)*osy)/(src.bounds.height()); 486 | 487 | // No oversampling option 488 | //u = float(pos.x + 0.5f)/(src.bounds.width()); 489 | //v = float(pos.y + 0.5f)/(src.bounds.height()); 490 | 491 | if( panoramaOutput == 0 ) 492 | { 493 | outputDir = spherical_tex2dir( float2(u, v) ); 494 | } 495 | else if( panoramaOutput == 1 ) 496 | { 497 | outputDir = angular_tex2dir( float2(u, v) ); 498 | } 499 | else if( panoramaOutput == 2 ) 500 | { 501 | outputDir = ball_tex2dir( float2(u, v) ); 502 | } 503 | else if( panoramaOutput == 3 ) 504 | { 505 | outputDir = fisheye_tex2dir( float2(u, v) ); 506 | } 507 | else if( panoramaOutput == 4 ) 508 | { 509 | outputDir = cubic_tex2dir( float2(u, v) ); 510 | } 511 | else 512 | { 513 | outputDir = float3(0.0, 0.0, -1.0); 514 | } 515 | 516 | // 517 | // Compute the texture coordinate for the input panorama 518 | // 519 | float2 inputUV; 520 | if( panoramaInput == 0 ) 521 | { 522 | inputUV = spherical_dir2tex( outputDir ); 523 | } 524 | else if( panoramaInput == 1 ) 525 | { 526 | inputUV = angular_dir2tex( outputDir ); 527 | } 528 | else if( panoramaInput == 2 ) 529 | { 530 | inputUV = ball_dir2tex( outputDir ); 531 | } 532 | else if( panoramaInput == 3 ) 533 | { 534 | inputUV = fisheye_dir2tex( outputDir ); 535 | } 536 | else if( panoramaInput == 4 ) 537 | { 538 | inputUV = cubic_dir2tex( outputDir ); 539 | } 540 | else 541 | { 542 | inputUV = float2(0.0, 0.0); 543 | } 544 | 545 | int i, j; 546 | i = int(floor(inputUV.x * (src.bounds.width())) ); 547 | j = int(floor(inputUV.y * (src.bounds.height())) ); 548 | 549 | i = min(i, int(src.bounds.width()-1)); 550 | j = min(j, int(src.bounds.height()-1)); 551 | 552 | valueSum += filterVal * src(i, j); 553 | 554 | // 555 | // Debugging options 556 | // 557 | if( sampling == -1 ) 558 | { 559 | valueSum.x = outputDir.x; 560 | valueSum.y = outputDir.y; 561 | valueSum.z = outputDir.z; 562 | } 563 | else if( sampling == -2 ) 564 | { 565 | valueSum.x = inputUV.x; 566 | valueSum.y = inputUV.y; 567 | valueSum.z = filterVal; 568 | } 569 | else if( sampling == -3 ) 570 | { 571 | valueSum.x = float(pos.x); 572 | valueSum.y = float(pos.y); 573 | valueSum.z = 0.f; 574 | } 575 | else if( sampling == -4 ) 576 | { 577 | valueSum.x = u; 578 | valueSum.y = v; 579 | valueSum.z = 0.f; 580 | } 581 | else if( sampling == -5 ) 582 | { 583 | valueSum.x = float(i); 584 | valueSum.y = float(j); 585 | valueSum.z = 0.f; 586 | } 587 | else if( sampling == -6 ) 588 | { 589 | valueSum.x = pos.x; 590 | valueSum.y = pos.y; 591 | valueSum.z = 0.f; 592 | } 593 | else if( sampling == -7 ) 594 | { 595 | valueSum.x = u * src.bounds.width(); 596 | valueSum.y = v * src.bounds.height(); 597 | valueSum.z = 0.f; 598 | } 599 | else if( sampling == -8 ) 600 | { 601 | valueSum.x = inputUV.x * src.bounds.width(); 602 | valueSum.y = inputUV.y * src.bounds.height(); 603 | valueSum.z = 0.f; 604 | } 605 | else if( sampling == -9 ) 606 | { 607 | valueSum.x = u * src.bounds.width() - (inputUV.x * src.bounds.width()); 608 | valueSum.y = v * src.bounds.height() - (inputUV.y * src.bounds.height()); 609 | valueSum.z = 0.f; 610 | } 611 | } 612 | } 613 | 614 | dst() = valueSum; 615 | } 616 | }; 617 | -------------------------------------------------------------------------------- /blink/LUTApply.blink: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2014-2015 Haarm-Pieter Duiker 3 | // 4 | 5 | // 6 | // A kernel that will apply 3d LUT to an image. The 3d LUT is represented as the Nuke cmsTestPattern 7 | // 8 | 9 | // 10 | // Map from a 3D LUT position to 2D pixel coordinate in the CMSTestPattern image 11 | // 12 | int2 position3dToNukePosition(int3 pos, int width, int height, int nukeBlockSize, int lutResolution) { 13 | int2 position; 14 | 15 | int pixel = (pos.z*lutResolution*lutResolution + pos.y*lutResolution + pos.x); 16 | 17 | position.x = (pixel%(width/nukeBlockSize))*nukeBlockSize; 18 | position.y = (pixel/(width/nukeBlockSize))*nukeBlockSize; 19 | 20 | // Put the position in the middle of the nukeBlockSize x nukeBlockSize block 21 | position += nukeBlockSize/2; 22 | 23 | return position; 24 | } 25 | 26 | // Utility 27 | float4 mix(float4 a, float4 b, float f) { 28 | float4 mixed; 29 | mixed.x = a.x*(1.f - f) + b.x*f; 30 | mixed.y = a.y*(1.f - f) + b.y*f; 31 | mixed.z = a.z*(1.f - f) + b.z*f; 32 | mixed.w = a.w*(1.f - f) + b.w*f; 33 | return mixed; 34 | } 35 | 36 | // 37 | // kernel 38 | // 39 | kernel LUTApplyKernel : public ImageComputationKernel 40 | { 41 | Image src; 42 | Image cmsPattern; 43 | Image dst; 44 | 45 | param: 46 | int interpolation; 47 | 48 | local: 49 | int lutResolution; 50 | int nukeBlockSize; 51 | 52 | void define() { 53 | // unused for now. 54 | defineParam(interpolation, "interpolation", 2); 55 | } 56 | 57 | void init() { 58 | // The Nuke CMSTestPattern node generates 7x7 pixel blocks for each LUT entry 59 | nukeBlockSize = 7; 60 | float pixels = cmsPattern.bounds.width() * cmsPattern.bounds.height() / (nukeBlockSize * nukeBlockSize); 61 | lutResolution = int(floor(pow(pixels, 0.333333333334f))); 62 | } 63 | 64 | void process(int2 pos) { 65 | SampleType(cmsPattern) cmsSample; 66 | 67 | // Sample the src image 68 | SampleType(src) srcSample; 69 | srcSample = src(pos.x, pos.y); 70 | 71 | // Use the 3D LUT to find the new value 72 | 73 | // Nearest point 74 | if( interpolation == 0 ) { 75 | int3 srcLUTPosition; 76 | srcLUTPosition.x = round(clamp(srcSample.x, 0.0f, 1.0f) * (lutResolution-1)); 77 | srcLUTPosition.y = round(clamp(srcSample.y, 0.0f, 1.0f) * (lutResolution-1)); 78 | srcLUTPosition.z = round(clamp(srcSample.z, 0.0f, 1.0f) * (lutResolution-1)); 79 | 80 | int2 cmsSamplePosition; 81 | cmsSamplePosition = position3dToNukePosition(srcLUTPosition, 82 | cmsPattern.bounds.width(), cmsPattern.bounds.height(), nukeBlockSize, lutResolution); 83 | 84 | cmsSample = cmsPattern(cmsSamplePosition.x, cmsSamplePosition.y); 85 | } // nearest 86 | 87 | // Tri-linear interpolation 88 | else if( interpolation == 1 ) { 89 | float3 srcSample3; 90 | srcSample3.x = srcSample.x; 91 | srcSample3.y = srcSample.y; 92 | srcSample3.z = srcSample.z; 93 | 94 | srcSample3 = clamp(srcSample3, float3(0.f), float3(1.f)); 95 | 96 | // index values interpolation factor for RGB 97 | float indexRf = (srcSample3.x * (lutResolution-1)); 98 | int indexR = int(floor(indexRf)); 99 | float interpR = indexRf - indexR; 100 | float indexRfb = floor(indexRf) / (lutResolution-1); 101 | 102 | float indexGf = (srcSample3.y * (lutResolution-1)); 103 | int indexG = int(floor(indexGf)); 104 | float interpG = indexGf - indexG; 105 | float indexGfb = floor(indexGf) / (lutResolution-1); 106 | 107 | float indexBf = (srcSample3.z * (lutResolution-1)); 108 | int indexB = int(floor(indexBf)); 109 | float interpB = indexBf - indexB; 110 | float indexBfb = floor(indexBf) / (lutResolution-1); 111 | 112 | SampleType(cmsPattern) cmsSamples[8]; 113 | int2 cmsSamplePosition; 114 | 115 | // sample r, g, b 116 | cmsSamplePosition = position3dToNukePosition(int3(indexR , indexG , indexB ), 117 | cmsPattern.bounds.width(), cmsPattern.bounds.height(), nukeBlockSize, lutResolution); 118 | cmsSamples[0] = cmsPattern(cmsSamplePosition.x, cmsSamplePosition.y); 119 | 120 | // sample r, g, b+1 121 | cmsSamplePosition = position3dToNukePosition(int3(indexR , indexG , indexB + 1), 122 | cmsPattern.bounds.width(), cmsPattern.bounds.height(), nukeBlockSize, lutResolution); 123 | cmsSamples[1] = cmsPattern(cmsSamplePosition.x, cmsSamplePosition.y); 124 | 125 | // sample r, g+1, b 126 | cmsSamplePosition = position3dToNukePosition(int3(indexR , indexG + 1, indexB ), 127 | cmsPattern.bounds.width(), cmsPattern.bounds.height(), nukeBlockSize, lutResolution); 128 | cmsSamples[2] = cmsPattern(cmsSamplePosition.x, cmsSamplePosition.y); 129 | 130 | // sample r, g+1, b+1 131 | cmsSamplePosition = position3dToNukePosition(int3(indexR , indexG + 1, indexB + 1), 132 | cmsPattern.bounds.width(), cmsPattern.bounds.height(), nukeBlockSize, lutResolution); 133 | cmsSamples[3] = cmsPattern(cmsSamplePosition.x, cmsSamplePosition.y); 134 | 135 | // sample r+1, g, b 136 | cmsSamplePosition = position3dToNukePosition(int3(indexR + 1, indexG , indexB ), 137 | cmsPattern.bounds.width(), cmsPattern.bounds.height(), nukeBlockSize, lutResolution); 138 | cmsSamples[4] = cmsPattern(cmsSamplePosition.x, cmsSamplePosition.y); 139 | 140 | // sample r+1, g, b+1 141 | cmsSamplePosition = position3dToNukePosition(int3(indexR + 1, indexG , indexB + 1), 142 | cmsPattern.bounds.width(), cmsPattern.bounds.height(), nukeBlockSize, lutResolution); 143 | cmsSamples[5] = cmsPattern(cmsSamplePosition.x, cmsSamplePosition.y); 144 | 145 | // sample r+1, g+1, b 146 | cmsSamplePosition = position3dToNukePosition(int3(indexR + 1, indexG + 1, indexB ), 147 | cmsPattern.bounds.width(), cmsPattern.bounds.height(), nukeBlockSize, lutResolution); 148 | cmsSamples[6] = cmsPattern(cmsSamplePosition.x, cmsSamplePosition.y); 149 | 150 | // sample r+1, g+1, b+1 151 | cmsSamplePosition = position3dToNukePosition(int3(indexR + 1, indexG + 1, indexB + 1), 152 | cmsPattern.bounds.width(), cmsPattern.bounds.height(), nukeBlockSize, lutResolution); 153 | cmsSamples[7] = cmsPattern(cmsSamplePosition.x, cmsSamplePosition.y); 154 | 155 | // Interpolate along the 4 lines in B 156 | cmsSamples[0] = mix(cmsSamples[0], cmsSamples[1], interpB); 157 | cmsSamples[2] = mix(cmsSamples[2], cmsSamples[3], interpB); 158 | cmsSamples[4] = mix(cmsSamples[4], cmsSamples[5], interpB); 159 | cmsSamples[6] = mix(cmsSamples[6], cmsSamples[7], interpB); 160 | 161 | // Interpolate along the 2 lines in G 162 | cmsSamples[0] = mix(cmsSamples[0], cmsSamples[2], interpG); 163 | cmsSamples[4] = mix(cmsSamples[4], cmsSamples[6], interpG); 164 | 165 | // Interpolate along the 1 line in R 166 | cmsSamples[0] = mix(cmsSamples[0], cmsSamples[4], interpR); 167 | 168 | cmsSample = cmsSamples[0]; 169 | } // tri-linear 170 | 171 | // Tetrahedral interpolation 172 | else if( interpolation == 2 ) { 173 | float3 srcSample3; 174 | srcSample3.x = srcSample.x; 175 | srcSample3.y = srcSample.y; 176 | srcSample3.z = srcSample.z; 177 | 178 | srcSample3 = clamp(srcSample3, float3(0.f), float3(1.f)); 179 | 180 | // index values interpolation factor for RGB 181 | float indexRf = (srcSample3.x * (lutResolution-1)); 182 | int indexR = int(floor(indexRf)); 183 | float interpR = indexRf - indexR; 184 | float indexRfb = floor(indexRf) / (lutResolution-1); 185 | 186 | float indexGf = (srcSample3.y * (lutResolution-1)); 187 | int indexG = int(floor(indexGf)); 188 | float interpG = indexGf - indexG; 189 | float indexGfb = floor(indexGf) / (lutResolution-1); 190 | 191 | float indexBf = (srcSample3.z * (lutResolution-1)); 192 | int indexB = int(floor(indexBf)); 193 | float interpB = indexBf - indexB; 194 | float indexBfb = floor(indexBf) / (lutResolution-1); 195 | 196 | SampleType(cmsPattern) cmsSamples[8]; 197 | int2 cmsSamplePosition; 198 | 199 | // sample r, g, b 200 | cmsSamplePosition = position3dToNukePosition(int3(indexR , indexG , indexB ), 201 | cmsPattern.bounds.width(), cmsPattern.bounds.height(), nukeBlockSize, lutResolution); 202 | cmsSamples[0] = cmsPattern(cmsSamplePosition.x, cmsSamplePosition.y); 203 | 204 | // sample r, g, b+1 205 | cmsSamplePosition = position3dToNukePosition(int3(indexR , indexG , indexB + 1), 206 | cmsPattern.bounds.width(), cmsPattern.bounds.height(), nukeBlockSize, lutResolution); 207 | cmsSamples[1] = cmsPattern(cmsSamplePosition.x, cmsSamplePosition.y); 208 | 209 | // sample r, g+1, b 210 | cmsSamplePosition = position3dToNukePosition(int3(indexR , indexG + 1, indexB ), 211 | cmsPattern.bounds.width(), cmsPattern.bounds.height(), nukeBlockSize, lutResolution); 212 | cmsSamples[2] = cmsPattern(cmsSamplePosition.x, cmsSamplePosition.y); 213 | 214 | // sample r, g+1, b+1 215 | cmsSamplePosition = position3dToNukePosition(int3(indexR , indexG + 1, indexB + 1), 216 | cmsPattern.bounds.width(), cmsPattern.bounds.height(), nukeBlockSize, lutResolution); 217 | cmsSamples[3] = cmsPattern(cmsSamplePosition.x, cmsSamplePosition.y); 218 | 219 | // sample r+1, g, b 220 | cmsSamplePosition = position3dToNukePosition(int3(indexR + 1, indexG , indexB ), 221 | cmsPattern.bounds.width(), cmsPattern.bounds.height(), nukeBlockSize, lutResolution); 222 | cmsSamples[4] = cmsPattern(cmsSamplePosition.x, cmsSamplePosition.y); 223 | 224 | // sample r+1, g, b+1 225 | cmsSamplePosition = position3dToNukePosition(int3(indexR + 1, indexG , indexB + 1), 226 | cmsPattern.bounds.width(), cmsPattern.bounds.height(), nukeBlockSize, lutResolution); 227 | cmsSamples[5] = cmsPattern(cmsSamplePosition.x, cmsSamplePosition.y); 228 | 229 | // sample r+1, g+1, b 230 | cmsSamplePosition = position3dToNukePosition(int3(indexR + 1, indexG + 1, indexB ), 231 | cmsPattern.bounds.width(), cmsPattern.bounds.height(), nukeBlockSize, lutResolution); 232 | cmsSamples[6] = cmsPattern(cmsSamplePosition.x, cmsSamplePosition.y); 233 | 234 | // sample r+1, g+1, b+1 235 | cmsSamplePosition = position3dToNukePosition(int3(indexR + 1, indexG + 1, indexB + 1), 236 | cmsPattern.bounds.width(), cmsPattern.bounds.height(), nukeBlockSize, lutResolution); 237 | cmsSamples[7] = cmsPattern(cmsSamplePosition.x, cmsSamplePosition.y); 238 | 239 | // Tetrahedral interoplation, as described by: 240 | // http://www.filmlight.ltd.uk/pdf/whitepapers/FL-TL-TN-0057-SoftwareLib.pdf 241 | // http://blogs.mathworks.com/steve/2006/11/24/tetrahedral-interpolation-for-colorspace-conversion/ 242 | // http://www.hpl.hp.com/techreports/98/HPL-98-95.html 243 | // Reference implementation from OCIO 244 | // https://github.com/imageworks/OpenColorIO/blob/master/src/core/Lut3DOp.cpp#L294 245 | 246 | // Rebind for consistency with Truelight paper 247 | float fx = interpR; 248 | float fy = interpG; 249 | float fz = interpB; 250 | 251 | SampleType(cmsPattern) startPos[8]; 252 | startPos[0] = cmsSamples[0]; 253 | startPos[1] = cmsSamples[1]; 254 | startPos[2] = cmsSamples[2]; 255 | startPos[3] = cmsSamples[3]; 256 | startPos[4] = cmsSamples[4]; 257 | startPos[5] = cmsSamples[5]; 258 | startPos[6] = cmsSamples[6]; 259 | startPos[7] = cmsSamples[7]; 260 | 261 | SampleType(cmsPattern) rgbaBuffer; 262 | 263 | // Compute index into LUT for surrounding corners 264 | const int n000 = 0; 265 | const int n100 = 4; 266 | const int n010 = 2; 267 | const int n001 = 1; 268 | const int n110 = 6; 269 | const int n101 = 5; 270 | const int n011 = 3; 271 | const int n111 = 7; 272 | 273 | if (fx > fy) { 274 | if (fy > fz) { 275 | rgbaBuffer.x = 276 | (1-fx) * startPos[n000].x + 277 | (fx-fy) * startPos[n100].x + 278 | (fy-fz) * startPos[n110].x + 279 | (fz) * startPos[n111].x; 280 | 281 | rgbaBuffer.y = 282 | (1-fx) * startPos[n000].y + 283 | (fx-fy) * startPos[n100].y + 284 | (fy-fz) * startPos[n110].y + 285 | (fz) * startPos[n111].y; 286 | 287 | rgbaBuffer.z = 288 | (1-fx) * startPos[n000].z + 289 | (fx-fy) * startPos[n100].z + 290 | (fy-fz) * startPos[n110].z + 291 | (fz) * startPos[n111].z; 292 | } 293 | else if (fx > fz) 294 | { 295 | rgbaBuffer.x = 296 | (1-fx) * startPos[n000].x + 297 | (fx-fz) * startPos[n100].x + 298 | (fz-fy) * startPos[n101].x + 299 | (fy) * startPos[n111].x; 300 | 301 | rgbaBuffer.y = 302 | (1-fx) * startPos[n000].y + 303 | (fx-fz) * startPos[n100].y + 304 | (fz-fy) * startPos[n101].y + 305 | (fy) * startPos[n111].y; 306 | 307 | rgbaBuffer.z = 308 | (1-fx) * startPos[n000].z + 309 | (fx-fz) * startPos[n100].z + 310 | (fz-fy) * startPos[n101].z + 311 | (fy) * startPos[n111].z; 312 | } 313 | else 314 | { 315 | rgbaBuffer.x = 316 | (1-fz) * startPos[n000].x + 317 | (fz-fx) * startPos[n001].x + 318 | (fx-fy) * startPos[n101].x + 319 | (fy) * startPos[n111].x; 320 | 321 | rgbaBuffer.y = 322 | (1-fz) * startPos[n000].y + 323 | (fz-fx) * startPos[n001].y + 324 | (fx-fy) * startPos[n101].y + 325 | (fy) * startPos[n111].y; 326 | 327 | rgbaBuffer.z = 328 | (1-fz) * startPos[n000].z + 329 | (fz-fx) * startPos[n001].z + 330 | (fx-fy) * startPos[n101].z + 331 | (fy) * startPos[n111].z; 332 | } 333 | } 334 | else 335 | { 336 | if (fz > fy) 337 | { 338 | rgbaBuffer.x = 339 | (1-fz) * startPos[n000].x + 340 | (fz-fy) * startPos[n001].x + 341 | (fy-fx) * startPos[n011].x + 342 | (fx) * startPos[n111].x; 343 | 344 | rgbaBuffer.y = 345 | (1-fz) * startPos[n000].y + 346 | (fz-fy) * startPos[n001].y + 347 | (fy-fx) * startPos[n011].y + 348 | (fx) * startPos[n111].y; 349 | 350 | rgbaBuffer.z = 351 | (1-fz) * startPos[n000].z + 352 | (fz-fy) * startPos[n001].z + 353 | (fy-fx) * startPos[n011].z + 354 | (fx) * startPos[n111].z; 355 | } 356 | else if (fz > fx) 357 | { 358 | rgbaBuffer.x = 359 | (1-fy) * startPos[n000].x + 360 | (fy-fz) * startPos[n010].x + 361 | (fz-fx) * startPos[n011].x + 362 | (fx) * startPos[n111].x; 363 | 364 | rgbaBuffer.y = 365 | (1-fy) * startPos[n000].y + 366 | (fy-fz) * startPos[n010].y + 367 | (fz-fx) * startPos[n011].y + 368 | (fx) * startPos[n111].y; 369 | 370 | rgbaBuffer.z = 371 | (1-fy) * startPos[n000].z + 372 | (fy-fz) * startPos[n010].z + 373 | (fz-fx) * startPos[n011].z + 374 | (fx) * startPos[n111].z; 375 | } 376 | else 377 | { 378 | rgbaBuffer.x = 379 | (1-fy) * startPos[n000].x + 380 | (fy-fx) * startPos[n010].x + 381 | (fx-fz) * startPos[n110].x + 382 | (fz) * startPos[n111].x; 383 | 384 | rgbaBuffer.y = 385 | (1-fy) * startPos[n000].y + 386 | (fy-fx) * startPos[n010].y + 387 | (fx-fz) * startPos[n110].y + 388 | (fz) * startPos[n111].y; 389 | 390 | rgbaBuffer.z = 391 | (1-fy) * startPos[n000].z + 392 | (fy-fx) * startPos[n010].z + 393 | (fx-fz) * startPos[n110].z + 394 | (fz) * startPos[n111].z; 395 | } 396 | } 397 | 398 | cmsSample = rgbaBuffer; 399 | 400 | } // tetrahedral 401 | 402 | // Write the new value to dst 403 | SampleType(dst) t; 404 | t.x = cmsSample.x; 405 | t.y = cmsSample.y; 406 | t.z = cmsSample.z; 407 | 408 | dst() = t; 409 | } 410 | }; 411 | -------------------------------------------------------------------------------- /blink/LUTApply1D.blink: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2014-2015 Haarm-Pieter Duiker 3 | // 4 | 5 | // 6 | // A kernel that will apply 1d LUT to an image. The 1d LUT is represented as a linear ramp image 7 | // 8 | 9 | // Utility 10 | float4 mix(float4 a, float4 b, float4 f) { 11 | float4 mixed; 12 | mixed.x = a.x*(1.f - f.x) + b.x*f.x; 13 | mixed.y = a.y*(1.f - f.y) + b.y*f.y; 14 | mixed.z = a.z*(1.f - f.z) + b.z*f.z; 15 | mixed.w = a.w*(1.f - f.w) + b.w*f.w; 16 | return mixed; 17 | } 18 | 19 | // 20 | // kernel 21 | // 22 | kernel LUTApply1DKernel : public ImageComputationKernel 23 | { 24 | Image src; 25 | Image lut1dImage; 26 | Image dst; 27 | 28 | param: 29 | int interpolation; 30 | 31 | local: 32 | int lutResolution; 33 | 34 | void define() { 35 | defineParam(interpolation, "interpolation", 1); 36 | } 37 | 38 | void init() { 39 | float pixels = lut1dImage.bounds.width(); 40 | lutResolution = int(pixels); 41 | } 42 | 43 | void process(int2 pos) { 44 | SampleType(lut1dImage) lut1dImageSample; 45 | 46 | // Sample the src image 47 | SampleType(src) srcSample; 48 | srcSample = src(pos.x, pos.y); 49 | 50 | lut1dImageSample.x = 0.f; 51 | lut1dImageSample.y = 0.f; 52 | lut1dImageSample.z = 0.f; 53 | 54 | // Use the 1D LUT to find the new value 55 | 56 | // Nearest point 57 | if( interpolation == 0 ) { 58 | int3 srcLUTPosition; 59 | srcLUTPosition.x = round(clamp(srcSample.x, 0.0f, 1.0f) * (lutResolution-1)); 60 | srcLUTPosition.y = round(clamp(srcSample.y, 0.0f, 1.0f) * (lutResolution-1)); 61 | srcLUTPosition.z = round(clamp(srcSample.z, 0.0f, 1.0f) * (lutResolution-1)); 62 | 63 | lut1dImageSample = lut1dImage(srcLUTPosition.x, 0); 64 | float r = lut1dImageSample.x; 65 | lut1dImageSample = lut1dImage(srcLUTPosition.y, 0); 66 | float g = lut1dImageSample.y; 67 | lut1dImageSample = lut1dImage(srcLUTPosition.z, 0); 68 | float b = lut1dImageSample.z; 69 | 70 | lut1dImageSample.x = r; 71 | lut1dImageSample.y = g; 72 | lut1dImageSample.z = b; 73 | } // nearest 74 | 75 | // Bi-linear interpolation 76 | else if( interpolation == 1 ) { 77 | int3 srcLUTPosition[2]; 78 | srcLUTPosition[0].x = floor(clamp(srcSample.x, 0.0f, 1.0f) * (lutResolution-1)); 79 | srcLUTPosition[0].y = floor(clamp(srcSample.y, 0.0f, 1.0f) * (lutResolution-1)); 80 | srcLUTPosition[0].z = floor(clamp(srcSample.z, 0.0f, 1.0f) * (lutResolution-1)); 81 | 82 | srcLUTPosition[1].x = ceil(clamp(srcSample.x, 0.0f, 1.0f) * (lutResolution-1)); 83 | srcLUTPosition[1].y = ceil(clamp(srcSample.y, 0.0f, 1.0f) * (lutResolution-1)); 84 | srcLUTPosition[1].z = ceil(clamp(srcSample.z, 0.0f, 1.0f) * (lutResolution-1)); 85 | 86 | float4 interp; 87 | interp.x = (clamp(srcSample.x, 0.0f, 1.0f) * (lutResolution-1)) - srcLUTPosition[0].x; 88 | interp.y = (clamp(srcSample.y, 0.0f, 1.0f) * (lutResolution-1)) - srcLUTPosition[0].y; 89 | interp.z = (clamp(srcSample.z, 0.0f, 1.0f) * (lutResolution-1)) - srcLUTPosition[0].z; 90 | interp.w = 1.0; 91 | 92 | // Two samples from LUT 93 | float4 lower, higher;; 94 | 95 | // sample r, g, b for lower position 96 | lut1dImageSample = lut1dImage(srcLUTPosition[0].x, 0); 97 | lower.x = lut1dImageSample.x; 98 | lut1dImageSample = lut1dImage(srcLUTPosition[0].y, 0); 99 | lower.y = lut1dImageSample.y; 100 | lut1dImageSample = lut1dImage(srcLUTPosition[0].z, 0); 101 | lower.z = lut1dImageSample.z; 102 | lower.w = 1.0; 103 | 104 | // sample r, g, b for higher position 105 | lut1dImageSample = lut1dImage(srcLUTPosition[1].x, 0); 106 | higher.x = lut1dImageSample.x; 107 | lut1dImageSample = lut1dImage(srcLUTPosition[1].y, 0); 108 | higher.y = lut1dImageSample.y; 109 | lut1dImageSample = lut1dImage(srcLUTPosition[1].z, 0); 110 | higher.z = lut1dImageSample.z; 111 | higher.w = 1.0; 112 | 113 | // Interpolate the samples 114 | lut1dImageSample = mix(lower, higher, interp); 115 | } // bi-linear 116 | 117 | // Write the new value to dst 118 | SampleType(dst) t; 119 | t.x = lut1dImageSample.x; 120 | t.y = lut1dImageSample.y; 121 | t.z = lut1dImageSample.z; 122 | 123 | dst() = t; 124 | } 125 | }; 126 | -------------------------------------------------------------------------------- /blink/LUTInvert.blink: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2014-2015 Haarm-Pieter Duiker 3 | // 4 | 5 | // 6 | // A kernel that will produce the inverse of a 3d LUT, represented as an image 7 | // 8 | 9 | // 10 | // A distance-based weighting function 11 | // 12 | float falloffFilter(float d, float f) { 13 | return exp(-d * f); 14 | } 15 | 16 | // 17 | // Map from the 2D position in the CMSTestPattern image to a 3D LUT position 18 | // 19 | int4 nukePosition2dToPosition3d(int2 pos, int width, int height, int nukeBlockSize, int lutResolution) { 20 | int4 position; 21 | 22 | int pixel = pos.y/nukeBlockSize*width/nukeBlockSize + pos.x/nukeBlockSize; 23 | position.w = pixel; 24 | 25 | position.x = pixel % lutResolution; 26 | position.y = (pixel / lutResolution) % lutResolution; 27 | position.z = (pixel / (lutResolution*lutResolution)) % lutResolution; 28 | 29 | return position; 30 | } 31 | 32 | // 33 | // kernel 34 | // 35 | kernel LUTInvertKernel : public ImageComputationKernel 36 | { 37 | Image src; 38 | Image dst; 39 | 40 | param: 41 | float cutoff; 42 | float falloff; 43 | 44 | local: 45 | int lutResolution; 46 | int nukeBlockSize; 47 | 48 | void define() { 49 | defineParam(cutoff, "cutoff", 0.5f); 50 | defineParam(falloff, "falloff", 5.f); 51 | } 52 | 53 | void init() { 54 | // The Nuke CMSTestPattern node generates 7x7 pixel blocks for each LUT entry 55 | nukeBlockSize = 7; 56 | float pixels = src.bounds.width() * src.bounds.height() / (nukeBlockSize * nukeBlockSize); 57 | lutResolution = int(floor(pow(pixels, 0.333333333334f))); 58 | } 59 | 60 | void process(int2 pos) { 61 | float3 value; 62 | float highDistance; 63 | 64 | // 65 | // Information for the input pixel position 66 | // 67 | int4 inputPosition; 68 | inputPosition = nukePosition2dToPosition3d(pos, 69 | src.bounds.width(), src.bounds.height(), nukeBlockSize, lutResolution); 70 | 71 | float3 inputSample; 72 | inputSample = float3(inputPosition.x, inputPosition.y, inputPosition.z) / (lutResolution-1.f); 73 | 74 | // 75 | // Skip the extra pixels at the top of the image 76 | // 77 | if( inputPosition.w >= lutResolution*lutResolution*lutResolution ) { 78 | value = float3(0.f); 79 | highDistance = 0.f; 80 | } 81 | else { 82 | int4 outputPosition; 83 | SampleType(src) sample; 84 | float3 outputSample; 85 | 86 | // 87 | // Brute force scattered data interpolation 88 | // - Step through every pixel 89 | // - Weight the pixel/sample by its distance from the input 90 | // - Add the weighted result to a running sum 91 | // - Divide by the sum of the weights 92 | // 93 | float3 weightedValueSum; 94 | float weightSum; 95 | 96 | float weight, distance; 97 | 98 | int2 highPosition; 99 | float3 highSample, highValue; 100 | 101 | weightedValueSum = float3(0.f); 102 | weightSum = 0.f; 103 | highDistance = 1000.f; 104 | 105 | // Step through each of the input pixels 106 | // - Only sample one pixel from each block though. Blocks are nukeBlockSize x nukeBlockSize big. 107 | for(int inX = nukeBlockSize/2; inX 0.f ) { 144 | value = weightedValueSum / weightSum; 145 | highDistance = weightSum; 146 | 147 | // Use the nearest sample if there were no weighted values 148 | } else { 149 | value = highValue; 150 | highDistance = 1000.f; 151 | } 152 | } 153 | 154 | // 155 | // Diagnostics 156 | // 157 | /* 158 | value.x = lutResolution; 159 | value.y = inputPosition.w; 160 | 161 | value.x = inputSample.x; 162 | value.y = inputSample.y; 163 | value.z = inputSample.z; 164 | */ 165 | 166 | // 167 | // Copy to output 168 | // 169 | SampleType(src) t; 170 | t.x = value.x; 171 | t.y = value.y; 172 | t.z = value.z; 173 | t.w = highDistance; 174 | 175 | dst() = t; 176 | } 177 | }; 178 | -------------------------------------------------------------------------------- /blink/LUTRecover.blink: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2014-2015 Haarm-Pieter Duiker 3 | // 4 | 5 | // 6 | // A kernel that will recover a 3d LUT by comparing two images 7 | // 8 | 9 | // 10 | // A distance-based weighting function 11 | // 12 | float falloffFilter(float d, float f) { 13 | return exp(-d * f); 14 | } 15 | 16 | // 17 | // Map from the 2D position in the CMSTestPattern image to a 3D LUT position 18 | // 19 | int4 nukePosition2dToPosition3d(int2 pos, int width, int height, int nukeBlockSize, int lutResolution) { 20 | int4 position; 21 | 22 | int pixel = pos.y/nukeBlockSize*width/nukeBlockSize + pos.x/nukeBlockSize; 23 | position.w = pixel; 24 | 25 | position.x = pixel % lutResolution; 26 | position.y = (pixel / lutResolution) % lutResolution; 27 | position.z = (pixel / (lutResolution*lutResolution)) % lutResolution; 28 | 29 | return position; 30 | } 31 | 32 | // 33 | // kernel 34 | // 35 | kernel LUTRecoverKernel : public ImageComputationKernel 36 | { 37 | Image cmsPattern; 38 | Image before; 39 | Image after; 40 | Image dst; 41 | 42 | param: 43 | float cutoff; 44 | float falloff; 45 | 46 | local: 47 | int lutResolution; 48 | int nukeBlockSize; 49 | 50 | void define() { 51 | defineParam(cutoff, "cutoff", 0.5f); 52 | defineParam(falloff, "falloff", 5.f); 53 | } 54 | 55 | void init() { 56 | // The Nuke CMSTestPattern node generates 7x7 pixel blocks for each LUT entry 57 | nukeBlockSize = 7; 58 | float pixels = cmsPattern.bounds.width() * cmsPattern.bounds.height() / (nukeBlockSize * nukeBlockSize); 59 | lutResolution = int(floor(pow(pixels, 0.333333333334f))); 60 | } 61 | 62 | void process(int2 pos) { 63 | float3 value; 64 | float highDistance; 65 | 66 | // 67 | // Information for the input pixel position 68 | // 69 | int4 cmsPosition; 70 | cmsPosition = nukePosition2dToPosition3d(pos, 71 | cmsPattern.bounds.width(), cmsPattern.bounds.height(), nukeBlockSize, lutResolution); 72 | 73 | float3 cmsSample; 74 | cmsSample = float3(cmsPosition.x, cmsPosition.y, cmsPosition.z) / (lutResolution-1.f); 75 | 76 | // 77 | // Skip the extra pixels at the top of the image 78 | // 79 | if( cmsPosition.w >= lutResolution*lutResolution*lutResolution ) { 80 | value = float3(0.f); 81 | highDistance = 0.f; 82 | } 83 | else { 84 | 85 | // 86 | // Brute force scattered data interpolation 87 | // Each pixel in the input cmsTestPattern corresponds to a LUT entry 88 | // For each pixel in the input cmsTestPattern 89 | // - Step through each pixel location in the before and after images 90 | // --- Compute a weight based on the before pixel color's proximity to the cms pixel 91 | // --- Multiply the after pixel's color by the weight 92 | // --- Add the weight and the weighted after pixel's color to running sum 93 | // - Divide by the sum of the weights 94 | // 95 | float3 weightedValueSum; 96 | float weightSum; 97 | 98 | float weight, distance; 99 | 100 | int2 highPosition; 101 | float3 highSample, highValue; 102 | 103 | SampleType(before) beforePixel; 104 | float3 beforeSample; 105 | SampleType(after) afterPixel; 106 | float3 afterSample; 107 | 108 | weightedValueSum = float3(0.f); 109 | weightSum = 0.f; 110 | highDistance = 1000.f; 111 | 112 | // Step through each of the before and after input pixels 113 | for(int inX = 0; inX 0.f ) { 145 | value = weightedValueSum / weightSum; 146 | highDistance = weightSum; 147 | 148 | // Use the nearest sample if there were no weighted values 149 | } else { 150 | value = highValue; 151 | highDistance = 1000.f; 152 | } 153 | } 154 | 155 | // 156 | // Diagnostics 157 | // 158 | /* 159 | value.x = lutResolution; 160 | value.y = inputPosition.w; 161 | 162 | value.x = inputSample.x; 163 | value.y = inputSample.y; 164 | value.z = inputSample.z; 165 | */ 166 | 167 | // 168 | // Copy to output 169 | // 170 | SampleType(cmsPattern) t; 171 | t.x = value.x; 172 | t.y = value.y; 173 | t.z = value.z; 174 | t.w = highDistance; 175 | 176 | dst() = t; 177 | } 178 | }; 179 | -------------------------------------------------------------------------------- /blink/LUTRecover1D.blink: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2014-2015 Haarm-Pieter Duiker 3 | // 4 | 5 | // 6 | // A kernel that will recover a 1d LUT by comparing two images 7 | // 8 | 9 | // 10 | // A distance-based weighting function 11 | // 12 | float falloffFilter(float d, float f) { 13 | return exp(-d * f); 14 | } 15 | 16 | // 17 | // Map from the 2D position in the CMSTestPattern image to a 1D LUT position 18 | // 19 | int nukePosition2dToPosition1d(int2 pos, int width, int lutResolution) { 20 | int4 position; 21 | 22 | float indexNormalized = float(pos.x)/(width-1); 23 | 24 | return indexNormalized*lutResolution; 25 | } 26 | 27 | // 28 | // kernel 29 | // 30 | kernel LUTRecover1DKernel : public ImageComputationKernel 31 | { 32 | Image lut1DPattern; 33 | Image before; 34 | Image after; 35 | Image dst; 36 | 37 | param: 38 | float cutoff; 39 | float falloff; 40 | 41 | local: 42 | int lutResolution; 43 | 44 | void define() { 45 | defineParam(cutoff, "cutoff", 0.5f); 46 | defineParam(falloff, "falloff", 5.f); 47 | } 48 | 49 | void init() { 50 | lutResolution = int(lut1DPattern.bounds.width()); 51 | } 52 | 53 | void process(int2 pos) { 54 | float3 value; 55 | float highDistance; 56 | 57 | // 58 | // Information for the input pixel position 59 | // 60 | int lut1DPosition; 61 | lut1DPosition = nukePosition2dToPosition1d(pos, 62 | lut1DPattern.bounds.width(), lutResolution); 63 | 64 | float lut1DSample; 65 | lut1DSample = float(lut1DPosition) / (lutResolution-1.f); 66 | 67 | // 68 | // Brute force scattered data interpolation 69 | // Each pixel in the input lut1DPattern corresponds to a LUT entry 70 | // For each pixel in the input lut1DPattern 71 | // - Step through each pixel location in the before and after images 72 | // --- For each channel, since we're computing a 1D LUT 73 | // ------ Compute a weight based on the before pixel color's proximity to the cms pixel 74 | // ------ Multiply the after pixel's color by the weight 75 | // ------ Add the weight and the weighted after pixel's color to running sum 76 | // ---- Divide by the sum of the weights 77 | // 78 | float weightedValueSum; 79 | float weightSum; 80 | 81 | float weight, distance; 82 | 83 | int2 highPosition; 84 | float highSample, highValue; 85 | 86 | SampleType(before) beforePixel; 87 | float beforeSample; 88 | SampleType(after) afterPixel; 89 | float afterSample; 90 | 91 | // Step through each channel 92 | for(int c = 0; c<3; c += 1) { 93 | weightedValueSum = float(0.f); 94 | weightSum = 0.f; 95 | highDistance = 1000.f; 96 | 97 | // Step through each of the before and after input pixels 98 | for(int inX = 0; inX 0.f ) { 134 | value[c] = weightedValueSum / weightSum; 135 | highDistance = weightSum; 136 | 137 | // Use the nearest sample if there were no weighted values 138 | } else { 139 | value[c] = highValue; 140 | highDistance = 1000.f; 141 | } 142 | } 143 | 144 | // 145 | // Diagnostics 146 | // 147 | /* 148 | value.x = lutResolution; 149 | value.y = inputPosition.w; 150 | 151 | value.x = inputSample.x; 152 | value.y = inputSample.y; 153 | value.z = inputSample.z; 154 | */ 155 | 156 | // 157 | // Copy to output 158 | // 159 | SampleType(lut1DPattern) t; 160 | t.x = value.x; 161 | t.y = value.y; 162 | t.z = value.z; 163 | t.w = highDistance; 164 | 165 | dst() = t; 166 | } 167 | }; 168 | -------------------------------------------------------------------------------- /blink/LUTRecoverMerge.blink: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2014-2015 Haarm-Pieter Duiker 3 | // 4 | 5 | // 6 | // A kernel that will merge two recovered 3d LUTs images 7 | // 8 | 9 | // 10 | // Map from the 2D position in the CMSTestPattern image to a 3D LUT position 11 | // 12 | int4 nukePosition2dToPosition3d(int2 pos, int width, int height, int nukeBlockSize, int lutResolution) { 13 | int4 position; 14 | 15 | int pixel = pos.y/nukeBlockSize*width/nukeBlockSize + pos.x/nukeBlockSize; 16 | position.w = pixel; 17 | 18 | position.x = pixel % lutResolution; 19 | position.y = (pixel / lutResolution) % lutResolution; 20 | position.z = (pixel / (lutResolution*lutResolution)) % lutResolution; 21 | 22 | return position; 23 | } 24 | 25 | // 26 | // kernel 27 | // 28 | kernel LUTRecoverMergeKernel : public ImageComputationKernel 29 | { 30 | Image recover1; 31 | Image recover2; 32 | Image dst; 33 | 34 | param: 35 | 36 | local: 37 | int lutResolution; 38 | int nukeBlockSize; 39 | 40 | void define() { 41 | } 42 | 43 | void init() { 44 | // The Nuke CMSTestPattern node generates 7x7 pixel blocks for each LUT entry 45 | nukeBlockSize = 7; 46 | float pixels = recover1.bounds.width() * recover1.bounds.height() / (nukeBlockSize * nukeBlockSize); 47 | lutResolution = int(floor(pow(pixels, 0.333333333334f))); 48 | } 49 | 50 | void process(int2 pos) { 51 | float3 value; 52 | float highDistance; 53 | 54 | // 55 | // Information for the input pixel position 56 | // 57 | int4 cmsPosition; 58 | cmsPosition = nukePosition2dToPosition3d(pos, 59 | recover1.bounds.width(), recover1.bounds.height(), nukeBlockSize, lutResolution); 60 | 61 | float3 cmsSample; 62 | cmsSample = float3(cmsPosition.x, cmsPosition.y, cmsPosition.z) / (lutResolution-1.f); 63 | 64 | // 65 | // Skip the extra pixels at the top of the image 66 | // 67 | if( cmsPosition.w >= lutResolution*lutResolution*lutResolution ) { 68 | value = float3(0.f); 69 | highDistance = 0.f; 70 | } 71 | else { 72 | // 73 | // The alpha value for each recovered LUT is the weight of the recovered 74 | // sample. Divide each sample by the weight, sum the divided samples, sum 75 | // the weights and multiple out the weight once more. 76 | // 77 | 78 | float3 weightedValueSum; 79 | float weightSum; 80 | 81 | SampleType(recover1) recover1Pixel; 82 | float3 recover1Sample; 83 | float recover1Weight; 84 | SampleType(recover2) recover2Pixel; 85 | float3 recover2Sample; 86 | float recover2Weight; 87 | 88 | weightedValueSum = float3(0.f); 89 | weightSum = 0.f; 90 | highDistance = 1000.f; 91 | 92 | // Get sample values 93 | recover1Pixel = recover1(pos.x, pos.y); 94 | recover1Sample = float3(recover1Pixel.x, recover1Pixel.y, 95 | recover1Pixel.z); 96 | recover1Weight = recover1Pixel.w; 97 | 98 | recover2Pixel = recover2(pos.x, pos.y); 99 | recover2Sample = float3(recover2Pixel.x, recover2Pixel.y, 100 | recover2Pixel.z); 101 | recover2Weight = recover2Pixel.w; 102 | 103 | // Add samples into weighted sums 104 | if( recover1Weight > 0.f ) { 105 | weightedValueSum += recover1Sample * recover1Weight; 106 | weightSum += recover1Weight; 107 | } 108 | 109 | if( recover2Weight > 0.f ) { 110 | weightedValueSum += recover2Sample * recover2Weight; 111 | weightSum += recover2Weight; 112 | } 113 | 114 | // Divide out weighting 115 | if( weightSum > 0.f ) { 116 | value = weightedValueSum / weightSum; 117 | highDistance = weightSum; 118 | 119 | // Use the nearest sample if there were no weighted values 120 | } else { 121 | value = float3(1.0f, 0.f, 0.f); 122 | highDistance = 0.f; 123 | } 124 | } 125 | 126 | // 127 | // Copy to output 128 | // 129 | SampleType(dst) t; 130 | t.x = value.x; 131 | t.y = value.y; 132 | t.z = value.z; 133 | t.w = highDistance; 134 | 135 | dst() = t; 136 | } 137 | }; 138 | -------------------------------------------------------------------------------- /blink/LineIntegral.blink: -------------------------------------------------------------------------------- 1 | // 2 | // A kernel that will compute the integral of each line in the image 3 | // 4 | 5 | // 6 | // kernel 7 | // 8 | kernel LineIntegralKernel : public ImageComputationKernel 9 | { 10 | Image src; 11 | Image dst; 12 | 13 | param: 14 | 15 | local: 16 | 17 | void define() { 18 | } 19 | 20 | void init() { 21 | } 22 | 23 | void process(int2 pos) { 24 | float3 integral; 25 | integral = float3(0.f); 26 | 27 | int inY; 28 | SampleType(src) sample; 29 | 30 | // Step through each of the input pixels in the current row 31 | inY = pos.y; 32 | for(int inX = 0; inX 1: 89 | merl_sample_output = "%s.%s.bsdf" % (components[0], quad) 90 | else: 91 | merl_sample_output = "%s.bsdf" % components[0] 92 | merl_sample_output_abs = os.path.join(bsdf_output_folder, merl_sample_output) 93 | 94 | print( "\tInput : %s\n\tOutput : %s" % (merl_sample_input, merl_sample_output_abs) ) 95 | convertMerl( merl_sample_input, merl_sample_output_abs, quad, quad_n, fourier_m ) 96 | except Exception, e: 97 | print( "\tException processing sample / quadrature combination" ) 98 | print( repr(e) ) 99 | 100 | print( "" ) 101 | 102 | 103 | if __name__ == '__main__': 104 | main() 105 | 106 | -------------------------------------------------------------------------------- /lightStage/mayaLightStageImport.py: -------------------------------------------------------------------------------- 1 | ''' 2 | A script to create Maya lights and cameras from Otoy light stage data files 3 | 4 | Usage: 5 | 6 | import os 7 | import sys 8 | 9 | sys.path.append( "/path/to/script" ) 10 | import mayaLightStageImport as mlsi 11 | 12 | lightStageData = "/path/to/lightStage/data" 13 | cameraDir = os.path.join( lightStageData, "CH2_cameras" ) 14 | lightingDir = os.path.join( lightStageData, "LS_lighting_info" ) 15 | 16 | # Create lights, key frames to match light stage key frames 17 | lightStageGroup = mlsi.createLightStageLights( lightingDir ) 18 | 19 | # Create cameras 20 | cameraGroup = mlsi.createLightStageCameras(cameraDir) 21 | ''' 22 | 23 | import math 24 | import os 25 | import sys 26 | 27 | def parseCamera(cameraFile): 28 | camera = {} 29 | 30 | with open(cameraFile, 'r') as fileHandle: 31 | lines = fileHandle.readlines() 32 | 33 | for line in lines: 34 | tokens = line.strip().split('=') 35 | camera[tokens[0].strip().lower()] = map(float, tokens[1].split()) 36 | 37 | return camera 38 | 39 | def readCameras(camerasDir): 40 | cameraData = {} 41 | 42 | for fileName in os.listdir(camerasDir): 43 | if fileName.startswith("cam"): 44 | print(fileName) 45 | 46 | cameraName = fileName.split('.')[0] 47 | camera = parseCamera(os.path.join(camerasDir, fileName)) 48 | cameraData[cameraName] = camera 49 | 50 | return cameraData 51 | 52 | def parseLightDirections(directionsFile): 53 | print(directionsFile) 54 | 55 | directions = {} 56 | 57 | with open(directionsFile, 'r') as fileHandle: 58 | lines = fileHandle.readlines() 59 | 60 | for line in lines: 61 | tokens = line.strip().split() 62 | directions[int(tokens[0].strip())] = map(float, tokens[1:]) 63 | 64 | return directions 65 | 66 | def parseLightPolarization(polarizationFile): 67 | print(polarizationFile) 68 | 69 | polarization = {} 70 | 71 | with open(polarizationFile, 'r') as fileHandle: 72 | lines = fileHandle.readlines() 73 | 74 | for line in lines: 75 | tokens = line.strip().split() 76 | polarization[int(tokens[0].strip())] = int(tokens[1].strip()) 77 | 78 | return polarization 79 | 80 | def parseLightConfigurations(configurationsFile): 81 | print(configurationsFile) 82 | 83 | configurations = {} 84 | 85 | with open(configurationsFile, 'r') as fileHandle: 86 | lines = fileHandle.readlines() 87 | 88 | i = 1 89 | for line in lines: 90 | tokens = line.strip().split() 91 | configurations[i] = map(int, tokens) 92 | i += 1 93 | 94 | return configurations 95 | 96 | 97 | def readLights(lightingDir): 98 | lightData = {} 99 | 100 | for fileName in os.listdir(lightingDir): 101 | print(fileName) 102 | 103 | if fileName.startswith("directions"): 104 | directions = parseLightDirections(os.path.join(lightingDir, fileName)) 105 | 106 | lightData['directions'] = directions 107 | 108 | elif fileName.startswith("is_a_vertex"): 109 | polarization = parseLightPolarization(os.path.join(lightingDir, fileName)) 110 | 111 | lightData['polarization'] = polarization 112 | 113 | elif fileName.startswith("reference_lighting"): 114 | configurations = parseLightConfigurations(os.path.join(lightingDir, fileName)) 115 | 116 | lightData['configurations'] = configurations 117 | 118 | return lightData 119 | 120 | import maya.cmds as cmds 121 | 122 | def inchesToCentimeters(inches): 123 | return inches*2.54 124 | 125 | def halfInchesToCentimeters(inches): 126 | return inches*1.27 127 | 128 | def createLightStageLight(name, direction, diameterIn, distanceToFrontIn, useGroup=True): 129 | diameterCm = inchesToCentimeters(diameterIn) 130 | distanceToFrontCm = inchesToCentimeters(distanceToFrontIn) 131 | 132 | sphereLight = cmds.polySphere(name=name, r=0.5, sx=20, sy=20, ax=[0, 1, 0], cuv=2, ch=1)[0] 133 | lightScale = diameterCm 134 | cmds.setAttr("%s.%s" % (sphereLight, "scaleX"), lightScale) 135 | cmds.setAttr("%s.%s" % (sphereLight, "scaleY"), lightScale) 136 | cmds.setAttr("%s.%s" % (sphereLight, "scaleZ"), lightScale) 137 | 138 | if useGroup: 139 | cmds.setAttr("%s.%s" % (sphereLight, "scaleZ"), 0.0) 140 | 141 | lightGroup = cmds.group(sphereLight, name=("%sRotation" % sphereLight)) 142 | 143 | lightTranslate = distanceToFrontCm 144 | cmds.setAttr("%s.%s" % (sphereLight, "translateZ"), lightTranslate) 145 | 146 | rx = -math.asin( direction[1] )*180.0/3.14159 147 | ry = math.atan2( direction[0], direction[2] )*180.0/3.14159 148 | 149 | cmds.setAttr("%s.%s" % (lightGroup, "rotateX"), rx) 150 | cmds.setAttr("%s.%s" % (lightGroup, "rotateY"), ry) 151 | 152 | return lightGroup 153 | else: 154 | lightTranslate = map( lambda x: x*(distanceToFrontCm + diameterCm/2.), direction) 155 | cmds.setAttr("%s.%s" % (sphereLight, "translateX"), lightTranslate[0]) 156 | cmds.setAttr("%s.%s" % (sphereLight, "translateY"), lightTranslate[1]) 157 | cmds.setAttr("%s.%s" % (sphereLight, "translateZ"), lightTranslate[2]) 158 | 159 | return sphereLight 160 | 161 | def setLightConfigurationVisibility(lightConfigurations, lightNumber, name): 162 | for frame, configuration in lightConfigurations.iteritems(): 163 | #print( frame ) 164 | visible = ( lightNumber in configuration ) 165 | #print( visible ) 166 | cmds.currentTime( frame ) 167 | cmds.setAttr("%s.%s" % (name, "v"), visible) 168 | cmds.setKeyframe("%s.%s" % (name, "v")) 169 | 170 | def createLightStageLights(lightingDir): 171 | diameterIn = 4 172 | distanceToFrontIn = 55 173 | 174 | lightData = readLights(lightingDir) 175 | for dict, value in lightData.iteritems(): 176 | print( dict ) 177 | print( value ) 178 | 179 | lightDirections = lightData['directions'] 180 | lightPolarizations = lightData['polarization'] 181 | lightConfigurations = lightData['configurations'] 182 | 183 | lightsPolarized = [] 184 | lightsUnpolarized = [] 185 | for lightNumber, lightDirection in lightDirections.iteritems(): 186 | print( lightNumber, lightDirection ) 187 | if lightPolarizations[lightNumber] == 0: 188 | name = "lightStageLightUnPolarized" + str(lightNumber) 189 | lightsPolarized.append( createLightStageLight(name, lightDirection, diameterIn, distanceToFrontIn) ) 190 | setLightConfigurationVisibility(lightConfigurations, lightNumber, name) 191 | else: 192 | name = "lightStageLightPolarized" + str(lightNumber) 193 | lightsUnpolarized.append( createLightStageLight(name, lightDirection, diameterIn, distanceToFrontIn) ) 194 | setLightConfigurationVisibility(lightConfigurations, lightNumber, name) 195 | 196 | polarizedLightsGroup = cmds.group( lightsPolarized, name="polarizedLights" ) 197 | unpolarizedLightsGroup = cmds.group( lightsUnpolarized, name="polarizedLights" ) 198 | lightStageGroup = cmds.group( [polarizedLightsGroup, unpolarizedLightsGroup], name="lightStageLights" ) 199 | 200 | return lightStageGroup 201 | 202 | def createLightStageCamera(name, rx, ry, rz, translate, focalLengthPixels, ppX, ppY): 203 | c = cmds.camera(name=name)[0] 204 | 205 | # Rotation 206 | rotationMatrix = [0.0]*16 207 | #for i in range(0,3): rotationMatrix[i] = rx[i] 208 | #for i in range(0,3): rotationMatrix[i+4] = ry[i] 209 | #for i in range(0,3): rotationMatrix[i+8] = rz[i] 210 | 211 | # Transpose the rotation matrix values 212 | for i in range(0,3): rotationMatrix[i*4 ] = rx[i] 213 | for i in range(0,3): rotationMatrix[i*4+1] = ry[i] 214 | for i in range(0,3): rotationMatrix[i*4+2] = rz[i] 215 | rotationMatrix[15] = 1.0 216 | 217 | cmds.xform( c, a=True, matrix=rotationMatrix ) 218 | 219 | # Translation 220 | t = map( halfInchesToCentimeters, translate ) 221 | cmds.xform( c, a=True, translation=t ) 222 | 223 | # Scale 224 | #cmds.xform( c, a=True, scale=[10.0, 10.0, 10.0] ) 225 | 226 | # Film Back 227 | cmds.setAttr( "%s.verticalFilmAperture" % c, 1.417) 228 | cmds.setAttr( "%s.horizontalFilmAperture" % c, 0.9449) 229 | cmds.setAttr( "%s.cap" % c, l=True ) 230 | cmds.setAttr( "%s.filmFit" % c, 2) 231 | 232 | # Focal Length 233 | sensorWidthMM = 24.0 234 | 235 | imageWidthPixels = 3456 236 | imageHeightPixels = 5184 237 | 238 | focalLengthMM = focalLengthPixels * sensorWidthMM / imageWidthPixels 239 | cmds.setAttr( "%s.focalLength" % c, focalLengthMM) 240 | 241 | # Film Back Offset 242 | centerX = imageWidthPixels/2. 243 | offsetX = (centerX - ppX)/imageWidthPixels 244 | cmds.setAttr( "%s.horizontalFilmOffset" % c, offsetX) 245 | 246 | centerY = imageHeightPixels/2. 247 | offsetY = (centerY - ppY)/imageHeightPixels 248 | cmds.setAttr( "%s.verticalFilmOffset" % c, offsetY) 249 | 250 | return c 251 | 252 | def createLightStageCameras(cameraDir): 253 | cameraData = readCameras(cameraDir) 254 | 255 | mayaCameras = [] 256 | for cam, data in cameraData.iteritems(): 257 | mayaCamera = createLightStageCamera(cam, data['rx'], data['ry'], data['rz'], 258 | data['t'], data['fc'][0], data['pp'][0], data['pp'][1]) 259 | mayaCameras.append( mayaCamera ) 260 | 261 | cameraGroup = cmds.group( mayaCameras, name="lightStageCameras" ) 262 | return cameraGroup 263 | 264 | 265 | 266 | 267 | 268 | -------------------------------------------------------------------------------- /nuke/README.md: -------------------------------------------------------------------------------- 1 | ## Nuke gizmos and scripts ## 2 | 3 | A set of gizmos and scripts that add functionality to Nuke 4 | 5 | These were tested with Nuke version 10.0v1 6 | 7 | Dependencies 8 | - 9 | Nuke 10.0v1 10 | 11 | Installing Nuke gizmos 12 | - 13 | The Foundry provide these [instructions for installing Nuke gizmos](http://help.thefoundry.co.uk/nuke/content/comp_environment/configuring_nuke/loading_gizmos_plugins_scripts.html) 14 | -------------------------------------------------------------------------------- /nuke/gizmos/ColorMatrixPlus.gizmo: -------------------------------------------------------------------------------- 1 | #! /Applications/TheFoundry/Nuke10.0v1/Nuke10.0v1.app/Contents/MacOS//libnuke-10.0.1.dylib -nx 2 | version 10.0 v1 3 | Gizmo { 4 | addUserKnob {20 User} 5 | addUserKnob {41 channels T ColorMatrixInternal1.channels} 6 | addUserKnob {41 matrix T ColorMatrixInternal1.matrix} 7 | addUserKnob {41 invert T ColorMatrixInternal1.invert} 8 | addUserKnob {26 "" l mask} 9 | addUserKnob {41 maskChannelMask l "" -STARTLINE T ColorMatrixInternal1.maskChannelMask} 10 | addUserKnob {41 maskChannelInput l "" -STARTLINE T ColorMatrixInternal1.maskChannelInput} 11 | addUserKnob {41 inject T ColorMatrixInternal1.inject} 12 | addUserKnob {41 invert_mask l invert T ColorMatrixInternal1.invert_mask} 13 | addUserKnob {41 fringe T ColorMatrixInternal1.fringe} 14 | addUserKnob {41 unpremult l "(un)premult by" T ColorMatrixInternal1.unpremult} 15 | addUserKnob {41 invert_unpremult l invert T ColorMatrixInternal1.invert_unpremult} 16 | addUserKnob {41 mix T ColorMatrixInternal1.mix} 17 | addUserKnob {26 ""} 18 | addUserKnob {41 LoadSPI l "Load SPI Matrix" T ColorMatrixInternal1.LoadSPI} 19 | addUserKnob {41 SaveSPI l "Save SPI Matrix" T ColorMatrixInternal1.SaveSPI} 20 | addUserKnob {41 DupeToOCIO l "Duplicate as OCIO File Transform" T ColorMatrixInternal1.DupeToOCIO} 21 | addUserKnob {41 DivideByDeterminant l "Divide By Determinant" T ColorMatrixInternal1.DivideByDeterminant} 22 | addUserKnob {41 CombineMatrices l "Combine with other Matrix" T ColorMatrixInternal1.CombineMatrices} 23 | addUserKnob {41 CopyMatrix l "Copy Values From Selected Node" T ColorMatrixInternal1.CopyMatrix} 24 | } 25 | Input { 26 | inputs 0 27 | name Input1 28 | xpos -70 29 | ypos -127 30 | } 31 | ColorMatrix { 32 | matrix { 33 | {1 0 0} 34 | {0 1 0} 35 | {0 0 1} 36 | } 37 | name ColorMatrixInternal1 38 | selected true 39 | xpos -70 40 | ypos -57 41 | addUserKnob {20 User} 42 | addUserKnob {22 LoadSPI l "Load SPI Matrix" T "def loadSPIMatrix(spiFile, matrixNode):\n with open( spiFile, 'r') as file:\n lines = file.readlines()\n \n matrixValues = \[]\n for line in lines:\n matrixValues.extend( map(float, line.strip().split(' ')\[0:3]) )\n matrixNode\['matrix'].setValue(matrixValues)\n\nspiFile = filePath = nuke.getFilename('Save Matrix', '*.spimtx *.spimtx')\nselectedNode = nuke.selectedNode()\nloadSPIMatrix( spiFile, selectedNode )\n" +STARTLINE} 43 | addUserKnob {22 SaveSPI l "Save SPI Matrix" T "def writeSPIColorMatrix(matrixNode, spiFile):\n matrixValues = matrixNode\['matrix'].getValue()\n \n with open(spiFile, \"w\") as spiFileHandle:\n spiFileHandle.write( \"%3.6f %3.6f %3.6f 0.0\\n\" % (\n matrixValues\[0], matrixValues\[1], matrixValues\[2]) )\n spiFileHandle.write( \"%3.6f %3.6f %3.6f 0.0\\n\" % (\n matrixValues\[3], matrixValues\[4], matrixValues\[5]) )\n spiFileHandle.write( \"%3.6f %3.6f %3.6f 0.0\\n\" % (\n matrixValues\[6], matrixValues\[7], matrixValues\[8]) )\n\nfilePath = nuke.getFilename('Save Matrix', '*.spimtx *.spimtx')\nselectedNode = nuke.selectedNode()\n\nprint( \"Exporting matrix node : %s\" % selectedNode)\nprint( \"Exporting matrix to : %s\" % filePath)\n\nwriteSPIColorMatrix(selectedNode, filePath)\n" +STARTLINE} 44 | addUserKnob {22 DupeToOCIO l "Duplicate as OCIO File Transform" T "def writeSPIColorMatrix(matrixNode, spiFile):\n matrixValues = matrixNode\['matrix'].getValue()\n \n with open(spiFile, \"w\") as spiFileHandle:\n spiFileHandle.write( \"%3.6f %3.6f %3.6f 0.0\\n\" % (\n matrixValues\[0], matrixValues\[1], matrixValues\[2]) )\n spiFileHandle.write( \"%3.6f %3.6f %3.6f 0.0\\n\" % (\n matrixValues\[3], matrixValues\[4], matrixValues\[5]) )\n spiFileHandle.write( \"%3.6f %3.6f %3.6f 0.0\\n\" % (\n matrixValues\[6], matrixValues\[7], matrixValues\[8]) )\n\nfilePath = nuke.getFilename('Save Matrix', '*.spimtx *.spimtx')\nselectedNode = nuke.selectedNode()\n\nprint( \"Exporting matrix node : %s\" % selectedNode)\nprint( \"Exporting matrix to : %s\" % filePath)\n\nwriteSPIColorMatrix(selectedNode, filePath)\n\nwith nuke.root():\n nukeMatrixNode = nuke.createNode (\"OCIOFileTransform\")\nnukeMatrixNode\['file'].setValue(filePath)\nnukeMatrixNode\['working_space'].setValue(\"raw\")\n" +STARTLINE} 45 | addUserKnob {26 ""} 46 | addUserKnob {22 DivideByDeterminant l "Divide By Determinant" T "import math\nimport math\ndef normalizeMatrix(matrixNode):\n nukeMatrix3 = nodeToMatrix3(matrixNode)\n\n determinant = nukeMatrix3.determinant()\n print( \"det : %s\" % determinant )\n determinant_root = math.pow( math.fabs(determinant), 0.333333 )\n print( \"det root : %s\" % determinant_root )\n \n nukeMatrix3.scale( 1.0/determinant_root )\n\n matrixValues = \[]\n for i in range(9):\n matrixValues.append(nukeMatrix3\[i])\n matrixNode\['matrix'].setValue(matrixValues)\n\nselectedNode = nuke.selectedNode()\nnormalizeMatrix( selectedNode )" +STARTLINE} 47 | addUserKnob {22 CombineMatrices l "Combine with other Matrix" T "def nodeToMatrix3(matrixNode):\n matrixValues = matrixNode\['matrix'].getValue()\n nukeMatrix3 = nuke.math.Matrix3()\n for i in range(9):\n nukeMatrix3\[i] = matrixValues\[i]\n return nukeMatrix3\n\ndef matrix3ToNode(nukeMatrix3):\n matrixValues = \[]\n for i in range(9):\n matrixValues.append(nukeMatrix3\[i])\n\n with nuke.root():\n nukeMatrixNode = nuke.createNode (\"ColorMatrixPlus\")\n nukeMatrixNode\['matrix'].setValue(matrixValues)\n return nukeMatrixNode\n\ndef combineMatrixNodesNuke(matrixNodes=None):\n if matrixNodes == None:\n selectedNodes = nuke.selectedNodes()\n matrixNodes = \[]\n matrixNode\[0] = selectedNodes\[0]\n matrixNode\[1] = selectedNodes\[1]\n\n a = nodeToMatrix3(matrixNodes\[0])\n b = nodeToMatrix3(matrixNodes\[1])\n\n invertMatrix = matrixNodes\[0]\['invert'].getValue()\n if invertMatrix > 0.0:\n a = a.inverse()\n invertMatrix = matrixNodes\[1]\['invert'].getValue()\n if invertMatrix > 0.0:\n b = b.inverse()\n \n c = a * b\n\n combinedMatrixNode = matrix3ToNode(c)\n\nselectedNodes = nuke.root().selectedNodes()\n#selectedNodes = nuke.selectedNodes()\nprint( selectedNodes )\ncombineMatrixNodesNuke(\[selectedNodes\[0], selectedNodes\[1]])" +STARTLINE} 48 | addUserKnob {22 CopyMatrix l "Copy Values From Selected Node" T "def nodeToMatrix3(matrixNode):\n matrixValues = matrixNode\['matrix'].getValue()\n nukeMatrix3 = nuke.math.Matrix3()\n for i in range(9):\n nukeMatrix3\[i] = matrixValues\[i]\n return nukeMatrix3\n\ndef matrix3ToNode(nukeMatrix3):\n matrixValues = \[]\n for i in range(9):\n matrixValues.append(nukeMatrix3\[i])\n\n with nuke.root():\n nukeMatrixNode = nuke.createNode (\"matrixplus\")\n nukeMatrixNode\['matrix'].setValue(matrixValues)\n return nukeMatrixNode\n\n\nselectedNode = nuke.root().selectedNode()\nmatrixValues = nodeToMatrix3(selectedNode)\nthisNode = nuke.thisNode()\nthisNode\['matrix'].setValue(matrixValues)" +STARTLINE} 49 | } 50 | Output { 51 | name Output1 52 | xpos -70 53 | ypos 13 54 | } 55 | end_group 56 | -------------------------------------------------------------------------------- /nuke/gizmos/SpectralToRGB.gizmo: -------------------------------------------------------------------------------- 1 | #! /Applications/TheFoundry/Nuke10.0v1/Nuke10.0v1.app/Contents/MacOS//libnuke-10.0.1.dylib -nx 2 | version 10.0 v1 3 | Gizmo { 4 | addUserKnob {20 User} 5 | addUserKnob {41 CreateSpectralConversionExpression l "Create Spectral Conversion Expression" T ExpressionInternal1.CreateSpectralConversionExpression} 6 | addUserKnob {41 wavelengths T ExpressionInternal1.temp_expr0} 7 | addUserKnob {41 colorspace_out l out T ColorspaceInternal.colorspace_out} 8 | addUserKnob {41 illuminant_out l "" -STARTLINE T ColorspaceInternal.illuminant_out} 9 | addUserKnob {41 primary_out l "" -STARTLINE T ColorspaceInternal.primary_out} 10 | } 11 | Input { 12 | inputs 0 13 | name Input1 14 | xpos 269 15 | ypos 154 16 | } 17 | Expression { 18 | temp_name0 wavelengths 19 | temp_expr0 32 20 | expr0 "(0.0 + _374.nm*0.000293+ _389.nm*0.001572+ _404.nm*0.009390+ _418.nm*0.048996+ _433.nm*0.222478+ _448.nm*0.348940+ _462.nm*0.318700+ _477.nm*0.201086+ _492.nm*0.061266+ _506.nm*0.006296+ _521.nm*0.021735+ _536.nm*0.148111+ _550.nm*0.331438+ _565.nm*0.552951+ _580.nm*0.802876+ _595.nm*1.004319+ _609.nm*1.058444+ _624.nm*0.915219+ _639.nm*0.611314+ _653.nm*0.344456+ _668.nm*0.160133+ _683.nm*0.061703+ _697.nm*0.022700+ _712.nm*0.008395+ _727.nm*0.003004+ _741.nm*0.001076+ _756.nm*0.000370+ _771.nm*0.000130+ _785.nm*0.000048+ _800.nm*0.000017+ _815.nm*0.000006+ _830.nm*0.000002)*0.133356" 21 | expr1 "(0.0 + _374.nm*0.000009+ _389.nm*0.000045+ _404.nm*0.000264+ _418.nm*0.001362+ _433.nm*0.007693+ _448.nm*0.023647+ _462.nm*0.048000+ _477.nm*0.089106+ _492.nm*0.166009+ _506.nm*0.308578+ _521.nm*0.576328+ _536.nm*0.842899+ _550.nm*0.971261+ _565.nm*0.998815+ _580.nm*0.934831+ _595.nm*0.787137+ _609.nm*0.605314+ _624.nm*0.423058+ _639.nm*0.249826+ _653.nm*0.131500+ _668.nm*0.059198+ _683.nm*0.022500+ _697.nm*0.008210+ _712.nm*0.003032+ _727.nm*0.001085+ _741.nm*0.000389+ _756.nm*0.000134+ _771.nm*0.000047+ _785.nm*0.000017+ _800.nm*0.000006+ _815.nm*0.000002+ _830.nm*0.000001)*0.133356" 22 | expr2 "(0.0 + _374.nm*0.001373+ _389.nm*0.007414+ _404.nm*0.044471+ _418.nm*0.233692+ _433.nm*1.077209+ _448.nm*1.753552+ _462.nm*1.744100+ _477.nm*1.313188+ _492.nm*0.634152+ _506.nm*0.286169+ _521.nm*0.124535+ _536.nm*0.046326+ _550.nm*0.015864+ _565.nm*0.004717+ _580.nm*0.001919+ _595.nm*0.001237+ _609.nm*0.000724+ _624.nm*0.000225+ _639.nm*0.000042+ _653.nm*0.000008+ _668.nm*0.000000+ _683.nm*0.000000+ _697.nm*0.000000+ _712.nm*0.000000+ _727.nm*0.000000+ _741.nm*0.000000+ _756.nm*0.000000+ _771.nm*0.000000+ _785.nm*0.000000+ _800.nm*0.000000+ _815.nm*0.000000+ _830.nm*0.000000)*0.133356" 23 | name ExpressionInternal1 24 | selected true 25 | xpos 269 26 | ypos 218 27 | addUserKnob {20 User} 28 | addUserKnob {22 CreateSpectralConversionExpression l "Create Spectral Conversion Expression" T "#\n# Spectral interpolation\n#\nimport numpy as np\n\nCIE_X = \[0.0001299000, 0.0001458470, 0.0001638021, 0.0001840037,\n 0.0002066902, 0.0002321000, 0.0002607280, 0.0002930750,\n 0.0003293880, 0.0003699140, 0.0004149000, 0.0004641587,\n 0.0005189860, 0.0005818540, 0.0006552347, 0.0007416000,\n 0.0008450296, 0.0009645268, 0.001094949, 0.001231154,\n 0.001368000, 0.001502050, 0.001642328, 0.001802382,\n 0.001995757, 0.002236000, 0.002535385, 0.002892603,\n 0.003300829, 0.003753236, 0.004243000, 0.004762389,\n 0.005330048, 0.005978712, 0.006741117, 0.007650000,\n 0.008751373, 0.01002888, 0.01142170, 0.01286901,\n 0.01431000, 0.01570443, 0.01714744, 0.01878122,\n 0.02074801, 0.02319000, 0.02620736, 0.02978248,\n 0.03388092, 0.03846824, 0.04351000, 0.04899560,\n 0.05502260, 0.06171880, 0.06921200, 0.07763000,\n 0.08695811, 0.09717672, 0.1084063, 0.1207672,\n 0.1343800, 0.1493582, 0.1653957, 0.1819831,\n 0.1986110, 0.2147700, 0.2301868, 0.2448797,\n 0.2587773, 0.2718079, 0.2839000, 0.2949438,\n 0.3048965, 0.3137873, 0.3216454, 0.3285000,\n 0.3343513, 0.3392101, 0.3431213, 0.3461296,\n 0.3482800, 0.3495999, 0.3501474, 0.3500130,\n 0.3492870, 0.3480600, 0.3463733, 0.3442624,\n 0.3418088, 0.3390941, 0.3362000, 0.3331977,\n 0.3300411, 0.3266357, 0.3228868, 0.3187000,\n 0.3140251, 0.3088840, 0.3032904, 0.2972579,\n 0.2908000, 0.2839701, 0.2767214, 0.2689178,\n 0.2604227, 0.2511000, 0.2408475, 0.2298512,\n 0.2184072, 0.2068115, 0.1953600, 0.1842136,\n 0.1733273, 0.1626881, 0.1522833, 0.1421000,\n 0.1321786, 0.1225696, 0.1132752, 0.1042979,\n 0.09564000, 0.08729955, 0.07930804, 0.07171776,\n 0.06458099, 0.05795001, 0.05186211, 0.04628152,\n 0.04115088, 0.03641283, 0.03201000, 0.02791720,\n 0.02414440, 0.02068700, 0.01754040, 0.01470000,\n 0.01216179, 0.009919960, 0.007967240, 0.006296346,\n 0.004900000, 0.003777173, 0.002945320, 0.002424880,\n 0.002236293, 0.002400000, 0.002925520, 0.003836560,\n 0.005174840, 0.006982080, 0.009300000, 0.01214949,\n 0.01553588, 0.01947752, 0.02399277, 0.02910000,\n 0.03481485, 0.04112016, 0.04798504, 0.05537861,\n 0.06327000, 0.07163501, 0.08046224, 0.08973996,\n 0.09945645, 0.1096000, 0.1201674, 0.1311145,\n 0.1423679, 0.1538542, 0.1655000, 0.1772571,\n 0.1891400, 0.2011694, 0.2133658, 0.2257499,\n 0.2383209, 0.2510668, 0.2639922, 0.2771017,\n 0.2904000, 0.3038912, 0.3175726, 0.3314384,\n 0.3454828, 0.3597000, 0.3740839, 0.3886396,\n 0.4033784, 0.4183115, 0.4334499, 0.4487953,\n 0.4643360, 0.4800640, 0.4959713, 0.5120501,\n 0.5282959, 0.5446916, 0.5612094, 0.5778215,\n 0.5945000, 0.6112209, 0.6279758, 0.6447602,\n 0.6615697, 0.6784000, 0.6952392, 0.7120586,\n 0.7288284, 0.7455188, 0.7621000, 0.7785432,\n 0.7948256, 0.8109264, 0.8268248, 0.8425000,\n 0.8579325, 0.8730816, 0.8878944, 0.9023181,\n 0.9163000, 0.9297995, 0.9427984, 0.9552776,\n 0.9672179, 0.9786000, 0.9893856, 0.9995488,\n 1.0090892, 1.0180064, 1.0263000, 1.0339827,\n 1.0409860, 1.0471880, 1.0524667, 1.0567000,\n 1.0597944, 1.0617992, 1.0628068, 1.0629096,\n 1.0622000, 1.0607352, 1.0584436, 1.0552244,\n 1.0509768, 1.0456000, 1.0390369, 1.0313608,\n 1.0226662, 1.0130477, 1.0026000, 0.9913675,\n 0.9793314, 0.9664916, 0.9528479, 0.9384000,\n 0.9231940, 0.9072440, 0.8905020, 0.8729200,\n 0.8544499, 0.8350840, 0.8149460, 0.7941860,\n 0.7729540, 0.7514000, 0.7295836, 0.7075888,\n 0.6856022, 0.6638104, 0.6424000, 0.6215149,\n 0.6011138, 0.5811052, 0.5613977, 0.5419000,\n 0.5225995, 0.5035464, 0.4847436, 0.4661939,\n 0.4479000, 0.4298613, 0.4120980, 0.3946440,\n 0.3775333, 0.3608000, 0.3444563, 0.3285168,\n 0.3130192, 0.2980011, 0.2835000, 0.2695448,\n 0.2561184, 0.2431896, 0.2307272, 0.2187000,\n 0.2070971, 0.1959232, 0.1851708, 0.1748323,\n 0.1649000, 0.1553667, 0.1462300, 0.1374900,\n 0.1291467, 0.1212000, 0.1136397, 0.1064650,\n 0.09969044, 0.09333061, 0.08740000, 0.08190096,\n 0.07680428, 0.07207712, 0.06768664, 0.06360000,\n 0.05980685, 0.05628216, 0.05297104, 0.04981861,\n 0.04677000, 0.04378405, 0.04087536, 0.03807264,\n 0.03540461, 0.03290000, 0.03056419, 0.02838056,\n 0.02634484, 0.02445275, 0.02270000, 0.02108429,\n 0.01959988, 0.01823732, 0.01698717, 0.01584000,\n 0.01479064, 0.01383132, 0.01294868, 0.01212920,\n 0.01135916, 0.01062935, 0.009938846, 0.009288422,\n 0.008678854, 0.008110916, 0.007582388, 0.007088746,\n 0.006627313, 0.006195408, 0.005790346, 0.005409826,\n 0.005052583, 0.004717512, 0.004403507, 0.004109457,\n 0.003833913, 0.003575748, 0.003334342, 0.003109075,\n 0.002899327, 0.002704348, 0.002523020, 0.002354168,\n 0.002196616, 0.002049190, 0.001910960, 0.001781438,\n 0.001660110, 0.001546459, 0.001439971, 0.001340042,\n 0.001246275, 0.001158471, 0.001076430, 0.0009999493,\n 0.0009287358, 0.0008624332, 0.0008007503, 0.0007433960,\n 0.0006900786, 0.0006405156, 0.0005945021, 0.0005518646,\n 0.0005124290, 0.0004760213, 0.0004424536, 0.0004115117,\n 0.0003829814, 0.0003566491, 0.0003323011, 0.0003097586,\n 0.0002888871, 0.0002695394, 0.0002515682, 0.0002348261,\n 0.0002191710, 0.0002045258, 0.0001908405, 0.0001780654,\n 0.0001661505, 0.0001550236, 0.0001446219, 0.0001349098,\n 0.0001258520, 0.0001174130, 0.0001095515, 0.0001022245,\n 0.00009539445, 0.00008902390, 0.00008307527, 0.00007751269,\n 0.00007231304, 0.00006745778, 0.00006292844, 0.00005870652,\n 0.00005477028, 0.00005109918, 0.00004767654, 0.00004448567,\n 0.00004150994, 0.00003873324, 0.00003614203, 0.00003372352,\n 0.00003146487, 0.00002935326, 0.00002737573, 0.00002552433,\n 0.00002379376, 0.00002217870, 0.00002067383, 0.00001927226,\n 0.00001796640, 0.00001674991, 0.00001561648, 0.00001455977,\n 0.00001357387, 0.00001265436, 0.00001179723, 0.00001099844,\n 0.00001025398, 0.000009559646, 0.000008912044, 0.000008308358,\n 0.000007745769, 0.000007221456, 0.000006732475, 0.000006276423,\n 0.000005851304, 0.000005455118, 0.000005085868, 0.000004741466,\n 0.000004420236, 0.000004120783, 0.000003841716, 0.000003581652,\n 0.000003339127, 0.000003112949, 0.000002902121, 0.000002705645,\n 0.000002522525, 0.000002351726, 0.000002192415, 0.000002043902,\n 0.000001905497, 0.000001776509, 0.000001656215, 0.000001544022,\n 0.000001439440, 0.000001341977, 0.000001251141]\n\nCIE_Y = \[0.000003917000, 0.000004393581, 0.000004929604, 0.000005532136,\n 0.000006208245, 0.000006965000, 0.000007813219, 0.000008767336,\n 0.000009839844, 0.00001104323, 0.00001239000, 0.00001388641,\n 0.00001555728, 0.00001744296, 0.00001958375, 0.00002202000,\n 0.00002483965, 0.00002804126, 0.00003153104, 0.00003521521,\n 0.00003900000, 0.00004282640, 0.00004691460, 0.00005158960,\n 0.00005717640, 0.00006400000, 0.00007234421, 0.00008221224,\n 0.00009350816, 0.0001061361, 0.0001200000, 0.0001349840,\n 0.0001514920, 0.0001702080, 0.0001918160, 0.0002170000,\n 0.0002469067, 0.0002812400, 0.0003185200, 0.0003572667,\n 0.0003960000, 0.0004337147, 0.0004730240, 0.0005178760,\n 0.0005722187, 0.0006400000, 0.0007245600, 0.0008255000,\n 0.0009411600, 0.001069880, 0.001210000, 0.001362091,\n 0.001530752, 0.001720368, 0.001935323, 0.002180000,\n 0.002454800, 0.002764000, 0.003117800, 0.003526400,\n 0.004000000, 0.004546240, 0.005159320, 0.005829280,\n 0.006546160, 0.007300000, 0.008086507, 0.008908720,\n 0.009767680, 0.01066443, 0.01160000, 0.01257317,\n 0.01358272, 0.01462968, 0.01571509, 0.01684000,\n 0.01800736, 0.01921448, 0.02045392, 0.02171824,\n 0.02300000, 0.02429461, 0.02561024, 0.02695857,\n 0.02835125, 0.02980000, 0.03131083, 0.03288368,\n 0.03452112, 0.03622571, 0.03800000, 0.03984667,\n 0.04176800, 0.04376600, 0.04584267, 0.04800000,\n 0.05024368, 0.05257304, 0.05498056, 0.05745872,\n 0.06000000, 0.06260197, 0.06527752, 0.06804208,\n 0.07091109, 0.07390000, 0.07701600, 0.08026640,\n 0.08366680, 0.08723280, 0.09098000, 0.09491755,\n 0.09904584, 0.1033674, 0.1078846, 0.1126000,\n 0.1175320, 0.1226744, 0.1279928, 0.1334528,\n 0.1390200, 0.1446764, 0.1504693, 0.1564619,\n 0.1627177, 0.1693000, 0.1762431, 0.1835581,\n 0.1912735, 0.1994180, 0.2080200, 0.2171199,\n 0.2267345, 0.2368571, 0.2474812, 0.2586000,\n 0.2701849, 0.2822939, 0.2950505, 0.3085780,\n 0.3230000, 0.3384021, 0.3546858, 0.3716986,\n 0.3892875, 0.4073000, 0.4256299, 0.4443096,\n 0.4633944, 0.4829395, 0.5030000, 0.5235693,\n 0.5445120, 0.5656900, 0.5869653, 0.6082000,\n 0.6293456, 0.6503068, 0.6708752, 0.6908424,\n 0.7100000, 0.7281852, 0.7454636, 0.7619694,\n 0.7778368, 0.7932000, 0.8081104, 0.8224962,\n 0.8363068, 0.8494916, 0.8620000, 0.8738108,\n 0.8849624, 0.8954936, 0.9054432, 0.9148501,\n 0.9237348, 0.9320924, 0.9399226, 0.9472252,\n 0.9540000, 0.9602561, 0.9660074, 0.9712606,\n 0.9760225, 0.9803000, 0.9840924, 0.9874812,\n 0.9903128, 0.9928116, 0.9949501, 0.9967108,\n 0.9980983, 0.9991120, 0.9997482, 1.0000000,\n 0.9998567, 0.9993046, 0.9983255, 0.9968987,\n 0.9950000, 0.9926005, 0.9897426, 0.9864444,\n 0.9827241, 0.9786000, 0.9740837, 0.9691712,\n 0.9638568, 0.9581349, 0.9520000, 0.9454504,\n 0.9384992, 0.9311628, 0.9234576, 0.9154000,\n 0.9070064, 0.8982772, 0.8892048, 0.8797816,\n 0.8700000, 0.8598613, 0.8493920, 0.8386220,\n 0.8275813, 0.8163000, 0.8047947, 0.7930820,\n 0.7811920, 0.7691547, 0.7570000, 0.7447541,\n 0.7324224, 0.7200036, 0.7074965, 0.6949000,\n 0.6822192, 0.6694716, 0.6566744, 0.6438448,\n 0.6310000, 0.6181555, 0.6053144, 0.5924756,\n 0.5796379, 0.5668000, 0.5539611, 0.5411372,\n 0.5283528, 0.5156323, 0.5030000, 0.4904688,\n 0.4780304, 0.4656776, 0.4534032, 0.4412000,\n 0.4290800, 0.4170360, 0.4050320, 0.3930320,\n 0.3810000, 0.3689184, 0.3568272, 0.3447768,\n 0.3328176, 0.3210000, 0.3093381, 0.2978504,\n 0.2865936, 0.2756245, 0.2650000, 0.2547632,\n 0.2448896, 0.2353344, 0.2260528, 0.2170000,\n 0.2081616, 0.1995488, 0.1911552, 0.1829744,\n 0.1750000, 0.1672235, 0.1596464, 0.1522776,\n 0.1451259, 0.1382000, 0.1315003, 0.1250248,\n 0.1187792, 0.1127691, 0.1070000, 0.1014762,\n 0.09618864, 0.09112296, 0.08626485, 0.08160000,\n 0.07712064, 0.07282552, 0.06871008, 0.06476976,\n 0.06100000, 0.05739621, 0.05395504, 0.05067376,\n 0.04754965, 0.04458000, 0.04175872, 0.03908496,\n 0.03656384, 0.03420048, 0.03200000, 0.02996261,\n 0.02807664, 0.02632936, 0.02470805, 0.02320000,\n 0.02180077, 0.02050112, 0.01928108, 0.01812069,\n 0.01700000, 0.01590379, 0.01483718, 0.01381068,\n 0.01283478, 0.01192000, 0.01106831, 0.01027339,\n 0.009533311, 0.008846157, 0.008210000, 0.007623781,\n 0.007085424, 0.006591476, 0.006138485, 0.005723000,\n 0.005343059, 0.004995796, 0.004676404, 0.004380075,\n 0.004102000, 0.003838453, 0.003589099, 0.003354219,\n 0.003134093, 0.002929000, 0.002738139, 0.002559876,\n 0.002393244, 0.002237275, 0.002091000, 0.001953587,\n 0.001824580, 0.001703580, 0.001590187, 0.001484000,\n 0.001384496, 0.001291268, 0.001204092, 0.001122744,\n 0.001047000, 0.0009765896, 0.0009111088, 0.0008501332,\n 0.0007932384, 0.0007400000, 0.0006900827, 0.0006433100,\n 0.0005994960, 0.0005584547, 0.0005200000, 0.0004839136,\n 0.0004500528, 0.0004183452, 0.0003887184, 0.0003611000,\n 0.0003353835, 0.0003114404, 0.0002891656, 0.0002684539,\n 0.0002492000, 0.0002313019, 0.0002146856, 0.0001992884,\n 0.0001850475, 0.0001719000, 0.0001597781, 0.0001486044,\n 0.0001383016, 0.0001287925, 0.0001200000, 0.0001118595,\n 0.0001043224, 0.00009733560, 0.00009084587, 0.00008480000,\n 0.00007914667, 0.00007385800, 0.00006891600, 0.00006430267,\n 0.00006000000, 0.00005598187, 0.00005222560, 0.00004871840,\n 0.00004544747, 0.00004240000, 0.00003956104, 0.00003691512,\n 0.00003444868, 0.00003214816, 0.00003000000, 0.00002799125,\n 0.00002611356, 0.00002436024, 0.00002272461, 0.00002120000,\n 0.00001977855, 0.00001845285, 0.00001721687, 0.00001606459,\n 0.00001499000, 0.00001398728, 0.00001305155, 0.00001217818,\n 0.00001136254, 0.00001060000, 0.000009885877, 0.000009217304,\n 0.000008592362, 0.000008009133, 0.000007465700, 0.000006959567,\n 0.000006487995, 0.000006048699, 0.000005639396, 0.000005257800,\n 0.000004901771, 0.000004569720, 0.000004260194, 0.000003971739,\n 0.000003702900, 0.000003452163, 0.000003218302, 0.000003000300,\n 0.000002797139, 0.000002607800, 0.000002431220, 0.000002266531,\n 0.000002113013, 0.000001969943, 0.000001836600, 0.000001712230,\n 0.000001596228, 0.000001488090, 0.000001387314, 0.000001293400,\n 0.000001205820, 0.000001124143, 0.000001048009, 0.0000009770578,\n 0.0000009109300, 0.0000008492513, 0.0000007917212, 0.0000007380904,\n 0.0000006881098, 0.0000006415300, 0.0000005980895, 0.0000005575746,\n 0.0000005198080, 0.0000004846123, 0.0000004518100]\n\nCIE_Z = \[0.0006061000,\n 0.0006808792,\n 0.0007651456,\n 0.0008600124,\n 0.0009665928,\n 0.001086000,\n 0.001220586,\n 0.001372729,\n 0.001543579,\n 0.001734286,\n 0.001946000,\n 0.002177777,\n 0.002435809,\n 0.002731953,\n 0.003078064,\n 0.003486000,\n 0.003975227,\n 0.004540880,\n 0.005158320,\n 0.005802907,\n 0.006450001,\n 0.007083216,\n 0.007745488,\n 0.008501152,\n 0.009414544,\n 0.01054999,\n 0.01196580,\n 0.01365587,\n 0.01558805,\n 0.01773015,\n 0.02005001,\n 0.02251136,\n 0.02520288,\n 0.02827972,\n 0.03189704,\n 0.03621000,\n 0.04143771,\n 0.04750372,\n 0.05411988,\n 0.06099803,\n 0.06785001,\n 0.07448632,\n 0.08136156,\n 0.08915364,\n 0.09854048,\n 0.1102000,\n 0.1246133,\n 0.1417017,\n 0.1613035,\n 0.1832568,\n 0.2074000,\n 0.2336921,\n 0.2626114,\n 0.2947746,\n 0.3307985,\n 0.3713000,\n 0.4162091,\n 0.4654642,\n 0.5196948,\n 0.5795303,\n 0.6456000,\n 0.7184838,\n 0.7967133,\n 0.8778459,\n 0.9594390,\n 1.0390501,\n 1.1153673,\n 1.1884971,\n 1.2581233,\n 1.3239296,\n 1.3856000,\n 1.4426352,\n 1.4948035,\n 1.5421903,\n 1.5848807,\n 1.6229600,\n 1.6564048,\n 1.6852959,\n 1.7098745,\n 1.7303821,\n 1.7470600,\n 1.7600446,\n 1.7696233,\n 1.7762637,\n 1.7804334,\n 1.7826000,\n 1.7829682,\n 1.7816998,\n 1.7791982,\n 1.7758671,\n 1.7721100,\n 1.7682589,\n 1.7640390,\n 1.7589438,\n 1.7524663,\n 1.7441000,\n 1.7335595,\n 1.7208581,\n 1.7059369,\n 1.6887372,\n 1.6692000,\n 1.6475287,\n 1.6234127,\n 1.5960223,\n 1.5645280,\n 1.5281000,\n 1.4861114,\n 1.4395215,\n 1.3898799,\n 1.3387362,\n 1.2876400,\n 1.2374223,\n 1.1878243,\n 1.1387611,\n 1.0901480,\n 1.0419000,\n 0.9941976,\n 0.9473473,\n 0.9014531,\n 0.8566193,\n 0.8129501,\n 0.7705173,\n 0.7294448,\n 0.6899136,\n 0.6521049,\n 0.6162000,\n 0.5823286,\n 0.5504162,\n 0.5203376,\n 0.4919673,\n 0.4651800,\n 0.4399246,\n 0.4161836,\n 0.3938822,\n 0.3729459,\n 0.3533000,\n 0.3348578,\n 0.3175521,\n 0.3013375,\n 0.2861686,\n 0.2720000,\n 0.2588171,\n 0.2464838,\n 0.2347718,\n 0.2234533,\n 0.2123000,\n 0.2011692,\n 0.1901196,\n 0.1792254,\n 0.1685608,\n 0.1582000,\n 0.1481383,\n 0.1383758,\n 0.1289942,\n 0.1200751,\n 0.1117000,\n 0.1039048,\n 0.09666748,\n 0.08998272,\n 0.08384531,\n 0.07824999,\n 0.07320899,\n 0.06867816,\n 0.06456784,\n 0.06078835,\n 0.05725001,\n 0.05390435,\n 0.05074664,\n 0.04775276,\n 0.04489859,\n 0.04216000,\n 0.03950728,\n 0.03693564,\n 0.03445836,\n 0.03208872,\n 0.02984000,\n 0.02771181,\n 0.02569444,\n 0.02378716,\n 0.02198925,\n 0.02030000,\n 0.01871805,\n 0.01724036,\n 0.01586364,\n 0.01458461,\n 0.01340000,\n 0.01230723,\n 0.01130188,\n 0.01037792,\n 0.009529306,\n 0.008749999,\n 0.008035200,\n 0.007381600,\n 0.006785400,\n 0.006242800,\n 0.005749999,\n 0.005303600,\n 0.004899800,\n 0.004534200,\n 0.004202400,\n 0.003900000,\n 0.003623200,\n 0.003370600,\n 0.003141400,\n 0.002934800,\n 0.002749999,\n 0.002585200,\n 0.002438600,\n 0.002309400,\n 0.002196800,\n 0.002100000,\n 0.002017733,\n 0.001948200,\n 0.001889800,\n 0.001840933,\n 0.001800000,\n 0.001766267,\n 0.001737800,\n 0.001711200,\n 0.001683067,\n 0.001650001,\n 0.001610133,\n 0.001564400,\n 0.001513600,\n 0.001458533,\n 0.001400000,\n 0.001336667,\n 0.001270000,\n 0.001205000,\n 0.001146667,\n 0.001100000,\n 0.001068800,\n 0.001049400,\n 0.001035600,\n 0.001021200,\n 0.001000000,\n 0.0009686400,\n 0.0009299200,\n 0.0008868800,\n 0.0008425600,\n 0.0008000000,\n 0.0007609600,\n 0.0007236800,\n 0.0006859200,\n 0.0006454400,\n 0.0006000000,\n 0.0005478667,\n 0.0004916000,\n 0.0004354000,\n 0.0003834667,\n 0.0003400000,\n 0.0003072533,\n 0.0002831600,\n 0.0002654400,\n 0.0002518133,\n 0.0002400000,\n 0.0002295467,\n 0.0002206400,\n 0.0002119600,\n 0.0002021867,\n 0.0001900000,\n 0.0001742133,\n 0.0001556400,\n 0.0001359600,\n 0.0001168533,\n 0.0001000000,\n 0.00008613333,\n 0.00007460000,\n 0.00006500000,\n 0.00005693333,\n 0.00004999999,\n 0.00004416000,\n 0.00003948000,\n 0.00003572000,\n 0.00003264000,\n 0.00003000000,\n 0.00002765333,\n 0.00002556000,\n 0.00002364000,\n 0.00002181333,\n 0.00002000000,\n 0.00001813333,\n 0.00001620000,\n 0.00001420000,\n 0.00001213333,\n 0.00001000000,\n 0.000007733333,\n 0.000005400000,\n 0.000003200000,\n 0.000001333333,\n 0.000000000000,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0]\n\nCIE_lambda = \[360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374,\n 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389,\n 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404,\n 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419,\n 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434,\n 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449,\n 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464,\n 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479,\n 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494,\n 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509,\n 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524,\n 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539,\n 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554,\n 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569,\n 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584,\n 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599,\n 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614,\n 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629,\n 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644,\n 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659,\n 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674,\n 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689,\n 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704,\n 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719,\n 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734,\n 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749,\n 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764,\n 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779,\n 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794,\n 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809,\n 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824,\n 825, 826, 827, 828, 829, 830]\n\n# Input with lots of layers\nnode = nuke.thisNode()\nchannels = node.channels()\n#print( channels )\n\nwavelengths = \[int(x\[1:-3]) for x in channels if x\[-3:] == \".nm\"]\nwavelengths.sort()\nspan = wavelengths\[1] - wavelengths\[0]\n\nmiddle_wavelengths = np.zeros(len(wavelengths))\nmiddle_wavelengths\[0] = (360.0 + wavelengths\[0])*0.5\nfor i in range(1, len(wavelengths)):\n middle_wavelengths\[i] = ((wavelengths\[i-1] + wavelengths\[i])*0.5)\n\nprint( \"Updating expression to handle %d wavelengths - %s\" % (len(wavelengths), middle_wavelengths) )\n\nXc = np.interp(middle_wavelengths, CIE_lambda, CIE_X)\nYc = np.interp(middle_wavelengths, CIE_lambda, CIE_Y)\nZc = np.interp(middle_wavelengths, CIE_lambda, CIE_Z)\n\n# Producing something like\n# _448.nm*0.9 + _462.nm*0.05 + _477.nm*0.05\nXs = \" + \".join( \[\"_%d.nm*%f\" % x for x in zip(wavelengths, Xc)])\nYs = \" + \".join( \[\"_%d.nm*%f\" % x for x in zip(wavelengths, Yc)])\nZs = \" + \".join( \[\"_%d.nm*%f\" % x for x in zip(wavelengths, Zc)])\n\nCIE_Y_integral = 106.856895\n#sampledLambdaStart = wavelengths\[0] - span + 1\n#sampledLambdaEnd = wavelengths\[-1]\n\n# Hard coded for now\nsampledLambdaStart = 360\nsampledLambdaEnd = 830\nnSpectralSamples = len(wavelengths)\nscale = float(sampledLambdaEnd - sampledLambdaStart) / float(CIE_Y_integral * nSpectralSamples)\n\nXs = \"(%s)*%f\" % (Xs, scale)\nYs = \"(%s)*%f\" % (Ys, scale)\nZs = \"(%s)*%f\" % (Zs, scale)\n\n# Expression node\nnode\['expr0'].setValue( Xs )\nnode\['expr1'].setValue( Ys )\nnode\['expr2'].setValue( Zs )\n\nnode\['temp_name0'].setValue( 'wavelengths' )\nnode\['temp_expr0'].setValue( str(len(wavelengths)) )" +STARTLINE} 29 | } 30 | Colorspace { 31 | colorspace_in CIE-XYZ 32 | name ColorspaceInternal 33 | xpos 269 34 | ypos 272 35 | } 36 | Output { 37 | name Output1 38 | xpos 269 39 | ypos 345 40 | } 41 | end_group 42 | -------------------------------------------------------------------------------- /nuke/gizmos/SpectralToXYZ.gizmo: -------------------------------------------------------------------------------- 1 | #! /Applications/TheFoundry/Nuke10.0v1/Nuke10.0v1.app/Contents/MacOS//libnuke-10.0.1.dylib -nx 2 | version 10.0 v1 3 | Gizmo { 4 | addUserKnob {20 User} 5 | addUserKnob {41 CreateSpectralConversionExpression l "Create Spectral Conversion Expression" T ExpressionInternal1.CreateSpectralConversionExpression} 6 | addUserKnob {41 wavelengths T ExpressionInternal1.temp_expr0} 7 | } 8 | Input { 9 | inputs 0 10 | name Input1 11 | xpos 269 12 | ypos 154 13 | } 14 | Expression { 15 | temp_name0 wavelengths 16 | temp_expr0 32 17 | expr0 "(0.0 + _374.nm*0.000293+ _389.nm*0.001572+ _404.nm*0.009390+ _418.nm*0.048996+ _433.nm*0.222478+ _448.nm*0.348940+ _462.nm*0.318700+ _477.nm*0.201086+ _492.nm*0.061266+ _506.nm*0.006296+ _521.nm*0.021735+ _536.nm*0.148111+ _550.nm*0.331438+ _565.nm*0.552951+ _580.nm*0.802876+ _595.nm*1.004319+ _609.nm*1.058444+ _624.nm*0.915219+ _639.nm*0.611314+ _653.nm*0.344456+ _668.nm*0.160133+ _683.nm*0.061703+ _697.nm*0.022700+ _712.nm*0.008395+ _727.nm*0.003004+ _741.nm*0.001076+ _756.nm*0.000370+ _771.nm*0.000130+ _785.nm*0.000048+ _800.nm*0.000017+ _815.nm*0.000006+ _830.nm*0.000002)*0.133356" 18 | expr1 "(0.0 + _374.nm*0.000009+ _389.nm*0.000045+ _404.nm*0.000264+ _418.nm*0.001362+ _433.nm*0.007693+ _448.nm*0.023647+ _462.nm*0.048000+ _477.nm*0.089106+ _492.nm*0.166009+ _506.nm*0.308578+ _521.nm*0.576328+ _536.nm*0.842899+ _550.nm*0.971261+ _565.nm*0.998815+ _580.nm*0.934831+ _595.nm*0.787137+ _609.nm*0.605314+ _624.nm*0.423058+ _639.nm*0.249826+ _653.nm*0.131500+ _668.nm*0.059198+ _683.nm*0.022500+ _697.nm*0.008210+ _712.nm*0.003032+ _727.nm*0.001085+ _741.nm*0.000389+ _756.nm*0.000134+ _771.nm*0.000047+ _785.nm*0.000017+ _800.nm*0.000006+ _815.nm*0.000002+ _830.nm*0.000001)*0.133356" 19 | expr2 "(0.0 + _374.nm*0.001373+ _389.nm*0.007414+ _404.nm*0.044471+ _418.nm*0.233692+ _433.nm*1.077209+ _448.nm*1.753552+ _462.nm*1.744100+ _477.nm*1.313188+ _492.nm*0.634152+ _506.nm*0.286169+ _521.nm*0.124535+ _536.nm*0.046326+ _550.nm*0.015864+ _565.nm*0.004717+ _580.nm*0.001919+ _595.nm*0.001237+ _609.nm*0.000724+ _624.nm*0.000225+ _639.nm*0.000042+ _653.nm*0.000008+ _668.nm*0.000000+ _683.nm*0.000000+ _697.nm*0.000000+ _712.nm*0.000000+ _727.nm*0.000000+ _741.nm*0.000000+ _756.nm*0.000000+ _771.nm*0.000000+ _785.nm*0.000000+ _800.nm*0.000000+ _815.nm*0.000000+ _830.nm*0.000000)*0.133356" 20 | name ExpressionInternal1 21 | selected true 22 | xpos 269 23 | ypos 218 24 | addUserKnob {20 User} 25 | addUserKnob {22 CreateSpectralConversionExpression l "Create Spectral Conversion Expression" T "#\n# Spectral interpolation\n#\nimport numpy as np\n\nCIE_X = \[0.0001299000, 0.0001458470, 0.0001638021, 0.0001840037,\n 0.0002066902, 0.0002321000, 0.0002607280, 0.0002930750,\n 0.0003293880, 0.0003699140, 0.0004149000, 0.0004641587,\n 0.0005189860, 0.0005818540, 0.0006552347, 0.0007416000,\n 0.0008450296, 0.0009645268, 0.001094949, 0.001231154,\n 0.001368000, 0.001502050, 0.001642328, 0.001802382,\n 0.001995757, 0.002236000, 0.002535385, 0.002892603,\n 0.003300829, 0.003753236, 0.004243000, 0.004762389,\n 0.005330048, 0.005978712, 0.006741117, 0.007650000,\n 0.008751373, 0.01002888, 0.01142170, 0.01286901,\n 0.01431000, 0.01570443, 0.01714744, 0.01878122,\n 0.02074801, 0.02319000, 0.02620736, 0.02978248,\n 0.03388092, 0.03846824, 0.04351000, 0.04899560,\n 0.05502260, 0.06171880, 0.06921200, 0.07763000,\n 0.08695811, 0.09717672, 0.1084063, 0.1207672,\n 0.1343800, 0.1493582, 0.1653957, 0.1819831,\n 0.1986110, 0.2147700, 0.2301868, 0.2448797,\n 0.2587773, 0.2718079, 0.2839000, 0.2949438,\n 0.3048965, 0.3137873, 0.3216454, 0.3285000,\n 0.3343513, 0.3392101, 0.3431213, 0.3461296,\n 0.3482800, 0.3495999, 0.3501474, 0.3500130,\n 0.3492870, 0.3480600, 0.3463733, 0.3442624,\n 0.3418088, 0.3390941, 0.3362000, 0.3331977,\n 0.3300411, 0.3266357, 0.3228868, 0.3187000,\n 0.3140251, 0.3088840, 0.3032904, 0.2972579,\n 0.2908000, 0.2839701, 0.2767214, 0.2689178,\n 0.2604227, 0.2511000, 0.2408475, 0.2298512,\n 0.2184072, 0.2068115, 0.1953600, 0.1842136,\n 0.1733273, 0.1626881, 0.1522833, 0.1421000,\n 0.1321786, 0.1225696, 0.1132752, 0.1042979,\n 0.09564000, 0.08729955, 0.07930804, 0.07171776,\n 0.06458099, 0.05795001, 0.05186211, 0.04628152,\n 0.04115088, 0.03641283, 0.03201000, 0.02791720,\n 0.02414440, 0.02068700, 0.01754040, 0.01470000,\n 0.01216179, 0.009919960, 0.007967240, 0.006296346,\n 0.004900000, 0.003777173, 0.002945320, 0.002424880,\n 0.002236293, 0.002400000, 0.002925520, 0.003836560,\n 0.005174840, 0.006982080, 0.009300000, 0.01214949,\n 0.01553588, 0.01947752, 0.02399277, 0.02910000,\n 0.03481485, 0.04112016, 0.04798504, 0.05537861,\n 0.06327000, 0.07163501, 0.08046224, 0.08973996,\n 0.09945645, 0.1096000, 0.1201674, 0.1311145,\n 0.1423679, 0.1538542, 0.1655000, 0.1772571,\n 0.1891400, 0.2011694, 0.2133658, 0.2257499,\n 0.2383209, 0.2510668, 0.2639922, 0.2771017,\n 0.2904000, 0.3038912, 0.3175726, 0.3314384,\n 0.3454828, 0.3597000, 0.3740839, 0.3886396,\n 0.4033784, 0.4183115, 0.4334499, 0.4487953,\n 0.4643360, 0.4800640, 0.4959713, 0.5120501,\n 0.5282959, 0.5446916, 0.5612094, 0.5778215,\n 0.5945000, 0.6112209, 0.6279758, 0.6447602,\n 0.6615697, 0.6784000, 0.6952392, 0.7120586,\n 0.7288284, 0.7455188, 0.7621000, 0.7785432,\n 0.7948256, 0.8109264, 0.8268248, 0.8425000,\n 0.8579325, 0.8730816, 0.8878944, 0.9023181,\n 0.9163000, 0.9297995, 0.9427984, 0.9552776,\n 0.9672179, 0.9786000, 0.9893856, 0.9995488,\n 1.0090892, 1.0180064, 1.0263000, 1.0339827,\n 1.0409860, 1.0471880, 1.0524667, 1.0567000,\n 1.0597944, 1.0617992, 1.0628068, 1.0629096,\n 1.0622000, 1.0607352, 1.0584436, 1.0552244,\n 1.0509768, 1.0456000, 1.0390369, 1.0313608,\n 1.0226662, 1.0130477, 1.0026000, 0.9913675,\n 0.9793314, 0.9664916, 0.9528479, 0.9384000,\n 0.9231940, 0.9072440, 0.8905020, 0.8729200,\n 0.8544499, 0.8350840, 0.8149460, 0.7941860,\n 0.7729540, 0.7514000, 0.7295836, 0.7075888,\n 0.6856022, 0.6638104, 0.6424000, 0.6215149,\n 0.6011138, 0.5811052, 0.5613977, 0.5419000,\n 0.5225995, 0.5035464, 0.4847436, 0.4661939,\n 0.4479000, 0.4298613, 0.4120980, 0.3946440,\n 0.3775333, 0.3608000, 0.3444563, 0.3285168,\n 0.3130192, 0.2980011, 0.2835000, 0.2695448,\n 0.2561184, 0.2431896, 0.2307272, 0.2187000,\n 0.2070971, 0.1959232, 0.1851708, 0.1748323,\n 0.1649000, 0.1553667, 0.1462300, 0.1374900,\n 0.1291467, 0.1212000, 0.1136397, 0.1064650,\n 0.09969044, 0.09333061, 0.08740000, 0.08190096,\n 0.07680428, 0.07207712, 0.06768664, 0.06360000,\n 0.05980685, 0.05628216, 0.05297104, 0.04981861,\n 0.04677000, 0.04378405, 0.04087536, 0.03807264,\n 0.03540461, 0.03290000, 0.03056419, 0.02838056,\n 0.02634484, 0.02445275, 0.02270000, 0.02108429,\n 0.01959988, 0.01823732, 0.01698717, 0.01584000,\n 0.01479064, 0.01383132, 0.01294868, 0.01212920,\n 0.01135916, 0.01062935, 0.009938846, 0.009288422,\n 0.008678854, 0.008110916, 0.007582388, 0.007088746,\n 0.006627313, 0.006195408, 0.005790346, 0.005409826,\n 0.005052583, 0.004717512, 0.004403507, 0.004109457,\n 0.003833913, 0.003575748, 0.003334342, 0.003109075,\n 0.002899327, 0.002704348, 0.002523020, 0.002354168,\n 0.002196616, 0.002049190, 0.001910960, 0.001781438,\n 0.001660110, 0.001546459, 0.001439971, 0.001340042,\n 0.001246275, 0.001158471, 0.001076430, 0.0009999493,\n 0.0009287358, 0.0008624332, 0.0008007503, 0.0007433960,\n 0.0006900786, 0.0006405156, 0.0005945021, 0.0005518646,\n 0.0005124290, 0.0004760213, 0.0004424536, 0.0004115117,\n 0.0003829814, 0.0003566491, 0.0003323011, 0.0003097586,\n 0.0002888871, 0.0002695394, 0.0002515682, 0.0002348261,\n 0.0002191710, 0.0002045258, 0.0001908405, 0.0001780654,\n 0.0001661505, 0.0001550236, 0.0001446219, 0.0001349098,\n 0.0001258520, 0.0001174130, 0.0001095515, 0.0001022245,\n 0.00009539445, 0.00008902390, 0.00008307527, 0.00007751269,\n 0.00007231304, 0.00006745778, 0.00006292844, 0.00005870652,\n 0.00005477028, 0.00005109918, 0.00004767654, 0.00004448567,\n 0.00004150994, 0.00003873324, 0.00003614203, 0.00003372352,\n 0.00003146487, 0.00002935326, 0.00002737573, 0.00002552433,\n 0.00002379376, 0.00002217870, 0.00002067383, 0.00001927226,\n 0.00001796640, 0.00001674991, 0.00001561648, 0.00001455977,\n 0.00001357387, 0.00001265436, 0.00001179723, 0.00001099844,\n 0.00001025398, 0.000009559646, 0.000008912044, 0.000008308358,\n 0.000007745769, 0.000007221456, 0.000006732475, 0.000006276423,\n 0.000005851304, 0.000005455118, 0.000005085868, 0.000004741466,\n 0.000004420236, 0.000004120783, 0.000003841716, 0.000003581652,\n 0.000003339127, 0.000003112949, 0.000002902121, 0.000002705645,\n 0.000002522525, 0.000002351726, 0.000002192415, 0.000002043902,\n 0.000001905497, 0.000001776509, 0.000001656215, 0.000001544022,\n 0.000001439440, 0.000001341977, 0.000001251141]\n\nCIE_Y = \[0.000003917000, 0.000004393581, 0.000004929604, 0.000005532136,\n 0.000006208245, 0.000006965000, 0.000007813219, 0.000008767336,\n 0.000009839844, 0.00001104323, 0.00001239000, 0.00001388641,\n 0.00001555728, 0.00001744296, 0.00001958375, 0.00002202000,\n 0.00002483965, 0.00002804126, 0.00003153104, 0.00003521521,\n 0.00003900000, 0.00004282640, 0.00004691460, 0.00005158960,\n 0.00005717640, 0.00006400000, 0.00007234421, 0.00008221224,\n 0.00009350816, 0.0001061361, 0.0001200000, 0.0001349840,\n 0.0001514920, 0.0001702080, 0.0001918160, 0.0002170000,\n 0.0002469067, 0.0002812400, 0.0003185200, 0.0003572667,\n 0.0003960000, 0.0004337147, 0.0004730240, 0.0005178760,\n 0.0005722187, 0.0006400000, 0.0007245600, 0.0008255000,\n 0.0009411600, 0.001069880, 0.001210000, 0.001362091,\n 0.001530752, 0.001720368, 0.001935323, 0.002180000,\n 0.002454800, 0.002764000, 0.003117800, 0.003526400,\n 0.004000000, 0.004546240, 0.005159320, 0.005829280,\n 0.006546160, 0.007300000, 0.008086507, 0.008908720,\n 0.009767680, 0.01066443, 0.01160000, 0.01257317,\n 0.01358272, 0.01462968, 0.01571509, 0.01684000,\n 0.01800736, 0.01921448, 0.02045392, 0.02171824,\n 0.02300000, 0.02429461, 0.02561024, 0.02695857,\n 0.02835125, 0.02980000, 0.03131083, 0.03288368,\n 0.03452112, 0.03622571, 0.03800000, 0.03984667,\n 0.04176800, 0.04376600, 0.04584267, 0.04800000,\n 0.05024368, 0.05257304, 0.05498056, 0.05745872,\n 0.06000000, 0.06260197, 0.06527752, 0.06804208,\n 0.07091109, 0.07390000, 0.07701600, 0.08026640,\n 0.08366680, 0.08723280, 0.09098000, 0.09491755,\n 0.09904584, 0.1033674, 0.1078846, 0.1126000,\n 0.1175320, 0.1226744, 0.1279928, 0.1334528,\n 0.1390200, 0.1446764, 0.1504693, 0.1564619,\n 0.1627177, 0.1693000, 0.1762431, 0.1835581,\n 0.1912735, 0.1994180, 0.2080200, 0.2171199,\n 0.2267345, 0.2368571, 0.2474812, 0.2586000,\n 0.2701849, 0.2822939, 0.2950505, 0.3085780,\n 0.3230000, 0.3384021, 0.3546858, 0.3716986,\n 0.3892875, 0.4073000, 0.4256299, 0.4443096,\n 0.4633944, 0.4829395, 0.5030000, 0.5235693,\n 0.5445120, 0.5656900, 0.5869653, 0.6082000,\n 0.6293456, 0.6503068, 0.6708752, 0.6908424,\n 0.7100000, 0.7281852, 0.7454636, 0.7619694,\n 0.7778368, 0.7932000, 0.8081104, 0.8224962,\n 0.8363068, 0.8494916, 0.8620000, 0.8738108,\n 0.8849624, 0.8954936, 0.9054432, 0.9148501,\n 0.9237348, 0.9320924, 0.9399226, 0.9472252,\n 0.9540000, 0.9602561, 0.9660074, 0.9712606,\n 0.9760225, 0.9803000, 0.9840924, 0.9874812,\n 0.9903128, 0.9928116, 0.9949501, 0.9967108,\n 0.9980983, 0.9991120, 0.9997482, 1.0000000,\n 0.9998567, 0.9993046, 0.9983255, 0.9968987,\n 0.9950000, 0.9926005, 0.9897426, 0.9864444,\n 0.9827241, 0.9786000, 0.9740837, 0.9691712,\n 0.9638568, 0.9581349, 0.9520000, 0.9454504,\n 0.9384992, 0.9311628, 0.9234576, 0.9154000,\n 0.9070064, 0.8982772, 0.8892048, 0.8797816,\n 0.8700000, 0.8598613, 0.8493920, 0.8386220,\n 0.8275813, 0.8163000, 0.8047947, 0.7930820,\n 0.7811920, 0.7691547, 0.7570000, 0.7447541,\n 0.7324224, 0.7200036, 0.7074965, 0.6949000,\n 0.6822192, 0.6694716, 0.6566744, 0.6438448,\n 0.6310000, 0.6181555, 0.6053144, 0.5924756,\n 0.5796379, 0.5668000, 0.5539611, 0.5411372,\n 0.5283528, 0.5156323, 0.5030000, 0.4904688,\n 0.4780304, 0.4656776, 0.4534032, 0.4412000,\n 0.4290800, 0.4170360, 0.4050320, 0.3930320,\n 0.3810000, 0.3689184, 0.3568272, 0.3447768,\n 0.3328176, 0.3210000, 0.3093381, 0.2978504,\n 0.2865936, 0.2756245, 0.2650000, 0.2547632,\n 0.2448896, 0.2353344, 0.2260528, 0.2170000,\n 0.2081616, 0.1995488, 0.1911552, 0.1829744,\n 0.1750000, 0.1672235, 0.1596464, 0.1522776,\n 0.1451259, 0.1382000, 0.1315003, 0.1250248,\n 0.1187792, 0.1127691, 0.1070000, 0.1014762,\n 0.09618864, 0.09112296, 0.08626485, 0.08160000,\n 0.07712064, 0.07282552, 0.06871008, 0.06476976,\n 0.06100000, 0.05739621, 0.05395504, 0.05067376,\n 0.04754965, 0.04458000, 0.04175872, 0.03908496,\n 0.03656384, 0.03420048, 0.03200000, 0.02996261,\n 0.02807664, 0.02632936, 0.02470805, 0.02320000,\n 0.02180077, 0.02050112, 0.01928108, 0.01812069,\n 0.01700000, 0.01590379, 0.01483718, 0.01381068,\n 0.01283478, 0.01192000, 0.01106831, 0.01027339,\n 0.009533311, 0.008846157, 0.008210000, 0.007623781,\n 0.007085424, 0.006591476, 0.006138485, 0.005723000,\n 0.005343059, 0.004995796, 0.004676404, 0.004380075,\n 0.004102000, 0.003838453, 0.003589099, 0.003354219,\n 0.003134093, 0.002929000, 0.002738139, 0.002559876,\n 0.002393244, 0.002237275, 0.002091000, 0.001953587,\n 0.001824580, 0.001703580, 0.001590187, 0.001484000,\n 0.001384496, 0.001291268, 0.001204092, 0.001122744,\n 0.001047000, 0.0009765896, 0.0009111088, 0.0008501332,\n 0.0007932384, 0.0007400000, 0.0006900827, 0.0006433100,\n 0.0005994960, 0.0005584547, 0.0005200000, 0.0004839136,\n 0.0004500528, 0.0004183452, 0.0003887184, 0.0003611000,\n 0.0003353835, 0.0003114404, 0.0002891656, 0.0002684539,\n 0.0002492000, 0.0002313019, 0.0002146856, 0.0001992884,\n 0.0001850475, 0.0001719000, 0.0001597781, 0.0001486044,\n 0.0001383016, 0.0001287925, 0.0001200000, 0.0001118595,\n 0.0001043224, 0.00009733560, 0.00009084587, 0.00008480000,\n 0.00007914667, 0.00007385800, 0.00006891600, 0.00006430267,\n 0.00006000000, 0.00005598187, 0.00005222560, 0.00004871840,\n 0.00004544747, 0.00004240000, 0.00003956104, 0.00003691512,\n 0.00003444868, 0.00003214816, 0.00003000000, 0.00002799125,\n 0.00002611356, 0.00002436024, 0.00002272461, 0.00002120000,\n 0.00001977855, 0.00001845285, 0.00001721687, 0.00001606459,\n 0.00001499000, 0.00001398728, 0.00001305155, 0.00001217818,\n 0.00001136254, 0.00001060000, 0.000009885877, 0.000009217304,\n 0.000008592362, 0.000008009133, 0.000007465700, 0.000006959567,\n 0.000006487995, 0.000006048699, 0.000005639396, 0.000005257800,\n 0.000004901771, 0.000004569720, 0.000004260194, 0.000003971739,\n 0.000003702900, 0.000003452163, 0.000003218302, 0.000003000300,\n 0.000002797139, 0.000002607800, 0.000002431220, 0.000002266531,\n 0.000002113013, 0.000001969943, 0.000001836600, 0.000001712230,\n 0.000001596228, 0.000001488090, 0.000001387314, 0.000001293400,\n 0.000001205820, 0.000001124143, 0.000001048009, 0.0000009770578,\n 0.0000009109300, 0.0000008492513, 0.0000007917212, 0.0000007380904,\n 0.0000006881098, 0.0000006415300, 0.0000005980895, 0.0000005575746,\n 0.0000005198080, 0.0000004846123, 0.0000004518100]\n\nCIE_Z = \[0.0006061000,\n 0.0006808792,\n 0.0007651456,\n 0.0008600124,\n 0.0009665928,\n 0.001086000,\n 0.001220586,\n 0.001372729,\n 0.001543579,\n 0.001734286,\n 0.001946000,\n 0.002177777,\n 0.002435809,\n 0.002731953,\n 0.003078064,\n 0.003486000,\n 0.003975227,\n 0.004540880,\n 0.005158320,\n 0.005802907,\n 0.006450001,\n 0.007083216,\n 0.007745488,\n 0.008501152,\n 0.009414544,\n 0.01054999,\n 0.01196580,\n 0.01365587,\n 0.01558805,\n 0.01773015,\n 0.02005001,\n 0.02251136,\n 0.02520288,\n 0.02827972,\n 0.03189704,\n 0.03621000,\n 0.04143771,\n 0.04750372,\n 0.05411988,\n 0.06099803,\n 0.06785001,\n 0.07448632,\n 0.08136156,\n 0.08915364,\n 0.09854048,\n 0.1102000,\n 0.1246133,\n 0.1417017,\n 0.1613035,\n 0.1832568,\n 0.2074000,\n 0.2336921,\n 0.2626114,\n 0.2947746,\n 0.3307985,\n 0.3713000,\n 0.4162091,\n 0.4654642,\n 0.5196948,\n 0.5795303,\n 0.6456000,\n 0.7184838,\n 0.7967133,\n 0.8778459,\n 0.9594390,\n 1.0390501,\n 1.1153673,\n 1.1884971,\n 1.2581233,\n 1.3239296,\n 1.3856000,\n 1.4426352,\n 1.4948035,\n 1.5421903,\n 1.5848807,\n 1.6229600,\n 1.6564048,\n 1.6852959,\n 1.7098745,\n 1.7303821,\n 1.7470600,\n 1.7600446,\n 1.7696233,\n 1.7762637,\n 1.7804334,\n 1.7826000,\n 1.7829682,\n 1.7816998,\n 1.7791982,\n 1.7758671,\n 1.7721100,\n 1.7682589,\n 1.7640390,\n 1.7589438,\n 1.7524663,\n 1.7441000,\n 1.7335595,\n 1.7208581,\n 1.7059369,\n 1.6887372,\n 1.6692000,\n 1.6475287,\n 1.6234127,\n 1.5960223,\n 1.5645280,\n 1.5281000,\n 1.4861114,\n 1.4395215,\n 1.3898799,\n 1.3387362,\n 1.2876400,\n 1.2374223,\n 1.1878243,\n 1.1387611,\n 1.0901480,\n 1.0419000,\n 0.9941976,\n 0.9473473,\n 0.9014531,\n 0.8566193,\n 0.8129501,\n 0.7705173,\n 0.7294448,\n 0.6899136,\n 0.6521049,\n 0.6162000,\n 0.5823286,\n 0.5504162,\n 0.5203376,\n 0.4919673,\n 0.4651800,\n 0.4399246,\n 0.4161836,\n 0.3938822,\n 0.3729459,\n 0.3533000,\n 0.3348578,\n 0.3175521,\n 0.3013375,\n 0.2861686,\n 0.2720000,\n 0.2588171,\n 0.2464838,\n 0.2347718,\n 0.2234533,\n 0.2123000,\n 0.2011692,\n 0.1901196,\n 0.1792254,\n 0.1685608,\n 0.1582000,\n 0.1481383,\n 0.1383758,\n 0.1289942,\n 0.1200751,\n 0.1117000,\n 0.1039048,\n 0.09666748,\n 0.08998272,\n 0.08384531,\n 0.07824999,\n 0.07320899,\n 0.06867816,\n 0.06456784,\n 0.06078835,\n 0.05725001,\n 0.05390435,\n 0.05074664,\n 0.04775276,\n 0.04489859,\n 0.04216000,\n 0.03950728,\n 0.03693564,\n 0.03445836,\n 0.03208872,\n 0.02984000,\n 0.02771181,\n 0.02569444,\n 0.02378716,\n 0.02198925,\n 0.02030000,\n 0.01871805,\n 0.01724036,\n 0.01586364,\n 0.01458461,\n 0.01340000,\n 0.01230723,\n 0.01130188,\n 0.01037792,\n 0.009529306,\n 0.008749999,\n 0.008035200,\n 0.007381600,\n 0.006785400,\n 0.006242800,\n 0.005749999,\n 0.005303600,\n 0.004899800,\n 0.004534200,\n 0.004202400,\n 0.003900000,\n 0.003623200,\n 0.003370600,\n 0.003141400,\n 0.002934800,\n 0.002749999,\n 0.002585200,\n 0.002438600,\n 0.002309400,\n 0.002196800,\n 0.002100000,\n 0.002017733,\n 0.001948200,\n 0.001889800,\n 0.001840933,\n 0.001800000,\n 0.001766267,\n 0.001737800,\n 0.001711200,\n 0.001683067,\n 0.001650001,\n 0.001610133,\n 0.001564400,\n 0.001513600,\n 0.001458533,\n 0.001400000,\n 0.001336667,\n 0.001270000,\n 0.001205000,\n 0.001146667,\n 0.001100000,\n 0.001068800,\n 0.001049400,\n 0.001035600,\n 0.001021200,\n 0.001000000,\n 0.0009686400,\n 0.0009299200,\n 0.0008868800,\n 0.0008425600,\n 0.0008000000,\n 0.0007609600,\n 0.0007236800,\n 0.0006859200,\n 0.0006454400,\n 0.0006000000,\n 0.0005478667,\n 0.0004916000,\n 0.0004354000,\n 0.0003834667,\n 0.0003400000,\n 0.0003072533,\n 0.0002831600,\n 0.0002654400,\n 0.0002518133,\n 0.0002400000,\n 0.0002295467,\n 0.0002206400,\n 0.0002119600,\n 0.0002021867,\n 0.0001900000,\n 0.0001742133,\n 0.0001556400,\n 0.0001359600,\n 0.0001168533,\n 0.0001000000,\n 0.00008613333,\n 0.00007460000,\n 0.00006500000,\n 0.00005693333,\n 0.00004999999,\n 0.00004416000,\n 0.00003948000,\n 0.00003572000,\n 0.00003264000,\n 0.00003000000,\n 0.00002765333,\n 0.00002556000,\n 0.00002364000,\n 0.00002181333,\n 0.00002000000,\n 0.00001813333,\n 0.00001620000,\n 0.00001420000,\n 0.00001213333,\n 0.00001000000,\n 0.000007733333,\n 0.000005400000,\n 0.000003200000,\n 0.000001333333,\n 0.000000000000,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0,\n 0.0]\n\nCIE_lambda = \[360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374,\n 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389,\n 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404,\n 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419,\n 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434,\n 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449,\n 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464,\n 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479,\n 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494,\n 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509,\n 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524,\n 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539,\n 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554,\n 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569,\n 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584,\n 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599,\n 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614,\n 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629,\n 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644,\n 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659,\n 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674,\n 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689,\n 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704,\n 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719,\n 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734,\n 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749,\n 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764,\n 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779,\n 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794,\n 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809,\n 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824,\n 825, 826, 827, 828, 829, 830]\n\n# Input with lots of layers\nnode = nuke.thisNode()\nchannels = node.channels()\n#print( channels )\n\nwavelengths = \[int(x\[1:-3]) for x in channels if x\[-3:] == \".nm\"]\nwavelengths.sort()\nspan = wavelengths\[1] - wavelengths\[0]\n\nmiddle_wavelengths = np.zeros(len(wavelengths))\nmiddle_wavelengths\[0] = (360.0 + wavelengths\[0])*0.5\nfor i in range(1, len(wavelengths)):\n middle_wavelengths\[i] = ((wavelengths\[i-1] + wavelengths\[i])*0.5)\n\nprint( \"Updating expression to handle %d wavelengths - %s\" % (len(wavelengths), middle_wavelengths) )\n\nXc = np.interp(middle_wavelengths, CIE_lambda, CIE_X)\nYc = np.interp(middle_wavelengths, CIE_lambda, CIE_Y)\nZc = np.interp(middle_wavelengths, CIE_lambda, CIE_Z)\n\n# Producing something like\n# _448.nm*0.9 + _462.nm*0.05 + _477.nm*0.05\nXs = \" + \".join( \[\"_%d.nm*%f\" % x for x in zip(wavelengths, Xc)])\nYs = \" + \".join( \[\"_%d.nm*%f\" % x for x in zip(wavelengths, Yc)])\nZs = \" + \".join( \[\"_%d.nm*%f\" % x for x in zip(wavelengths, Zc)])\n\nCIE_Y_integral = 106.856895\n#sampledLambdaStart = wavelengths\[0] - span + 1\n#sampledLambdaEnd = wavelengths\[-1]\n\n# Hard coded for now\nsampledLambdaStart = 360\nsampledLambdaEnd = 830\nnSpectralSamples = len(wavelengths)\nscale = float(sampledLambdaEnd - sampledLambdaStart) / float(CIE_Y_integral * nSpectralSamples)\n\nXs = \"(%s)*%f\" % (Xs, scale)\nYs = \"(%s)*%f\" % (Ys, scale)\nZs = \"(%s)*%f\" % (Zs, scale)\n\n# Expression node\nnode\['expr0'].setValue( Xs )\nnode\['expr1'].setValue( Ys )\nnode\['expr2'].setValue( Zs )\n\nnode\['temp_name0'].setValue( 'wavelengths' )\nnode\['temp_expr0'].setValue( str(len(wavelengths)) )" +STARTLINE} 26 | } 27 | Output { 28 | name Output1 29 | xpos 269 30 | ypos 345 31 | } 32 | end_group 33 | -------------------------------------------------------------------------------- /nuke/python/nuke_matrix_transfer.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | def createMatrixInverseNode(matrixNode): 4 | matrixValues = matrixNode['matrix'].getValue() 5 | a = np.array(matrixValues) 6 | a = a.reshape(3, 3) 7 | 8 | ainv = np.linalg.inv(a) 9 | 10 | inverseMatrixNode = nuke.createNode ("ColorMatrix") 11 | matrixInverseValues = ainv.reshape(1,9).tolist()[0] 12 | inverseMatrixNode['matrix'].setValue(matrixInverseValues) 13 | 14 | selectedNode = nuke.selectedNode() 15 | createMatrixInverseNode(selectedNode) 16 | 17 | def combineMatrixNodes(matrixNode1, matrixNode2): 18 | matrixValues1 = matrixNode1['matrix'].getValue() 19 | a = np.array(matrixValues1) 20 | a = a.reshape(3, 3) 21 | 22 | matrixValues2 = matrixNode2['matrix'].getValue() 23 | b = np.array(matrixValues2) 24 | b = b.reshape(3, 3) 25 | 26 | c = np.dot(a, b) 27 | 28 | combinedMatrixNode = nuke.createNode ("ColorMatrix") 29 | combinedMatrixValues = c.reshape(1,9).tolist()[0] 30 | combinedMatrixNode['matrix'].setValue(combinedMatrixValues) 31 | 32 | selectedNodes = nuke.selectedNodes() 33 | combineMatrixNodes(selectedNodes[0], selectedNodes[1]) 34 | 35 | def writeSPIColorMatrix(matrixNode, spiFile): 36 | matrixValues = matrixNode['matrix'].getValue() 37 | 38 | with open(spiFile, "w") as spiFileHandle: 39 | spiFileHandle.write( "%3.6f %3.6f %3.6f 0.0\n" % ( 40 | matrixValues[0], matrixValues[1], matrixValues[2]) ) 41 | spiFileHandle.write( "%3.6f %3.6f %3.6f 0.0\n" % ( 42 | matrixValues[3], matrixValues[4], matrixValues[5]) ) 43 | spiFileHandle.write( "%3.6f %3.6f %3.6f 0.0\n" % ( 44 | matrixValues[6], matrixValues[7], matrixValues[8]) ) 45 | 46 | gamutsFolder = "/Volumes/Titan/Simulator/Scenes/FremontVerticalSlice/Sequences/Shared/cameras/gamuts" 47 | selectedNode = nuke.selectedNode() 48 | spiFile = "%s/canonraw_to_srgb.spimtx" % gamutsFolder 49 | writeSPIColorMatrix(matrixNode, spiFile): 50 | 51 | selectedNode = nuke.selectedNode() 52 | spiFile = "%s/Cam1_canonraw_to_srgb_20170427.spimtx" % gamutsFolder 53 | writeSPIColorMatrix(selectedNode, spiFile) 54 | 55 | def matrix3ToList(nukeMatrix3): 56 | matrixValues = [] 57 | for i in range(9): 58 | matrixValues.append(nukeMatrix3[i]) 59 | return matrixValues 60 | 61 | def listToMatrix3(pyList): 62 | a = nuke.math.Matrix3() 63 | for i in range(9): 64 | a[i] = pyList[i] 65 | return a 66 | 67 | def nodeToMatrix3(matrixNode): 68 | matrixValues = matrixNode['matrix'].getValue() 69 | nukeMatrix3 = nuke.math.Matrix3() 70 | for i in range(9): 71 | nukeMatrix3[i] = matrixValues[i] 72 | return nukeMatrix3 73 | 74 | def matrix3ToNode(nukeMatrix3): 75 | matrixValues = [] 76 | for i in range(9): 77 | matrixValues.append(nukeMatrix3[i]) 78 | nukeMatrixNode = nuke.createNode ("ColorMatrix") 79 | nukeMatrixNode['matrix'].setValue(matrixValues) 80 | return nukeMatrixNode 81 | 82 | def createMatrixInverseNodeNuke(matrixNode=None): 83 | if matrixNode == None: 84 | matrixNode = nuke.selectedNode() 85 | 86 | matrix = nodeToMatrix3(matrixNode) 87 | matrixInverse = matrix.inverse() 88 | matrixInverseNode = matrix3ToNode(matrixInverse) 89 | 90 | def combineMatrixNodesNuke(matrixNodes=None): 91 | if matrixNodes == None: 92 | selectedNodes = nuke.selectedNodes() 93 | matrixNodes = [] 94 | matrixNode[0] = selectedNodes[0] 95 | matrixNode[1] = selectedNodes[1] 96 | 97 | a = nodeToMatrix3(matrixNodes[0]) 98 | b = nodeToMatrix3(matrixNodes[1]) 99 | 100 | invertMatrix = matrixNode[0]['invert'].getValue() 101 | if invertMatrix > 0.0: 102 | a = a.inverse() 103 | invertMatrix = matrixNode[1]['invert'].getValue() 104 | if invertMatrix > 0.0: 105 | b = b.inverse() 106 | 107 | c = a * b 108 | 109 | combinedMatrixNode = matrix3ToNode(c) 110 | 111 | selectedNodes = nuke.selectedNodes() 112 | combineMatrixNodesNuke(selectedNodes[0], selectedNodes[1]) 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /nuke/python/spectral_to_xyz.py: -------------------------------------------------------------------------------- 1 | # 2 | # Spectral interpolation 3 | # 4 | import numpy as np 5 | 6 | CIE_X = [0.0001299000, 0.0001458470, 0.0001638021, 0.0001840037, 7 | 0.0002066902, 0.0002321000, 0.0002607280, 0.0002930750, 8 | 0.0003293880, 0.0003699140, 0.0004149000, 0.0004641587, 9 | 0.0005189860, 0.0005818540, 0.0006552347, 0.0007416000, 10 | 0.0008450296, 0.0009645268, 0.001094949, 0.001231154, 11 | 0.001368000, 0.001502050, 0.001642328, 0.001802382, 12 | 0.001995757, 0.002236000, 0.002535385, 0.002892603, 13 | 0.003300829, 0.003753236, 0.004243000, 0.004762389, 14 | 0.005330048, 0.005978712, 0.006741117, 0.007650000, 15 | 0.008751373, 0.01002888, 0.01142170, 0.01286901, 16 | 0.01431000, 0.01570443, 0.01714744, 0.01878122, 17 | 0.02074801, 0.02319000, 0.02620736, 0.02978248, 18 | 0.03388092, 0.03846824, 0.04351000, 0.04899560, 19 | 0.05502260, 0.06171880, 0.06921200, 0.07763000, 20 | 0.08695811, 0.09717672, 0.1084063, 0.1207672, 21 | 0.1343800, 0.1493582, 0.1653957, 0.1819831, 22 | 0.1986110, 0.2147700, 0.2301868, 0.2448797, 23 | 0.2587773, 0.2718079, 0.2839000, 0.2949438, 24 | 0.3048965, 0.3137873, 0.3216454, 0.3285000, 25 | 0.3343513, 0.3392101, 0.3431213, 0.3461296, 26 | 0.3482800, 0.3495999, 0.3501474, 0.3500130, 27 | 0.3492870, 0.3480600, 0.3463733, 0.3442624, 28 | 0.3418088, 0.3390941, 0.3362000, 0.3331977, 29 | 0.3300411, 0.3266357, 0.3228868, 0.3187000, 30 | 0.3140251, 0.3088840, 0.3032904, 0.2972579, 31 | 0.2908000, 0.2839701, 0.2767214, 0.2689178, 32 | 0.2604227, 0.2511000, 0.2408475, 0.2298512, 33 | 0.2184072, 0.2068115, 0.1953600, 0.1842136, 34 | 0.1733273, 0.1626881, 0.1522833, 0.1421000, 35 | 0.1321786, 0.1225696, 0.1132752, 0.1042979, 36 | 0.09564000, 0.08729955, 0.07930804, 0.07171776, 37 | 0.06458099, 0.05795001, 0.05186211, 0.04628152, 38 | 0.04115088, 0.03641283, 0.03201000, 0.02791720, 39 | 0.02414440, 0.02068700, 0.01754040, 0.01470000, 40 | 0.01216179, 0.009919960, 0.007967240, 0.006296346, 41 | 0.004900000, 0.003777173, 0.002945320, 0.002424880, 42 | 0.002236293, 0.002400000, 0.002925520, 0.003836560, 43 | 0.005174840, 0.006982080, 0.009300000, 0.01214949, 44 | 0.01553588, 0.01947752, 0.02399277, 0.02910000, 45 | 0.03481485, 0.04112016, 0.04798504, 0.05537861, 46 | 0.06327000, 0.07163501, 0.08046224, 0.08973996, 47 | 0.09945645, 0.1096000, 0.1201674, 0.1311145, 48 | 0.1423679, 0.1538542, 0.1655000, 0.1772571, 49 | 0.1891400, 0.2011694, 0.2133658, 0.2257499, 50 | 0.2383209, 0.2510668, 0.2639922, 0.2771017, 51 | 0.2904000, 0.3038912, 0.3175726, 0.3314384, 52 | 0.3454828, 0.3597000, 0.3740839, 0.3886396, 53 | 0.4033784, 0.4183115, 0.4334499, 0.4487953, 54 | 0.4643360, 0.4800640, 0.4959713, 0.5120501, 55 | 0.5282959, 0.5446916, 0.5612094, 0.5778215, 56 | 0.5945000, 0.6112209, 0.6279758, 0.6447602, 57 | 0.6615697, 0.6784000, 0.6952392, 0.7120586, 58 | 0.7288284, 0.7455188, 0.7621000, 0.7785432, 59 | 0.7948256, 0.8109264, 0.8268248, 0.8425000, 60 | 0.8579325, 0.8730816, 0.8878944, 0.9023181, 61 | 0.9163000, 0.9297995, 0.9427984, 0.9552776, 62 | 0.9672179, 0.9786000, 0.9893856, 0.9995488, 63 | 1.0090892, 1.0180064, 1.0263000, 1.0339827, 64 | 1.0409860, 1.0471880, 1.0524667, 1.0567000, 65 | 1.0597944, 1.0617992, 1.0628068, 1.0629096, 66 | 1.0622000, 1.0607352, 1.0584436, 1.0552244, 67 | 1.0509768, 1.0456000, 1.0390369, 1.0313608, 68 | 1.0226662, 1.0130477, 1.0026000, 0.9913675, 69 | 0.9793314, 0.9664916, 0.9528479, 0.9384000, 70 | 0.9231940, 0.9072440, 0.8905020, 0.8729200, 71 | 0.8544499, 0.8350840, 0.8149460, 0.7941860, 72 | 0.7729540, 0.7514000, 0.7295836, 0.7075888, 73 | 0.6856022, 0.6638104, 0.6424000, 0.6215149, 74 | 0.6011138, 0.5811052, 0.5613977, 0.5419000, 75 | 0.5225995, 0.5035464, 0.4847436, 0.4661939, 76 | 0.4479000, 0.4298613, 0.4120980, 0.3946440, 77 | 0.3775333, 0.3608000, 0.3444563, 0.3285168, 78 | 0.3130192, 0.2980011, 0.2835000, 0.2695448, 79 | 0.2561184, 0.2431896, 0.2307272, 0.2187000, 80 | 0.2070971, 0.1959232, 0.1851708, 0.1748323, 81 | 0.1649000, 0.1553667, 0.1462300, 0.1374900, 82 | 0.1291467, 0.1212000, 0.1136397, 0.1064650, 83 | 0.09969044, 0.09333061, 0.08740000, 0.08190096, 84 | 0.07680428, 0.07207712, 0.06768664, 0.06360000, 85 | 0.05980685, 0.05628216, 0.05297104, 0.04981861, 86 | 0.04677000, 0.04378405, 0.04087536, 0.03807264, 87 | 0.03540461, 0.03290000, 0.03056419, 0.02838056, 88 | 0.02634484, 0.02445275, 0.02270000, 0.02108429, 89 | 0.01959988, 0.01823732, 0.01698717, 0.01584000, 90 | 0.01479064, 0.01383132, 0.01294868, 0.01212920, 91 | 0.01135916, 0.01062935, 0.009938846, 0.009288422, 92 | 0.008678854, 0.008110916, 0.007582388, 0.007088746, 93 | 0.006627313, 0.006195408, 0.005790346, 0.005409826, 94 | 0.005052583, 0.004717512, 0.004403507, 0.004109457, 95 | 0.003833913, 0.003575748, 0.003334342, 0.003109075, 96 | 0.002899327, 0.002704348, 0.002523020, 0.002354168, 97 | 0.002196616, 0.002049190, 0.001910960, 0.001781438, 98 | 0.001660110, 0.001546459, 0.001439971, 0.001340042, 99 | 0.001246275, 0.001158471, 0.001076430, 0.0009999493, 100 | 0.0009287358, 0.0008624332, 0.0008007503, 0.0007433960, 101 | 0.0006900786, 0.0006405156, 0.0005945021, 0.0005518646, 102 | 0.0005124290, 0.0004760213, 0.0004424536, 0.0004115117, 103 | 0.0003829814, 0.0003566491, 0.0003323011, 0.0003097586, 104 | 0.0002888871, 0.0002695394, 0.0002515682, 0.0002348261, 105 | 0.0002191710, 0.0002045258, 0.0001908405, 0.0001780654, 106 | 0.0001661505, 0.0001550236, 0.0001446219, 0.0001349098, 107 | 0.0001258520, 0.0001174130, 0.0001095515, 0.0001022245, 108 | 0.00009539445, 0.00008902390, 0.00008307527, 0.00007751269, 109 | 0.00007231304, 0.00006745778, 0.00006292844, 0.00005870652, 110 | 0.00005477028, 0.00005109918, 0.00004767654, 0.00004448567, 111 | 0.00004150994, 0.00003873324, 0.00003614203, 0.00003372352, 112 | 0.00003146487, 0.00002935326, 0.00002737573, 0.00002552433, 113 | 0.00002379376, 0.00002217870, 0.00002067383, 0.00001927226, 114 | 0.00001796640, 0.00001674991, 0.00001561648, 0.00001455977, 115 | 0.00001357387, 0.00001265436, 0.00001179723, 0.00001099844, 116 | 0.00001025398, 0.000009559646, 0.000008912044, 0.000008308358, 117 | 0.000007745769, 0.000007221456, 0.000006732475, 0.000006276423, 118 | 0.000005851304, 0.000005455118, 0.000005085868, 0.000004741466, 119 | 0.000004420236, 0.000004120783, 0.000003841716, 0.000003581652, 120 | 0.000003339127, 0.000003112949, 0.000002902121, 0.000002705645, 121 | 0.000002522525, 0.000002351726, 0.000002192415, 0.000002043902, 122 | 0.000001905497, 0.000001776509, 0.000001656215, 0.000001544022, 123 | 0.000001439440, 0.000001341977, 0.000001251141] 124 | 125 | CIE_Y = [0.000003917000, 0.000004393581, 0.000004929604, 0.000005532136, 126 | 0.000006208245, 0.000006965000, 0.000007813219, 0.000008767336, 127 | 0.000009839844, 0.00001104323, 0.00001239000, 0.00001388641, 128 | 0.00001555728, 0.00001744296, 0.00001958375, 0.00002202000, 129 | 0.00002483965, 0.00002804126, 0.00003153104, 0.00003521521, 130 | 0.00003900000, 0.00004282640, 0.00004691460, 0.00005158960, 131 | 0.00005717640, 0.00006400000, 0.00007234421, 0.00008221224, 132 | 0.00009350816, 0.0001061361, 0.0001200000, 0.0001349840, 133 | 0.0001514920, 0.0001702080, 0.0001918160, 0.0002170000, 134 | 0.0002469067, 0.0002812400, 0.0003185200, 0.0003572667, 135 | 0.0003960000, 0.0004337147, 0.0004730240, 0.0005178760, 136 | 0.0005722187, 0.0006400000, 0.0007245600, 0.0008255000, 137 | 0.0009411600, 0.001069880, 0.001210000, 0.001362091, 138 | 0.001530752, 0.001720368, 0.001935323, 0.002180000, 139 | 0.002454800, 0.002764000, 0.003117800, 0.003526400, 140 | 0.004000000, 0.004546240, 0.005159320, 0.005829280, 141 | 0.006546160, 0.007300000, 0.008086507, 0.008908720, 142 | 0.009767680, 0.01066443, 0.01160000, 0.01257317, 143 | 0.01358272, 0.01462968, 0.01571509, 0.01684000, 144 | 0.01800736, 0.01921448, 0.02045392, 0.02171824, 145 | 0.02300000, 0.02429461, 0.02561024, 0.02695857, 146 | 0.02835125, 0.02980000, 0.03131083, 0.03288368, 147 | 0.03452112, 0.03622571, 0.03800000, 0.03984667, 148 | 0.04176800, 0.04376600, 0.04584267, 0.04800000, 149 | 0.05024368, 0.05257304, 0.05498056, 0.05745872, 150 | 0.06000000, 0.06260197, 0.06527752, 0.06804208, 151 | 0.07091109, 0.07390000, 0.07701600, 0.08026640, 152 | 0.08366680, 0.08723280, 0.09098000, 0.09491755, 153 | 0.09904584, 0.1033674, 0.1078846, 0.1126000, 154 | 0.1175320, 0.1226744, 0.1279928, 0.1334528, 155 | 0.1390200, 0.1446764, 0.1504693, 0.1564619, 156 | 0.1627177, 0.1693000, 0.1762431, 0.1835581, 157 | 0.1912735, 0.1994180, 0.2080200, 0.2171199, 158 | 0.2267345, 0.2368571, 0.2474812, 0.2586000, 159 | 0.2701849, 0.2822939, 0.2950505, 0.3085780, 160 | 0.3230000, 0.3384021, 0.3546858, 0.3716986, 161 | 0.3892875, 0.4073000, 0.4256299, 0.4443096, 162 | 0.4633944, 0.4829395, 0.5030000, 0.5235693, 163 | 0.5445120, 0.5656900, 0.5869653, 0.6082000, 164 | 0.6293456, 0.6503068, 0.6708752, 0.6908424, 165 | 0.7100000, 0.7281852, 0.7454636, 0.7619694, 166 | 0.7778368, 0.7932000, 0.8081104, 0.8224962, 167 | 0.8363068, 0.8494916, 0.8620000, 0.8738108, 168 | 0.8849624, 0.8954936, 0.9054432, 0.9148501, 169 | 0.9237348, 0.9320924, 0.9399226, 0.9472252, 170 | 0.9540000, 0.9602561, 0.9660074, 0.9712606, 171 | 0.9760225, 0.9803000, 0.9840924, 0.9874812, 172 | 0.9903128, 0.9928116, 0.9949501, 0.9967108, 173 | 0.9980983, 0.9991120, 0.9997482, 1.0000000, 174 | 0.9998567, 0.9993046, 0.9983255, 0.9968987, 175 | 0.9950000, 0.9926005, 0.9897426, 0.9864444, 176 | 0.9827241, 0.9786000, 0.9740837, 0.9691712, 177 | 0.9638568, 0.9581349, 0.9520000, 0.9454504, 178 | 0.9384992, 0.9311628, 0.9234576, 0.9154000, 179 | 0.9070064, 0.8982772, 0.8892048, 0.8797816, 180 | 0.8700000, 0.8598613, 0.8493920, 0.8386220, 181 | 0.8275813, 0.8163000, 0.8047947, 0.7930820, 182 | 0.7811920, 0.7691547, 0.7570000, 0.7447541, 183 | 0.7324224, 0.7200036, 0.7074965, 0.6949000, 184 | 0.6822192, 0.6694716, 0.6566744, 0.6438448, 185 | 0.6310000, 0.6181555, 0.6053144, 0.5924756, 186 | 0.5796379, 0.5668000, 0.5539611, 0.5411372, 187 | 0.5283528, 0.5156323, 0.5030000, 0.4904688, 188 | 0.4780304, 0.4656776, 0.4534032, 0.4412000, 189 | 0.4290800, 0.4170360, 0.4050320, 0.3930320, 190 | 0.3810000, 0.3689184, 0.3568272, 0.3447768, 191 | 0.3328176, 0.3210000, 0.3093381, 0.2978504, 192 | 0.2865936, 0.2756245, 0.2650000, 0.2547632, 193 | 0.2448896, 0.2353344, 0.2260528, 0.2170000, 194 | 0.2081616, 0.1995488, 0.1911552, 0.1829744, 195 | 0.1750000, 0.1672235, 0.1596464, 0.1522776, 196 | 0.1451259, 0.1382000, 0.1315003, 0.1250248, 197 | 0.1187792, 0.1127691, 0.1070000, 0.1014762, 198 | 0.09618864, 0.09112296, 0.08626485, 0.08160000, 199 | 0.07712064, 0.07282552, 0.06871008, 0.06476976, 200 | 0.06100000, 0.05739621, 0.05395504, 0.05067376, 201 | 0.04754965, 0.04458000, 0.04175872, 0.03908496, 202 | 0.03656384, 0.03420048, 0.03200000, 0.02996261, 203 | 0.02807664, 0.02632936, 0.02470805, 0.02320000, 204 | 0.02180077, 0.02050112, 0.01928108, 0.01812069, 205 | 0.01700000, 0.01590379, 0.01483718, 0.01381068, 206 | 0.01283478, 0.01192000, 0.01106831, 0.01027339, 207 | 0.009533311, 0.008846157, 0.008210000, 0.007623781, 208 | 0.007085424, 0.006591476, 0.006138485, 0.005723000, 209 | 0.005343059, 0.004995796, 0.004676404, 0.004380075, 210 | 0.004102000, 0.003838453, 0.003589099, 0.003354219, 211 | 0.003134093, 0.002929000, 0.002738139, 0.002559876, 212 | 0.002393244, 0.002237275, 0.002091000, 0.001953587, 213 | 0.001824580, 0.001703580, 0.001590187, 0.001484000, 214 | 0.001384496, 0.001291268, 0.001204092, 0.001122744, 215 | 0.001047000, 0.0009765896, 0.0009111088, 0.0008501332, 216 | 0.0007932384, 0.0007400000, 0.0006900827, 0.0006433100, 217 | 0.0005994960, 0.0005584547, 0.0005200000, 0.0004839136, 218 | 0.0004500528, 0.0004183452, 0.0003887184, 0.0003611000, 219 | 0.0003353835, 0.0003114404, 0.0002891656, 0.0002684539, 220 | 0.0002492000, 0.0002313019, 0.0002146856, 0.0001992884, 221 | 0.0001850475, 0.0001719000, 0.0001597781, 0.0001486044, 222 | 0.0001383016, 0.0001287925, 0.0001200000, 0.0001118595, 223 | 0.0001043224, 0.00009733560, 0.00009084587, 0.00008480000, 224 | 0.00007914667, 0.00007385800, 0.00006891600, 0.00006430267, 225 | 0.00006000000, 0.00005598187, 0.00005222560, 0.00004871840, 226 | 0.00004544747, 0.00004240000, 0.00003956104, 0.00003691512, 227 | 0.00003444868, 0.00003214816, 0.00003000000, 0.00002799125, 228 | 0.00002611356, 0.00002436024, 0.00002272461, 0.00002120000, 229 | 0.00001977855, 0.00001845285, 0.00001721687, 0.00001606459, 230 | 0.00001499000, 0.00001398728, 0.00001305155, 0.00001217818, 231 | 0.00001136254, 0.00001060000, 0.000009885877, 0.000009217304, 232 | 0.000008592362, 0.000008009133, 0.000007465700, 0.000006959567, 233 | 0.000006487995, 0.000006048699, 0.000005639396, 0.000005257800, 234 | 0.000004901771, 0.000004569720, 0.000004260194, 0.000003971739, 235 | 0.000003702900, 0.000003452163, 0.000003218302, 0.000003000300, 236 | 0.000002797139, 0.000002607800, 0.000002431220, 0.000002266531, 237 | 0.000002113013, 0.000001969943, 0.000001836600, 0.000001712230, 238 | 0.000001596228, 0.000001488090, 0.000001387314, 0.000001293400, 239 | 0.000001205820, 0.000001124143, 0.000001048009, 0.0000009770578, 240 | 0.0000009109300, 0.0000008492513, 0.0000007917212, 0.0000007380904, 241 | 0.0000006881098, 0.0000006415300, 0.0000005980895, 0.0000005575746, 242 | 0.0000005198080, 0.0000004846123, 0.0000004518100] 243 | 244 | CIE_Z = [0.0006061000, 245 | 0.0006808792, 246 | 0.0007651456, 247 | 0.0008600124, 248 | 0.0009665928, 249 | 0.001086000, 250 | 0.001220586, 251 | 0.001372729, 252 | 0.001543579, 253 | 0.001734286, 254 | 0.001946000, 255 | 0.002177777, 256 | 0.002435809, 257 | 0.002731953, 258 | 0.003078064, 259 | 0.003486000, 260 | 0.003975227, 261 | 0.004540880, 262 | 0.005158320, 263 | 0.005802907, 264 | 0.006450001, 265 | 0.007083216, 266 | 0.007745488, 267 | 0.008501152, 268 | 0.009414544, 269 | 0.01054999, 270 | 0.01196580, 271 | 0.01365587, 272 | 0.01558805, 273 | 0.01773015, 274 | 0.02005001, 275 | 0.02251136, 276 | 0.02520288, 277 | 0.02827972, 278 | 0.03189704, 279 | 0.03621000, 280 | 0.04143771, 281 | 0.04750372, 282 | 0.05411988, 283 | 0.06099803, 284 | 0.06785001, 285 | 0.07448632, 286 | 0.08136156, 287 | 0.08915364, 288 | 0.09854048, 289 | 0.1102000, 290 | 0.1246133, 291 | 0.1417017, 292 | 0.1613035, 293 | 0.1832568, 294 | 0.2074000, 295 | 0.2336921, 296 | 0.2626114, 297 | 0.2947746, 298 | 0.3307985, 299 | 0.3713000, 300 | 0.4162091, 301 | 0.4654642, 302 | 0.5196948, 303 | 0.5795303, 304 | 0.6456000, 305 | 0.7184838, 306 | 0.7967133, 307 | 0.8778459, 308 | 0.9594390, 309 | 1.0390501, 310 | 1.1153673, 311 | 1.1884971, 312 | 1.2581233, 313 | 1.3239296, 314 | 1.3856000, 315 | 1.4426352, 316 | 1.4948035, 317 | 1.5421903, 318 | 1.5848807, 319 | 1.6229600, 320 | 1.6564048, 321 | 1.6852959, 322 | 1.7098745, 323 | 1.7303821, 324 | 1.7470600, 325 | 1.7600446, 326 | 1.7696233, 327 | 1.7762637, 328 | 1.7804334, 329 | 1.7826000, 330 | 1.7829682, 331 | 1.7816998, 332 | 1.7791982, 333 | 1.7758671, 334 | 1.7721100, 335 | 1.7682589, 336 | 1.7640390, 337 | 1.7589438, 338 | 1.7524663, 339 | 1.7441000, 340 | 1.7335595, 341 | 1.7208581, 342 | 1.7059369, 343 | 1.6887372, 344 | 1.6692000, 345 | 1.6475287, 346 | 1.6234127, 347 | 1.5960223, 348 | 1.5645280, 349 | 1.5281000, 350 | 1.4861114, 351 | 1.4395215, 352 | 1.3898799, 353 | 1.3387362, 354 | 1.2876400, 355 | 1.2374223, 356 | 1.1878243, 357 | 1.1387611, 358 | 1.0901480, 359 | 1.0419000, 360 | 0.9941976, 361 | 0.9473473, 362 | 0.9014531, 363 | 0.8566193, 364 | 0.8129501, 365 | 0.7705173, 366 | 0.7294448, 367 | 0.6899136, 368 | 0.6521049, 369 | 0.6162000, 370 | 0.5823286, 371 | 0.5504162, 372 | 0.5203376, 373 | 0.4919673, 374 | 0.4651800, 375 | 0.4399246, 376 | 0.4161836, 377 | 0.3938822, 378 | 0.3729459, 379 | 0.3533000, 380 | 0.3348578, 381 | 0.3175521, 382 | 0.3013375, 383 | 0.2861686, 384 | 0.2720000, 385 | 0.2588171, 386 | 0.2464838, 387 | 0.2347718, 388 | 0.2234533, 389 | 0.2123000, 390 | 0.2011692, 391 | 0.1901196, 392 | 0.1792254, 393 | 0.1685608, 394 | 0.1582000, 395 | 0.1481383, 396 | 0.1383758, 397 | 0.1289942, 398 | 0.1200751, 399 | 0.1117000, 400 | 0.1039048, 401 | 0.09666748, 402 | 0.08998272, 403 | 0.08384531, 404 | 0.07824999, 405 | 0.07320899, 406 | 0.06867816, 407 | 0.06456784, 408 | 0.06078835, 409 | 0.05725001, 410 | 0.05390435, 411 | 0.05074664, 412 | 0.04775276, 413 | 0.04489859, 414 | 0.04216000, 415 | 0.03950728, 416 | 0.03693564, 417 | 0.03445836, 418 | 0.03208872, 419 | 0.02984000, 420 | 0.02771181, 421 | 0.02569444, 422 | 0.02378716, 423 | 0.02198925, 424 | 0.02030000, 425 | 0.01871805, 426 | 0.01724036, 427 | 0.01586364, 428 | 0.01458461, 429 | 0.01340000, 430 | 0.01230723, 431 | 0.01130188, 432 | 0.01037792, 433 | 0.009529306, 434 | 0.008749999, 435 | 0.008035200, 436 | 0.007381600, 437 | 0.006785400, 438 | 0.006242800, 439 | 0.005749999, 440 | 0.005303600, 441 | 0.004899800, 442 | 0.004534200, 443 | 0.004202400, 444 | 0.003900000, 445 | 0.003623200, 446 | 0.003370600, 447 | 0.003141400, 448 | 0.002934800, 449 | 0.002749999, 450 | 0.002585200, 451 | 0.002438600, 452 | 0.002309400, 453 | 0.002196800, 454 | 0.002100000, 455 | 0.002017733, 456 | 0.001948200, 457 | 0.001889800, 458 | 0.001840933, 459 | 0.001800000, 460 | 0.001766267, 461 | 0.001737800, 462 | 0.001711200, 463 | 0.001683067, 464 | 0.001650001, 465 | 0.001610133, 466 | 0.001564400, 467 | 0.001513600, 468 | 0.001458533, 469 | 0.001400000, 470 | 0.001336667, 471 | 0.001270000, 472 | 0.001205000, 473 | 0.001146667, 474 | 0.001100000, 475 | 0.001068800, 476 | 0.001049400, 477 | 0.001035600, 478 | 0.001021200, 479 | 0.001000000, 480 | 0.0009686400, 481 | 0.0009299200, 482 | 0.0008868800, 483 | 0.0008425600, 484 | 0.0008000000, 485 | 0.0007609600, 486 | 0.0007236800, 487 | 0.0006859200, 488 | 0.0006454400, 489 | 0.0006000000, 490 | 0.0005478667, 491 | 0.0004916000, 492 | 0.0004354000, 493 | 0.0003834667, 494 | 0.0003400000, 495 | 0.0003072533, 496 | 0.0002831600, 497 | 0.0002654400, 498 | 0.0002518133, 499 | 0.0002400000, 500 | 0.0002295467, 501 | 0.0002206400, 502 | 0.0002119600, 503 | 0.0002021867, 504 | 0.0001900000, 505 | 0.0001742133, 506 | 0.0001556400, 507 | 0.0001359600, 508 | 0.0001168533, 509 | 0.0001000000, 510 | 0.00008613333, 511 | 0.00007460000, 512 | 0.00006500000, 513 | 0.00005693333, 514 | 0.00004999999, 515 | 0.00004416000, 516 | 0.00003948000, 517 | 0.00003572000, 518 | 0.00003264000, 519 | 0.00003000000, 520 | 0.00002765333, 521 | 0.00002556000, 522 | 0.00002364000, 523 | 0.00002181333, 524 | 0.00002000000, 525 | 0.00001813333, 526 | 0.00001620000, 527 | 0.00001420000, 528 | 0.00001213333, 529 | 0.00001000000, 530 | 0.000007733333, 531 | 0.000005400000, 532 | 0.000003200000, 533 | 0.000001333333, 534 | 0.000000000000, 535 | 0.0, 536 | 0.0, 537 | 0.0, 538 | 0.0, 539 | 0.0, 540 | 0.0, 541 | 0.0, 542 | 0.0, 543 | 0.0, 544 | 0.0, 545 | 0.0, 546 | 0.0, 547 | 0.0, 548 | 0.0, 549 | 0.0, 550 | 0.0, 551 | 0.0, 552 | 0.0, 553 | 0.0, 554 | 0.0, 555 | 0.0, 556 | 0.0, 557 | 0.0, 558 | 0.0, 559 | 0.0, 560 | 0.0, 561 | 0.0, 562 | 0.0, 563 | 0.0, 564 | 0.0, 565 | 0.0, 566 | 0.0, 567 | 0.0, 568 | 0.0, 569 | 0.0, 570 | 0.0, 571 | 0.0, 572 | 0.0, 573 | 0.0, 574 | 0.0, 575 | 0.0, 576 | 0.0, 577 | 0.0, 578 | 0.0, 579 | 0.0, 580 | 0.0, 581 | 0.0, 582 | 0.0, 583 | 0.0, 584 | 0.0, 585 | 0.0, 586 | 0.0, 587 | 0.0, 588 | 0.0, 589 | 0.0, 590 | 0.0, 591 | 0.0, 592 | 0.0, 593 | 0.0, 594 | 0.0, 595 | 0.0, 596 | 0.0, 597 | 0.0, 598 | 0.0, 599 | 0.0, 600 | 0.0, 601 | 0.0, 602 | 0.0, 603 | 0.0, 604 | 0.0, 605 | 0.0, 606 | 0.0, 607 | 0.0, 608 | 0.0, 609 | 0.0, 610 | 0.0, 611 | 0.0, 612 | 0.0, 613 | 0.0, 614 | 0.0, 615 | 0.0, 616 | 0.0, 617 | 0.0, 618 | 0.0, 619 | 0.0, 620 | 0.0, 621 | 0.0, 622 | 0.0, 623 | 0.0, 624 | 0.0, 625 | 0.0, 626 | 0.0, 627 | 0.0, 628 | 0.0, 629 | 0.0, 630 | 0.0, 631 | 0.0, 632 | 0.0, 633 | 0.0, 634 | 0.0, 635 | 0.0, 636 | 0.0, 637 | 0.0, 638 | 0.0, 639 | 0.0, 640 | 0.0, 641 | 0.0, 642 | 0.0, 643 | 0.0, 644 | 0.0, 645 | 0.0, 646 | 0.0, 647 | 0.0, 648 | 0.0, 649 | 0.0, 650 | 0.0, 651 | 0.0, 652 | 0.0, 653 | 0.0, 654 | 0.0, 655 | 0.0, 656 | 0.0, 657 | 0.0, 658 | 0.0, 659 | 0.0, 660 | 0.0, 661 | 0.0, 662 | 0.0, 663 | 0.0, 664 | 0.0, 665 | 0.0, 666 | 0.0, 667 | 0.0, 668 | 0.0, 669 | 0.0, 670 | 0.0, 671 | 0.0, 672 | 0.0, 673 | 0.0, 674 | 0.0, 675 | 0.0, 676 | 0.0, 677 | 0.0, 678 | 0.0, 679 | 0.0, 680 | 0.0, 681 | 0.0, 682 | 0.0, 683 | 0.0, 684 | 0.0, 685 | 0.0, 686 | 0.0, 687 | 0.0, 688 | 0.0, 689 | 0.0, 690 | 0.0, 691 | 0.0, 692 | 0.0, 693 | 0.0, 694 | 0.0, 695 | 0.0, 696 | 0.0, 697 | 0.0, 698 | 0.0, 699 | 0.0, 700 | 0.0, 701 | 0.0, 702 | 0.0, 703 | 0.0, 704 | 0.0, 705 | 0.0, 706 | 0.0, 707 | 0.0, 708 | 0.0, 709 | 0.0, 710 | 0.0, 711 | 0.0, 712 | 0.0, 713 | 0.0, 714 | 0.0] 715 | 716 | CIE_lambda = [360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 717 | 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 718 | 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 719 | 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 720 | 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 721 | 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 722 | 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 723 | 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 724 | 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 725 | 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 726 | 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 727 | 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 728 | 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 729 | 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 730 | 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 731 | 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 732 | 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 733 | 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 734 | 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 735 | 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 736 | 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 737 | 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 738 | 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 739 | 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 740 | 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 741 | 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 742 | 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 743 | 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 744 | 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 745 | 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 746 | 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 747 | 825, 826, 827, 828, 829, 830] 748 | 749 | # Input with lots of layers 750 | node = nuke.thisNode() 751 | channels = node.channels() 752 | #print( channels ) 753 | 754 | wavelengths = [int(x[1:-3]) for x in channels if x[-3:] == ".nm"] 755 | wavelengths.sort() 756 | span = wavelengths[1] - wavelengths[0] 757 | 758 | middle_wavelengths = np.zeros(len(wavelengths)) 759 | middle_wavelengths[0] = (360.0 + wavelengths[0])*0.5 760 | for i in range(1, len(wavelengths)): 761 | middle_wavelengths[i] = ((wavelengths[i-1] + wavelengths[i])*0.5) 762 | 763 | print( "Updating expression to handle %d wavelengths - %s" % (len(wavelengths), middle_wavelengths) ) 764 | 765 | Xc = np.interp(middle_wavelengths, CIE_lambda, CIE_X) 766 | Yc = np.interp(middle_wavelengths, CIE_lambda, CIE_Y) 767 | Zc = np.interp(middle_wavelengths, CIE_lambda, CIE_Z) 768 | 769 | # Producing something like 770 | # _448.nm*0.9 + _462.nm*0.05 + _477.nm*0.05 771 | Xs = " + ".join( ["_%d.nm*%f" % x for x in zip(wavelengths, Xc)]) 772 | Ys = " + ".join( ["_%d.nm*%f" % x for x in zip(wavelengths, Yc)]) 773 | Zs = " + ".join( ["_%d.nm*%f" % x for x in zip(wavelengths, Zc)]) 774 | 775 | CIE_Y_integral = 106.856895 776 | #sampledLambdaStart = wavelengths[0] 777 | #sampledLambdaEnd = wavelengths[-1] 778 | # Hard coded for now 779 | sampledLambdaStart = 360 780 | sampledLambdaEnd = 830 781 | nSpectralSamples = len(wavelengths) 782 | scale = float(sampledLambdaEnd - sampledLambdaStart) / float(CIE_Y_integral * nSpectralSamples) 783 | 784 | Xs = "(%s)*%f" % (Xs, scale) 785 | Ys = "(%s)*%f" % (Ys, scale) 786 | Zs = "(%s)*%f" % (Zs, scale) 787 | 788 | # Expression node 789 | node['expr0'].setValue( Xs ) 790 | node['expr1'].setValue( Ys ) 791 | node['expr2'].setValue( Zs ) 792 | 793 | node['temp_name0'].setValue( 'wavelengths' ) 794 | node['temp_expr0'].setValue( str(len(wavelengths)) ) 795 | 796 | -------------------------------------------------------------------------------- /opencv/README.md: -------------------------------------------------------------------------------- 1 | ## OpenCV-based Python scripts ## 2 | 3 | A set of scripts that wrap functionality from the OpenCV Python bindings. 4 | 5 | These were tested with OpenCV version 3.3.1 6 | 7 | Dependencies 8 | - 9 | This *Python* script depends on the following libraries: 10 | 11 | - **OpenCV**: https://opencv.org/ 12 | - **OpenImageIO**: http://openimageio.org 13 | - Detailed build instructions can be found here: [OpenImageIO Build Instructions](https://sites.google.com/site/openimageio/checking-out-and-building-openimageio) 14 | 15 | Building on Mac OSX 16 | - 17 | Use the following commands to build this packages on Mac OSX 18 | 19 | - Update the homebrew repository of install scripts to make sure that OpenImageIO is included. 20 | - brew tap homebrew/science 21 | - Required Dependencies for OpenImageIO 22 | - brew install -vd libRaw 23 | - Optional Dependencies for OpenImageIO 24 | - brew install -vd OpenCV 25 | - OpenImageIO 26 | - brew install -vd openimageio --with-python 27 | -------------------------------------------------------------------------------- /opencv/findOpticalFlow.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import array 3 | import numpy as np 4 | import sys 5 | 6 | import OpenImageIO as oiio 7 | from OpenImageIO import ImageBuf, ImageSpec, ImageBufAlgo, ImageInput, ROI 8 | 9 | def ImageBufReorient(imageBuf, orientation): 10 | ''' 11 | Resets the orientation of the image 12 | ''' 13 | 14 | ''' 15 | Orientation 6 and 8 seem to be reversed in OIIO, at least for Canon 16 | cameras... This needs to be investigated further. 17 | ''' 18 | if orientation == 6: 19 | imageBuf.specmod().attribute ("Orientation", 1) 20 | ImageBufAlgo.rotate90(imageBuf, imageBuf) 21 | ImageBufAlgo.reorient (imageBuf, imageBuf) 22 | 23 | elif orientation == 8: 24 | imageBuf.specmod().attribute ("Orientation", 1) 25 | ImageBufAlgo.rotate270(imageBuf, imageBuf) 26 | ImageBufAlgo.reorient (imageBuf, imageBuf) 27 | 28 | else: 29 | ImageBufAlgo.reorient (imageBuf, imageBuf) 30 | 31 | def OpenCVImageBufferFromOIIOImageBuffer(oiioImageBuffer): 32 | oiioSpec = oiioImageBuffer.spec() 33 | (width, height, channels) = (oiioSpec.width, oiioSpec.height, oiioSpec.nchannels) 34 | oiioFormat = oiioSpec.format 35 | oiioChanneltype = oiioFormat.basetype 36 | 37 | #print( "OpenCVImageBufferFromOIIOImageBuffer", width, height, channels, oiioChanneltype ) 38 | 39 | # Promote halfs to full float as Python may not handle those properly 40 | if oiioChanneltype == oiio.BASETYPE.HALF: 41 | oiioChanneltype = oiio.BASETYPE.FLOAT 42 | 43 | oiioToNPBitDepth = { 44 | oiio.BASETYPE.UINT8 : np.uint8, 45 | oiio.BASETYPE.UINT16 : np.uint16, 46 | oiio.BASETYPE.UINT32 : np.uint32, 47 | oiio.BASETYPE.HALF : np.float16, 48 | oiio.BASETYPE.FLOAT : np.float32, 49 | oiio.BASETYPE.DOUBLE : np.float64, 50 | } 51 | 52 | # Default to float 53 | if oiioChanneltype in oiioToNPBitDepth: 54 | npChannelType = oiioToNPBitDepth[oiioChanneltype] 55 | else: 56 | print( "oiio to opencv - Using fallback bit depth" ) 57 | npChannelType = np.float32 58 | 59 | opencvImageBuffer = np.array(oiioImageBuffer.get_pixels(oiioChanneltype), dtype=npChannelType).reshape(height, width, channels) 60 | 61 | return opencvImageBuffer 62 | 63 | def OIIOImageBufferFromOpenCVImageBuffer(opencvImageBuffer): 64 | (height, width, channels) = opencvImageBuffer.shape 65 | npChanneltype = opencvImageBuffer.dtype 66 | 67 | #print( "OIIOImageBufferFromOpenCVImageBuffer", width, height, channels, npChanneltype ) 68 | 69 | npToArrayBitDepth = { 70 | np.dtype('uint8') : 'B', 71 | np.dtype('uint16') : 'H', 72 | np.dtype('uint32') : 'I', 73 | np.dtype('float32') : 'f', 74 | np.dtype('float64') : 'd', 75 | } 76 | 77 | npToOIIOBitDepth = { 78 | np.dtype('uint8') : oiio.BASETYPE.UINT8, 79 | np.dtype('uint16') : oiio.BASETYPE.UINT16, 80 | np.dtype('uint32') : oiio.BASETYPE.UINT32, 81 | np.dtype('float32') : oiio.BASETYPE.FLOAT, 82 | np.dtype('float64') : oiio.BASETYPE.DOUBLE, 83 | } 84 | 85 | # Support this when oiio more directly integrates with numpy 86 | # np.dtype('float16') : oiio.BASETYPE.HALF, 87 | 88 | if (npChanneltype in npToArrayBitDepth and 89 | npChanneltype in npToOIIOBitDepth): 90 | arrayChannelType = npToArrayBitDepth[npChanneltype] 91 | oiioChanneltype = npToOIIOBitDepth[npChanneltype] 92 | else: 93 | print( "opencv to oiio - Using fallback bit depth" ) 94 | arrayChannelType = 'f' 95 | oiioChanneltype = oiio.BASETYPE.FLOAT 96 | 97 | spec = ImageSpec(width, height, channels, oiioChanneltype) 98 | oiioImageBuffer = ImageBuf(spec) 99 | roi = oiio.ROI(0, width, 0, height, 0, 1, 0, channels) 100 | conversion = oiioImageBuffer.set_pixels( roi, array.array(arrayChannelType, opencvImageBuffer.flatten()) ) 101 | if not conversion: 102 | print( "opencv to oiio - Error converting the OpenCV buffer to an OpenImageIO buffer" ) 103 | oiioImageBuffer = None 104 | 105 | return oiioImageBuffer 106 | 107 | def applyOpticalFlow(img, flow): 108 | h, w = flow.shape[:2] 109 | base = np.dstack(np.meshgrid(np.arange(w), np.arange(h))) 110 | pixel_map = np.array(base + -flow, dtype=np.float32) 111 | 112 | res = cv2.remap(img, pixel_map, None, cv2.INTER_LINEAR) 113 | return res 114 | 115 | def findOpticalFlow(inputImage1, 116 | inputImage2, 117 | outputWarpedImage, 118 | outputFlowImage, 119 | verbose, 120 | opticalFlowImplementation="simpleflow"): 121 | 122 | oiioImageBuffer1 = ImageBuf( inputImage1 ) 123 | ImageBufReorient(oiioImageBuffer1, oiioImageBuffer1.orientation) 124 | 125 | oiioImageBuffer2 = ImageBuf( inputImage2 ) 126 | ImageBufReorient(oiioImageBuffer2, oiioImageBuffer2.orientation) 127 | 128 | if verbose: 129 | print( "load and convert 1 - %s" % inputImage1 ) 130 | openCVImageBuffer1 = OpenCVImageBufferFromOIIOImageBuffer(oiioImageBuffer1) 131 | if verbose: 132 | print( "load and convert 2 - %s" % inputImage2 ) 133 | openCVImageBuffer2 = OpenCVImageBufferFromOIIOImageBuffer(oiioImageBuffer2) 134 | 135 | if verbose: 136 | print( "resolution : %s" % str(openCVImageBuffer1.shape) ) 137 | print( "calculate optical flow 1 -> 2") 138 | 139 | if opticalFlowImplementation == "old_farneback": 140 | if verbose: 141 | print( "older farneback implementation" ) 142 | 143 | if verbose: 144 | print( "to grey 1") 145 | gray1 = cv2.cvtColor(openCVImageBuffer1, cv2.COLOR_BGR2GRAY) 146 | 147 | if verbose: 148 | print( "to grey 2") 149 | gray2 = cv2.cvtColor(openCVImageBuffer2, cv2.COLOR_BGR2GRAY) 150 | 151 | previous_flow = None 152 | pyramid_scale = 0.5 153 | pyramid_levels = 5 154 | window_size = 50 155 | iterations_per_pyramid_level = 20 156 | pixel_neighborhood_size = 3 157 | neighborhood_match_smoothing_factor = 1.0 158 | flags = cv2.OPTFLOW_FARNEBACK_GAUSSIAN 159 | 160 | if verbose: 161 | print( "calculate") 162 | opencvFlow = cv2.calcOpticalFlowFarneback(gray1, gray2, 163 | previous_flow, pyramid_scale, pyramid_levels, window_size, iterations_per_pyramid_level, 164 | pixel_neighborhood_size, neighborhood_match_smoothing_factor, flags) 165 | 166 | elif opticalFlowImplementation == "farneback": 167 | if verbose: 168 | print( "farneback implementation" ) 169 | 170 | if verbose: 171 | print( "to grey 1") 172 | gray1 = cv2.cvtColor(openCVImageBuffer1, cv2.COLOR_BGR2GRAY) 173 | 174 | if verbose: 175 | print( "to grey 2") 176 | gray2 = cv2.cvtColor(openCVImageBuffer2, cv2.COLOR_BGR2GRAY) 177 | 178 | # Set of constants should be added 179 | implementation = cv2.optflow.createOptFlow_Farneback() 180 | if verbose: 181 | print( "calculate") 182 | opencvFlow = implementation.calc(gray1, gray2, None) 183 | 184 | elif opticalFlowImplementation == "dualtvl1": 185 | if verbose: 186 | print( "dualtvl1 implementation" ) 187 | 188 | if verbose: 189 | print( "to grey 1") 190 | gray1 = cv2.cvtColor(openCVImageBuffer1, cv2.COLOR_BGR2GRAY) 191 | 192 | if verbose: 193 | print( "to grey 2") 194 | gray2 = cv2.cvtColor(openCVImageBuffer2, cv2.COLOR_BGR2GRAY) 195 | 196 | # Set of constants should be added 197 | implementation = cv2.createOptFlow_DualTVL1() 198 | if verbose: 199 | print( "calculate") 200 | opencvFlow = implementation.calc(gray1, gray2, None) 201 | 202 | elif opticalFlowImplementation == "sparsetodense": 203 | if verbose: 204 | print( "sparse to dense implementation" ) 205 | # Current set of constants... Ranges and good values should be documented 206 | if verbose: 207 | print( "calculate") 208 | opencvFlow = cv2.optflow.calcOpticalFlowSparseToDense(openCVImageBuffer1, openCVImageBuffer2, None, 209 | 8, 128, 0.05, True, 500.0, 1.5) 210 | 211 | elif opticalFlowImplementation == "deepflow": 212 | if verbose: 213 | print( "deep flow implementation" ) 214 | 215 | if verbose: 216 | print( "to grey 1") 217 | gray1 = cv2.cvtColor(openCVImageBuffer1, cv2.COLOR_BGR2GRAY) 218 | 219 | if verbose: 220 | print( "to grey 2") 221 | gray2 = cv2.cvtColor(openCVImageBuffer2, cv2.COLOR_BGR2GRAY) 222 | 223 | # Set of constants should be added 224 | implementation = cv2.optflow.createOptFlow_DeepFlow() 225 | if verbose: 226 | print( "calculate") 227 | opencvFlow = implementation.calc(gray1, gray2, None) 228 | 229 | elif opticalFlowImplementation == "dis": 230 | if verbose: 231 | print( "dis implementation" ) 232 | 233 | if verbose: 234 | print( "to grey 1") 235 | gray1 = cv2.cvtColor(openCVImageBuffer1, cv2.COLOR_BGR2GRAY) 236 | 237 | if verbose: 238 | print( "to grey 2") 239 | gray2 = cv2.cvtColor(openCVImageBuffer2, cv2.COLOR_BGR2GRAY) 240 | 241 | # Set of constants should be added 242 | implementation = cv2.optflow.createOptFlow_DIS() 243 | if verbose: 244 | print( "calculate") 245 | opencvFlow = implementation.calc(gray1, gray2, None) 246 | 247 | elif opticalFlowImplementation == "pcaflow": 248 | if verbose: 249 | print( "pca flow implementation" ) 250 | 251 | if verbose: 252 | print( "to grey 1") 253 | gray1 = cv2.cvtColor(openCVImageBuffer1, cv2.COLOR_BGR2GRAY) 254 | 255 | if verbose: 256 | print( "to grey 2") 257 | gray2 = cv2.cvtColor(openCVImageBuffer2, cv2.COLOR_BGR2GRAY) 258 | 259 | # Set of constants should be added 260 | implementation = cv2.optflow.createOptFlow_PCAFlow() 261 | if verbose: 262 | print( "calculate") 263 | opencvFlow = implementation.calc(gray1, gray2, None) 264 | 265 | elif opticalFlowImplementation == "simpleflow": 266 | if verbose: 267 | print( "simple flow implementation" ) 268 | # Current set of constants... Ranges and good values should be documented 269 | opencvFlow = cv2.optflow.calcOpticalFlowSF(openCVImageBuffer1, openCVImageBuffer2, 270 | 3, 2, 4, 4.1, 25.5, 18, 55.0, 25.5, 0.35, 18, 55.0, 25.5, 10) 271 | 272 | else: 273 | print( "Unknown optical flow implementation : %s" % opticalFlowImplementation ) 274 | opencvFlow = None 275 | 276 | if outputWarpedImage and (opencvFlow is not None): 277 | if verbose: 278 | print( "warping 1 -> 2") 279 | opencvWarped = applyOpticalFlow(openCVImageBuffer1, opencvFlow) 280 | 281 | if verbose: 282 | print( "converting and writing warped image - %s" % outputWarpedImage ) 283 | oiioWarped = OIIOImageBufferFromOpenCVImageBuffer( opencvWarped ) 284 | oiioWarped.write( outputWarpedImage ) 285 | else: 286 | opencvWarped = None 287 | 288 | if outputFlowImage and (opencvFlow is not None): 289 | if verbose: 290 | print( "converting and writing flow image - %s" % outputFlowImage ) 291 | 292 | oiioFlowBuffer = OIIOImageBufferFromOpenCVImageBuffer( opencvFlow ) 293 | oiioFlowBuffer.write( outputFlowImage ) 294 | 295 | return (opencvWarped, opencvFlow) 296 | 297 | # 298 | # Get the options, load a set of images and merge them 299 | # 300 | def main(): 301 | import optparse 302 | 303 | usage = "%prog [options]\n" 304 | usage += "\n" 305 | 306 | p = optparse.OptionParser(description='Recover the camera response curve from a set of exposures', 307 | prog='recoverCameraResponse', 308 | version='1.0', 309 | usage=usage) 310 | 311 | p.add_option('--inputImage1', default=None) 312 | p.add_option('--inputImage2', default=None) 313 | p.add_option('--outputWarpedImage', default=None) 314 | p.add_option('--outputFlowImage', default=None) 315 | p.add_option('--opticalFlowImplementation', default="deepflow") 316 | 317 | p.add_option('--verbose', '-v', action="store_true") 318 | 319 | options, arguments = p.parse_args() 320 | 321 | # 322 | # Get options 323 | # 324 | inputImage1 = options.inputImage1 325 | inputImage2 = options.inputImage2 326 | outputWarpedImage = options.outputWarpedImage 327 | outputFlowImage = options.outputFlowImage 328 | verbose = options.verbose 329 | opticalFlowImplementation = options.opticalFlowImplementation 330 | 331 | try: 332 | argsStart = sys.argv.index('--') + 1 333 | args = sys.argv[argsStart:] 334 | except: 335 | argsStart = len(sys.argv)+1 336 | args = [] 337 | 338 | if verbose: 339 | print( "command line : \n%s\n" % " ".join(sys.argv) ) 340 | 341 | if inputImage1 and inputImage2: 342 | findOpticalFlow(inputImage1, inputImage2, outputWarpedImage, outputFlowImage, verbose, 343 | opticalFlowImplementation=opticalFlowImplementation) 344 | else: 345 | print( "\nTwo input images must be supplied.\n" ) 346 | usage() 347 | # main 348 | 349 | if __name__ == '__main__': 350 | main() 351 | -------------------------------------------------------------------------------- /opencv/recoverCameraResponse.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | 4 | import cv2 5 | import numpy as np 6 | 7 | import OpenImageIO as oiio 8 | from OpenImageIO import ImageBuf 9 | 10 | # Formats with exif data 11 | generalExtensions = ["jpg", "tiff", "tif"] 12 | 13 | def getExposureInformation(metadata): 14 | exposure = {} 15 | for attr in metadata: 16 | #print( "\t%s : %s" % (attr.name, attr.value) ) 17 | if attr.name in ['ExposureTime', 18 | 'FNumber', 19 | 'Exif:PhotographicSensitivity', 20 | 'Exif:ISOSpeedRatings', 21 | 'Exif:ApertureValue', 22 | 'Exif:BrightnessValue', 23 | 'Exif:ExposureBiasValue']: 24 | #print( "\tStoring %s : %s" % (attr.name, attr.value) ) 25 | exposure[attr.name] = attr.value 26 | 27 | return exposure 28 | 29 | def ImageAttributes(inputImage): 30 | ''' 31 | Get image bit channel type, width, height, number of channels and metadata 32 | ''' 33 | inputImageSpec = inputImage.spec() 34 | channelType = inputImageSpec.format.basetype 35 | orientation = inputImage.orientation 36 | width = inputImageSpec.width 37 | height = inputImageSpec.height 38 | 39 | channels = inputImageSpec.nchannels 40 | metadata = inputImageSpec.extra_attribs 41 | return (channelType, width, height, channels, orientation, metadata, inputImageSpec) 42 | 43 | def getShutterSpeed( imagePath, 44 | verbose = False ): 45 | imageBuffer = ImageBuf( imagePath ) 46 | # Get attributes 47 | (channelType, width, height, channels, orientation, metadata, inputSpec) = ImageAttributes(imageBuffer) 48 | 49 | exposure = getExposureInformation(metadata) 50 | 51 | if verbose: 52 | print( imagePath ) 53 | print( "\tChannel Type : %s" % (channelType) ) 54 | print( "\tWidth : %s" % (width) ) 55 | print( "\tHeight : %s" % (height) ) 56 | print( "\tChannels : %s" % (channels) ) 57 | print( "\tOrientation : %s" % (orientation) ) 58 | print( "\tExposure : %s" % (exposure) ) 59 | print( "\tMetadata # : %s" % (len(metadata)) ) 60 | print( "\tInv Shutter. : %s" % (exposure['ExposureTime'])) 61 | 62 | return exposure['ExposureTime'] 63 | 64 | def recover_camera_response(inputFolder = '.', 65 | exposureListFile = None, 66 | outputResponseCurve = "camera_response.spi1d", 67 | outputResponseFormat = "spi1d", 68 | calibrationApproach = "berkeley", 69 | mergeExposures = False, 70 | mergedExposuresOutput = None, 71 | verbose = False, 72 | robertsonMaxIter = 30.0, 73 | robertsonThreshold = 0.01, 74 | berkeleyLambda = 20.0, 75 | berkeleySamples = 1024, 76 | berkeleySamplePlacementRandom = False): 77 | extensions = generalExtensions 78 | 79 | if exposureListFile: 80 | with open(exposureListFile, 'r') as f: 81 | exposuresList = f.readlines() 82 | 83 | exposuresList = [x.strip() for x in exposuresList if len(x) > 1] 84 | 85 | imageUris = [x.split(' ')[0] for x in exposuresList] 86 | exposure_times = [1.0/float(x.split(' ')[1]) for x in exposuresList] 87 | 88 | else: 89 | imageUris = sorted( os.listdir( inputFolder ) ) 90 | imageUris = [x for x in imageUris if (os.path.splitext(x)[-1].lower()[1:] in extensions) and (x[0] != '.')] 91 | 92 | if verbose: 93 | print( imageUris ) 94 | 95 | cwd = os.getcwd() 96 | os.chdir( inputFolder ) 97 | 98 | exposure_times = [0]*len(imageUris) 99 | for i in range(len(imageUris)): 100 | exposure_times[i] = getShutterSpeed( imageUris[i], verbose=verbose ) 101 | 102 | # List has to be sorted from longest shutter speed to shortest for opencv functions to work 103 | exposure_times, imageUris = (list(x) for x in zip(*sorted(zip(exposure_times, imageUris)))) 104 | imageUris.reverse() 105 | 106 | exposure_times.reverse() 107 | exposure_times = np.array(exposure_times, dtype=np.float32) 108 | 109 | if verbose: 110 | for exposure in zip(exposure_times, imageUris): 111 | print( "Image : %s, Shutter speed : %2.6f" % (exposure[1], exposure[0]) ) 112 | 113 | img_list = [cv2.imread(fn) for fn in imageUris ] 114 | 115 | if not exposureListFile: 116 | os.chdir( cwd ) 117 | 118 | if calibrationApproach == "robertson": 119 | merge = cv2.createMergeRobertson() 120 | calibrate = cv2.createCalibrateRobertson() 121 | 122 | calibrate.setMaxIter(robertsonMaxIter) 123 | calibrate.setThreshold(robertsonThreshold) 124 | 125 | if verbose: 126 | print( calibrationApproach ) 127 | print( "\tmax iter : %d" % robertsonMaxIter ) 128 | print( "\tthreshold : %f" % robertsonThreshold ) 129 | else: 130 | merge = cv2.createMergeDebevec() 131 | calibrate = cv2.createCalibrateDebevec() 132 | 133 | calibrate.setLambda(berkeleyLambda) 134 | calibrate.setSamples(berkeleySamples) 135 | calibrate.setRandom(berkeleySamplePlacementRandom) 136 | 137 | if verbose: 138 | print( calibrationApproach ) 139 | print( "\tlambda : %3.2f" % berkeleyLambda ) 140 | print( "\tsamples : %d" % berkeleySamples ) 141 | print( "\trandom : %s" % berkeleySamplePlacementRandom ) 142 | 143 | if verbose: 144 | print( "recovering camera response" ) 145 | 146 | curve = calibrate.process(img_list, times=exposure_times) 147 | 148 | if verbose: 149 | print( "writing camera response - %s, %s" % (outputResponseFormat, outputResponseCurve) ) 150 | 151 | if outputResponseFormat == "spi1d": 152 | with open(outputResponseCurve, "w") as f: 153 | f.write( "Version 1\n" ) 154 | f.write( "From 0.000000 1.000000\n" ) 155 | f.write( "Length 256\n" ) 156 | f.write( "Components 3\n" ) 157 | f.write( "{\n" ) 158 | for i in range(len(curve)): 159 | f.write( "%3.6f %3.6f %3.6f\n" % (curve[i][0][0]*0.18, curve[i][0][1]*0.18, curve[i][0][2]*0.18) ) 160 | f.write( "}\n" ) 161 | else: 162 | with open(outputResponseCurve, "w") as f: 163 | for i in range(len(curve)): 164 | f.write( "%3.6f %3.6f %3.6f\n" % (curve[i][0][0], curve[i][0][1], curve[i][0][2]) ) 165 | 166 | if mergedExposuresOutput: 167 | if verbose: 168 | print( "merging exposures" ) 169 | 170 | hdr = merge.process(img_list, times=exposure_times.copy(), response=curve.copy()) 171 | cv2.imwrite(mergedExposuresOutput, hdr) 172 | 173 | # 174 | # Get the options, load a set of images and merge them 175 | # 176 | def main(): 177 | import optparse 178 | 179 | usage = "%prog [options]\n" 180 | usage += "\n" 181 | 182 | p = optparse.OptionParser(description='Recover the camera response curve from a set of exposures', 183 | prog='recoverCameraResponse', 184 | version='1.0', 185 | usage=usage) 186 | 187 | p.add_option('--inputFolder', '-i', default='.') 188 | p.add_option('--exposureListFile', '-e', default=None) 189 | p.add_option('--outputResponseCurve', '-o', default=None) 190 | p.add_option('--outputResponseFormat', '-f', default='spi1d', type='string', 191 | help="spi1d, raw") 192 | p.add_option('--calibrationApproach', '-c', default='berkeley', type='string', 193 | help="berkeley, robertson") 194 | p.add_option('--mergedExposuresOutput', '-m', default=None) 195 | p.add_option('--verbose', '-v', action="store_true") 196 | 197 | p.add_option('--robertsonMaxIter', default=30) 198 | p.add_option('--robertsonThreshold', default=0.01) 199 | 200 | p.add_option('--berkeleyLambda', default=20.0) 201 | p.add_option('--berkeleySamples', default=1024) 202 | p.add_option('--berkeleySamplePlacementRandom', default=False) 203 | 204 | options, arguments = p.parse_args() 205 | 206 | # 207 | # Get options 208 | # 209 | inputFolder = options.inputFolder 210 | exposureListFile = options.exposureListFile 211 | outputResponseCurve = options.outputResponseCurve 212 | outputResponseFormat = options.outputResponseFormat 213 | calibrationApproach = options.calibrationApproach 214 | mergedExposuresOutput = options.mergedExposuresOutput 215 | verbose = options.verbose 216 | 217 | robertsonMaxIter = int(options.robertsonMaxIter) 218 | robertsonThreshold = float(options.robertsonThreshold) 219 | berkeleyLambda = float(options.berkeleyLambda) 220 | berkeleySamples = int(options.berkeleySamples) 221 | berkeleySamplePlacementRandom = options.berkeleySamplePlacementRandom == True 222 | 223 | try: 224 | argsStart = sys.argv.index('--') + 1 225 | args = sys.argv[argsStart:] 226 | except: 227 | argsStart = len(sys.argv)+1 228 | args = [] 229 | 230 | if verbose: 231 | print( "command line : \n%s\n" % " ".join(sys.argv) ) 232 | 233 | recover_camera_response(inputFolder = inputFolder, 234 | exposureListFile = exposureListFile, 235 | outputResponseCurve = outputResponseCurve, 236 | outputResponseFormat = outputResponseFormat, 237 | calibrationApproach = calibrationApproach, 238 | mergedExposuresOutput = mergedExposuresOutput, 239 | verbose = verbose, 240 | robertsonMaxIter = robertsonMaxIter, 241 | robertsonThreshold = robertsonThreshold, 242 | berkeleyLambda = berkeleyLambda, 243 | berkeleySamples = berkeleySamples, 244 | berkeleySamplePlacementRandom = berkeleySamplePlacementRandom) 245 | # main 246 | 247 | if __name__ == '__main__': 248 | main() 249 | 250 | -------------------------------------------------------------------------------- /touchDesigner/README.md: -------------------------------------------------------------------------------- 1 | Touch Designer Utilities 2 | = 3 | 4 | Extensions to Touch Designer 5 | 6 | 3D LUT Support 7 | - 8 | To use the glsl in Touch Designer, follow these steps 9 | - Create a GLSL TOP. 10 | - Call this 'glsl_lookup_3d' 11 | - Create a Text DAT. 12 | - Call this 'glsl_source_lookup_3d'. This name is important. 13 | - Create a MovieIn TOP. 14 | - Load in your 3d LUT image. 15 | - The identity LUT image is in the 'scripts' folder. It is not the same as the Nuke CMSPattern LUT image. 16 | - Connect the image that you want to apply the LUT to to your the GLSL TOP's first input 17 | - Connect the LUT MovieIn TOP to the GLSL TOP's second input 18 | - Open the GLSL TOP's parameters (as seen in the screenshots) 19 | - In the 'GLSL' parameter tab, type 'glsl_source_lookup_3d' into the Pixel Shader parameter 20 | - In the 'Common' parameter tab, switch 'Input Smoothness' to 'Nearest Pixel' 21 | 22 | If you want to use a LUT with a different resolution or tile layout, swap out the parameter on the second to last line of the GLSL file. They are currently 32, 8, 4 for a 32x32x32 LUT that is laid out 8 tiles wide and 4 tiles high in the LUT image. 23 | 24 | 25 | -------------------------------------------------------------------------------- /touchDesigner/scripts/nuke_lookup3d_Capture.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpd/general/59cf7e0608bc8e7e3b4b383ce971d18ede2d97c4/touchDesigner/scripts/nuke_lookup3d_Capture.JPG -------------------------------------------------------------------------------- /touchDesigner/scripts/ramp3d_32_fp.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpd/general/59cf7e0608bc8e7e3b4b383ce971d18ede2d97c4/touchDesigner/scripts/ramp3d_32_fp.tiff -------------------------------------------------------------------------------- /touchDesigner/scripts/ramp3d_64_fp.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpd/general/59cf7e0608bc8e7e3b4b383ce971d18ede2d97c4/touchDesigner/scripts/ramp3d_64_fp.tiff -------------------------------------------------------------------------------- /touchDesigner/scripts/touchDesigner_lookup3d_common_parameters_Capture.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpd/general/59cf7e0608bc8e7e3b4b383ce971d18ede2d97c4/touchDesigner/scripts/touchDesigner_lookup3d_common_parameters_Capture.JPG -------------------------------------------------------------------------------- /touchDesigner/scripts/touchDesigner_lookup3d_pixelShader_parameter_Capture.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpd/general/59cf7e0608bc8e7e3b4b383ce971d18ede2d97c4/touchDesigner/scripts/touchDesigner_lookup3d_pixelShader_parameter_Capture.JPG -------------------------------------------------------------------------------- /touchDesigner/touchDesigner_lookup_3d.glsl.txt: -------------------------------------------------------------------------------- 1 | layout(location = 0) out vec4 fragColor; 2 | 3 | vec2 uvCoordinateLUT3d1(vec4 base, 4 | int FilmLutWidth, 5 | int FilmLutTilesWide, 6 | int FilmLutTilesHigh) 7 | { 8 | vec2 uv; 9 | 10 | float Padding = .5/(FilmLutWidth); 11 | float PaddingU = .5/(FilmLutWidth * FilmLutTilesWide); 12 | float PaddingV = .5/(FilmLutWidth * FilmLutTilesHigh); 13 | 14 | // index 1 15 | int indexB = int(clamp(base.b, 0, 1) * FilmLutWidth-1); 16 | int tileU = indexB % FilmLutTilesWide; 17 | int tileV = indexB / FilmLutTilesWide; 18 | 19 | uv.r = mix(PaddingU,1-PaddingU,base.r)/FilmLutTilesWide + tileU*1.f/FilmLutTilesWide; 20 | uv.g = mix(PaddingV,1-PaddingV,base.g)/FilmLutTilesHigh + tileV*1.f/FilmLutTilesHigh; 21 | 22 | return uv; 23 | } 24 | 25 | vec4 26 | texture3dTonemap1(vec4 base, 27 | sampler2D tonemapSampler, 28 | int FilmLutWidth, 29 | int FilmLutTilesWide, 30 | int FilmLutTileHigh ) 31 | { 32 | vec4 tonemappedColor[8]; 33 | 34 | // clamp because we only use values between 0 and 1 35 | base = clamp(base, 0, 1); 36 | 37 | // index values interpolation factor for RGB 38 | float indexRf = (base.r * (FilmLutWidth-1)); 39 | int indexR = int(floor(indexRf)); 40 | float interpR = fract(indexRf); 41 | float indexRfb = floor(indexRf) / (FilmLutWidth-1); 42 | 43 | float indexGf = (base.g * (FilmLutWidth-1)); 44 | int indexG = int(floor(indexGf)); 45 | float interpG = fract(indexGf); 46 | float indexGfb = floor(indexGf) / (FilmLutWidth-1); 47 | 48 | float indexBf = (base.b * (FilmLutWidth-1)); 49 | int indexB = int(floor(indexBf)); 50 | float interpB = fract(indexBf); 51 | float indexBfb = floor(indexBf) / (FilmLutWidth-1); 52 | 53 | float delta = 1.f / (FilmLutWidth-1); 54 | 55 | vec2 uv; 56 | 57 | // Sample the 8 points around the current sample position 58 | 59 | // sample r, g, b 60 | uv = uvCoordinateLUT3d1(vec4(indexRfb , indexGfb , indexBfb , 1.f), 61 | FilmLutWidth, FilmLutTilesWide, FilmLutTileHigh); 62 | tonemappedColor[0] = texture(tonemapSampler, uv); 63 | 64 | // sample r, g, b+1 65 | uv = uvCoordinateLUT3d1(vec4(indexRfb , indexGfb , indexBfb + delta, 1.f), 66 | FilmLutWidth, FilmLutTilesWide, FilmLutTileHigh); 67 | tonemappedColor[1] = texture(tonemapSampler, uv); 68 | 69 | // sample r, g+1, b 70 | uv = uvCoordinateLUT3d1(vec4(indexRfb , indexGfb + delta, indexBfb , 1.f), 71 | FilmLutWidth, FilmLutTilesWide, FilmLutTileHigh); 72 | tonemappedColor[2] = texture(tonemapSampler, uv); 73 | 74 | // sample r, g+1, b+1 75 | uv = uvCoordinateLUT3d1(vec4(indexRfb , indexGfb + delta, indexBfb + delta, 1.f), 76 | FilmLutWidth, FilmLutTilesWide, FilmLutTileHigh); 77 | tonemappedColor[3] = texture(tonemapSampler, uv); 78 | 79 | // sample r+1, g, b 80 | uv = uvCoordinateLUT3d1(vec4(indexRfb + delta, indexGfb , indexBfb , 1.f), 81 | FilmLutWidth, FilmLutTilesWide, FilmLutTileHigh); 82 | tonemappedColor[4] = texture(tonemapSampler, uv); 83 | 84 | // sample r+1, g, b+1 85 | uv = uvCoordinateLUT3d1(vec4(indexRfb + delta, indexGfb , indexBfb + delta, 1.f), 86 | FilmLutWidth, FilmLutTilesWide, FilmLutTileHigh); 87 | tonemappedColor[5] = texture(tonemapSampler, uv); 88 | 89 | // sample r+1, g+1, b 90 | uv = uvCoordinateLUT3d1(vec4(indexRfb + delta, indexGfb + delta, indexBfb , 1.f), 91 | FilmLutWidth, FilmLutTilesWide, FilmLutTileHigh); 92 | tonemappedColor[6] = texture(tonemapSampler, uv); 93 | 94 | // sample r+1, g+1, b+1 95 | uv = uvCoordinateLUT3d1(vec4(indexRfb + delta, indexGfb + delta, indexBfb + delta, 1.f), 96 | FilmLutWidth, FilmLutTilesWide, FilmLutTileHigh); 97 | tonemappedColor[7] = texture(tonemapSampler, uv); 98 | 99 | 100 | // Interpolate along the 4 lines in B 101 | tonemappedColor[0] = mix(tonemappedColor[0], tonemappedColor[1], interpB); 102 | tonemappedColor[2] = mix(tonemappedColor[2], tonemappedColor[3], interpB); 103 | tonemappedColor[4] = mix(tonemappedColor[4], tonemappedColor[5], interpB); 104 | tonemappedColor[6] = mix(tonemappedColor[6], tonemappedColor[7], interpB); 105 | 106 | // Interpolate along the 2 lines in G 107 | tonemappedColor[0] = mix(tonemappedColor[0], tonemappedColor[2], interpG); 108 | tonemappedColor[4] = mix(tonemappedColor[4], tonemappedColor[6], interpG); 109 | 110 | // Interpolate along the 1 line in R 111 | tonemappedColor[0] = mix(tonemappedColor[0], tonemappedColor[4], interpR); 112 | 113 | return tonemappedColor[0]; 114 | } 115 | 116 | 117 | void main() 118 | { 119 | vec4 base = texture(sTD2DInputs[0], vUV.st); 120 | 121 | fragColor = texture3dTonemap1(base, sTD2DInputs[1], 32, 8, 4); 122 | } 123 | --------------------------------------------------------------------------------