User Tag List

Page 1 of 3 1 2 3 LastLast
Results 1 to 10 of 30

Thread: [REQUEST] 3D LUT Shader

  1. #1
    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)

    Post [Request] 3D LUT Shader

    I have been using ReShade and ENB to color grade my video games for a while now, and was wondering if this 3D LUT code (or any 3D LUT code for that matter) could be converted to an MMF 2.5 shader?

    Original Source

    UE4, Unity compatible 256x16 look up table(LUT)

    Base LUT Image:
    Code:
    float2 CLut_pSize = float2(0.00390625, 0.0625);// 1 / float2(256, 16);
    color.rgb  = saturate(color.rgb);
    color.b   *= 15;
    float4 CLut_UV = 0;
    CLut_UV.w  = floor(color.b);
    CLut_UV.xy = color.rg * 15 * CLut_pSize + 0.5 * CLut_pSize ;
    CLut_UV.x += CLut_UV.w * CLut_pSize.y;
    color.rgb  = lerp( tex2Dlod(_s7, CLut_UV.xyzz).rgb, tex2Dlod(_s7, CLut_UV.xyzz + float4(CLut_pSize.y, 0, 0, 0)).rgb, color.b - CLut_UV.w);

    Further example for higher res LUT image:
    Code:
    //dx10/11
        float2 CLut_pSize =  1 / float2(4096, 64);
        color.rgb  = saturate(color.rgb) * 63;
        float4 CLut_UV;
        CLut_UV.w  = floor(color.b);
        CLut_UV.xy = (color.rg + 0.5) * CLut_pSize;
        CLut_UV.x += CLut_UV.w * CLut_pSize.y;
        CLut_UV.z  = CLut_UV.x + CLut_pSize.y;
        color.rgb  = lerp(LUTtex.SampleLevel(Sampler1, CLut_UV.xy, 0).rgb, LUTtex.SampleLevel(Sampler1, CLut_UV.zy, 0).rgb, color.b - CLut_UV.w);
    If so, could it be modified to have multiple LUTs to define, and fade between them at runtime? If not with the multi-lut single texture shown below, then perhaps with multiple individual textures.

    Example of multiple LUTs in a single texture:


    UI:
    Code:
    int   lut_D <   string UIName="lut_D";   float UIMin=0;   float UIMax=9;> = {0};
    int   lut_N <   string UIName="lut_N";   float UIMin=0;   float UIMax=9;> = {0};
    int   lut_I <   string UIName="lut_I";   float UIMin=0;   float UIMax=9;> = {0};
    Resources:
    Code:
    Texture2D          LUTtex_D< string UIName = "3DLut0";  string ResourceName = "LUTtex_D.png"; >; //day
    Texture2D          LUTtex_N< string UIName = "3DLut0";  string ResourceName = "LUTtex_N.png"; >; //night
    Texture2D          LUTtex_I< string UIName = "3DLut0";  string ResourceName = "LUTtex_I.png"; >; // interior
    Code:
    if(enablelut)
    {
        float2 CLut_pSize = {0.00390625, 0.0625};// 1 / float2(256, 16)
        color.rgb         = saturate(color.rgb) * 15;
        
        float3 CLut_UV;    
        CLut_UV.z = floor(color.z);
        color.z  -= CLut_UV.z;
        color.xy  = (color.xy + 0.5) * CLut_pSize;
        color.x  += CLut_UV.z * CLut_pSize.y;
        color.y  *= 0.1; // 1 / 10
    
        CLut_UV.x = color.x;
        CLut_UV.z = CLut_UV.x + CLut_pSize.y;
        CLut_UV.y = color.y + lut_D * 0.1;
        float3 lutcolor_D = lerp(LUTtex_D.SampleLevel(Sampler1, CLut_UV.xy, 0).rgb, LUTtex_D.SampleLevel(Sampler1, CLut_UV.zy, 0).rgb, color.z);
        CLut_UV.y = color.y + lut_N * 0.1;
        float3 lutcolor_N = lerp(LUTtex_N.SampleLevel(Sampler1, CLut_UV.xy, 0).rgb, LUTtex_N.SampleLevel(Sampler1, CLut_UV.zy, 0).rgb, color.z);
        CLut_UV.y = color.y + lut_I * 0.1;
        float3 lutcolor_I = lerp(LUTtex_I.SampleLevel(Sampler1, CLut_UV.xy, 0).rgb, LUTtex_I.SampleLevel(Sampler1, CLut_UV.zy, 0).rgb, color.z);
    
        color.rgb         = lerp(lerp( lutcolor_N, lutcolor_D, ENightDayFactor), lutcolor_I, EInteriorFactor);
    }
    Another example from ReShade:
    Code:
    texture ColorLUTDstTex	< string source = "ReShade/CustomFX/Textures/" TuningColorLUTDstTexture; > {Width = TuningColorLUTTileAmountX; Height = TuningColorLUTTileAmountY; Format = RGBA8;};
    sampler	ColorLUTDstColor 	{ Texture = ColorLUTDstTex; };
    
    #define TuningColorLUTNorm float2(1.0/float(TuningColorLUTTileAmountX),1.0/float(TuningColorLUTTileAmountY))
    
    float4 PS_TuningPalette(float4 vpos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target
    {
    	float4 original = tex2D(RFX_backbufferColor, texcoord.xy);
    
    	float4 ColorLUTDst = float4((original.rg*float(TuningColorLUTTileAmountY-1)+0.5f)*TuningColorLUTNorm,original.b*float(TuningColorLUTTileAmountY-1),original.w);
    	ColorLUTDst.x += trunc(ColorLUTDst.z)*TuningColorLUTNorm.y;
    	ColorLUTDst = lerp(tex2D(ColorLUTDstColor, ColorLUTDst.xy),tex2D(ColorLUTDstColor, float2(ColorLUTDst.x+TuningColorLUTNorm.y,ColorLUTDst.y)),frac(ColorLUTDst.z));
    	original = lerp(original,ColorLUTDst,TuningColorLUTIntensity);
    	return original;

  2. #2
    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)
    No one?

  3. #3
    Clicker Fusion 2.5 DeveloperFusion 2.5+ DLC

    Join Date
    Jul 2008
    Location
    UK
    Posts
    1,553
    Mentioned
    16 Post(s)
    Tagged
    0 Thread(s)
    MMF2 (and CF2.5) supports pixel shader models up to 2.0a, while the code you provided uses functions only supported in 4.0 and later. That's not really the issue here though, as the shader could easily be rewritten without them.

    The real problem is that MMF2 only uses (bi?)linear texture filtering on object textures, and not on textures which are passed as image parameters (eg. your LUT image), for which it uses nearest-point sampling - and for this, you really need linear texture filtering to be able to interpolate between the colors in your LUT image (otherwise you'd end up with an image reduced to only 16x16x16 = 4096 colors, which would look awful).

    Explanation of the difference:
    https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx

    The only way around it would be to sample from something like 8 different points, and interpolate between all of them, which would be very, very complicated (and not terribly efficient).

  4. #4
    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)
    Thank you for responding MuddyMole.

    I personally prefer using larger resolution LUTs anyway. I use a 4096 X 64 lut that I created from the texture below:



    To make the 4096 X 64 lut from that, I just pulled the rows in photoshop into a single line, top to bottom order, reordered left to right. It basically is a higher resolution version of the 256 x 16 LUT with 64 blocks instead of 16.

    AFAIK, the 512x512 (or 4096x64) texture contains every possible color in the sRGB colorspace, so there would be no need to interpolate, or am I wrong and totally misunderstanding?

  5. #5
    Clicker Fusion 2.5 DeveloperFusion 2.5+ DLC

    Join Date
    Jul 2008
    Location
    UK
    Posts
    1,553
    Mentioned
    16 Post(s)
    Tagged
    0 Thread(s)
    You'd need a texture 256 x 65536 (or 4096 x 4096), which is bigger than DX9 (and many graphics cards) support, and there'd likely be a performance hit from using such a huge texture anyway.

  6. #6
    Clicker Fusion 2.5 DeveloperFusion 2.5+ DLCAndroid Export ModuleSWF Export ModuleUnicode Add-on
    Looki's Avatar
    Join Date
    Aug 2006
    Location
    Karlsruhe, Germany
    Posts
    3,741
    Mentioned
    5 Post(s)
    Tagged
    1 Thread(s)
    I haven't read this entire thread, but MuddyMole, it is possible to override the sampler state of a texture quite easily!
    Here's what I've used a lot (not so much in shaders I've released - but I had to make a LOT of specialized shaders for Heart Forth, Alicia ):
    sampler2D img = sampler_state {
    MinFilter = Linear;
    MagFilter = Linear;
    AddressU = Border;
    AddressV = Border;
    BorderColor = float4(0, 0, 0, 0);
    };

    Which forces interpolation for all texture lookups and returns a transparent pixel for all texture lookups outside 0..1

  7. #7
    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)
    I really hope this is possible, then. The ability to change the look of the game on the fly with advanced grading is very enticing.

  8. #8
    Clicker Fusion 2.5 DeveloperFusion 2.5+ DLC

    Join Date
    Jul 2008
    Location
    UK
    Posts
    1,553
    Mentioned
    16 Post(s)
    Tagged
    0 Thread(s)
    @Looki: thank you - that's very interesting, and potentially useful. I didn't know that was possible.
    I'll look into it later (possibly not today, as I've got a lot on).

  9. #9
    Clicker Fusion 2.5 DeveloperFusion 2.5+ DLC

    Join Date
    Jul 2008
    Location
    UK
    Posts
    1,553
    Mentioned
    16 Post(s)
    Tagged
    0 Thread(s)
    So I had a brief go at it, and it should be do-able, but it's tricky and I can't be bothered to keep trying.
    The image on the right is the original; the image on the left is after applying a "neutral" LUT, so it should look about the same.



    It's not far off, but there's a problem: look at the red, yellow (on the right), light blue and dark green pencils - there's either too much or not enough red.
    This is due to issues with sampling at the boundary between two 16x16 squares, where the red component instantly jumps from 0 to 255 - possibly the result of slight rounding and calculation errors, caused by the limited precision of floats; possibly just a mistake in my code.
    It could probably be tweaked to work, but I've come across this kind of issue before, and they can be a real pain to solve, so I'm not going to waste my time on it.


    EDIT: Sorry, ignore that... As I was typing, it gave me an idea, and it's actually fixed the problem



    A quick sepia effect:

  10. #10
    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)
    OMG Fantastic MuddyMole! Getting this working is a BIG DEAL! At least to me anyway. I cannot thank you enough for working on this.

Page 1 of 3 1 2 3 LastLast

Similar Threads

  1. [Request] Alpha Threshold shader
    By NaitorStudios 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
  •