User Tag List

Page 2 of 3 FirstFirst 1 2 3 LastLast
Results 11 to 20 of 25

Thread: [REQUEST] 3D LUT Shader

  1. #11
    Clicker Fusion 2.5 Developer

    Join Date
    Jul 2008
    Posts
    1,305
    Mentioned
    13 Post(s)
    Tagged
    0 Thread(s)
    Usage Notes:
    This shader is to be used as an overlay, adjusting the color of everything behind it.
    It requires a 17x17x17 (289x17) LUT image to be passed as the image parameter "lut".

    Download:
    https://1drv.ms/u/s!Atq7cUIJ7uexhSFPnsGJ91pHPh_r

    .XML File:
    Code:
    <effect>
    <name>Color Grading</name>
    <description>Uses a 3d lookup table (LUT) to modify image colors.</description>
    <author>Sketchy / MuddyMole</author>
    <parameter>
        <name>LUT Image</name>
        <code>lut</code>
        <type>IMAGE</type>
        <property>IMAGE</property>
        <value></value>
    </parameter>
    <BackgroundTexture>1</BackgroundTexture>
    </effect>

    .FX File:
    Code:
    sampler2D bkd : register(s1);
    sampler2D lut : register(s2) = sampler_state {
        MinFilter = Linear;
        MagFilter = Linear;
    };
    
    float4 ps_main(in float2 In : TEXCOORD0) : COLOR0 {
        float4 imgColor = tex2D( bkd, In );
        float red = ( imgColor.r * 16 + 0.5 ) / 289;
        float green = ( imgColor.g * 16 + 0.5 ) / 17;
        float blueA = floor( imgColor.b  * 16 ) / 17;
        float blueB = ceil( imgColor.b  * 16 ) / 17;
        float4 colorA = tex2D( lut, float2( blueA + red, green ));
        float4 colorB = tex2D( lut, float2( blueB + red, green ));
        float lerpAB = ( imgColor.b - ( blueA + red )) / (( blueB + red ) - ( blueA + red ));
        float4 colorOut = lerp( colorA, colorB, lerpAB );
        return colorOut;
    }
    
    technique tech_main {
        pass P0 {
            PixelShader = compile ps_2_0 ps_main();
        }
    }
    Default 17x17x17 LUT:


    Examples:
    (negative image)
    (posterize)
    (sepia)
    (Schindler's List)

  2. #12
    Clicker Fusion 2.5Install Creator Pro
    Fusion 2.5 (Steam)Android Export Module (Steam)HTML5 Export Module (Steam)iOS Export Module (Steam)Universal Windows Platform Export Module (Steam)
    TreyM's Avatar
    Join Date
    Apr 2011
    Posts
    25
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Fantastic sir! If you have PayPal, please send me your info via PM so I can donate to you.

  3. #13
    Clicker Fusion 2.5Install Creator Pro
    Fusion 2.5 (Steam)Android Export Module (Steam)HTML5 Export Module (Steam)iOS Export Module (Steam)Universal Windows Platform Export Module (Steam)
    TreyM's Avatar
    Join Date
    Apr 2011
    Posts
    25
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    One last thing. This is not a complaint. I really appreciate what you have done.

    Is there any way to make the blend coefficient work? It sort of works as it is, with 255 being no effect, and dropping down to 254 applies the effect in full. What I'm asking is basically, is there any way to control the strength of the effect? If not, I totally understand. I am very happy with the ability to do color grading in CTF 2.5!

  4. #14
    Clicker Fusion 2.5Install Creator Pro
    Fusion 2.5 (Steam)Android Export Module (Steam)HTML5 Export Module (Steam)iOS Export Module (Steam)Universal Windows Platform Export Module (Steam)
    TreyM's Avatar
    Join Date
    Apr 2011
    Posts
    25
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks again for making this, MuddyMole.
    Did some digging and modified your code to work with other LUT sizes:

    Code for 4096px X 64px (64,64,64) LUT:
    Code:
    sampler2D bkd : register(s1);
    sampler2D lut : register(s2) = sampler_state {
        MinFilter = Linear;
        MagFilter = Linear;
    };
    
    float4 ps_main(in float2 In : TEXCOORD0) : COLOR0 {
        float4 imgColor = tex2D( bkd, In );
        float red = ( imgColor.r * 63 + 0.5 ) / 4096;
        float green = ( imgColor.g * 63 + 0.5 ) / 64;
        float blueA = floor( imgColor.b  * 63 ) / 64;
        float blueB = ceil( imgColor.b  * 63 ) / 64;
        float4 colorA = tex2D( lut, float2( blueA + red, green ));
        float4 colorB = tex2D( lut, float2( blueB + red, green ));
        float lerpAB = ( imgColor.b - ( blueA + red )) / (( blueB + red ) - ( blueA + red ));
        float4 colorOut = lerp( colorA, colorB, lerpAB );
        return colorOut;
    }
    
    technique tech_main {
        pass P0 {
            PixelShader = compile ps_2_0 ps_main();
        }
    }

    ^ Right click, save as

    As far as the rest of the code goes, I'm still a bit lost lol.

    I did the pass-through test as you did and did not observe errors:


    And here is a test grade using a lut I had laying around:


    I also tried my hand at adding an intensity value to the shader and XML, but failed miserably.


    -------------------------------------

    For reference for other users, here is the code for a 1024px X 32px (32,32,32) LUT:
    Code:
    sampler2D bkd : register(s1);
    sampler2D lut : register(s2) = sampler_state {
        MinFilter = Linear;
        MagFilter = Linear;
    };
    
    float4 ps_main(in float2 In : TEXCOORD0) : COLOR0 {
        float4 imgColor = tex2D( bkd, In );
        float red = ( imgColor.r * 31 + 0.5 ) / 1024;
        float green = ( imgColor.g * 31 + 0.5 ) / 32;
        float blueA = floor( imgColor.b  * 31 ) / 32;
        float blueB = ceil( imgColor.b  * 31 ) / 32;
        float4 colorA = tex2D( lut, float2( blueA + red, green ));
        float4 colorB = tex2D( lut, float2( blueB + red, green ));
        float lerpAB = ( imgColor.b - ( blueA + red )) / (( blueB + red ) - ( blueA + red ));
        float4 colorOut = lerp( colorA, colorB, lerpAB );
        return colorOut;
    }
    
    technique tech_main {
        pass P0 {
            PixelShader = compile ps_2_0 ps_main();
        }
    }

    ^ Right click, save as

    -------------------------------------

    And here is the code for a 256px X 16px (16,16,16) LUT:
    Code:
    sampler2D bkd : register(s1);
    sampler2D lut : register(s2) = sampler_state {
        MinFilter = Linear;
        MagFilter = Linear;
    };
    
    float4 ps_main(in float2 In : TEXCOORD0) : COLOR0 {
        float4 imgColor = tex2D( bkd, In );
        float red = ( imgColor.r * 15 + 0.5 ) / 256;
        float green = ( imgColor.g * 15 + 0.5 ) / 16;
        float blueA = floor( imgColor.b  * 15 ) / 16;
        float blueB = ceil( imgColor.b  * 15 ) / 16;
        float4 colorA = tex2D( lut, float2( blueA + red, green ));
        float4 colorB = tex2D( lut, float2( blueB + red, green ));
        float lerpAB = ( imgColor.b - ( blueA + red )) / (( blueB + red ) - ( blueA + red ));
        float4 colorOut = lerp( colorA, colorB, lerpAB );
        return colorOut;
    }
    
    technique tech_main {
        pass P0 {
            PixelShader = compile ps_2_0 ps_main();
        }
    }

    ^ Right click, save as

    The benefit of using a larger LUT size is greater accuracy across complex color changes. For most users, the 256 X 16 will be good enough, as will MuddyMole's 289 X 17 LUT (which should be slightly more accurate.)
    As far as I know, the 4096 X 64 is a near-perfect translation, while the smaller sizes interpolate the colors to a far heavier degree.

    As far as performance differences, I have no idea. I don't have a project large enough to test it, and even if I did, my computer is really overkill for MMF anyway so I doubt I'd see much of a performance drop.

  5. #15
    Clicker Fusion 2.5 Developer

    Join Date
    Jul 2008
    Posts
    1,305
    Mentioned
    13 Post(s)
    Tagged
    0 Thread(s)
    Yeah, it's not really the finished article - it could do with a few additions...
    - square LUT images (eg. 8x8 instead of 64x1), to improve performance and compatibility.
    - easily selectable LUT size, using a parameter in MMF2.
    - the option to fade between 2 LUT images.

    I'm actually quite busy though, and since I'm not promising to add any of those features any time soon, I thought I'd just post what I'd done.

    The shader is actually extremely simple in principle - the tricky part is correctly offsetting all the coordinates to make sure that you sample from exactly the right spots (which is what "(n * 16 + 0.5) / 17" does).

  6. #16
    Clicker Fusion 2.5Install Creator Pro
    Fusion 2.5 (Steam)Android Export Module (Steam)HTML5 Export Module (Steam)iOS Export Module (Steam)Universal Windows Platform Export Module (Steam)
    TreyM's Avatar
    Join Date
    Apr 2011
    Posts
    25
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Do the code modifications I made make the image coordinates not as accurate then? I really appreciate the time you took to make it in the first place.

  7. #17
    Clicker Fusion 2.5 Developer

    Join Date
    Jul 2008
    Posts
    1,305
    Mentioned
    13 Post(s)
    Tagged
    0 Thread(s)
    No, your changes are fine - it's just much easier to change one parameter in MMF2 than to modify lots of values in the shader file itself.
    I was thinking before that graphics cards always internally use square textures with dimensions that are a power of two (thought I read that somewhere?), so the square LUTs would be more efficient, but actually it seems this is not the case, so I won't be modifying the shader to use square LUTs.

    This is the latest (final) version:
    https://1drv.ms/u/s!Atq7cUIJ7uexhSFPnsGJ91pHPh_r

  8. #18
    Clicker Fusion 2.5 DeveloperAndroid Export ModuleHTML5 Export ModuleSWF Export Module
    happygreenfrog's Avatar
    Join Date
    May 2011
    Location
    I.L.T.D.O.I.R (I.L.T.D.O.I.R's Location: The Dimension Of Infinite Recursion)
    Posts
    4,307
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)
    Graphics cards don't always use SQUARE textures with dimensions that are a power of 2. However, I'm pretty sure the dimensions are, in fact, best as a power of 2 (I've never heard the square bit before, quite frankly).

    Just thought I'd point that out.

    On a more related note, this seems like it could be a useful shader! Nice work!

  9. #19
    Clicker Fusion 2.5 Developer

    Join Date
    Jul 2008
    Posts
    1,305
    Mentioned
    13 Post(s)
    Tagged
    0 Thread(s)
    Yeah, that seems to be the case, although the performance difference appears to be quite minimal (esp. by the time it's just one object anyway, rather than hundreds of polygons). There are also apparently still some other restrictions on non-power-of-two textures that don't apply to MMF2 shaders.

    Anyway, yes, I think the shader could be very useful for day/night/weather effects, but I'm not too sure what other applications it would have...

  10. #20
    Clicker Fusion 2.5Install Creator Pro
    Fusion 2.5 (Steam)Android Export Module (Steam)HTML5 Export Module (Steam)iOS Export Module (Steam)Universal Windows Platform Export Module (Steam)
    TreyM's Avatar
    Join Date
    Apr 2011
    Posts
    25
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for the update MuddyMole! You're a beast.

Page 2 of 3 FirstFirst 1 2 3 LastLast

Similar Threads

  1. [Request] Alpha Threshold shader
    By Fuuriokun in forum Shader Development
    Replies: 2
    Last Post: 6th October 2016, 04:01 PM
  2. Shader Request: Channel offset
    By Caiman in forum Hardware Accelerated Runtime
    Replies: 4
    Last Post: 4th May 2011, 08:53 PM
  3. Shader Request: Selective Blur
    By alxmrg in forum Hardware Accelerated Runtime
    Replies: 2
    Last Post: 10th July 2010, 08:51 PM
  4. [REQUEST] Some Shader Effects
    By Game_Master in forum Hardware Accelerated Runtime
    Replies: 3
    Last Post: 13th July 2009, 02:12 PM
  5. Pixel shader request.
    By Nifflas in forum Hardware Accelerated Runtime
    Replies: 5
    Last Post: 8th May 2008, 11:50 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •