Please use english language
It is currently 25 Feb 2020, 22:57

All times are UTC





Post new topic Reply to topic  [ 19 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: 13 Aug 2014, 22:18 
Offline
*sensei*

Joined: 28 Jul 2013, 23:26
Posts: 372
Hi all,
A while ago I asked for some examples of the effect, while I was pointed to some online articles, the results were really underwhelming. I have since constructed my own effect which at least reacts as it should and is fully configurable.

What this effect does:
It can isolate certain colors (hue's) and desaturate everything around it (scroll down for a screenshot). You can create SinCity like looks or, for example only leave the red channel open instead. You can select this in the GUI and set the range to which the effect should take place around that hue (including surrounding hue's, or not). You can use this effect for various other purposes related to color when you combine it, be creative, it's pretty powerful.

Hue color goes like this where the left represents the value 0.0 and right 1.0. The GUI element to set this is called 'Hue Middle'. The variable 'Hue Range' will tell how much has to be displayed of the colors directly to the left and right of whatever you have selected as Hue Middle.
Image

Nice Hue Middle values to try, but feel free to use whatever you like
Red: 0.0
Yellow: 0.167
Green: 0.333
Cyan: 0.5 (Skyrim sky color is somewhere around 0.55)
Blue: 0.667
Magenta: 0.833

Ie. If I want my picture to contain mainly blue's and green's I would select hue middle: 0.5 and set range 0.333, then I will get blue and green represented at 50% their normal saturation since the max value of hue range is the value at which it becomes greyscale. With the same logic; if I want only reds and exclude everything else I would set hue middle at 0.0 and range at 0.167 (or maybe even smaller if I absolutely don't want to see orange and purple hue's, like 0.083).

Version 1.1
- Modified code a little (cleaner)
- Extended Hue Range from 0.5 max to 1.0 max. At 1.0 max you can use the inverted effect so instead of filtering everything out except a certain color, you can now filter out a certain color and leave everything else in place as well.
Version 1.2
- Bugfix in higher hue ranges, they should react normal now (pink, purples and reds)
- Code changes, other method to calculate Hue and Saturation which is more efficient on GPU
- Can't see any more problems with it, so should be final
Version 1.3
- Added HSL controls on request, need to replace entire code
Version 1.4
- Reworked code to be cleaner and more efficient

Use as you see fit, credits would be appreciated.

GUI elements
Code:
float3 ccFilterLuma <string UIName="Color Filter: Luma";            string UIWidget="Color";   > = {0.2125, 0.7154, 0.0721};
float hueMid <      string UIName="Color Filter: Hue Middle";         string UIWidget="Spinner";   float UIMin=0.0;   float UIMax=1.0;   float UIStep=0.001;   > = {0.0};
float hueRange <   string UIName="Color Filter: Hue Range";         string UIWidget="Spinner";   float UIMin=0.0;   float UIMax=0.9;   float UIStep=0.001;   > = {0.2};
float satLimit <   string UIName="Color Filter: Saturation Limit";      string UIWidget="Spinner";   float UIMin=0.0;   float UIMax=1.0;   float UIStep=0.001;   > = {1.0};
float fxcolorMix <   string UIName="Color Filter: Effect Strength";      string UIWidget="Spinner";   float UIMin=0.0;   float UIMax=1.0;   float UIStep=0.001;   > = {1.0};
float HueShiftD <   string UIName="Day HSL: Hue Shift";         string UIWidget="Spinner";   float UIMin=0.0;   float UIMax=1.0;   float UIStep=0.001;   > = {0.0};
float SaturationD <   string UIName="Day HSL: Saturation";      string UIWidget="Spinner";   float UIMin=0.0;   float UIMax=1.0;   float UIStep=0.001;   > = {0.0};
float LightnessD <   string UIName="Day HSL: Highlights";      string UIWidget="Spinner";   float UIMin=0.0;   float UIMax=1.0;   float UIStep=0.001;   > = {0.0};
float ShadowsD <   string UIName="Day HSL: Shadows";         string UIWidget="Spinner";   float UIMin=0.0;   float UIMax=1.0;   float UIStep=0.001;   > = {0.0};
float HueShiftN <   string UIName="Night HSL: Hue Shift";      string UIWidget="Spinner";   float UIMin=0.0;   float UIMax=1.0;   float UIStep=0.001;   > = {0.0};
float SaturationN <   string UIName="Night HSL: Saturation";      string UIWidget="Spinner";   float UIMin=0.0;   float UIMax=1.0;   float UIStep=0.001;   > = {0.0};
float LightnessN <   string UIName="Night HSL: Highlights";      string UIWidget="Spinner";   float UIMin=0.0;   float UIMax=1.0;   float UIStep=0.001;   > = {0.0};
float ShadowsN <   string UIName="Night HSL: Shadows";         string UIWidget="Spinner";   float UIMin=0.0;   float UIMax=1.0;   float UIStep=0.001;   > = {0.0};
float HueShiftI <   string UIName="Interior HSL: Hue Shift";   string UIWidget="Spinner";   float UIMin=0.0;   float UIMax=1.0;   float UIStep=0.001;   > = {0.0};
float SaturationI <   string UIName="Interior HSL: Saturation";   string UIWidget="Spinner";   float UIMin=0.0;   float UIMax=1.0;   float UIStep=0.001;   > = {0.0};
float LightnessI <   string UIName="Interior HSL: Highlights";   string UIWidget="Spinner";   float UIMin=0.0;   float UIMax=1.0;   float UIStep=0.001;   > = {0.0};
float ShadowsI <   string UIName="Interior HSL: Shadows";      string UIWidget="Spinner";   float UIMin=0.0;   float UIMax=1.0;   float UIStep=0.001;   > = {0.0};


Helper functions - need to be placed OUTSIDE of the pixel shader

Code:
float smootherstep(float edge0, float edge1, float x)
{
   x = clamp((x - edge0)/(edge1 - edge0), 0.0, 1.0);
   return x*x*x*(x*(x*6 - 15) + 10);
}

float3 HUEToRGB(in float H)
{
   float R = abs(H * 6 - 3) - 1;
   float G = 2 - abs(H * 6 - 2);
   float B = 2 - abs(H * 6 - 4);
   return saturate(float3(R,G,B));
}

float Epsilon = 1e-10;

float3 RGBToHCV(in float3 RGB)
{
   // Based on work by Sam Hocevar and Emil Persson
   float4 P = (RGB.g < RGB.b) ? float4(RGB.bg, -1.0, 2.0/3.0) : float4(RGB.gb, 0.0, -1.0/3.0);
   float4 Q = (RGB.r < P.x) ? float4(P.xyw, RGB.r) : float4(RGB.r, P.yzx);
   float C = Q.x - min(Q.w, Q.y);
   float H = abs((Q.w - Q.y) / (6 * C + Epsilon) + Q.z);
   return float3(H, C, Q.x);
}

float3 RGBToHSL(in float3 RGB)
{
   float3 HCV = RGBToHCV(RGB);
   float L = HCV.z - HCV.y * 0.5;
   float S = HCV.y / (1 - abs(L * 2 - 1) + Epsilon);
   return float3(HCV.x, S, L);
}

float3 HSLToRGB(in float3 HSL)
{
   float3 RGB = HUEToRGB(HSL.x);
   float C = (1 - abs(2 * HSL.z - 1)) * HSL.y;
   return (RGB - 0.5) * C + HSL.z;
}


And the code for the actual effect. I am sure it can be done nicer, but this is fully functional - place inside Pixel Shader, needs to be the last effect related to coloring (in enbeffect.fx OR effect.txt, whichever contains the last). IF you have vibrancy effect you should place this before vibrancy. That will allow added controls. For example: You can use the effect to emphasize certain colors... say I select a hue of 0.5 (blue) and a range around that. Then I desaturate the surrounding just a little bit using the effect strength so blue hue's really stand out. And right after I do a vibrancy effect to pull the surroundings back to normal levels and the result would be strong blues without tinting the other colors to blue as a normal "color balance" tweak would do.

HSL Filter will work with curves and not plain adding/subtracting stuff because that's better left to Level controls.

Code:
//COLOR ISOLATION FILTER
float4 r0; float r1; float2 r2;
r0.xyz=saturate(color.xyz);
r0.w=dot(r0.xyz, ccFilterLuma.xyz/dot(ccFilterLuma.xyz, 1));
r1.x=RGBToHSL(r0.xyz).x;
r2.xy=float2(hueMid-hueRange, hueMid+hueRange);
if(r2.y>1 && r1.x<r2.y-1)
   r1.x+=1;
if(r2.x<0 && r1.x>r2.x+1)
   r1.x-=1;
if(r1.x<hueMid)
   r0.xyz=lerp(r0.w, r0.xyz, smootherstep(r2.x, hueMid, r1.x)*satLimit);
if(r1.x>=hueMid)
   r0.xyz=lerp(r0.w, r0.xyz, (1-smootherstep(hueMid, r2.y, r1.x))*satLimit);
color.xyz=lerp(color.xyz, r0.xyz, fxcolorMix);

//HSL EFFECTS
r0.xyzw=lerp(lerp(float4(HueShiftN, SaturationN, LightnessN, ShadowsN), float4(HueShiftD, SaturationD, LightnessD, ShadowsD), ENightDayFactor), float4(HueShiftI, SaturationI, LightnessI, ShadowsI), EInteriorFactor);
color.xyz=RGBToHSL(saturate(color.xyz));
color.x=color.x+color.x-step(1, color.x+r0.x);
color.y=color.y+((1-color.y)*(r0.y*color.y));
color.z=color.z+((1-color.z)*(r0.z*color.z));
color.z=color.z+((1-color.z)*(r0.w*(1-color.z)));
color.xyz=HSLToRGB(saturate(color.xyz));


Just a simple example shot, you could filter out any color you want and depending on the range of the effect leave certain hue's in place.

Image

Image

Image

I hope you enjoy :mrgreen:

Cheers.


Last edited by prod80 on 04 Feb 2015, 01:24, edited 35 times in total.

Top
 Profile  
 
Tomoko
PostPosted: 13 Aug 2014, 23:02 
Offline
*master*
User avatar

Joined: 01 May 2013, 23:17
Posts: 106
Thank you for this great effect :) I've been waiting for it ages as you know :D

_________________
Somber Enb
Somber Enb Lut Sepia


Top
 Profile  
 
PostPosted: 13 Aug 2014, 23:11 
Offline
*sensei*

Joined: 28 Jul 2013, 23:26
Posts: 372
Welcome Tali :)

I forgot a piece of code (grayValue function, but I think it's already in your file) ... updated now so it's complete.


Top
 Profile  
 
PostPosted: 14 Aug 2014, 23:28 
Offline
*blah-blah-blah maniac*

Joined: 31 Dec 2011, 19:42
Posts: 504
Thanks! Already incorporated this and it's great.

_________________
NLA v.2.0 beta - A test version of the latest NLA release.
Natural Lighting and Atmospherics for ENB - A Skyrim weather mod and preset.
High-Res bark textures - Some bark textures I made.
Dark Souls 2 ENB preset - Preset for Dark Souls 2.


Top
 Profile  
 
PostPosted: 15 Aug 2014, 23:32 
Offline
*sensei*

Joined: 28 Jul 2013, 23:26
Posts: 372
Thanks CM!

Now with bugfixes :D


Top
 Profile  
 
PostPosted: 16 Aug 2014, 01:13 
Offline
*blah-blah-blah maniac*
User avatar

Joined: 15 Mar 2013, 10:24
Posts: 1020
Location: Earth
prod80
hey, is there an already complied effect.fx file? would love to try it out but don't know how or where to put those codes :(

_________________
cpu i5 4670 gpu GTX980Ti ram 16GB os Win7 64

YouTube Channel
Flickr Gallery


Top
 Profile  
 
PostPosted: 16 Aug 2014, 01:15 
Offline
*sensei*

Joined: 28 Jul 2013, 23:26
Posts: 372
You could try this one (fx + fx.ini) in Serenity ENB 8.2, the main version without changed colors, ofcourse
<link removed>

The effect in GUI is called "Color Filter"

cheers


Last edited by prod80 on 16 Aug 2014, 16:48, edited 1 time in total.

Top
 Profile  
 
PostPosted: 16 Aug 2014, 01:16 
Offline
*blah-blah-blah maniac*
User avatar

Joined: 15 Mar 2013, 10:24
Posts: 1020
Location: Earth
thanks, i'll give it a go ;)

_________________
cpu i5 4670 gpu GTX980Ti ram 16GB os Win7 64

YouTube Channel
Flickr Gallery


Top
 Profile  
 
PostPosted: 16 Aug 2014, 22:55 
Offline

Joined: 16 Aug 2014, 22:51
Posts: 2
Hi !
Sorry I'm a noob but very interested in your Sin City effect, that is handsome ! :D
BUT, how to do it ? I mean, where do I have to copy your code ? I'm completely lost..
Thanks a lot :)


Top
 Profile  
 
PostPosted: 16 Aug 2014, 23:50 
Offline
*sensei*

Joined: 28 Jul 2013, 23:26
Posts: 372
Well the code has to be placed inside of enbeffect.fx file. It's not copied here so that I can do that for everyone... It's here for ENB tweakers. So, unless someone releases an ENB with that code inside you'll have to find someone with HLSL knowledge willing to do it for you. Pretty sure one of these days an ENB becomes available with that code inside. Probably my own (Serenity ENB) will get an update when I feel like it, and then this code will be available with that ENB.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 19 posts ]  Go to page 1, 2  Next

All times are UTC


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group