mirror of
				https://github.com/RetroDECK/Duckstation.git
				synced 2025-04-10 19:15:14 +00:00 
			
		
		
		
	
		
			
	
	
		
			175 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			175 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | /*===============================================================================*\ | ||
|  | |########################     [Dolphin FX Suite 2.20]      #######################| | ||
|  | |##########################        By Asmodean          ##########################| | ||
|  | ||                                                                               || | ||
|  | ||          This program is free software; you can redistribute it and/or        || | ||
|  | ||          modify it under the terms of the GNU General Public License          || | ||
|  | ||          as published by the Free Software Foundation; either version 2       || | ||
|  | ||          of the License, or (at your option) any later version.               || | ||
|  | ||                                                                               || | ||
|  | ||          This program is distributed in the hope that it will be useful,      || | ||
|  | ||          but WITHOUT ANY WARRANTY; without even the implied warranty of       || | ||
|  | ||          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        || | ||
|  | ||          GNU General Public License for more details. (C)2015                 || | ||
|  | ||                                                                               || | ||
|  | |#################################################################################| | ||
|  | \*===============================================================================*/ | ||
|  | 
 | ||
|  | // Sourced from https://raw.githubusercontent.com/Asmodean-/dolphin/89d640cd557189bb5f921fc219150c74c39bdc55/Data/Sys/Shaders/DolphinFX.glsl with modifications. | ||
|  | 
 | ||
|  | /* | ||
|  | [configuration] | ||
|  | 
 | ||
|  | [OptionRangeFloat] | ||
|  | GUIName = EdgeStrength | ||
|  | OptionName = A_EDGE_STRENGTH | ||
|  | MinValue = 0.00 | ||
|  | MaxValue = 4.00 | ||
|  | StepAmount = 0.01 | ||
|  | DefaultValue = 1.00 | ||
|  | 
 | ||
|  | [OptionRangeFloat] | ||
|  | GUIName = EdgeFilter | ||
|  | OptionName = B_EDGE_FILTER | ||
|  | MinValue = 0.25 | ||
|  | MaxValue = 1.00 | ||
|  | StepAmount = 0.01 | ||
|  | DefaultValue = 0.60 | ||
|  | 
 | ||
|  | [OptionRangeFloat] | ||
|  | GUIName = EdgeThickness | ||
|  | OptionName = C_EDGE_THICKNESS | ||
|  | MinValue = 0.25 | ||
|  | MaxValue = 2.00 | ||
|  | StepAmount = 0.01 | ||
|  | DefaultValue = 1.00 | ||
|  | 
 | ||
|  | [OptionRangeInteger] | ||
|  | GUIName = PaletteType | ||
|  | OptionName = D_PALETTE_TYPE | ||
|  | MinValue = 0 | ||
|  | MaxValue = 2 | ||
|  | StepAmount = 1 | ||
|  | DefaultValue = 1 | ||
|  | 
 | ||
|  | [OptionRangeInteger] | ||
|  | GUIName = UseYuvLuma | ||
|  | OptionName = E_YUV_LUMA | ||
|  | MinValue = 0 | ||
|  | MaxValue = 1 | ||
|  | StepAmount = 1 | ||
|  | DefaultValue = 0 | ||
|  | 
 | ||
|  | [OptionRangeInteger] | ||
|  | GUIName = ColourRounding | ||
|  | OptionName = G_COLOR_ROUNDING | ||
|  | MinValue = 0 | ||
|  | MaxValue = 1 | ||
|  | StepAmount = 1 | ||
|  | DefaultValue = 1 | ||
|  | 
 | ||
|  | [/configuration] | ||
|  | */ | ||
|  | 
 | ||
|  | //Average relative luminance | ||
|  | CONSTANT float3 lumCoeff = float3(0.2126729, 0.7151522, 0.0721750); | ||
|  | float AvgLuminance(float3 color) | ||
|  | { | ||
|  |     return sqrt( | ||
|  |     (color.x * color.x * lumCoeff.x) + | ||
|  |     (color.y * color.y * lumCoeff.y) + | ||
|  |     (color.z * color.z * lumCoeff.z)); | ||
|  | } | ||
|  | 
 | ||
|  | float3 YUVtoRGB(float3 YUV) | ||
|  | { | ||
|  |    const float3x3 m = float3x3( | ||
|  |     1.000, 0.000, 1.28033, | ||
|  |     1.000,-0.21482,-0.38059, | ||
|  |     1.000, 2.12798, 0.000 ); | ||
|  | 
 | ||
|  |     return mul(m, YUV); | ||
|  | } | ||
|  | 
 | ||
|  | float3 RGBtoYUV(float3 RGB) | ||
|  | { | ||
|  |     const float3x3 m = float3x3( | ||
|  |     0.2126, 0.7152, 0.0722, | ||
|  |    -0.09991,-0.33609, 0.436, | ||
|  |     0.615, -0.55861, -0.05639 ); | ||
|  | 
 | ||
|  |     return mul(m, RGB); | ||
|  | } | ||
|  | 
 | ||
|  | void main() | ||
|  | { | ||
|  |     float4 color = Sample(); | ||
|  |     float2 texcoord = GetCoordinates(); | ||
|  |     float2 pixelSize = GetInvResolution(); | ||
|  |     float2 texSize = GetResolution(); | ||
|  | 
 | ||
|  |     float3 yuv; | ||
|  |     float3 sum = color.rgb; | ||
|  | 
 | ||
|  |     const int NUM = 9; | ||
|  |     const float2 RoundingOffset = float2(0.25, 0.25); | ||
|  |     const float3 thresholds = float3(9.0, 8.0, 6.0); | ||
|  | 
 | ||
|  |     float lum[NUM]; | ||
|  |     float3 col[NUM]; | ||
|  |     float2 set[NUM] = BEGIN_ARRAY(float2, NUM) | ||
|  |     float2(-0.0078125, -0.0078125), | ||
|  |     float2(0.00, -0.0078125), | ||
|  |     float2(0.0078125, -0.0078125), | ||
|  |     float2(-0.0078125, 0.00), | ||
|  |     float2(0.00, 0.00), | ||
|  |     float2(0.0078125, 0.00), | ||
|  |     float2(-0.0078125, 0.0078125), | ||
|  |     float2(0.00, 0.0078125), | ||
|  |     float2(0.0078125, 0.0078125) END_ARRAY; | ||
|  | 
 | ||
|  |     for (int i = 0; i < NUM; i++) | ||
|  |     { | ||
|  |         col[i] = SampleLocation(texcoord + set[i] * RoundingOffset).rgb; | ||
|  | 
 | ||
|  |         if (GetOption(G_COLOR_ROUNDING) == 1) { | ||
|  |         col[i].r = round(col[i].r * thresholds.r) / thresholds.r; | ||
|  |         col[i].g = round(col[i].g * thresholds.g) / thresholds.g; | ||
|  |         col[i].b = round(col[i].b * thresholds.b) / thresholds.b; } | ||
|  | 
 | ||
|  |         lum[i] = AvgLuminance(col[i].xyz); | ||
|  |         yuv = RGBtoYUV(col[i]); | ||
|  | 
 | ||
|  |         if (GetOption(E_YUV_LUMA) == 0) | ||
|  |         { yuv.r = round(yuv.r * thresholds.r) / thresholds.r; } | ||
|  |         else | ||
|  |         { yuv.r = saturate(round(yuv.r * lum[i]) / thresholds.r + lum[i]); } | ||
|  | 
 | ||
|  |         yuv = YUVtoRGB(yuv); | ||
|  |         sum += yuv; | ||
|  |     } | ||
|  | 
 | ||
|  |     float3 shadedColor = (sum / NUM); | ||
|  |     float2 pixel = float2((1.0/texSize.x) * GetOption(C_EDGE_THICKNESS), | ||
|  |                           (1.0/texSize.y) * GetOption(C_EDGE_THICKNESS)); | ||
|  | 
 | ||
|  |     float edgeX = dot(SampleLocation(texcoord + pixel).rgb, lumCoeff); | ||
|  |     edgeX = dot(float4(SampleLocation(texcoord - pixel).rgb, edgeX), float4(lumCoeff, -1.0)); | ||
|  | 
 | ||
|  |     float edgeY = dot(SampleLocation(texcoord + float2(pixel.x, -pixel.y)).rgb, lumCoeff); | ||
|  |     edgeY = dot(float4(SampleLocation(texcoord + float2(-pixel.x, pixel.y)).rgb, edgeY), float4(lumCoeff, -1.0)); | ||
|  | 
 | ||
|  |     float edge = dot(float2(edgeX, edgeY), float2(edgeX, edgeY)); | ||
|  | 
 | ||
|  |     if (GetOption(D_PALETTE_TYPE) == 0) | ||
|  |         { color.rgb = lerp(color.rgb, color.rgb + pow(edge, GetOption(B_EDGE_FILTER)) * -GetOption(A_EDGE_STRENGTH), GetOption(A_EDGE_STRENGTH)); } | ||
|  |     else if (GetOption(D_PALETTE_TYPE) == 1) | ||
|  |         { color.rgb = lerp(color.rgb + pow(edge, GetOption(B_EDGE_FILTER)) * -GetOption(A_EDGE_STRENGTH), shadedColor, 0.25); } | ||
|  |     else if (GetOption(D_PALETTE_TYPE) == 2) | ||
|  |         { color.rgb = lerp(shadedColor + edge * -GetOption(A_EDGE_STRENGTH), pow(edge, GetOption(B_EDGE_FILTER)) * -GetOption(A_EDGE_STRENGTH) + color.rgb, 0.50); } | ||
|  | 
 | ||
|  |     color.a = AvgLuminance(color.rgb); | ||
|  | 
 | ||
|  |     SetOutput(saturate(color)); | ||
|  | } |