yasuhirohoshino / ofxGpuLut

http://yasuhirohoshino.com/archives/works/ofxgpulut
MIT License
27 stars 8 forks source link

[question] what tool do you recommends to batch convert from .cube to .png? #3

Closed moebiussurfing closed 4 years ago

moebiussurfing commented 4 years ago

hey @yasuhirohoshino , Thanks for this.

I am trying to batch convert some bundle of LUT .cube files easily. Any tip around?

I found this guide and this free app for Windows that does the job fine: https://www.emawind.com/convert-a-cube-file-into-a-png-file-using-free-software/ but it looks tedious to convert one by one...

moebiussurfing commented 4 years ago

I found this tool that can batch but trying to figure out the appropriate settings to fit your png format...

http://support.grossgrade.com/en/index.html?topic_batchlutconverter.htm There's a preset format called 'Hald CLUT Image (PNG)" but grid dimensions differ, even having the correct.

Output files look like more rectangles than 8x8 and not squared: Noir_6 AF2I9526 512x512px size

yasuhirohoshino commented 4 years ago

Sorry, I don't know batch convert tool. But the LutFilterExample is in openFrameworks/example/graphics folder. It can load .cube files and apply LUT to the image using CPU. Referencing and modifying that example, I think you can make batch convert app.

moebiussurfing commented 4 years ago

thanks @yasuhirohoshino, and do you think I could modify your addon to load .cube files on the fly? Maybe I can use the code of the OF LUT example to convert the .cube to a texture on here:

void ofxGpuLut::load(ofImage lutImage){
    load(lutImage.getTexture());
}

I'll look into, because on your example all the LUT textures are loaded in setup(), no sure if the shaders can be build in runtime...

any tips about?

There are tones of .cube files around that could be nice to run without any conversion to png...

johanjohan commented 4 years ago

@yasuhirohoshino @smallfly , ofxLut only reads "special" 3d luts of length 32. you can find the specs and code for a general reader by adobe at https://wwwimages2.adobe.com/content/dam/acom/en/products/speedgrade/cc/pdfs/cube-lut-specification-1.0.pdf it would be quite easy to read the cube lut, apply it on the 512x512 identity png and pass that into your load() function. the math of applying a lut with trilinear interpolation seems quite tricky, i could not find much info online.

johanjohan commented 4 years ago

just found this: https://github.com/youandhubris/GPU-LUT-OpenFrameworks

johanjohan commented 4 years ago

this seems good, not tested yet: https://github.com/ray-cast/lut

moebiussurfing commented 4 years ago

just found this: https://github.com/youandhubris/GPU-LUT-OpenFrameworks

thanks a lot @johanjohan ! that code worked really well. it's from you? I'll make an addon.

I found a very nice app: GrossGrade it can batch convert "tones" of LUTs to this size 32 that you said in .cube format. so do not need to convert to bigger and "rare" .png files really handy.

johanjohan commented 4 years ago

@moebiussurfing you are welcome! no not my code. Testing it I realized that you can easily extend it to taking pow2 tables, ie 16, 32, 64.

something like


    const string key_LUT_3D_SIZE = "LUT_3D_SIZE";

    lut3dSize = 32; // most common
    while (!file.eof()) {
        string row;
        getline(file, row);

        if (row.empty()) continue;

        RGB line;
        if (sscanf(row.c_str(), "%f %f %f", &line.r, &line.g, &line.b) == 3) {
            LUT.push_back(line);
        }
        else if (ofIsStringInString(row, key_LUT_3D_SIZE)) {
            vector<string> subs = ofSplitString(ofTrim(row), " ");
            if (subs.size() >= 2) {
                ofLogNotice(__FUNCTION__) << "found key_LUT_3D_SIZE: " << subs[1];
                lut3dSize = ofToInt(subs[1]);
            }
        }
    } // while

    if (LUT.size() != (pow(lut3dSize, 3.0))){
        ofLogError() << "LUT size is incorrect.";
        std::exit(1);
    }
    else if (ofNextPow2(lut3dSize) != lut3dSize){
        ofLogError() << "LUT needs to be pow2.";
        std::exit(1);
    }

    ofLogNotice(__FUNCTION__) << "LUT.size(): " << LUT.size() << " --> " << int(ceil(pow(LUT.size(), 1.0 / 3.0)));
    ofLogNotice(__FUNCTION__) << "lut3dSize: " << lut3dSize;

    // Create a 3D texture
    // Reference from http://content.gpwiki.org/index.php/OpenGL:Tutorials:3D_Textures
    glEnable(GL_TEXTURE_3D);

    glGenTextures(1, &texture3D);
    glBindTexture(GL_TEXTURE_3D, texture3D);

    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT);

    glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, lut3dSize, lut3dSize, lut3dSize, 0, GL_RGB, // lut3dSize now
        GL_FLOAT, &LUT[0]);

    glBindTexture(GL_TEXTURE_3D, 0);
    glDisable(GL_TEXTURE_3D);
johanjohan commented 4 years ago

just found this: https://github.com/youandhubris/GPU-LUT-OpenFrameworks

thanks a lot @johanjohan ! that code worked really well. it's from you? I'll make an addon.

I found a very nice app: GrossGrade it can batch convert "tones" of LUTs to this size 32 that you said in .cube format. so do not need to convert to bigger and "rare" .png files really handy.

it would be really easy to load cube on the fly, apply them in fbo to identity png, and pass that as ofImage into ofxGpuLut.load

johanjohan commented 4 years ago

I found a very nice app: GrossGrade

wow, great!

johanjohan commented 4 years ago

Just incorporated these ideas into a plugin: https://github.com/johanjohan/ofx3jGpuLutCube

moebiussurfing commented 4 years ago

cool @johanjohan hehe, I just finished & pushed mine too: https://github.com/moebiussurfing/ofxGpuLutCube

johanjohan commented 4 years ago

your are kidding @moebiussurfing ! even almost identical names... congratulation