update crt-guest shaders and presets, white_point and color-mangler

This commit is contained in:
hunterk 2019-05-02 12:56:13 -05:00
parent 08202e7e14
commit f69940807b
23 changed files with 2160 additions and 596 deletions

View File

@ -0,0 +1,39 @@
shaders = 5
shader0 = shaders/guest/lut/lut.glsl
filter_linear0 = false
scale_type0 = source
scale0 = 1.0
textures = "SamplerLUT1;SamplerLUT2;SamplerLUT3"
SamplerLUT1 = shaders/guest/lut/sony_trinitron1.png
SamplerLUT1_linear = true
SamplerLUT2 = shaders/guest/lut/sony_trinitron2.png
SamplerLUT2_linear = true
SamplerLUT3 = shaders/guest/lut/other1.png
SamplerLUT3_linear = true
shader1 = shaders/guest/fast/smoothing.glsl
filter_linear1 = false
scale_type1 = source
scale1 = 1.0
shader2 = shaders/guest/fast/linearize-multipass.glsl
filter_linear2 = false
scale_type2 = source
scale2 = 1.0
float_framebuffer2 = true
shader3 = shaders/guest/fast/crt-guest-dr-venom-pass1.glsl
filter_linear3 = false
scale_type_x3 = viewport
scale_x3 = 1.0
scale_type_y3 = source
scale_y3 = 1.0
float_framebuffer3 = true
shader4 = shaders/guest/fast/crt-guest-dr-venom-pass2.glsl
filter_linear4 = false
scale_type4 = viewport
scale_x4 = 1.0
scale_y4 = 1.0

View File

@ -1,40 +1,64 @@
shaders = 7
shaders = 10
shader0 = shaders/guest/afterglow.glsl
shader0 = shaders/guest/lut/lut.glsl
filter_linear0 = false
scale_type0 = source
scale0 = 1.0
shader1 = shaders/guest/d65-d50.glsl
textures = "SamplerLUT1;SamplerLUT2;SamplerLUT3"
SamplerLUT1 = shaders/guest/lut/sony_trinitron1.png
SamplerLUT1_linear = true
SamplerLUT2 = shaders/guest/lut/sony_trinitron2.png
SamplerLUT2_linear = true
SamplerLUT3 = shaders/guest/lut/other1.png
SamplerLUT3_linear = true
shader1 = shaders/guest/color-profiles.glsl
filter_linear1 = false
scale_type1 = source
scale1 = 1.0
shader2 = shaders/guest/avg-lum.glsl
shader2 = shaders/guest/d65-d50.glsl
filter_linear2 = false
scale_type2 = source
scale2 = 1.0
mipmap_input2 = true
shader3 = shaders/guest/linearize.glsl
shader3 = shaders/guest/afterglow.glsl
filter_linear3 = false
scale_type3 = source
scale3 = 1.0
float_framebuffer3 = true
shader4 = shaders/guest/blur_horiz.glsl
shader4 = shaders/guest/avg-lum0.glsl
filter_linear4 = false
scale_type4 = source
scale4 = 1.0
float_framebuffer4 = true
shader5 = shaders/guest/blur_vert.glsl
shader5 = shaders/guest/avg-lum.glsl
filter_linear5 = false
scale_type5 = source
scale5 = 1.0
float_framebuffer5 = true
mipmap_input5 = true
shader6 = shaders/guest/crt-guest-dr-venom.glsl
filter_linear6 = true
scale_type6 = viewport
shader6 = shaders/guest/linearize.glsl
filter_linear6 = false
scale_type6 = source
scale6 = 1.0
float_framebuffer6 = true
shader7 = shaders/guest/blur_horiz.glsl
filter_linear7 = false
scale_type7 = source
scale7 = 1.0
float_framebuffer7 = true
shader8 = shaders/guest/blur_vert.glsl
filter_linear8 = false
scale_type8 = source
scale8 = 1.0
float_framebuffer8 = true
shader9 = shaders/guest/crt-guest-dr-venom.glsl
filter_linear9 = true
scale_type9 = viewport
scale_x9 = 1.0
scale_y9 = 1.0

View File

@ -0,0 +1,365 @@
____ ____ _____ ____ _ ____ __ __
/ ___| _ \_ _| / ___|_ _ ___ ___| |_ | _ \ _ _\ \ / /__ _ __ ___ _ __ ___
| | | |_) || |_____| | _| | | |/ _ \/ __| __|____| | | | '__\ \ / / _ \ '_ \ / _ \| '_ ` _ \
| |___| _ < | |_____| |_| | |_| | __/\__ \ ||_____| |_| | |_ \ V / __/ | | | (_) | | | | | |
\____|_| \_\|_| \____|\__,_|\___||___/\__| |____/|_(_) \_/ \___|_| |_|\___/|_| |_| |_|
CRT - Guest - Dr.Venom
Copyright (C) 2018-2019 guest(r) - guest.r@gmail.com
Incorporates many good ideas and suggestions from Dr.Venom.
This guide: Rev 1, April 28th 2019
----------------
# Introduction #
----------------
This shader mimics the look of Cathode Ray Tubes (CRTs) on modern LCD monitors.
Its main goal is to be accurate out of the box, and keep plenty of customization options for the CRT purists to tinker with. That's you if you're reading this :)
Since the range of shader parameters can be a bit overwhelming we've created this little readme to explain some of the options.
If you have questions, please don't hesitate to reach out to us!
Most of the stuff in this guide has been discussed on English Amiga Board here: http://eab.abime.net/showthread.php?t=95969&page=2
--------------
# Afterglow #
--------------
The RGB phosphors in CRTs have a decay time when going from fully lit to off. When going from bright lit status to off the luminance level instantly falls to about 10%, but then tend to linger at that level for a bit. This is what we call "afterglow". This afterglow of phosphors causes slightly visible trails when bright objects are moving fast on a dark background.
For an example of this "CRT phosphor afterglowing" see this video on youtube: https://youtu.be/N72uiXFgrh0
If you look at the UFO flying by from second 13 to 18 you can clearly see the trail in motion. In the video it looks slightly exaggerated because of the way cameras work.
The shader allows to control the strength of afterglow per Red, Green, Blue "phospors". Generally the blue phosphor has the least afterglow, so you may want to have red and green a bit stronger than blue.
Afterglow switch ON/OFF // Turn afterglow feature ON/OFF
Afterglow Red (more is more) // controls the initial brightness of the afterglow on the red phosphor. Higher values makes red more visible in the afterglow. Default is 0.07
Persistence Red (more is less) // Controls the decay time, i.e. if red should fade away quickly from its initial brightness or slowly. A higher value makes the red phosphor fade away more quickly. Default value is 0.05.
Afterglow Green
Persistence Green
Afterglow Blue
Persistence Blue
Afterglow saturation // Determines the saturation of the RGB afterglow. Generally afterglow has very low saturation so it defaults to a low value of 0.1. Higher values give more saturation.
-------------
# TATE mode #
-------------
Yes we do in weird lingo :) In short TATE means "vertical" orientation for arcade monitors. The term ”Tate” is apparently a shortened form of the Japanese verb “tateru,” which means “to stand.” Pronounced “tah-teh,” though the common mispronunciation of “tayte” has gained semi-acceptance. Also commonly spelled with all capital letters (“TATE”), though it is not an acronym.
In the shader when you set TATE to 1 both the scanlines and mask orientation will rotate by 90 degrees to accommodate to Arcade games that are in vertical orientation, like 1942 shooters and the like. Mostly useful for when running MAME vertical games.
-------------------------
# Smart Integer Scaling #
-------------------------
When the video scaling is set to full screen, it may happen that the scanlines appear slightly uneven. To remedy this you can enable this option. It will scale vertically to the nearest suitable integer scale factor. The "smart" part is that it will take into account "overscan" as it appeared on TVs, so it may scale the image slightly larger than the screen size to keep things full screen while also enabling integer scale factor. When it makes use of this overscan up to about 10% of the image may fall outside of the visible area. If the nearest integer larger scale factor would go over this this bound, it chooses the nearest lower integer scale, which will come at the cost of some black bars around the image. Just try and learn :).
Values are:
0 = off
1 = smart integer scale vertically
2 = smart integer scale vertically and keep aspect ratio
----------------
# Raster Bloom #
----------------
Raster bloom is a feature that occurs on some CRTs, where the image will slightly expand on brighter images. This may give some extra "pop" to short flashing bright images, like big explosions and such. Almost all CRTs are experiencing raster bloom to some extent, but how much and whether it's really visible depends largely on the CRT model and how much it has aged / been maintained.
The following two youtube videos show examples of raster blooming.
The first movie shows metal slug on a CRT TV. If you go to second 75 and look at the bottom right where it says "Credit 04", you'll see how this text gets pushed slightly to the outside of the bezel when the screen gets bright and it coming back in on darker screens. This is sort of the default case where bloom sizes up the image by 1 to 2%.
https://youtu.be/_K-kTSUaekk
The next one shows an older TV where the voltage regulation has clearly been diminished. From 1:15 in this youtube:
https://youtu.be/zbGYwPwf-zA
The guy is turning the brightness of the monitor up and down. You can see how the white raster expands quite a bit when the brightness on the monitor is turned up and then shrinks back when it's lowered. This is what we call the 10% blooming case. I.e. it has a defect and needs servicing, opposed to the 1 - 2% normal bloom on properly calibrated sets.
The following parameters control Raster Bloom in the shader:
Raster bloom % // This determines the raster bloom scale factor. A value of 2 to 3% will result in realistic raster bloom. Larger values will exaggerate the effect, or you're really into mimicking a faulty CRT :).
R. Bloom Overscan Mode // This setting determines whether a fully bright image may push the image outside of the screen / bezel or not. Possible settings:
(This assumes that automatic full screen scaling is enabled in Retroarch video options.)
0 = Raster bloom is always within the boundaries of the visible screen
1 = holds the middle between option 0 and 2 :)
2 = Raster bloom pushes part of the image outside of the visible area on bright screens.
Setting 1 and 2 more or less mimic the behavior as seen in the metal slug x video mentioned above.
-------------------------
# Saturation adjustment #
-------------------------
This controls how saturated the image is. Higher values give more saturation. This may be useful with emulated systems like e.g. SNES, which tend to have a more saturated image than default.
--------------------------
# Gamma In and Gamma Out #
--------------------------
Setting Gamma In ("input gamma") to 2.4 affects the following:
- horizontal interpolation is done in gamma space, where brighter colors spread a bit more over darker ones. Should match interpolation of CRT's.
- scanlines are applied differently
- masks are better distributed over the spectrum
Generally it's best to keep this value at the default of 2.4 as it mostly concerns a shader internal conversion step where this default value results in desired behavior
Gamma Out:
Of course we have to switch back to the normal color space, so there is the Gamma Out out functionality. In some CRT shaders it's about 10% lower compared with the input gamma. Different input/output gamma values affect saturation and brightness.
Since there is an option to use neutral input/output gamma (1.0), you can observe the difference within the shader.
I think most importantly is that this part of the shader functions as intended and can be tweaked to personal preference.
I think the most catchy part here is that CRT's have this 2.2-2.25 gamma and I defaulted 2.4. It roots in sRGB a bit and I got used to it. You can set output gamma (often referred to as CRT gamma) to 2.25 np.
From the CRT color research (at the end of this section) it was found that the researched CRTs had a Gamma of 2.25. So to have the shader color profiles displayed properly one has to set the Gamma Out to 2.25.
----------------
# Bright boost #
----------------
This setting makes the image brighter. Making the image brighter is useful / necessary when scanlines are enabled, as scanline simulation reduces brightness of the image.
Good values for "bright boost" are between 1.1 and 1.3 depending on preference. Note that there's a tradeoff, higher values for brightboost make the image brighter, but can cause clipping of colors, making the image become more "flat". On lower color systems, like 8-bit, this clipping may be seen as soon as you go over 1.2. It's best to experiment a bit to see what suits one's own taste.
-------------
# Scanlines #
-------------
One of the most distinguishable features of CRTs when run in progressive mode are visible scanlines. I.e. the image is characterized by distinguishable brighter lines (the "scanlines"), and darker/black in-between lines. Sometime people refer to these darker lines when they say scanlines, but the bottom line is the same ;-)
Since good scanline simulation is one of the most determining aspects of good CRT simulation, there are no less than 5 parameters that control this feature:
Scanline Type // 0 = normal scanlines; 1 = more intense scanline type ; 2 = more aggressive / accentuated scanline type. Default = 0
Scanline beamshape // The scanline beamshape "low" and "high" parameters define the look of the scanlines. With these two settings the scanlines can be made thinner or thicker, less or more rounded at the edges and degrees between them. In particular the scanline beamshape low value defines the scanline shape near the middle and the beamshape high value defines the scanline shape near the edges. For example a setting of 5.0,15.0 creates a stronger but more flat like looking scanline. The default values work very well, but you may want to experiment depending on your screen resolution and preference.
Scanline dark // On a real CRT darker scanlines are thinner than bright scanlines. This setting determines by how much. Raising the value makes them thinner. Default is 1.35.
Scanline bright // On a real CRT bright scanlines are thicker than darker scanlines. This setting determines how much thicker. Lowering the values will make them thicker. Default is 1.10.
Increased bright scanline beam // This accentuates the brighter parts or pixels within a single scanline. On a real CRT bright pixels within a scanline will appear thicker. This setting controls by how much. Default is 0.65.
---------------------------
# Sharpness and smoothing #
---------------------------
The following parameters determine the smoothness versus sharpness balance of the image.
A real CRT has the peculiar but very nice characteristic that single pixels are smooth, while the overall image is sharp. This opposed to modern LCDs, where both individual pixels and the total image are very sharp. To recreate the soft "pillow shape" phosphor dot characteristics while keeping overall image sharp there 4 parameters that control this balance.
Horizontal sharpness // This setting determines the overall image sharpness mostly. Higher values create a sharper image. Default is 5.25.
Substractive sharpness // This is a nice "hack" that may be used in combination with "horizontal sharpness". Higher values give more sharpness to pixels and mask. Default is 0.05.
Horizontal Smoothing // This is some candy that blends pixels more that are close in color tint to each other. Gives a nice touch to especially high color systems that have many grades of color (like playstation).
Smart Smoothing Threshold // This works in cooperation with "Horizontal Smoothing". It sets the threshold for how far apart "same" color tints must be for horizontal smoothing to apply.
-------------
# Curvature #
-------------
The physical properties of (earlier) shadow mask CRTs make them to have a slightly curved screen. For some of these CRTs the image may appear slightly curved as well, although that largely depends on make and model and how well the set is calibrated. The following two parameters allow for the curvature to be configured in the vertical and horizontal direction.
CurvatureX // default is OFF. In case you like curvature, a recommended value is 0.03.
CurvatureY // Default is OFF. In case you like curvature, a recommended value is 0.04.
--------
# Glow #
--------
Phosphors typically create a small surrounding glow on objects. This is especially noticeable when bright objects are shown on a dark background, and even more so when watching a CRT in a dim environment. Whether this glow exists because the light emission gets scattered slightly in the front glass of the tube or something else we would like to know :).
In the shader the glow strength, radius and grade (fall-off) can be configured.
Glow Strength // Determines the overall strength of the glow . Default is 0.02.
H. Glow Radius // Determines the radius of the glow in horizontal direction. Higher values create a bigger radius. Default is 4.0.
Horizontal Glow Grade // Determines the grade/ fall-off / fade of the glow. Higher values make the glow fade out more quickly.
V. Glow Radius // Same as horizontal parameter but for vertical.
Vertical Glow Grade // Same as horizontal parameter but for vertical.
--------
# Mask #
--------
Together with scanlines the second most distinguishable feature of CRTs is the very subtle pattern, also called "mask", apparent in images displayed on a CRT. The type of pattern largely depends on the technology used, shadow mask (dotmask and slotmask) versus aperture grille (trinitron). All these types of masks can be simulated with the shader.
CRT Mask: 0:CGWG, 1-4:Lottes, 5-6:'Trinitron', 7: slotmask (see below) // The shader allows to set 7 different types of masks
0 = CGCW - a very light generic mask pattern
1 - 4 = Lottes masks, 4 different types of masks that simulate a shadow mask more or less.
5 - 6 = Trinitron. These are very effective mask types, that closely resemble the appearance of Trinitron's aperture grill. "5" is a finer version, mostly for use on 1080p, "6" is a more coarse version, mostly for use on 4K resolution.
7 = slotmask, to be used in conjunction with the additional slotmask parameters.
Mask types 1 to 6 strength can be set with these two parameters:
Lottes maskDark // lower values generally make the mask appear more strongly
Lottes maskLight // higher values generally make the mask appear more strongly
When using "7" slotmask, below parameters need to be set:
CRT Mask Size (2.0 is nice in 4k) // set to 1 for 1080p, 2 for 4K resolution
Slot Mask Strength // Overall strength of the slot mask. Good values are around 0.5
Slot Mask Width // Determines the horizontal size of the slotmask pattern. Use 2 or 3 for 1080p, 4-6 for 4K resolution.
Slot Mask Height: 2x1 or 4x1" // Determines the vertical size of the slotmask pattern. Use 1 for 1080p, or 2 for 4K resolution.
Finally there's a parameter that influences the look of mask 5 - 7.
Mask 5&6 cutoff // This determines how soon black appears between pixels for colors that are close to the R, G, or B primaries. This is suitable for both Trinitron and Slotmask. Default is 0.2. Higher values create a quicker cutoff to black between these pixels.
-----------------------
# Color Temperature % #
-----------------------
Each CRT monitor has a "whitepoint" setting, which influences how warm or cold the colors will look. The whitepoint setting differed quite a bit between different CRT models. Some had a 5000K (D50) whitepoint, i.e. "warm" colors, and some had a 9300K whitepoint,i.e. very "cold" colors. Most will sit somewhere in between, with today's standard being 6500K (D65). Note that a warmer setting tends the greys noticeably to a more yellowish brown, while the colder setting moves it to a more blueish grey.
At setting 0 the "color temperature %" is equivalent to the D65 whitepoint, let's say "neutral". Lower it to move towards the more warm 5000K point, or raise it to move it more towards the 9300K cold point.
-------------------
# PVM Like Colors #
-------------------
PVM Like Colors // This is a bit of candy that tries to simulate some of the color aberrations that appear with Sony PVM and BVM monitors.
-------------------
# LUT Colors #
-------------------
The shader has two ways to simulating "CRT Colors". LUT colors and CRT Color Profiles. LUT colors use lookup tables to transform the sRGB color profile to something more close to CRT colors. These LUTs come from varying sources, and the accuracy regarding CRT color simulation is a bit of an unknown, but at the least they provide some nice alternative color schemes which you may like.
--------------------- ---------------
# CRT Color Profile # & # Color Space #
--------------------- ---------------
"CRT colors" changes the default colors to something more close to what the RGB Phosphors in CRTs produce.
These profiles are about subtle changes, but if you were used to the display of CRTs you may remember the display having more vivid greens, softer yellows and red, etc. It all depends on the type of CRT you were looking at, but admittedly CRT colors are different from the default sRGB color gamut that is prevalent in today's LCD screens.
The CRT colors are based on research of the CIE chromaticity coordinates of the most common phosphors used back in the day. Therefore we ended up with 3 "specs" which are EBU standard phosphors, P22-RGB phosphors and the SMPTE-C standard. These three profiles can be selected under "CRT colors" as number 1, 2 and 3.
Then there are two additional "calibrated" profiles that actually quite closely match a Philips based CRT monitor and a Trinitron monitor. They are profile number 4 and 5.
Some more information on these profiles can be read below.
The main drawback currently is that Phosphor color primaries are partly outside the sRGB spectrum, such that for these profiles a "Wide Color Gamut" monitor is needed / recommended. This is what the "Color space" option is for. If you happen to own a monitor that is able to display DCI-P3 color gamut, then set this option to "1". Option "2" is for AdobeRGB and "3" for Rec. 2020. DCI-P3 is verified to be quite accurate.
In conclusion:
The good news is that we've got "CRT colors" largely covered now with the correct specs and two "quite accurate" calibrated profiles. The bad news is that with a default sRGB monitor the profiles will be more or less clipped and look wrong, depending on the content. Then we have some good news, as it seems that DCI-P3 or some other wide color gamut will be part of the HDR-500+ spec (see here: https://displayhdr.org/wp-content/uploads/2019/02/DisplayHDR_SpecChart_Rows_190219.jpg ) So within a few years wide color gamut should become mainstream in monitors. The question remains whether for HDR-500+ certified monitors this wide color gamut can be enabled by the user or emulator, or whether it will be only available in HDR content encoded mode. Time will tell.
Lastly, let's not forget we are talking about subtle differences from the default sRGB colors here. Let's just say you have to be slightly OCD on CRT tech to really appreciate the difference :-)
For those interested below is some additional information on each of the profiles and the specific chromaticity values used. This is purely additional information, there is no need (or possibility) to do anything with these in the shader settings.
"CRT Colors" for CRT-Guest-Dr-Venom -- Additional information.
3 x spec
2 x calibration
Specifications for three standards
1. EBU Standard Phosphors
// Amongst others used in Sony BVMs and Higher-end PVMs
// Tolerances are described in the E.B.U. standard reference document "E.B.U. standard for chromaticity tolerances for studio monitors" tech-3213-E.
// PVM-1440QM service manual quotes 0.01 as tolerance on the RGB CIE coordinates.
xb0 = "150.000000"
xg0 = "290.000000"
xr0 = "640.000000"
yb0 = "60.000000"
yg0 = "600.000000"
yr0 = "330.000000"
Whitepoint is D65
X 95,04 --> Xw0 950.4
Y 100 --> Yw0 1000
Z 108,88 --> Zw0 1088.8
2. P22 Phosphors
// These phosphors are often quoted as the "default" phosphors used in CRTs
// Also used in lower-end PVMs, see Sony PVM-20M4E 20M2E Colour Video Monitor.pdf
// These can still be bought :-) https://www.phosphor-technology.com/crt-phosphors/ -- includes CIE coordinates.
xb0 = "148.000000"
xg0 = "310.000000"
xr0 = "647.000000"
yb0 = "62.000000"
yg0 = "594.000000"
yr0 = "343.000000"
3. SMPTE-C
// Spec for most of America.
// I have forgone on the 1953 NTSC standard, as apart from very few early color TV's the 1953 NTSC standard was never actually used. Instead less saturated primaries were used to achieve brighter screens.
// Taken from the WIKI on NTSC (https://en.wikipedia.org/wiki/NTSC) In 1968-69 the Conrac Corp., working with RCA, defined a set of controlled phosphors for use in broadcast color picture video monitors. This specification survives today as the SMPTE "C" phosphor specification:
xb0 = "155.000000"
xg0 = "310.000000"
xr0 = "630.000000"
yb0 = "70.000000"
yg0 = "595.000000"
yr0 = "340.000000"
Whitepoint is D65
X 95,04 --> Xw0 950.4
Y 100 --> Yw0 1000
Z 108,88 --> Zw0 1088.8
4. Calibrated profile for Philips CRT monitors. Of course an approximation, but I'm pleased with the "quite accurate" results.
// Manually calibrated and compared to real Philips based CRT monitors, running side by side with the shader on a 10-bit DCI-P3 gamut panel. This calibrated CRT profile covers amongst others Philips CM8533, Philips VS-0080, and Commodore 1084.
// Note the whitepoint is significantly different from D65. It's closer to 6100K, but clearly not on the blackbody curve. Possibly an ISO-line target, given the slight hue on the whitepoint. Other than that it could be aging / whitepoint drift. I compared four CRT monitors, one of them in very mint condition, and they all have this slight hue on the whitepoint, so I would guess this is how they came out of the factory. But then again since these things are now getting close to 30 years old, who knows? Either way the profile should be good: factory out or true to life aged CRTs... :D.
// It's important this specific whitepoint is used in the shader or the colors will not be accurate.
// Also it's important to note that this profile should be used with "Gamma Out" at 2.25 or the colors will be less accurate.
xb0 = "154.000000"
xg0 = "300.000000"
xr0 = "635.000000"
yb0 = "60.000000"
yg0 = "620.000000"
yr0 = "339.000000"
Whitepoint:
Xw0 = "910.000000"
Yw0 = "1000.000000"
Zw0 = "960.000000"
5. Calibrated profile for Sony Trinitron Monitor.
// In a similar fashion as the Philips CRT based profile, this is a manually calibrated profile for a Sony Trinitron monitor, model KX-14CP1.
// This monitor uses a Whitepoint that is close to 9300K. The Z value in the calibration process has been raised to the point where the "blue-ishness" of the white matches. To achieve further 9300K white, I guess one has to raise the hardware whitepoint of the host PC monitor...
// It's important this specific whitepoint is used in the shader or the colors will not be accurate.
// Also it's important to note that this profile should be used with "Gamma Out" at 2.25 or the colors will be less accurate.
xb0 = "152.000000"
xg0 = "279.000000"
xr0 = "647.000000"
yb0 = "60.000000"
yg0 = "635.000000"
yr0 = "335.000000"
Whitepoint:
Xw0 = "903.000000"
Yw0 = "1000.000000"
Zw0 = "1185.000000"
End :)

View File

@ -28,7 +28,6 @@
#pragma parameter AB "Afterglow Blue" 0.07 0.0 1.0 0.01
#pragma parameter PB "Persistence Blue" 0.05 0.0 1.0 0.01
#pragma parameter sat "Afterglow saturation" 0.10 0.0 1.0 0.01
#pragma parameter GTH "Afterglow threshold" 5.0 0.0 255.0 1.0
#if defined(VERTEX)
@ -126,7 +125,6 @@ uniform COMPAT_PRECISION float PG;
uniform COMPAT_PRECISION float AB;
uniform COMPAT_PRECISION float PB;
uniform COMPAT_PRECISION float sat;
uniform COMPAT_PRECISION float GTH;
#else
#define SW 1.00
#define AR 0.07
@ -136,10 +134,9 @@ uniform COMPAT_PRECISION float GTH;
#define AB 0.07
#define PB 0.05
#define sat 0.10
#define GTH 5.0
#endif
#define eps 1e-4
#define eps 1e-3
vec3 afterglow(float number)
{
@ -149,7 +146,6 @@ vec3 afterglow(float number)
void main()
{
vec3 color = COMPAT_TEXTURE(Source, TEX0.xy).rgb;
// vec3 color0 = COMPAT_TEXTURE(PrevTexture, TEX0.xy).rgb * afterglow(1.0);
vec3 color1 = COMPAT_TEXTURE(Prev1Texture, TEX0.xy).rgb * afterglow(1.0);
vec3 color2 = COMPAT_TEXTURE(Prev2Texture, TEX0.xy).rgb * afterglow(2.0);
vec3 color3 = COMPAT_TEXTURE(Prev3Texture, TEX0.xy).rgb * afterglow(3.0);
@ -163,7 +159,7 @@ void main()
glow = normalize(pow(glow + vec3(eps), vec3(sat)))*l;
float w = 1.0;
if ((color.r + color.g + color.b) > GTH/255.0) w = 0.0;
if ((color.r + color.g + color.b) > 7.0/255.0) w = 0.0;
FragColor = vec4(color + SW*w*glow,1.0);
}

View File

@ -1,8 +1,8 @@
#version 130
/*
Average Luminance Shader
Average Luminance Shader, Smart Smoothing Difference Shader
Copyright (C) 2018 guest(r) - guest.r@gmail.com
Copyright (C) 2018-2019 guest(r) - guest.r@gmail.com
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -22,7 +22,8 @@
*/
// Parameter lines go here:
#pragma parameter grade "Raster Bloom Grade" 0.65 0.10 1.0 0.05
#pragma parameter STH "Smart Smoothing Threshold" 0.7 0.4 1.2 0.05
#if defined(VERTEX)
@ -91,6 +92,8 @@ uniform COMPAT_PRECISION vec2 OutputSize;
uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;
uniform sampler2D Texture;
uniform sampler2D PassPrev2Texture;
COMPAT_VARYING vec4 TEX0;
// in variables go here as COMPAT_VARYING whatever
@ -103,30 +106,56 @@ COMPAT_VARYING vec4 TEX0;
#ifdef PARAMETER_UNIFORM
// All parameter floats need to have COMPAT_PRECISION in front of them
uniform COMPAT_PRECISION float grade;
uniform COMPAT_PRECISION float STH;
#else
#define grade 0.65
#define STH 0.7
#endif
float df (vec3 A, vec3 B)
{
float diff = length(A-B);
float luma = clamp(length(0.5*min(A,B) + 0.25*(A+B) + 1e-8), 0.0001, 1.0);
float diff1 = diff/luma;
return 1.0 - clamp(7.0*(max(1.5*diff,diff1)-STH), 0.0, 1.0);
}
void main()
{
float xtotal = floor(InputSize.x/32.0);
float ytotal = floor(InputSize.y/32.0);
float xtotal = floor(InputSize.x/64.0);
float ytotal = floor(InputSize.y/64.0);
float ltotal = 0.0;
vec2 dx = vec2(SourceSize.z, 0.0)*32.0;
vec2 dy = vec2(0.0, SourceSize.w)*32.0;
vec2 dx = vec2(SourceSize.z, 0.0)*64.0;
vec2 dy = vec2(0.0, SourceSize.w)*64.0;
vec2 offset = 0.25*(dx+dy);
for (float i = 0.0; i <= xtotal; i++)
{
for (float j = 0.0; j <= ytotal; j++)
{
ltotal += length(textureLod(Source, i*dx + j*dy, 5.0).rgb);
ltotal+= max(0.25, length(textureLod(Source, i*dx + j*dy + offset, 6.0).rgb));
}
}
}
ltotal = inversesqrt(3.0)*ltotal / ((xtotal+1.0)*(ytotal+1.0));
FragColor = vec4(pow(ltotal, grade));
ltotal = 0.577350269 * ltotal / ((xtotal+1.0)*(ytotal+1.0));
dx = vec2(SourceSize.z, 0.0);
dy = vec2(0.0, SourceSize.w);
vec3 l1 = COMPAT_TEXTURE(PassPrev2Texture, TEX0.xy -dx).xyz;
vec3 ct = COMPAT_TEXTURE(PassPrev2Texture, TEX0.xy ).xyz;
vec3 r1 = COMPAT_TEXTURE(PassPrev2Texture, TEX0.xy +dx).xyz;
vec3 t1 = COMPAT_TEXTURE(PassPrev2Texture, TEX0.xy -dy).xyz;
vec3 b1 = COMPAT_TEXTURE(PassPrev2Texture, TEX0.xy +dy).xyz;
float dl = df(ct, l1);
float dr = df(ct, r1);
float dt = df(ct, t1);
float db = df(ct, b1);
float resx = dl; float resy = dr; float resz = floor(9.0*dt)/10.0 + floor(9.0*db)/100.0;
FragColor = vec4(resx,resy,resz,pow(ltotal, 0.65));
}
#endif

View File

@ -0,0 +1,110 @@
// Avg. Luminance Smoothing
// Parameter lines go here:
#if defined(VERTEX)
#if __VERSION__ >= 130
#define COMPAT_VARYING out
#define COMPAT_ATTRIBUTE in
#define COMPAT_TEXTURE texture
#else
#define COMPAT_VARYING varying
#define COMPAT_ATTRIBUTE attribute
#define COMPAT_TEXTURE texture2D
#endif
#ifdef GL_ES
#define COMPAT_PRECISION mediump
#else
#define COMPAT_PRECISION
#endif
COMPAT_ATTRIBUTE vec4 VertexCoord;
COMPAT_ATTRIBUTE vec4 COLOR;
COMPAT_ATTRIBUTE vec4 TexCoord;
COMPAT_VARYING vec4 COL0;
COMPAT_VARYING vec4 TEX0;
uniform mat4 MVPMatrix;
uniform COMPAT_PRECISION int FrameDirection;
uniform COMPAT_PRECISION int FrameCount;
uniform COMPAT_PRECISION vec2 OutputSize;
uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;
void main()
{
gl_Position = MVPMatrix * VertexCoord;
COL0 = COLOR;
TEX0.xy = TexCoord.xy;
}
#elif defined(FRAGMENT)
#if __VERSION__ >= 130
#define COMPAT_VARYING in
#define COMPAT_TEXTURE texture
out vec4 FragColor;
#else
#define COMPAT_VARYING varying
#define FragColor gl_FragColor
#define COMPAT_TEXTURE texture2D
#endif
#ifdef GL_ES
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#define COMPAT_PRECISION mediump
#else
#define COMPAT_PRECISION
#endif
uniform COMPAT_PRECISION int FrameDirection;
uniform COMPAT_PRECISION int FrameCount;
uniform COMPAT_PRECISION vec2 OutputSize;
uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;
uniform sampler2D Texture;
uniform sampler2D PrevTexture;
uniform sampler2D Prev1Texture;
uniform sampler2D Prev2Texture;
uniform sampler2D Prev3Texture;
uniform sampler2D Prev4Texture;
uniform sampler2D Prev5Texture;
uniform sampler2D Prev6Texture;
COMPAT_VARYING vec4 TEX0;
// in variables go here as COMPAT_VARYING whatever
// compatibility #defines
#define Source Texture
#define vTexCoord TEX0.xy
#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
#define outsize vec4(OutputSize, 1.0 / OutputSize)
#ifdef PARAMETER_UNIFORM
// All parameter floats need to have COMPAT_PRECISION in front of them
#else
#endif
void main()
{
vec3 color = COMPAT_TEXTURE(PrevTexture, TEX0.xy).rgb;
color+= COMPAT_TEXTURE(Prev6Texture, TEX0.xy).rgb;
color+= COMPAT_TEXTURE(Prev5Texture, TEX0.xy).rgb;
color+= COMPAT_TEXTURE(Prev4Texture, TEX0.xy).rgb;
color+= COMPAT_TEXTURE(Prev3Texture, TEX0.xy).rgb;
color+= COMPAT_TEXTURE(Prev2Texture, TEX0.xy).rgb;
color+= COMPAT_TEXTURE(Prev1Texture, TEX0.xy).rgb;
FragColor = vec4(color/7.0,1.0);
}
#endif

View File

@ -0,0 +1,222 @@
/*
CRT Color Profiles
Copyright (C) 2019 guest(r) and Dr. Venom
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.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Parameter lines go here:
#pragma parameter CP "CRT Color Profile" 0.0 -1.0 5.0 1.0
#pragma parameter CS "Color Space: sRGB, DCI, Adobe, Rec.2020" 0.0 0.0 3.0 1.0
#if defined(VERTEX)
#if __VERSION__ >= 130
#define COMPAT_VARYING out
#define COMPAT_ATTRIBUTE in
#define COMPAT_TEXTURE texture
#else
#define COMPAT_VARYING varying
#define COMPAT_ATTRIBUTE attribute
#define COMPAT_TEXTURE texture2D
#endif
#ifdef GL_ES
#define COMPAT_PRECISION mediump
#else
#define COMPAT_PRECISION
#endif
COMPAT_ATTRIBUTE vec4 VertexCoord;
COMPAT_ATTRIBUTE vec4 COLOR;
COMPAT_ATTRIBUTE vec4 TexCoord;
COMPAT_VARYING vec4 COL0;
COMPAT_VARYING vec4 TEX0;
uniform mat4 MVPMatrix;
uniform COMPAT_PRECISION int FrameDirection;
uniform COMPAT_PRECISION int FrameCount;
uniform COMPAT_PRECISION vec2 OutputSize;
uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;
void main()
{
gl_Position = MVPMatrix * VertexCoord;
COL0 = COLOR;
TEX0.xy = TexCoord.xy;
}
#elif defined(FRAGMENT)
#if __VERSION__ >= 130
#define COMPAT_VARYING in
#define COMPAT_TEXTURE texture
out vec4 FragColor;
#else
#define COMPAT_VARYING varying
#define FragColor gl_FragColor
#define COMPAT_TEXTURE texture2D
#endif
#ifdef GL_ES
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#define COMPAT_PRECISION mediump
#else
#define COMPAT_PRECISION
#endif
uniform COMPAT_PRECISION int FrameDirection;
uniform COMPAT_PRECISION int FrameCount;
uniform COMPAT_PRECISION vec2 OutputSize;
uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;
uniform sampler2D Texture;
COMPAT_VARYING vec4 TEX0;
// in variables go here as COMPAT_VARYING whatever
// compatibility #defines
#define Source Texture
#define vTexCoord TEX0.xy
#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
#define outsize vec4(OutputSize, 1.0 / OutputSize)
#ifdef PARAMETER_UNIFORM
// All parameter floats need to have COMPAT_PRECISION in front of them
uniform COMPAT_PRECISION float CP;
uniform COMPAT_PRECISION float CS;
#else
#define CP 0.0
#define CS 0.0
#endif
mat3 Profile0 =
transpose(mat3(
0.412391, 0.357584, 0.180481,
0.212639, 0.715169, 0.072192,
0.019331, 0.119195, 0.950532
));
mat3 Profile1 =
transpose(mat3(
0.430554, 0.341550, 0.178352,
0.222004, 0.706655, 0.071341,
0.020182, 0.129553, 0.939322
));
mat3 Profile2 =
transpose(mat3(
0.396686, 0.372504, 0.181266,
0.210299, 0.713766, 0.075936,
0.006131, 0.115356, 0.967571
));
mat3 Profile3 =
transpose(mat3(
0.393521, 0.365258, 0.191677,
0.212376, 0.701060, 0.086564,
0.018739, 0.111934, 0.958385
));
mat3 Profile4 =
transpose(mat3(
0.392258, 0.351135, 0.166603,
0.209410, 0.725680, 0.064910,
0.016061, 0.093636, 0.850324
));
mat3 Profile5 =
transpose(mat3(
0.377923, 0.317366, 0.207738,
0.195679, 0.722319, 0.082002,
0.010514, 0.097826, 1.076960
));
mat3 ToSRGB =
transpose(mat3(
3.240970, -1.537383, -0.498611,
-0.969244, 1.875968, 0.041555,
0.055630, -0.203977, 1.056972
));
mat3 ToDCI =
transpose(mat3(
2.725394, -1.018003, -0.440163,
-0.795168, 1.689732, 0.022647,
0.041242, -0.087639, 1.100929
));
mat3 ToAdobe =
transpose(mat3(
2.041588, -0.565007, -0.344731,
-0.969244, 1.875968, 0.041555,
0.013444, -0.118362, 1.015175
));
mat3 ToREC =
transpose(mat3(
1.716651, -0.355671, -0.253366,
-0.666684, 1.616481, 0.015769,
0.017640, -0.042771, 0.942103
));
void main()
{
vec3 c = COMPAT_TEXTURE(Source, TEX0.xy).rgb;
float p;
mat3 m_out;
if (CS == 0.0) { p = 2.4; m_out = ToSRGB; } else
if (CS == 1.0) { p = 2.6; m_out = ToDCI; } else
if (CS == 2.0) { p = 2.2; m_out = ToAdobe;} else
if (CS == 3.0) { p = 2.4; m_out = ToREC; }
vec3 color = pow(c, vec3(p));
mat3 m_in = Profile0;
if (CP == 0.0) { m_in = Profile0; } else
if (CP == 1.0) { m_in = Profile1; } else
if (CP == 2.0) { m_in = Profile2; } else
if (CP == 3.0) { m_in = Profile3; } else
if (CP == 4.0) { m_in = Profile4; } else
if (CP == 5.0) { m_in = Profile5; }
color = m_in*color;
color = m_out*color;
color = pow(color, vec3(1.0/p));
if (CP == -1.0) color = c;
FragColor = vec4(color,1.0);
}
#endif

View File

@ -0,0 +1,76 @@
shaders = 11
shader0 = ../../../ntsc/shaders/ntsc-pass1-composite-2phase.glsl
shader1 = ../../../ntsc/shaders/ntsc-pass2-2phase-gamma.glsl
filter_linear0 = false
filter_linear1 = false
scale_type_x0 = source
scale_type_y0 = source
scale_x0 = 4.0
scale_y0 = 1.0
frame_count_mod0 = 2
float_framebuffer0 = true
scale_type1 = source
scale_x1 = 0.5
scale_y1 = 1.0
shader2 = lut/lut.glsl
filter_linear2 = false
scale_type2 = source
scale2 = 1.0
textures = "SamplerLUT1;SamplerLUT2;SamplerLUT3"
SamplerLUT1 = lut/sony_trinitron1.png
SamplerLUT1_linear = true
SamplerLUT2 = lut/sony_trinitron2.png
SamplerLUT2_linear = true
SamplerLUT3 = lut/other1.png
SamplerLUT3_linear = true
shader3 = d65-d50.glsl
filter_linear3 = false
scale_type3 = source
scale3 = 1.0
shader4 = afterglow.glsl
filter_linear4 = false
scale_type4 = source
scale4 = 1.0
shader5 = avg-lum0.glsl
filter_linear5 = false
scale_type5 = source
scale5 = 1.0
shader6 = avg-lum.glsl
filter_linear6 = false
scale_type6 = source
scale6 = 1.0
mipmap_input6 = true
shader7 = linearize.glsl
filter_linear7 = false
scale_type7 = source
scale7 = 1.0
float_framebuffer7 = true
shader8 = blur_horiz.glsl
filter_linear8 = false
scale_type8 = source
scale8 = 1.0
float_framebuffer8 = true
shader9 = blur_vert.glsl
filter_linear9 = false
scale_type9 = source
scale9 = 1.0
float_framebuffer9 = true
shader10 = crt-guest-dr-venom.glsl
filter_linear10 = true
scale_type10 = viewport
scale_x10 = 1.0
scale_y10 = 1.0

View File

@ -1,407 +0,0 @@
/*
CRT - Guest - Dr. Venom
Copyright (C) 2018-2019 guest(r) - guest.r@gmail.com
Incorporates many good ideas and suggestions from Dr. Venom.
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.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Parameter lines go here:
#pragma parameter IOS "Smart X Integer Scaling" 0.0 0.0 1.0 1.0
#pragma parameter OS "R. Bloom Overscan Mode" 2.0 0.0 2.0 1.0
#pragma parameter BLOOM "Raster bloom %" 0.0 0.0 20.0 1.0
#pragma parameter brightboost "Bright boost" 1.10 0.50 2.00 0.01
#pragma parameter saturation "Saturation adjustment" 1.0 0.1 2.0 0.05
#pragma parameter gsl "Alternate scanlines" 0.0 0.0 1.0 1.0
#pragma parameter scanline "Scanline adjust" 8.0 1.0 12.0 1.0
#pragma parameter beam_min "Scanline dark" 1.30 0.5 2.0 0.05
#pragma parameter beam_max "Scanline bright" 1.00 0.5 2.0 0.05
#pragma parameter h_sharp "Horizontal sharpness" 4.0 1.5 20.0 0.25
#pragma parameter s_sharp "Substractive sharpness" 0.10 0.0 0.20 0.01
#pragma parameter csize "Corner size" 0.0 0.0 0.05 0.01
#pragma parameter warpX "CurvatureX (default 0.03)" 0.0 0.0 0.125 0.01
#pragma parameter warpY "CurvatureY (default 0.04)" 0.0 0.0 0.125 0.01
#pragma parameter glow "Glow Strength" 0.04 0.0 0.5 0.01
#pragma parameter shadowMask "Mask Style (0 = CGWG)" -1.0 -1.0 5.0 1.0
#pragma parameter maskDark "Lottes maskDark" 0.5 0.0 2.0 0.1
#pragma parameter maskLight "Lottes maskLight" 1.5 0.0 2.0 0.1
#pragma parameter CGWG "CGWG Mask Str." 0.4 0.0 1.0 0.05
#pragma parameter GTW "Gamma Tweak" 1.10 0.5 1.5 0.01
#pragma parameter gamma_out "Gamma out" 2.4 1.0 3.0 0.05
#if defined(VERTEX)
#if __VERSION__ >= 130
#define COMPAT_VARYING out
#define COMPAT_ATTRIBUTE in
#define COMPAT_TEXTURE texture
#else
#define COMPAT_VARYING varying
#define COMPAT_ATTRIBUTE attribute
#define COMPAT_TEXTURE texture2D
#endif
#ifdef GL_ES
#define COMPAT_PRECISION mediump
#else
#define COMPAT_PRECISION
#endif
COMPAT_ATTRIBUTE vec4 VertexCoord;
COMPAT_ATTRIBUTE vec4 COLOR;
COMPAT_ATTRIBUTE vec4 TexCoord;
COMPAT_VARYING vec4 COL0;
COMPAT_VARYING vec4 TEX0;
vec4 _oPosition1;
uniform mat4 MVPMatrix;
uniform COMPAT_PRECISION int FrameDirection;
uniform COMPAT_PRECISION int FrameCount;
uniform COMPAT_PRECISION vec2 OutputSize;
uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;
void main()
{
gl_Position = MVPMatrix * VertexCoord;
COL0 = COLOR;
TEX0.xy = TexCoord.xy * 1.00001;
}
#elif defined(FRAGMENT)
#if __VERSION__ >= 130
#define COMPAT_VARYING in
#define COMPAT_TEXTURE texture
out vec4 FragColor;
#else
#define COMPAT_VARYING varying
#define FragColor gl_FragColor
#define COMPAT_TEXTURE texture2D
#endif
#ifdef GL_ES
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#define COMPAT_PRECISION mediump
#else
#define COMPAT_PRECISION
#endif
uniform COMPAT_PRECISION int FrameDirection;
uniform COMPAT_PRECISION int FrameCount;
uniform COMPAT_PRECISION vec2 OutputSize;
uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;
uniform sampler2D Texture;
uniform sampler2D PassPrev3Texture;
uniform sampler2D PassPrev4Texture;
COMPAT_VARYING vec4 TEX0;
// compatibility #defines
#define Source Texture
#define vTexCoord TEX0.xy
#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
#define OutputSize vec4(OutputSize, 1.0 / OutputSize)
#ifdef PARAMETER_UNIFORM
// All parameter floats need to have COMPAT_PRECISION in front of them
uniform COMPAT_PRECISION float IOS;
uniform COMPAT_PRECISION float OS;
uniform COMPAT_PRECISION float BLOOM;
uniform COMPAT_PRECISION float brightboost;
uniform COMPAT_PRECISION float saturation;
uniform COMPAT_PRECISION float gsl;
uniform COMPAT_PRECISION float scanline;
uniform COMPAT_PRECISION float beam_min;
uniform COMPAT_PRECISION float beam_max;
uniform COMPAT_PRECISION float h_sharp;
uniform COMPAT_PRECISION float s_sharp;
uniform COMPAT_PRECISION float csize;
uniform COMPAT_PRECISION float warpX;
uniform COMPAT_PRECISION float warpY;
uniform COMPAT_PRECISION float glow;
uniform COMPAT_PRECISION float shadowMask;
uniform COMPAT_PRECISION float maskDark;
uniform COMPAT_PRECISION float maskLight;
uniform COMPAT_PRECISION float CGWG;
uniform COMPAT_PRECISION float GTW;
uniform COMPAT_PRECISION float gamma_out;
#else
#define IOS 0.00 // Smart Integer Scaling
#define OS 2.00 // Do overscan
#define BLOOM 0.00 // Bloom overscan percentage
#define brightboost 1.10 // adjust brightness
#define saturation 1.00 // 1.0 is normal saturation
#define gsl 0.0 // Alternate scanlines
#define scanline 8.0 // scanline param, vertical sharpness
#define beam_min 1.30 // dark area beam min - wide
#define beam_max 1.00 // bright area beam max - narrow
#define h_sharp 5.00 // pixel sharpness
#define s_sharp 0.00 // substractive sharpness
#define csize 0.00 // corner size
#define warpX 0.031 // Curvature X
#define warpY 0.041 // Curvature Y
#define glow 0.04 // Glow Strength
#define shadowMask 0.00 // Mask Style
#define maskDark 0.50 // Dark "Phosphor"
#define maskLight 1.50 // Light "Phosphor"
#define CGWG 0.40 // CGWG Mask Strength
#define GTW 1.10 // Gamma tweak
#define gamma_out 2.40 // output gamma
#endif
#define eps 1e-10
float b_min = 1.0 + 7.0*(beam_min - 0.5)*0.666666666;
float b_max = 1.0 + 7.0*(beam_max - 0.5)*0.666666666;
float scn_s = 0.3 + 0.7*(scanline - 1.0)*0.090909090;
vec3 sw(float x, vec3 color)
{
vec3 tmp = mix(vec3(beam_min),vec3(beam_max), color);
vec3 ex = vec3(x)*tmp;
return exp2(-scanline*ex*ex);
}
vec3 sw2(float x, vec3 c)
{
vec3 s = mix(vec3(b_min), vec3(b_max), c);
return clamp(smoothstep(vec3(0.0), vec3(scn_s), pow(vec3(x),s)), 0.0001, 1.0);
}
// Shadow mask (mostly from PD Lottes shader).
vec3 Mask(vec2 pos)
{
vec3 mask = vec3(maskDark, maskDark, maskDark);
float mf = floor(mod(pos.x,2.0));
float mf2 = floor(mod(pos.x + pos.y,2.0));
float mc = 1.0 - CGWG;
float mc2 = mc * 0.7;
// No mask
if (shadowMask == -1.0)
{
mask = vec3(1.0);
}
// Light mask.
else if (shadowMask == 5.0)
{
if (mf2 == 0.0) { mask = vec3(1.0); }
else { mask = vec3(mc2); }
}
// Phosphor.
else if (shadowMask == 0.0)
{
if (mf == 0.0) { mask.r = 1.0; mask.g = mc; mask.b = 1.0; }
else { mask.r = mc; mask.g = 1.0; mask.b = mc; }
}
// Very compressed TV style shadow mask.
else if (shadowMask == 1.0)
{
float line = maskLight;
float odd = 0.0;
if (fract(pos.x/6.0) < 0.5)
odd = 1.0;
if (fract((pos.y + odd)/2.0) < 0.5)
line = maskDark;
pos.x = fract(pos.x/3.0);
if (pos.x < 0.333) mask.r = maskLight;
else if (pos.x < 0.666) mask.g = maskLight;
else mask.b = maskLight;
mask*=line;
}
// Aperture-grille.
else if (shadowMask == 2.0)
{
pos.x = fract(pos.x/3.0);
if (pos.x < 0.333) mask.r = maskLight;
else if (pos.x < 0.666) mask.g = maskLight;
else mask.b = maskLight;
}
// Stretched VGA style shadow mask (same as prior shaders).
else if (shadowMask == 3.0)
{
pos.x += pos.y*3.0;
pos.x = fract(pos.x/6.0);
if (pos.x < 0.333) mask.r = maskLight;
else if (pos.x < 0.666) mask.g = maskLight;
else mask.b = maskLight;
}
// VGA style shadow mask.
else if (shadowMask == 4.0)
{
pos.xy = floor(pos.xy*vec2(1.0, 0.5));
pos.x += pos.y*3.0;
pos.x = fract(pos.x/6.0);
if (pos.x < 0.333) mask.r = maskLight;
else if (pos.x < 0.666) mask.g = maskLight;
else mask.b = maskLight;
}
return mask;
}
// Distortion of scanlines, and end of screen alpha (PD Lottes Curvature)
vec2 Warp(vec2 pos)
{
pos = pos*2.0-1.0;
pos *= vec2(1.0 + (pos.y*pos.y)*warpX, 1.0 + (pos.x*pos.x)*warpY);
return pos*0.5 + 0.5;
}
vec2 Overscan(vec2 pos, float dx, float dy){
pos=pos*2.0-1.0;
pos*=vec2(dx,dy);
return pos*0.5+0.5;
}
float Overscan2(float pos, float dy){
pos=pos*2.0-1.0;
pos*=dy;
return pos*0.5+0.5;
}
// Borrowed from cgwg's crt-geom, under GPL
float corner(vec2 coord)
{
coord *= SourceSize.xy / InputSize.xy;
coord = (coord - vec2(0.5)) * 1.0 + vec2(0.5);
coord = min(coord, vec2(1.0)-coord) * vec2(1.0, OutputSize.y/OutputSize.x);
vec2 cdist = vec2(max(csize,0.002));
coord = (cdist - min(coord,cdist));
float dist = sqrt(dot(coord,coord));
return clamp((cdist.x-dist)*700.0,0.0, 1.0);
}
const float sqrt3 = 1.732050807568877;
vec3 gamma_correct(vec3 color, vec3 tmp)
{
return color*mix(GTW, 1.0, max(max(tmp.r,tmp.g),tmp.b));
}
void main()
{
vec3 lum = COMPAT_TEXTURE(PassPrev4Texture, vec2(0.33,0.33)).xyz;
// Calculating texel coordinates
vec2 texcoord = TEX0.xy;
if (IOS == 1.0){
float ofactor = OutputSize.x/InputSize.x;
float intfactor = round(ofactor);
float diff = ofactor/intfactor;
texcoord.x = Overscan2(TEX0.x*(SourceSize.x/InputSize.x), diff)*(InputSize.x/SourceSize.x);
}
float factor = 1.00 + (1.0-0.5*OS)*BLOOM/100.0 - lum.x*BLOOM/100.0;
texcoord = Overscan(texcoord*(SourceSize.xy/InputSize.xy), factor, factor)*(InputSize.xy/SourceSize.xy);
vec2 pos = Warp(texcoord*(TextureSize.xy/InputSize.xy))*(InputSize.xy/TextureSize.xy);
vec2 pos0 = Warp(TEX0.xy*(TextureSize.xy/InputSize.xy))*(InputSize.xy/TextureSize.xy);
vec2 ps = SourceSize.zw;
vec2 OGL2Pos = pos * SourceSize.xy - vec2(0.5,0.0);
vec2 fp = fract(OGL2Pos);
vec2 dx = vec2(ps.x,0.0);
vec2 dy = vec2(0.0, ps.y);
vec2 pC4 = floor(OGL2Pos) * ps + 0.5*ps;
// Reading the texels
vec2 y2 = 2.0*dy;
bool sharp = (s_sharp > 0.0);
float wl2 = 1.5 + fp.y; wl2*=wl2; wl2 = exp2(-h_sharp*wl2); wl2 = max(wl2 - s_sharp, -wl2);
float wl1 = 0.5 + fp.y; wl1*=wl1; wl1 = exp2(-h_sharp*wl1); wl1 = max(wl1 - s_sharp, -0.4*s_sharp);
float wct = 0.5 - fp.y; wct*=wct; wct = exp2(-h_sharp*wct); wct = max(wct - s_sharp, s_sharp);
float wr1 = 1.5 - fp.y; wr1*=wr1; wr1 = exp2(-h_sharp*wr1); wr1 = max(wr1 - s_sharp, -0.4*s_sharp);
float wr2 = 2.5 - fp.y; wr2*=wr2; wr2 = exp2(-h_sharp*wr2); wr2 = max(wr2 - s_sharp, -wr2);
float wt = 1.0/(wl2+wl1+wct+wr1+wr2);
vec3 l2 = COMPAT_TEXTURE(PassPrev3Texture, pC4 -y2).xyz;
vec3 l1 = COMPAT_TEXTURE(PassPrev3Texture, pC4 -dy).xyz;
vec3 ct = COMPAT_TEXTURE(PassPrev3Texture, pC4 ).xyz;
vec3 r1 = COMPAT_TEXTURE(PassPrev3Texture, pC4 +dy).xyz;
vec3 r2 = COMPAT_TEXTURE(PassPrev3Texture, pC4 +y2).xyz;
vec3 color1 = (l2*wl2 + l1*wl1 + ct*wct + r1*wr1 + r2*wr2)*wt;
if (sharp) color1 = clamp(color1, min(min(l1,r1),ct), max(max(l1,r1),ct));
l2 = COMPAT_TEXTURE(PassPrev3Texture, pC4 -y2 +dx).xyz;
l1 = COMPAT_TEXTURE(PassPrev3Texture, pC4 -dy +dx).xyz;
ct = COMPAT_TEXTURE(PassPrev3Texture, pC4 +dx).xyz;
r1 = COMPAT_TEXTURE(PassPrev3Texture, pC4 +dy +dx).xyz;
r2 = COMPAT_TEXTURE(PassPrev3Texture, pC4 +y2 +dx).xyz;
vec3 color2 = (l2*wl2 + l1*wl1 + ct*wct + r1*wr1 + r2*wr2)*wt;
if (sharp) color2 = clamp(color2, min(min(l1,r1),ct), max(max(l1,r1),ct));
// calculating scanlines
float f = fp.x;
vec3 w1 = sw(f,color1);
vec3 w2 = sw(1.0-f,color2);
if (gsl == 1.0) { w1 = sw2(1.0-f,color1); w2 = sw2(f,color2);}
vec3 color = color1*w1 + color2*w2;
vec3 ctmp = color/(w1+w2);
color = pow(color, vec3(1.0/gamma_out));
float l = length(color);
color = normalize(pow(color + vec3(eps), vec3(saturation,saturation,saturation)))*l;
color*=brightboost;
color = gamma_correct(color,ctmp);
color = pow(color, vec3(gamma_out));
color = min(color, 1.0);
// Apply Mask
color = color*Mask(gl_FragCoord.yx * 1.000001);
vec3 Bloom = COMPAT_TEXTURE(Texture, pos).xyz;
color+=glow*Bloom;
color = min(color, 1.0);
color = pow(color, vec3(1.0/gamma_out));
FragColor = vec4(color*corner(pos0), 1.0);
}
#endif

View File

@ -23,27 +23,36 @@
// Parameter lines go here:
#pragma parameter TATE "TATE Mode" 0.0 0.0 1.0 1.0
#pragma parameter IOS "Smart Integer Scaling" 0.0 0.0 1.0 1.0
#pragma parameter OS "R. Bloom Overscan Mode" 2.0 0.0 2.0 1.0
#pragma parameter IOS "Smart Integer Scaling: 1.0:Y, 2.0:'X'+Y" 0.0 0.0 2.0 1.0
#pragma parameter OS "R. Bloom Overscan Mode" 1.0 0.0 2.0 1.0
#pragma parameter BLOOM "Raster bloom %" 0.0 0.0 20.0 1.0
#pragma parameter brightboost "Bright boost" 1.10 0.50 2.00 0.01
#pragma parameter saturation "Saturation adjustment" 1.0 0.1 2.0 0.05
#pragma parameter gsl "Alternate scanlines" 0.0 0.0 1.0 1.0
#pragma parameter scanline "Scanline adjust" 8.0 1.0 12.0 1.0
#pragma parameter beam_min "Scanline dark" 1.30 0.5 2.0 0.05
#pragma parameter beam_max "Scanline bright" 1.00 0.5 2.0 0.05
#pragma parameter h_sharp "Horizontal sharpness" 5.0 1.5 20.0 0.25
#pragma parameter s_sharp "Substractive sharpness" 0.0 0.0 0.20 0.01
#pragma parameter csize "Corner size" 0.0 0.0 0.05 0.01
#pragma parameter brightboost "Bright boost" 1.35 0.50 2.00 0.01
#pragma parameter gsl "Scanline Type" 0.0 0.0 2.0 1.0
#pragma parameter scanline1 "Scanline beam shape low" 8.0 1.0 15.0 1.0
#pragma parameter scanline2 "Scanline beam shape high" 8.0 5.0 23.0 1.0
#pragma parameter beam_min "Scanline dark" 1.35 0.5 2.0 0.05
#pragma parameter beam_max "Scanline bright" 1.05 0.5 2.0 0.05
#pragma parameter beam_size "Increased bright scanline beam" 0.65 0.0 1.0 0.05
#pragma parameter h_sharp "Horizontal sharpness" 5.25 1.5 20.0 0.25
#pragma parameter s_sharp "Substractive sharpness" 0.05 0.0 0.20 0.01
#pragma parameter h_smart "Smart Horizontal Smoothing" 0.0 0.0 1.0 0.1
#pragma parameter csize "Corner size" 0.0 0.0 0.07 0.01
#pragma parameter bsize "Border smoothness" 600.0 100.0 600.0 25.0
#pragma parameter warpX "CurvatureX (default 0.03)" 0.0 0.0 0.125 0.01
#pragma parameter warpY "CurvatureY (default 0.04)" 0.0 0.0 0.125 0.01
#pragma parameter glow "Glow Strength" 0.04 0.0 0.5 0.01
#pragma parameter shadowMask "Mask Style (0 = CGWG)" 0.0 -1.0 5.0 1.0
#pragma parameter maskDark "Lottes maskDark" 0.5 0.0 2.0 0.1
#pragma parameter maskLight "Lottes maskLight" 1.5 0.0 2.0 0.1
#pragma parameter CGWG "CGWG Mask Str." 0.4 0.0 1.0 0.05
#pragma parameter GTW "Gamma Tweak" 1.10 0.5 1.5 0.01
#pragma parameter gamma_out "Gamma out" 2.4 1.0 3.0 0.05
#pragma parameter glow "Glow Strength" 0.02 0.0 0.5 0.01
#pragma parameter shadowMask "CRT Mask: 0:CGWG, 1-4:Lottes, 5-6:'Trinitron'" 0.0 -1.0 7.0 1.0
#pragma parameter masksize "CRT Mask Size (2.0 is nice in 4k)" 1.0 1.0 2.0 1.0
#pragma parameter vertmask "PVM Like Colors" 0.0 0.0 0.25 0.01
#pragma parameter slotmask "Slot Mask Strength" 0.0 0.0 1.0 0.05
#pragma parameter slotwidth "Slot Mask Width" 2.0 2.0 6.0 0.5
#pragma parameter double_slot "Slot Mask Height: 2x1 or 4x1" 1.0 1.0 2.0 1.0
#pragma parameter mcut "Mask 5&6 cutoff" 0.2 0.0 0.5 0.05
#pragma parameter maskDark "Lottes maskDark" 0.5 0.0 2.0 0.05
#pragma parameter maskLight "Lottes maskLight" 1.5 0.0 2.0 0.05
#pragma parameter CGWG "CGWG Mask Str." 0.3 0.0 1.0 0.05
#pragma parameter GTW "Gamma Tweak" 1.05 0.5 1.5 0.01
#pragma parameter gamma_out "Gamma out" 2.4 1.0 3.5 0.05
#if defined(VERTEX)
@ -115,6 +124,7 @@ uniform COMPAT_PRECISION vec2 InputSize;
uniform sampler2D Texture;
uniform sampler2D PassPrev3Texture;
uniform sampler2D PassPrev4Texture;
uniform sampler2D PassPrev6Texture;
COMPAT_VARYING vec4 TEX0;
// compatibility #defines
@ -131,18 +141,27 @@ uniform COMPAT_PRECISION float IOS;
uniform COMPAT_PRECISION float OS;
uniform COMPAT_PRECISION float BLOOM;
uniform COMPAT_PRECISION float brightboost;
uniform COMPAT_PRECISION float saturation;
uniform COMPAT_PRECISION float gsl;
uniform COMPAT_PRECISION float scanline;
uniform COMPAT_PRECISION float scanline1;
uniform COMPAT_PRECISION float scanline2;
uniform COMPAT_PRECISION float beam_min;
uniform COMPAT_PRECISION float beam_max;
uniform COMPAT_PRECISION float beam_size;
uniform COMPAT_PRECISION float h_sharp;
uniform COMPAT_PRECISION float s_sharp;
uniform COMPAT_PRECISION float h_smart;
uniform COMPAT_PRECISION float csize;
uniform COMPAT_PRECISION float bsize;
uniform COMPAT_PRECISION float warpX;
uniform COMPAT_PRECISION float warpY;
uniform COMPAT_PRECISION float glow;
uniform COMPAT_PRECISION float shadowMask;
uniform COMPAT_PRECISION float masksize;
uniform COMPAT_PRECISION float vertmask;
uniform COMPAT_PRECISION float slotmask;
uniform COMPAT_PRECISION float slotwidth;
uniform COMPAT_PRECISION float double_slot;
uniform COMPAT_PRECISION float mcut;
uniform COMPAT_PRECISION float maskDark;
uniform COMPAT_PRECISION float maskLight;
uniform COMPAT_PRECISION float CGWG;
@ -153,72 +172,86 @@ uniform COMPAT_PRECISION float gamma_out;
#define IOS 0.00 // Smart Integer Scaling
#define OS 2.00 // Do overscan
#define BLOOM 0.00 // Bloom overscan percentage
#define brightboost 1.10 // adjust brightness
#define saturation 1.00 // 1.0 is normal saturation
#define brightboost 1.30 // adjust brightness
#define gsl 0.0 // Alternate scanlines
#define scanline 8.0 // scanline param, vertical sharpness
#define beam_min 1.30 // dark area beam min - wide
#define beam_max 1.00 // bright area beam max - narrow
#define h_sharp 5.00 // pixel sharpness
#define s_sharp 0.00 // substractive sharpness
#define scanline1 8.0 // scanline param, vertical sharpness
#define scanline2 8.0 // scanline param, vertical sharpness
#define beam_min 1.35 // dark area beam min - narrow
#define beam_max 1.05 // bright area beam max - wide
#define beam_size 0.65 // increased max. beam size
#define h_sharp 5.25 // pixel sharpness
#define s_sharp 0.05 // substractive sharpness
#define h_smart 0.00 // smart horizontal smoothing
#define csize 0.00 // corner size
#define warpX 0.031 // Curvature X
#define warpY 0.041 // Curvature Y
#define glow 0.04 // Glow Strength
#define shadowMask 0.00 // Mask Style
#define bsize 0.00 // border smoothness
#define warpX 0.00 // Curvature X
#define warpY 0.00 // Curvature Y
#define glow 0.02 // Glow Strength
#define shadowMask 5.00 // Mask Style
#define masksize 1.00 // Mask Size
#define vertmask 0.00 // Vertical mask
#define slotmask 0.00 // Slot Mask ON/OFF
#define slotwidth 2.00 // Slot Mask Width
#define double_slot 1.00 // Slot Mask Height
#define mcut 0.20 // Mask 5&6 cutoff
#define maskDark 0.50 // Dark "Phosphor"
#define maskLight 1.50 // Light "Phosphor"
#define CGWG 0.40 // CGWG Mask Strength
#define CGWG 0.30 // CGWG Mask Strength
#define GTW 1.10 // Gamma tweak
#define gamma_out 2.40 // output gamma
#endif
#define eps 1e-10
float b_min = 1.0 + 7.0*(beam_min - 0.5)*0.666666666;
float b_max = 1.0 + 7.0*(beam_max - 0.5)*0.666666666;
float scn_s = 0.3 + 0.7*(scanline - 1.0)*0.090909090;
float st(float x, float scanline)
{
return exp2(-scanline*x*x);
}
vec3 sw(float x, vec3 color)
vec3 sw0(vec3 x, vec3 color, float scanline)
{
vec3 tmp = mix(vec3(beam_min),vec3(beam_max), color);
vec3 ex = vec3(x)*tmp;
vec3 ex = x*tmp;
return exp2(-scanline*ex*ex);
}
vec3 sw2(float x, vec3 c)
{
vec3 s = mix(vec3(b_min), vec3(b_max), c);
return clamp(smoothstep(vec3(0.0), vec3(scn_s), pow(vec3(x),s)), 0.0001, 1.0);
}
vec3 sw1(vec3 x, vec3 color, float scanline)
{
float mx = max(max(color.r, color.g),color.b);
x = mix (x, beam_min*x, max(x-0.4*mx,0.0));
vec3 tmp = mix(vec3(1.2*beam_min),vec3(beam_max), color);
vec3 ex = x*tmp;
float br = clamp(0.8*beam_min - 1.0, 0.2, 0.45);
return exp2(-scanline*ex*ex)/(1.0-br+br*color);
}
// Shadow mask (mostly from PD Lottes shader).
vec3 Mask(vec2 pos)
vec3 sw2(vec3 x, vec3 color, float scanline)
{
vec3 tmp = mix(vec3(2.75*beam_min),vec3(beam_max), color);
tmp = mix(vec3(beam_max), tmp, pow(x, vec3(max(max(color.r, color.g),color.b)+0.3)));
vec3 ex = x*tmp;
return exp2(-scanline*ex*ex)/(0.6 + 0.4*color);
}
// Shadow mask (1-4 from PD CRT Lottes shader).
vec3 Mask(vec2 pos, vec3 c)
{
pos = floor(pos/masksize);
vec3 mask = vec3(maskDark, maskDark, maskDark);
float mf = floor(mod(pos.x,2.0));
float mf2 = floor(mod(pos.x + pos.y,2.0));
float mc = 1.0 - CGWG;
float mc2 = mc * 0.7;
// No mask
if (shadowMask == -1.0)
{
mask = vec3(1.0);
}
// Light mask.
else if (shadowMask == 5.0)
{
if (mf2 == 0.0) { mask = vec3(1.0); }
else { mask = vec3(mc2); }
}
// Phosphor.
else if (shadowMask == 0.0)
{
if (mf == 0.0) { mask.r = 1.0; mask.g = mc; mask.b = 1.0; }
else { mask.r = mc; mask.g = 1.0; mask.b = mc; }
pos.x = fract(pos.x*0.5);
float mc = 1.0 - CGWG;
if (pos.x < 0.5) { mask.r = 1.1; mask.g = mc; mask.b = 1.1; }
else { mask.r = mc; mask.g = 1.1; mask.b = mc; }
}
// Very compressed TV style shadow mask.
@ -237,6 +270,7 @@ vec3 Mask(vec2 pos)
if (pos.x < 0.333) mask.r = maskLight;
else if (pos.x < 0.666) mask.g = maskLight;
else mask.b = maskLight;
mask*=line;
}
@ -272,10 +306,64 @@ vec3 Mask(vec2 pos)
else if (pos.x < 0.666) mask.g = maskLight;
else mask.b = maskLight;
}
// Alternate mask 5
else if (shadowMask == 5.0)
{
float mx = max(max(c.r,c.g),c.b);
vec3 maskTmp = vec3( min( 1.25*max(mx-mcut,0.0)/(1.0-mcut) ,maskDark + 0.2*(1.0-maskDark)*mx));
float adj = 0.80*maskLight - 0.5*(0.80*maskLight - 1.0)*mx + 0.75*(1.0-mx);
mask = maskTmp;
pos.x = fract(pos.x/2.0);
if (pos.x < 0.5)
{ mask.r = adj;
mask.b = adj;
}
else mask.g = adj;
}
// Alternate mask 6
else if (shadowMask == 6.0)
{
float mx = max(max(c.r,c.g),c.b);
vec3 maskTmp = vec3( min( 1.33*max(mx-mcut,0.0)/(1.0-mcut) ,maskDark + 0.225*(1.0-maskDark)*mx));
float adj = 0.80*maskLight - 0.5*(0.80*maskLight - 1.0)*mx + 0.75*(1.0-mx);
mask = maskTmp;
pos.x = fract(pos.x/3.0);
if (pos.x < 0.333) mask.r = adj;
else if (pos.x < 0.666) mask.g = adj;
else mask.b = adj;
}
// Alternate mask 7
else if (shadowMask == 7.0)
{
float mx = max(max(c.r,c.g),c.b);
float maskTmp = min(1.6*max(mx-mcut,0.0)/(1.0-mcut) ,1.0 + 0.6*(1.0-mx));
mask = vec3(maskTmp);
pos.x = fract(pos.x/2.0);
if (pos.x < 0.5) mask = vec3(1.0 + 0.6*(1.0-mx));
}
return mask;
}
float SlotMask(vec2 pos, vec3 c)
{
if (slotmask == 0.0) return 1.0;
float mx = pow(max(max(c.r,c.g),c.b),1.33);
float mlen = slotwidth*2.0;
float px = fract(pos.x/mlen);
float py = floor(fract(pos.y/(2.0*double_slot))*2.0*double_slot);
float slot_dark = mix(1.0-slotmask, 1.0-0.80*slotmask, mx);
float slot = 1.0 + 0.7*slotmask*(1.0-mx);
if (py == 0.0 && px < 0.5) slot = slot_dark; else
if (py == double_slot && px >= 0.5) slot = slot_dark;
return slot;
}
// Distortion of scanlines, and end of screen alpha (PD Lottes Curvature)
vec2 Warp(vec2 pos)
{
@ -290,11 +378,6 @@ vec2 Overscan(vec2 pos, float dx, float dy){
return pos*0.5+0.5;
}
float Overscan2(float pos, float dy){
pos=pos*2.0-1.0;
pos*=dy;
return pos*0.5+0.5;
}
// Borrowed from cgwg's crt-geom, under GPL
@ -303,13 +386,11 @@ float corner(vec2 coord)
coord *= SourceSize.xy / InputSize.xy;
coord = (coord - vec2(0.5)) * 1.0 + vec2(0.5);
coord = min(coord, vec2(1.0)-coord) * vec2(1.0, OutputSize.y/OutputSize.x);
vec2 cdist = vec2(max(csize,0.002));
vec2 cdist = vec2(max(csize, max((1.0-smoothstep(100.0,600.0,bsize))*0.01,0.002)));
coord = (cdist - min(coord,cdist));
float dist = sqrt(dot(coord,coord));
return clamp((cdist.x-dist)*700.0,0.0, 1.0);
}
const float sqrt3 = 1.732050807568877;
return clamp((cdist.x-dist)*bsize,0.0, 1.0);
}
vec3 gamma_correct(vec3 color, vec3 tmp)
{
@ -318,23 +399,21 @@ vec3 gamma_correct(vec3 color, vec3 tmp)
void main()
{
vec3 lum = COMPAT_TEXTURE(PassPrev4Texture, vec2(0.33,0.33)).xyz;
float lum = COMPAT_TEXTURE(PassPrev4Texture, vec2(0.33,0.33)).a;
// Calculating texel coordinates
vec2 texcoord = TEX0.xy;
if (IOS == 1.0){
if (IOS > 0.0){
vec2 ofactor = OutputSize.xy/InputSize.xy;
vec2 intfactor = round(ofactor);
vec2 diff = ofactor/intfactor;
vec2 smartcoord;
smartcoord.x = Overscan2(TEX0.x*(SourceSize.x/InputSize.x), diff.x)*(InputSize.x/SourceSize.x);
smartcoord.y = Overscan2(TEX0.y*(SourceSize.y/InputSize.y), diff.y)*(InputSize.y/SourceSize.y);
texcoord = (TATE > 0.5) ? vec2(smartcoord.x, texcoord.y) :
vec2(texcoord.x, smartcoord.y);
float scan = mix(diff.y, diff.x, TATE);
texcoord = Overscan(texcoord*(SourceSize.xy/InputSize.xy), scan, scan)*(InputSize.xy/SourceSize.xy);
if (IOS == 1.0) texcoord = mix(vec2(TEX0.x, texcoord.y), vec2(texcoord.x, TEX0.y), TATE);
}
float factor = 1.00 + (1.0-0.5*OS)*BLOOM/100.0 - lum.x*BLOOM/100.0;
float factor = 1.00 + (1.0-0.5*OS)*BLOOM/100.0 - lum*BLOOM/100.0;
texcoord = Overscan(texcoord*(SourceSize.xy/InputSize.xy), factor, factor)*(InputSize.xy/SourceSize.xy);
vec2 pos = Warp(texcoord*(TextureSize.xy/InputSize.xy))*(InputSize.xy/TextureSize.xy);
vec2 pos0 = Warp(TEX0.xy*(TextureSize.xy/InputSize.xy))*(InputSize.xy/TextureSize.xy);
@ -365,22 +444,53 @@ void main()
}
bool sharp = (s_sharp > 0.0);
float wl2 = 1.5 + fpx; wl2*=wl2; wl2 = exp2(-h_sharp*wl2); wl2 = max(wl2 - s_sharp, -wl2);
float wl1 = 0.5 + fpx; wl1*=wl1; wl1 = exp2(-h_sharp*wl1); wl1 = max(wl1 - s_sharp, -0.4*s_sharp);
float wct = 0.5 - fpx; wct*=wct; wct = exp2(-h_sharp*wct); wct = max(wct - s_sharp, s_sharp);
float wr1 = 1.5 - fpx; wr1*=wr1; wr1 = exp2(-h_sharp*wr1); wr1 = max(wr1 - s_sharp, -0.4*s_sharp);
float wr2 = 2.5 - fpx; wr2*=wr2; wr2 = exp2(-h_sharp*wr2); wr2 = max(wr2 - s_sharp, -wr2);
float wt = 1.0/(wl2+wl1+wct+wr1+wr2);
float hsharp_tl, hsharp_tr, hsharp_bl, hsharp_br, hsharp_tc, hsharp_bc;
if (h_smart == 0.0)
{
hsharp_tl = h_sharp; hsharp_tr = h_sharp; hsharp_bl = h_sharp; hsharp_br = h_sharp; hsharp_tc = h_sharp; hsharp_bc = h_sharp;
}
else
{
// reading differences for smoothing
vec3 diffs_top = COMPAT_TEXTURE(PassPrev4Texture, pC4 ).xyz;
vec3 diffs_bot = COMPAT_TEXTURE(PassPrev4Texture, pC4 + offy).xyz;
if(TATE > 0.5)
{
diffs_top.x = floor(10.0*diffs_top.z)*0.11111; diffs_top.y = fract(10.0*diffs_top.z)*1.11111;
diffs_bot.x = floor(10.0*diffs_bot.z)*0.11111; diffs_bot.y = fract(10.0*diffs_bot.z)*1.11111;
}
float ls = mix (4.5, 2.25, h_smart);
hsharp_tl = mix(h_sharp, ls, diffs_top.x);
hsharp_tr = mix(h_sharp, ls, diffs_top.y);
hsharp_bl = mix(h_sharp, ls, diffs_bot.x);
hsharp_br = mix(h_sharp, ls, diffs_bot.y);
hsharp_tc = hsharp_tl;
hsharp_bc = hsharp_bl;
if (fpx == 0.5) { hsharp_tc = 0.5*(hsharp_tl + hsharp_tr); hsharp_bc = 0.5*(hsharp_bl + hsharp_br); }
if (fpx > 0.5) { hsharp_tc = hsharp_tr; hsharp_bc = hsharp_bl; }
}
float wl2 = 1.5 + fpx; wl2*=wl2; float twl2 = exp2(-hsharp_tl*wl2); twl2 = max(twl2 - s_sharp, -twl2); float bwl2 = exp2(-hsharp_bl*wl2); bwl2 = max(bwl2 - s_sharp, -bwl2);
float wl1 = 0.5 + fpx; wl1*=wl1; float twl1 = exp2(-hsharp_tl*wl1); twl1 = max(twl1 - s_sharp, -0.4*s_sharp); float bwl1 = exp2(-hsharp_bl*wl1); bwl1 = max(bwl1 - s_sharp, -0.4*s_sharp);
float wct = 0.5 - fpx; wct*=wct; float twct = exp2(-hsharp_tc*wct); twct = max(twct - s_sharp, s_sharp); float bwct = exp2(-hsharp_bc*wct); bwct = max(bwct - s_sharp, s_sharp);
float wr1 = 1.5 - fpx; wr1*=wr1; float twr1 = exp2(-hsharp_tr*wr1); twr1 = max(twr1 - s_sharp, -0.4*s_sharp); float bwr1 = exp2(-hsharp_br*wr1); bwr1 = max(bwr1 - s_sharp, -0.4*s_sharp);
float wr2 = 2.5 - fpx; wr2*=wr2; float twr2 = exp2(-hsharp_tr*wr2); twr2 = max(twr2 - s_sharp, -twr2); float bwr2 = exp2(-hsharp_br*wr2); bwr2 = max(bwr2 - s_sharp, -bwr2);
float wtt = 1.0/(twl2+twl1+twct+twr1+twr2);
float wtb = 1.0/(bwl2+bwl1+bwct+bwr1+bwr2);
vec3 l2 = COMPAT_TEXTURE(PassPrev3Texture, pC4 -off2).xyz;
vec3 l1 = COMPAT_TEXTURE(PassPrev3Texture, pC4 -offx).xyz;
vec3 ct = COMPAT_TEXTURE(PassPrev3Texture, pC4 ).xyz;
vec3 ct = COMPAT_TEXTURE(PassPrev3Texture, pC4 ).xyz;
vec3 r1 = COMPAT_TEXTURE(PassPrev3Texture, pC4 +offx).xyz;
vec3 r2 = COMPAT_TEXTURE(PassPrev3Texture, pC4 +off2).xyz;
vec3 color1 = (l2*wl2 + l1*wl1 + ct*wct + r1*wr1 + r2*wr2)*wt;
vec3 color1 = (l2*twl2 + l1*twl1 + ct*twct + r1*twr1 + r2*twr2)*wtt;
if (sharp) color1 = clamp(color1, min(min(l1,r1),ct), max(max(l1,r1),ct));
l2 = COMPAT_TEXTURE(PassPrev3Texture, pC4 -off2 +offy).xyz;
@ -388,39 +498,55 @@ void main()
ct = COMPAT_TEXTURE(PassPrev3Texture, pC4 +offy).xyz;
r1 = COMPAT_TEXTURE(PassPrev3Texture, pC4 +offx +offy).xyz;
r2 = COMPAT_TEXTURE(PassPrev3Texture, pC4 +off2 +offy).xyz;
vec3 color2 = (l2*wl2 + l1*wl1 + ct*wct + r1*wr1 + r2*wr2)*wt;
vec3 color2 = (l2*bwl2 + l1*bwl1 + ct*bwct + r1*bwr1 + r2*bwr2)*wtb;
if (sharp) color2 = clamp(color2, min(min(l1,r1),ct), max(max(l1,r1),ct));
// calculating scanlines
float f = (TATE < 0.5) ? fp.y : fp.x;
vec3 w1 = sw(f,color1);
vec3 w2 = sw(1.0-f,color2);
if (gsl == 1.0) { w1 = sw2(1.0-f,color1); w2 = sw2(f,color2);}
float shape1 = mix(scanline1, scanline2, f);
float shape2 = mix(scanline1, scanline2, 1.0-f);
float wt1 = st(f, shape1);
float wt2 = st(1.0-f, shape2);
vec3 color0 = color1*wt1 + color2*wt2;
vec3 ctmp = color0/(wt1+wt2);
vec3 tmp = pow(ctmp, vec3(1.0/gamma_out));
vec3 w1,w2 = vec3(0.0);
vec3 cref1 = mix(ctmp, color1, beam_size);
vec3 cref2 = mix(ctmp, color2, beam_size);
vec3 shift = vec3(-vertmask, vertmask, -vertmask);
vec3 f1 = clamp(vec3(f) + shift*0.5*(1.0+f), 0.0, 1.0);
vec3 f2 = clamp(vec3(1.0-f) - shift*0.5*(2.0-f), 0.0, 1.0);
if (gsl == 0.0) { w1 = sw0(f1,cref1,shape1); w2 = sw0(f2,cref2,shape2);} else
if (gsl == 1.0) { w1 = sw1(f1,cref1,shape1); w2 = sw1(f2,cref2,shape2);} else
if (gsl == 2.0) { w1 = sw2(f1,cref1,shape1); w2 = sw2(f2,cref2,shape2);}
vec3 color = color1*w1 + color2*w2;
vec3 ctmp = color/(w1+w2);
color = pow(color, vec3(1.0/gamma_out));
float l = length(color);
color = normalize(pow(color + vec3(eps), vec3(saturation,saturation,saturation)))*l;
color*=brightboost;
color = gamma_correct(color,ctmp);
color = pow(color, vec3(gamma_out));
color = min(color, 1.0);
color*=brightboost;
color = min(color, 1.0);
// Apply Mask
color *= (TATE < 0.5) ? Mask(gl_FragCoord.xy * 1.000001) :
Mask(gl_FragCoord.yx * 1.000001);
color *= (TATE < 0.5) ? Mask(gl_FragCoord.xy * 1.000001,tmp) :
Mask(gl_FragCoord.yx * 1.000001,tmp);
color = min(color,1.0);
color *= (TATE < 0.5) ? SlotMask(gl_FragCoord.xy * 1.000001,tmp) :
SlotMask(gl_FragCoord.yx * 1.000001,tmp);
vec3 Bloom = COMPAT_TEXTURE(Texture, pos).xyz;
color+=glow*Bloom;
color = min(color, 1.0);
color = pow(color, vec3(1.0/gamma_out));
FragColor = vec4(color*corner(pos0), 1.0);

View File

@ -1,6 +1,6 @@
// Parameter lines go here:
#pragma parameter WP "D65 to D50 strength %" 0.0 -100.0 100.0 5.0
#pragma parameter WP "Color Temperature %" 0.0 -100.0 100.0 5.0
#if defined(VERTEX)
@ -85,28 +85,48 @@ uniform COMPAT_PRECISION float WP;
#else
#define WP 0.0
#endif
const mat3 D65_to_XYZ = mat3 (
0.4306190, 0.2220379, 0.0201853,
0.3415419, 0.7066384, 0.1295504,
0.1783091, 0.0713236, 0.9390944);
const mat3 D65 = mat3 (
0.5767309, 0.2973769, 0.0270343,
0.1855540, 0.6273491, 0.0706872,
0.1881852, 0.0752741, 0.9911085);
const mat3 D50 = mat3 (
1.7552599, -0.5441336, 0.0063467,
-0.4836786, 1.5068789, -0.0175761,
-0.2530000, 0.0215528, 1.2256959);
const mat3 XYZ_to_D65 = mat3 (
3.0628971, -0.9692660, 0.0678775,
-1.3931791, 1.8760108, -0.2288548,
-0.4757517, 0.0415560, 1.0693490);
const mat3 D50_to_XYZ = mat3 (
0.4552773, 0.2323025, 0.0145457,
0.3675500, 0.7077956, 0.1049154,
0.1413926, 0.0599019, 0.7057489);
const mat3 XYZ_to_D50 = mat3 (
2.9603944, -0.9787684, 0.0844874,
-1.4678519, 1.9161415, -0.2545973,
-0.4685105, 0.0334540, 1.4216174);
void main()
{
vec3 color = COMPAT_TEXTURE(Source, TEX0.xy).rgb;
float p = 2.4;
vec3 c65 = D65*color;
vec3 c50 = D50*c65;
color = pow(color, vec3(p));
float m = WP/100.0;
vec3 warmer = D50_to_XYZ*color;
warmer = XYZ_to_D65*warmer;
color = (1.0-m)*color + m*c50;
vec3 cooler = D65_to_XYZ*color;
cooler = XYZ_to_D50*cooler;
float m = abs(WP)/100.0;
vec3 comp = (WP < 0.0) ? cooler : warmer;
color = mix(color, comp, m);
color = pow(color, vec3(1.0/p));
FragColor = vec4(color,1.0);
}

View File

@ -0,0 +1,183 @@
/*
CRT - Guest - Dr. Venom - Pass1
Copyright (C) 2018-2019 guest(r) - guest.r@gmail.com
Incorporates many good ideas and suggestions from Dr. Venom.
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.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Parameter lines go here:
#pragma parameter h_sharp "Horizontal sharpness" 5.00 1.5 20.0 0.25
#pragma parameter s_sharp "Substractive sharpness" 0.05 0.0 0.20 0.01
#pragma parameter h_smart "Smart Horizontal Smoothing" 0.0 0.0 1.0 0.1
#if defined(VERTEX)
#if __VERSION__ >= 130
#define COMPAT_VARYING out
#define COMPAT_ATTRIBUTE in
#define COMPAT_TEXTURE texture
#else
#define COMPAT_VARYING varying
#define COMPAT_ATTRIBUTE attribute
#define COMPAT_TEXTURE texture2D
#endif
#ifdef GL_ES
#define COMPAT_PRECISION mediump
#else
#define COMPAT_PRECISION
#endif
COMPAT_ATTRIBUTE vec4 VertexCoord;
COMPAT_ATTRIBUTE vec4 COLOR;
COMPAT_ATTRIBUTE vec4 TexCoord;
COMPAT_VARYING vec4 COL0;
COMPAT_VARYING vec4 TEX0;
vec4 _oPosition1;
uniform mat4 MVPMatrix;
uniform COMPAT_PRECISION int FrameDirection;
uniform COMPAT_PRECISION int FrameCount;
uniform COMPAT_PRECISION vec2 OutputSize;
uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;
void main()
{
gl_Position = MVPMatrix * VertexCoord;
COL0 = COLOR;
TEX0.xy = TexCoord.xy * 1.00001;
}
#elif defined(FRAGMENT)
#if __VERSION__ >= 130
#define COMPAT_VARYING in
#define COMPAT_TEXTURE texture
out vec4 FragColor;
#else
#define COMPAT_VARYING varying
#define FragColor gl_FragColor
#define COMPAT_TEXTURE texture2D
#endif
#ifdef GL_ES
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#define COMPAT_PRECISION mediump
#else
#define COMPAT_PRECISION
#endif
uniform COMPAT_PRECISION int FrameDirection;
uniform COMPAT_PRECISION int FrameCount;
uniform COMPAT_PRECISION vec2 OutputSize;
uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;
uniform sampler2D Texture;
uniform sampler2D PassPrev2Texture;
COMPAT_VARYING vec4 TEX0;
// compatibility #defines
#define Source Texture
#define vTexCoord TEX0.xy
#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
#define OutputSize vec4(OutputSize, 1.0 / OutputSize)
#ifdef PARAMETER_UNIFORM
// All parameter floats need to have COMPAT_PRECISION in front of them
uniform COMPAT_PRECISION float h_sharp;
uniform COMPAT_PRECISION float s_sharp;
uniform COMPAT_PRECISION float h_smart;
#else
#define h_sharp 5.00 // pixel sharpness
#define s_sharp 0.05 // substractive sharpness
#define h_smart 0.00 // smart horizontal smoothing
#endif
void main()
{
vec2 ps = SourceSize.zw;
vec2 OGL2Pos = vTexCoord * SourceSize.xy;
vec2 fp = fract(OGL2Pos);
vec2 dx = vec2(ps.x,0.0);
vec2 dy = vec2(0.0, ps.y);
vec2 pC4 = floor(OGL2Pos) * ps + 0.5*ps;
// Reading the texels
vec2 x2 = 2.0*dx;
vec2 y2 = 2.0*dy;
bool sharp = (s_sharp > 0.0);
float hsharp_tl, hsharp_tr, hsharp_tc; float s_sharpl = s_sharp; float s_sharpr = s_sharp; float s_sharpc = s_sharp;
if (h_smart == 0.0)
{
hsharp_tl = h_sharp; hsharp_tr = h_sharp; hsharp_tc = h_sharp;
}
else
{
// reading differences for smoothing
vec2 diffs = COMPAT_TEXTURE(PassPrev2Texture, pC4).xy;
float ls = mix (4.25, 2.25, h_smart);
hsharp_tl = mix(h_sharp, ls, diffs.x);
hsharp_tr = mix(h_sharp, ls, diffs.y);
s_sharpl = mix(s_sharp, 0.0, diffs.x);
s_sharpr = mix(s_sharp, 0.0, diffs.y);
hsharp_tc = hsharp_tl;
if (fp.x == 0.5) { hsharp_tc = 0.5*(hsharp_tl + hsharp_tr); s_sharpc = 0.5*(s_sharpl + s_sharpr); }
if (fp.x > 0.5) { hsharp_tc = hsharp_tr; }
}
float wl2 = 1.5 + fp.x; wl2*=wl2; float twl2 = exp2(-hsharp_tl*wl2); twl2 = max(twl2 - s_sharpl, -twl2);
float wl1 = 0.5 + fp.x; wl1*=wl1; float twl1 = exp2(-hsharp_tl*wl1); twl1 = max(twl1 - s_sharpl, -0.4*s_sharpl);
float wct = 0.5 - fp.x; wct*=wct; float twct = exp2(-hsharp_tc*wct); twct = max(twct - s_sharpc, s_sharpc);
float wr1 = 1.5 - fp.x; wr1*=wr1; float twr1 = exp2(-hsharp_tr*wr1); twr1 = max(twr1 - s_sharpr, -0.4*s_sharpr);
float wr2 = 2.5 - fp.x; wr2*=wr2; float twr2 = exp2(-hsharp_tr*wr2); twr2 = max(twr2 - s_sharpr, -twr2);
float wtt = 1.0/(twl2+twl1+twct+twr1+twr2);
vec3 l2 = COMPAT_TEXTURE(Source, pC4 -x2).xyz;
vec3 l1 = COMPAT_TEXTURE(Source, pC4 -dx).xyz;
vec3 ct = COMPAT_TEXTURE(Source, pC4 ).xyz;
vec3 r1 = COMPAT_TEXTURE(Source, pC4 +dx).xyz;
vec3 r2 = COMPAT_TEXTURE(Source, pC4 +x2).xyz;
vec3 color = (l2*twl2 + l1*twl1 + ct*twct + r1*twr1 + r2*twr2)*wtt;
if (sharp) color = clamp(color, 0.8*min(min(l1,r1),ct), 1.2*max(max(l1,r1),ct));
FragColor = vec4(color, 1.0);
}
#endif

View File

@ -0,0 +1,399 @@
/*
CRT - Guest - Dr. Venom - Pass2
Copyright (C) 2018-2019 guest(r) - guest.r@gmail.com
Incorporates many good ideas and suggestions from Dr. Venom.
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.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Parameter lines go here:
#pragma parameter brightboost "Bright boost" 1.30 0.50 2.00 0.01
#pragma parameter IOS "Smart Y Integer Scaling" 0.0 0.0 1.0 1.0
#pragma parameter gsl "Scanline Type" 1.0 0.0 2.0 1.0
#pragma parameter scanline1 "Scanline beam shape low" 8.0 1.0 15.0 1.0
#pragma parameter scanline2 "Scanline beam shape high" 8.0 5.0 23.0 1.0
#pragma parameter beam_min "Scanline dark" 1.25 0.5 2.0 0.05
#pragma parameter beam_max "Scanline bright" 1.05 0.5 2.0 0.05
#pragma parameter s_power "Scanline intensity" 1.0 0.5 2.5 0.05
#pragma parameter beam_size "Increased bright scanline beam" 0.65 0.0 1.0 0.05
#pragma parameter shadowMask "CRT Mask: 0:CGWG, 1-4:Lottes, 5-6:'Trinitron'" 5.0 -1.0 6.0 1.0
#pragma parameter masksize "CRT Mask Size (2.0 is nice in 4k)" 1.0 1.0 2.0 1.0
#pragma parameter vertmask "PVM Like Colors" 0.05 0.0 0.25 0.01
#pragma parameter slotmask "Slot Mask Strength" 0.0 0.0 1.0 0.05
#pragma parameter slotwidth "Slot Mask Width" 2.0 2.0 6.0 0.5
#pragma parameter double_slot "Slot Mask Height: 2x1 or 4x1" 1.0 1.0 2.0 1.0
#pragma parameter mcut "Mask 5&6 cutoff" 0.2 0.0 0.5 0.05
#pragma parameter maskDark "Mask Dark" 0.5 0.0 2.0 0.05
#pragma parameter maskLight "Mask Light" 1.5 0.0 2.0 0.05
#pragma parameter CGWG "CGWG Mask Str." 0.3 0.0 1.0 0.05
#pragma parameter gamma_out "Gamma out" 2.4 1.0 3.5 0.05
#if defined(VERTEX)
#if __VERSION__ >= 130
#define COMPAT_VARYING out
#define COMPAT_ATTRIBUTE in
#define COMPAT_TEXTURE texture
#else
#define COMPAT_VARYING varying
#define COMPAT_ATTRIBUTE attribute
#define COMPAT_TEXTURE texture2D
#endif
#ifdef GL_ES
#define COMPAT_PRECISION mediump
#else
#define COMPAT_PRECISION
#endif
COMPAT_ATTRIBUTE vec4 VertexCoord;
COMPAT_ATTRIBUTE vec4 COLOR;
COMPAT_ATTRIBUTE vec4 TexCoord;
COMPAT_VARYING vec4 COL0;
COMPAT_VARYING vec4 TEX0;
vec4 _oPosition1;
uniform mat4 MVPMatrix;
uniform COMPAT_PRECISION int FrameDirection;
uniform COMPAT_PRECISION int FrameCount;
uniform COMPAT_PRECISION vec2 OutputSize;
uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;
void main()
{
gl_Position = MVPMatrix * VertexCoord;
COL0 = COLOR;
TEX0.xy = TexCoord.xy * 1.00001;
}
#elif defined(FRAGMENT)
#if __VERSION__ >= 130
#define COMPAT_VARYING in
#define COMPAT_TEXTURE texture
out vec4 FragColor;
#else
#define COMPAT_VARYING varying
#define FragColor gl_FragColor
#define COMPAT_TEXTURE texture2D
#endif
#ifdef GL_ES
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#define COMPAT_PRECISION mediump
#else
#define COMPAT_PRECISION
#endif
uniform COMPAT_PRECISION int FrameDirection;
uniform COMPAT_PRECISION int FrameCount;
uniform COMPAT_PRECISION vec2 OutputSize;
uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;
uniform sampler2D Texture;
uniform sampler2D PassPrev3Texture;
uniform sampler2D PassPrev4Texture;
uniform sampler2D PassPrev6Texture;
COMPAT_VARYING vec4 TEX0;
// compatibility #defines
#define Source Texture
#define vTexCoord TEX0.xy
#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
#define OutputSize vec4(OutputSize, 1.0 / OutputSize)
#ifdef PARAMETER_UNIFORM
// All parameter floats need to have COMPAT_PRECISION in front of them
uniform COMPAT_PRECISION float brightboost;
uniform COMPAT_PRECISION float IOS;
uniform COMPAT_PRECISION float gsl;
uniform COMPAT_PRECISION float scanline1;
uniform COMPAT_PRECISION float scanline2;
uniform COMPAT_PRECISION float beam_min;
uniform COMPAT_PRECISION float beam_max;
uniform COMPAT_PRECISION float s_power;
uniform COMPAT_PRECISION float beam_size;
uniform COMPAT_PRECISION float shadowMask;
uniform COMPAT_PRECISION float masksize;
uniform COMPAT_PRECISION float vertmask;
uniform COMPAT_PRECISION float slotmask;
uniform COMPAT_PRECISION float slotwidth;
uniform COMPAT_PRECISION float double_slot;
uniform COMPAT_PRECISION float mcut;
uniform COMPAT_PRECISION float maskDark;
uniform COMPAT_PRECISION float maskLight;
uniform COMPAT_PRECISION float CGWG;
uniform COMPAT_PRECISION float gamma_out;
#else
#define brightboost 1.40 // adjust brightness
#define IOS 0.00 // smart integer scaling
#define gsl 1.00 // Alternate scanlines
#define scanline1 5.00 // scanline param, vertical sharpness
#define scanline2 12.00 // scanline param, vertical sharpness
#define beam_min 1.30 // dark area beam min - narrow
#define beam_max 1.10 // bright area beam max - wide
#define s_power 1.00 // scanline intensity
#define beam_size 0.65 // increased max. beam size
#define shadowMask 5.00 // Mask Style
#define masksize 1.00 // Mask Size
#define vertmask 0.00 // Vertical mask
#define slotmask 0.00 // Slot Mask ON/OFF
#define slotwidth 2.00 // Slot Mask Width
#define double_slot 1.00 // Slot Mask Height
#define mcut 0.20 // Mask 5&6 cutoff
#define maskDark 0.50 // Dark "Phosphor"
#define maskLight 1.50 // Light "Phosphor"
#define CGWG 0.30 // CGWG Mask Strength
#define gamma_out 2.40 // output gamma
#endif
#define eps 1e-10
float st(float x, float scanline)
{
return exp2(-scanline*x*x);
}
vec3 sw0(vec3 x, vec3 color, float scanline)
{
vec3 tmp = mix(vec3(beam_min),vec3(beam_max), color);
vec3 ex = x*tmp;
return exp2(-scanline*ex*ex);
}
vec3 sw1(vec3 x, vec3 color, float scanline)
{
float mx = max(max(color.r, color.g),color.b);
x = mix (x, beam_min*x, max(x-0.4*mx,0.0));
vec3 tmp = mix(vec3(1.2*beam_min),vec3(beam_max), color);
vec3 ex = x*tmp;
float br = clamp(0.8*beam_min - 1.0, 0.2, 0.45);
return exp2(-scanline*ex*ex)/(1.0-br+br*color);
}
vec3 sw2(vec3 x, vec3 color, float scanline)
{
vec3 tmp = mix(vec3(2.75*beam_min),vec3(beam_max), color);
tmp = mix(vec3(beam_max), tmp, pow(x, vec3(max(max(color.r, color.g),color.b)+0.3)));
vec3 ex = x*tmp;
return exp2(-scanline*ex*ex)/(0.6 + 0.4*color);
}
// Shadow mask (1-4 from PD CRT Lottes shader).
vec3 Mask(vec2 pos, vec3 c)
{
pos = floor(pos/masksize);
vec3 mask = vec3(maskDark, maskDark, maskDark);
// No mask
if (shadowMask == -1.0)
{
mask = vec3(1.0);
}
// Phosphor.
else if (shadowMask == 0.0)
{
pos.x = fract(pos.x*0.5);
float mc = 1.0 - CGWG;
if (pos.x < 0.5) { mask.r = 1.1; mask.g = mc; mask.b = 1.1; }
else { mask.r = mc; mask.g = 1.1; mask.b = mc; }
}
// Very compressed TV style shadow mask.
else if (shadowMask == 1.0)
{
float line = maskLight;
float odd = 0.0;
if (fract(pos.x/6.0) < 0.5)
odd = 1.0;
if (fract((pos.y + odd)/2.0) < 0.5)
line = maskDark;
pos.x = fract(pos.x/3.0);
if (pos.x < 0.333) mask.r = maskLight;
else if (pos.x < 0.666) mask.g = maskLight;
else mask.b = maskLight;
mask*=line;
}
// Aperture-grille.
else if (shadowMask == 2.0)
{
pos.x = fract(pos.x/3.0);
if (pos.x < 0.333) mask.r = maskLight;
else if (pos.x < 0.666) mask.g = maskLight;
else mask.b = maskLight;
}
// Stretched VGA style shadow mask (same as prior shaders).
else if (shadowMask == 3.0)
{
pos.x += pos.y*3.0;
pos.x = fract(pos.x/6.0);
if (pos.x < 0.333) mask.r = maskLight;
else if (pos.x < 0.666) mask.g = maskLight;
else mask.b = maskLight;
}
// VGA style shadow mask.
else if (shadowMask == 4.0)
{
pos.xy = floor(pos.xy*vec2(1.0, 0.5));
pos.x += pos.y*3.0;
pos.x = fract(pos.x/6.0);
if (pos.x < 0.333) mask.r = maskLight;
else if (pos.x < 0.666) mask.g = maskLight;
else mask.b = maskLight;
}
// Alternate mask 5
else if (shadowMask == 5.0)
{
float mx = max(max(c.r,c.g),c.b);
vec3 maskTmp = vec3( min( 1.25*max(mx-mcut,0.0)/(1.0-mcut) ,maskDark + 0.2*(1.0-maskDark)*mx));
float adj = 0.80*maskLight - 0.5*(0.80*maskLight - 1.0)*mx + 0.75*(1.0-mx);
mask = maskTmp;
pos.x = fract(pos.x/2.0);
if (pos.x < 0.5)
{ mask.r = adj;
mask.b = adj;
}
else mask.g = adj;
}
// Alternate mask 6
else if (shadowMask == 6.0)
{
float mx = max(max(c.r,c.g),c.b);
vec3 maskTmp = vec3( min( 1.5*max(mx-mcut,0.0)/(1.0-mcut) ,maskDark + 0.225*(1.0-maskDark)*mx));
float adj = 0.80*maskLight - 0.5*(0.80*maskLight - 1.0)*mx + 0.75*(1.0-mx);
mask = maskTmp;
pos.x = fract(pos.x/3.0);
if (pos.x < 0.333) mask.r = adj;
else if (pos.x < 0.666) mask.g = adj;
else mask.b = adj;
}
return mask;
}
float SlotMask(vec2 pos, vec3 c)
{
if (slotmask == 0.0) return 1.0;
float mx = pow(max(max(c.r,c.g),c.b),1.33);
float mlen = slotwidth*2.0;
float px = fract(pos.x/mlen);
float py = floor(fract(pos.y/(2.0*double_slot))*2.0*double_slot);
float slot_dark = mix(1.0-slotmask, 1.0-0.80*slotmask, mx);
float slot = 1.0 + 0.7*slotmask*(1.0-mx);
if (py == 0.0 && px < 0.5) slot = slot_dark; else
if (py == double_slot && px >= 0.5) slot = slot_dark;
return slot;
}
float Overscan2(float pos, float dy){
pos=pos*2.0-1.0;
pos*=dy;
return pos*0.5+0.5;
}
void main()
{
vec2 texcoord = vTexCoord;
if (IOS == 1.0){
float ofactor = OutputSize.y/InputSize.y;
float intfactor = round(ofactor);
float diff = ofactor/intfactor;
texcoord.y = Overscan2(texcoord.y*(SourceSize.y/InputSize.y), diff)*(InputSize.y/SourceSize.y);
}
vec2 ps = SourceSize.zw;
vec2 OGL2Pos = texcoord * SourceSize.xy - vec2(0.0,0.5);
vec2 fp = fract(OGL2Pos);
vec2 dx = vec2(ps.x,0.0);
vec2 dy = vec2(0.0, ps.y);
vec2 pC4 = floor(OGL2Pos) * ps + 0.5*ps;
vec3 color1 = COMPAT_TEXTURE(Source, pC4 ).xyz;
vec3 color2 = COMPAT_TEXTURE(Source, pC4 +dy).xyz;
// calculating scanlines
float f = fp.y;
float shape1 = mix(scanline1, scanline2, f);
float shape2 = mix(scanline1, scanline2, 1.0-f);
float wt1 = st(f, shape1);
float wt2 = st(1.0-f, shape2);
vec3 color0 = color1*wt1 + color2*wt2;
vec3 ctmp = color0/(wt1+wt2);
vec3 tmp = pow(ctmp, vec3(1.0/gamma_out));
vec3 w1,w2 = vec3(0.0);
vec3 cref1 = mix(ctmp, color1, beam_size);
vec3 cref2 = mix(ctmp, color2, beam_size);
vec3 shift = vec3(-vertmask, vertmask, -vertmask);
vec3 f1 = clamp(vec3(f) + shift*0.5*(1.0+f), 0.0, 1.0);
vec3 f2 = clamp(vec3(1.0-f) - shift*0.5*(2.0-f), 0.0, 1.0);
if (gsl == 0.0) { w1 = sw0(f1,cref1,shape1); w2 = sw0(f2,cref2,shape2);} else
if (gsl == 1.0) { w1 = sw1(f1,cref1,shape1); w2 = sw1(f2,cref2,shape2);} else
if (gsl == 2.0) { w1 = sw2(f1,cref1,shape1); w2 = sw2(f2,cref2,shape2);}
vec3 color = color1*pow(w1, vec3(s_power)) + color2*pow(w2, vec3(s_power));
color*=brightboost;
color = min(color, 1.0);
// Apply Mask
color *= Mask(gl_FragCoord.xy * 1.000001,tmp);
color = min(color,1.0);
color *= SlotMask(gl_FragCoord.xy * 1.000001,tmp);
color = pow(color, vec3(1.0/gamma_out));
FragColor = vec4(color, 1.0);
}
#endif

View File

@ -0,0 +1,91 @@
#if defined(VERTEX)
#if __VERSION__ >= 130
#define COMPAT_VARYING out
#define COMPAT_ATTRIBUTE in
#define COMPAT_TEXTURE texture
#else
#define COMPAT_VARYING varying
#define COMPAT_ATTRIBUTE attribute
#define COMPAT_TEXTURE texture2D
#endif
#ifdef GL_ES
#define COMPAT_PRECISION mediump
#else
#define COMPAT_PRECISION
#endif
COMPAT_ATTRIBUTE vec4 VertexCoord;
COMPAT_ATTRIBUTE vec4 COLOR;
COMPAT_ATTRIBUTE vec4 TexCoord;
COMPAT_VARYING vec4 COL0;
COMPAT_VARYING vec4 TEX0;
uniform mat4 MVPMatrix;
uniform COMPAT_PRECISION int FrameDirection;
uniform COMPAT_PRECISION int FrameCount;
uniform COMPAT_PRECISION vec2 OutputSize;
uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;
void main()
{
gl_Position = MVPMatrix * VertexCoord;
COL0 = COLOR;
TEX0.xy = TexCoord.xy;
}
#elif defined(FRAGMENT)
#if __VERSION__ >= 130
#define COMPAT_VARYING in
#define COMPAT_TEXTURE texture
out vec4 FragColor;
#else
#define COMPAT_VARYING varying
#define FragColor gl_FragColor
#define COMPAT_TEXTURE texture2D
#endif
#ifdef GL_ES
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#define COMPAT_PRECISION mediump
#else
#define COMPAT_PRECISION
#endif
uniform COMPAT_PRECISION int FrameDirection;
uniform COMPAT_PRECISION int FrameCount;
uniform COMPAT_PRECISION vec2 OutputSize;
uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;
uniform sampler2D Texture;
uniform sampler2D PassPrev2Texture;
COMPAT_VARYING vec4 TEX0;
// compatibility #defines
#define Source Texture
#define vTexCoord TEX0.xy
#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
#define outsize vec4(OutputSize, 1.0 / OutputSize)
// Parameter lines go here:
#pragma parameter GAMMA_INPUT "Gamma Input" 2.4 0.1 5.0 0.05
#ifdef PARAMETER_UNIFORM
// All parameter floats need to have COMPAT_PRECISION in front of them
uniform COMPAT_PRECISION float GAMMA_INPUT;
#else
#define GAMMA_INPUT 2.4
#endif
void main()
{
FragColor = pow(vec4(COMPAT_TEXTURE(PassPrev2Texture, vTexCoord)), vec4(GAMMA_INPUT));
}
#endif

View File

@ -0,0 +1,136 @@
#version 130
/*
Smart Smoothing Difference Shader
Copyright (C) 2019 guest(r) - guest.r@gmail.com
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.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Parameter lines go here:
#pragma parameter STH "Smart Smoothing Threshold" 0.7 0.4 1.2 0.05
#if defined(VERTEX)
#if __VERSION__ >= 130
#define COMPAT_VARYING out
#define COMPAT_ATTRIBUTE in
#define COMPAT_TEXTURE texture
#else
#define COMPAT_VARYING varying
#define COMPAT_ATTRIBUTE attribute
#define COMPAT_TEXTURE texture2D
#endif
#ifdef GL_ES
#define COMPAT_PRECISION mediump
#else
#define COMPAT_PRECISION
#endif
COMPAT_ATTRIBUTE vec4 VertexCoord;
COMPAT_ATTRIBUTE vec4 COLOR;
COMPAT_ATTRIBUTE vec4 TexCoord;
COMPAT_VARYING vec4 COL0;
COMPAT_VARYING vec4 TEX0;
uniform mat4 MVPMatrix;
uniform COMPAT_PRECISION int FrameDirection;
uniform COMPAT_PRECISION int FrameCount;
uniform COMPAT_PRECISION vec2 OutputSize;
uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;
void main()
{
gl_Position = MVPMatrix * VertexCoord;
COL0 = COLOR;
TEX0.xy = TexCoord.xy;
}
#elif defined(FRAGMENT)
#if __VERSION__ >= 130
#define COMPAT_VARYING in
#define COMPAT_TEXTURE texture
out vec4 FragColor;
#else
#define COMPAT_VARYING varying
#define FragColor gl_FragColor
#define COMPAT_TEXTURE texture2D
#endif
#ifdef GL_ES
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#define COMPAT_PRECISION mediump
#else
#define COMPAT_PRECISION
#endif
uniform COMPAT_PRECISION int FrameDirection;
uniform COMPAT_PRECISION int FrameCount;
uniform COMPAT_PRECISION vec2 OutputSize;
uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;
uniform sampler2D Texture;
COMPAT_VARYING vec4 TEX0;
// in variables go here as COMPAT_VARYING whatever
// compatibility #defines
#define Source Texture
#define vTexCoord TEX0.xy
#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
#define outsize vec4(OutputSize, 1.0 / OutputSize)
#ifdef PARAMETER_UNIFORM
// All parameter floats need to have COMPAT_PRECISION in front of them
uniform COMPAT_PRECISION float STH;
#else
#define STH 0.7
#endif
float df (vec3 A, vec3 B)
{
float diff = length(A-B);
float luma = clamp(length(0.5*min(A,B) + 0.25*(A+B) + 1e-8), 0.0001, 1.0);
float diff1 = diff/luma;
return 1.0 - clamp(7.0*(max(1.5*diff,diff1)-STH), 0.0, 1.0);
}
void main()
{
vec2 dx = vec2(SourceSize.z, 0.0);
vec2 dy = vec2(0.0, SourceSize.w);
vec3 l1 = COMPAT_TEXTURE(Source, vTexCoord.xy -dx).xyz;
vec3 ct = COMPAT_TEXTURE(Source, vTexCoord.xy ).xyz;
vec3 r1 = COMPAT_TEXTURE(Source, vTexCoord.xy +dx).xyz;
float dl = df(ct, l1);
float dr = df(ct, r1);
float resx = dl; float resy = dr;
FragColor = vec4(resx,resy,1.0,1.0);
}
#endif

View File

@ -65,7 +65,7 @@ uniform COMPAT_PRECISION vec2 OutputSize;
uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;
uniform sampler2D Texture;
uniform sampler2D PassPrev2Texture;
uniform sampler2D PassPrev3Texture;
COMPAT_VARYING vec4 TEX0;
// compatibility #defines
@ -86,6 +86,6 @@ uniform COMPAT_PRECISION float GAMMA_INPUT;
void main()
{
FragColor = pow(vec4(COMPAT_TEXTURE(PassPrev2Texture, vTexCoord)), vec4(GAMMA_INPUT));
FragColor = pow(vec4(COMPAT_TEXTURE(PassPrev3Texture, vTexCoord)), vec4(GAMMA_INPUT));
}
#endif

View File

@ -0,0 +1,159 @@
// Parameter lines go here:
#pragma parameter TNTC "LUT Colors" 0.0 0.0 3.0 1.0
#if defined(VERTEX)
#if __VERSION__ >= 130
#define COMPAT_VARYING out
#define COMPAT_ATTRIBUTE in
#define COMPAT_TEXTURE texture
#else
#define COMPAT_VARYING varying
#define COMPAT_ATTRIBUTE attribute
#define COMPAT_TEXTURE texture2D
#endif
#ifdef GL_ES
#define COMPAT_PRECISION mediump
#else
#define COMPAT_PRECISION
#endif
COMPAT_ATTRIBUTE vec4 VertexCoord;
COMPAT_ATTRIBUTE vec4 COLOR;
COMPAT_ATTRIBUTE vec4 TexCoord;
COMPAT_VARYING vec4 COL0;
COMPAT_VARYING vec4 TEX0;
vec4 _oPosition1;
uniform mat4 MVPMatrix;
uniform COMPAT_PRECISION int FrameDirection;
uniform COMPAT_PRECISION int FrameCount;
uniform COMPAT_PRECISION vec2 OutputSize;
uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;
// compatibility #defines
#define vTexCoord TEX0.xy
#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
#define OutSize vec4(OutputSize, 1.0 / OutputSize)
void main()
{
gl_Position = MVPMatrix * VertexCoord;
TEX0.xy = TexCoord.xy;
}
#elif defined(FRAGMENT)
#if __VERSION__ >= 130
#define COMPAT_VARYING in
#define COMPAT_TEXTURE texture
out vec4 FragColor;
#else
#define COMPAT_VARYING varying
#define FragColor gl_FragColor
#define COMPAT_TEXTURE texture2D
#endif
#ifdef GL_ES
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#define COMPAT_PRECISION mediump
#else
#define COMPAT_PRECISION
#endif
uniform COMPAT_PRECISION int FrameDirection;
uniform COMPAT_PRECISION int FrameCount;
uniform COMPAT_PRECISION vec2 OutputSize;
uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;
uniform sampler2D Texture;
uniform sampler2D SamplerLUT1;
uniform sampler2D SamplerLUT2;
uniform sampler2D SamplerLUT3;
COMPAT_VARYING vec4 TEX0;
// compatibility #defines
#define Source Texture
#define vTexCoord TEX0.xy
#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
#define OutSize vec4(OutputSize, 1.0 / OutputSize)
#ifdef PARAMETER_UNIFORM
uniform COMPAT_PRECISION float TNTC;
#else
#define TNTC 0.0
#endif
#define LUT_Size 32.0
const mat3 D65_to_XYZ = mat3 (
0.4306190, 0.2220379, 0.0201853,
0.3415419, 0.7066384, 0.1295504,
0.1783091, 0.0713236, 0.9390944);
const mat3 XYZ_to_D50 = mat3 (
2.9603944, -0.9787684, 0.0844874,
-1.4678519, 1.9161415, -0.2545973,
-0.4685105, 0.0334540, 1.4216174);
// This shouldn't be necessary but it seems some undefined values can
// creep in and each GPU vendor handles that differently. This keeps
// all values within a safe range
vec4 mixfix(vec4 a, vec4 b, float c)
{
return (a.z < 1.0) ? mix(a, b, c) : a;
}
void main()
{
vec4 imgColor = COMPAT_TEXTURE(Source, vTexCoord.xy);
float red = ( imgColor.r * (LUT_Size - 1.0) + 0.499999 ) / (LUT_Size * LUT_Size);
float green = ( imgColor.g * (LUT_Size - 1.0) + 0.499999 ) / LUT_Size;
float blue1 = (floor( imgColor.b * (LUT_Size - 1.0) ) / LUT_Size) + red;
float blue2 = (ceil( imgColor.b * (LUT_Size - 1.0) ) / LUT_Size) + red;
float mixer = clamp(max((imgColor.b - blue1) / (blue2 - blue1), 0.0), 0.0, 32.0);
vec4 color1, color2, res;
if (TNTC == 1.0)
{
color1 = COMPAT_TEXTURE( SamplerLUT1, vec2( blue1, green ));
color2 = COMPAT_TEXTURE( SamplerLUT1, vec2( blue2, green ));
res = mixfix(color1, color2, mixer);
float mx = max(res.r,max(res.g,res.b));
float l = mix(length(imgColor.rgb), length(res.rgb), max(mx-0.5,0.0));
res.rgb = mix(imgColor.rgb, res.rgb, clamp(25.0*(mx-0.02),0.0,1.0));
res.rgb = normalize(res.rgb+1e-10)*l;
vec3 cooler = D65_to_XYZ*res.rgb;
cooler = XYZ_to_D50*cooler;
res.rgb = mix(res.rgb, cooler, 0.25);
}
else if (TNTC == 2.0)
{
color1 = COMPAT_TEXTURE( SamplerLUT2, vec2( blue1, green ));
color2 = COMPAT_TEXTURE( SamplerLUT2, vec2( blue2, green ));
res = mixfix(color1, color2, mixer);
float l = mix(length(imgColor.rgb), length(res.rgb), 0.4);
res.rgb = normalize(res.rgb + 1e-10)*l;
}
else if (TNTC == 3.0)
{
color1 = COMPAT_TEXTURE( SamplerLUT3, vec2( blue1, green ));
color2 = COMPAT_TEXTURE( SamplerLUT3, vec2( blue2, green ));
res = mixfix(color1, color2, mixer);
res.rgb = pow(res.rgb, vec3(1.0/1.20));
float mx = max(res.r,max(res.g,res.b));
res.rgb = mix(imgColor.rgb, res.rgb, clamp(25.0*(mx-0.05),0.0,1.0));
float l = length(imgColor.rgb);
res.rgb = normalize(res.rgb + 1e-10)*l;
}
FragColor = vec4(mix(imgColor.rgb, res.rgb, min(TNTC,1.0)),1.0);
}
#endif

View File

@ -0,0 +1 @@
LUT's kindly provided by torridgristle.

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -4,8 +4,9 @@
License: Public domain
*/
#pragma parameter display_gamma "Display Gamma" 2.2 0.0 10.0 0.1
#pragma parameter target_gamma "Target Gamma" 2.2 0.0 10.0 0.1
#pragma parameter gamma_boost_r "Gamma Mod Red Channel" 0.0 -5.0 5.0 0.1
#pragma parameter gamma_boost_g "Gamma Mod Green Channel" 0.0 -5.0 5.0 0.1
#pragma parameter gamma_boost_b "Gamma Mod Blue Channel" 0.0 -5.0 5.0 0.1
#pragma parameter sat "Saturation" 1.0 0.0 3.0 0.01
#pragma parameter lum "Luminance" 1.0 0.0 5.0 0.01
#pragma parameter cntrst "Contrast" 1.0 0.0 2.0 0.01
@ -103,26 +104,11 @@ COMPAT_VARYING vec4 TEX0;
#define OutSize vec4(OutputSize, 1.0 / OutputSize)
#ifdef PARAMETER_UNIFORM
uniform COMPAT_PRECISION float display_gamma;
uniform COMPAT_PRECISION float target_gamma;
uniform COMPAT_PRECISION float sat;
uniform COMPAT_PRECISION float lum;
uniform COMPAT_PRECISION float cntrst;
uniform COMPAT_PRECISION float blr;
uniform COMPAT_PRECISION float blg;
uniform COMPAT_PRECISION float blb;
uniform COMPAT_PRECISION float r;
uniform COMPAT_PRECISION float g;
uniform COMPAT_PRECISION float b;
uniform COMPAT_PRECISION float rg;
uniform COMPAT_PRECISION float rb;
uniform COMPAT_PRECISION float gr;
uniform COMPAT_PRECISION float gb;
uniform COMPAT_PRECISION float br;
uniform COMPAT_PRECISION float bg;
uniform COMPAT_PRECISION float gamma_boost_r, gamma_boost_g, gamma_boost_b, sat, lum, cntrst, blr, blg, blb, r, g, b, rg, rb, gr, gb, br, bg;
#else
#define display_gamma 2.2
#define target_gamma 2.2
#define gamma_boost_r 0.0
#define gamma_boost_g 0.0
#define gamma_boost_b 0.0
#define sat 1.0
#define lum 1.0
#define cntrst 1.0
@ -142,7 +128,7 @@ uniform COMPAT_PRECISION float bg;
void main()
{
vec4 screen = pow(COMPAT_TEXTURE(Source, vTexCoord), vec4(target_gamma)).rgba;
vec4 screen = pow(COMPAT_TEXTURE(Source, vTexCoord), vec4(2.2)).rgba;
vec4 avglum = vec4(0.5);
screen = mix(screen, avglum, (1.0 - cntrst));
@ -152,13 +138,14 @@ void main()
br, bg, b, 0.0, //blue tint
blr, blg, blb, 0.0); //black tint
mat4 adjust = mat4((1.0 - sat) * 0.3086 + sat, (1.0 - sat) * 0.3086, (1.0 - sat) * 0.3086, 1.0,
(1.0 - sat) * 0.6094, (1.0 - sat) * 0.6094 + sat, (1.0 - sat) * 0.6094, 1.0,
(1.0 - sat) * 0.0820, (1.0 - sat) * 0.0820, (1.0 - sat) * 0.0820 + sat, 1.0,
mat4 adjust = mat4((1.0 - sat) * 0.2126 + sat, (1.0 - sat) * 0.2126, (1.0 - sat) * 0.2126, 1.0,
(1.0 - sat) * 0.7152, (1.0 - sat) * 0.7152 + sat, (1.0 - sat) * 0.7152, 1.0,
(1.0 - sat) * 0.0722, (1.0 - sat) * 0.0722, (1.0 - sat) * 0.0722 + sat, 1.0,
0.0, 0.0, 0.0, 1.0);
color *= adjust;
screen = clamp(screen * lum, 0.0, 1.0);
screen = color * screen;
FragColor = pow(screen, vec4(1.0 / display_gamma));
vec3 out_gamma = vec3(1.) / (vec3(2.2) - vec3(gamma_boost_r, gamma_boost_g, gamma_boost_b));
FragColor = pow(screen, vec4(out_gamma, 1.0));
}
#endif
#endif

View File

@ -5,6 +5,9 @@
#pragma parameter temperature "White Point" 6500.0 0.0 12000.0 100.0
#pragma parameter luma_preserve "Preserve Luminance" 1.0 0.0 1.0 1.0
#pragma parameter red "Red Shift" 0.0 -1.0 1.0 0.01
#pragma parameter green "Green Shift" 0.0 -1.0 1.0 0.01
#pragma parameter blue "Blue Shift" 0.0 -1.0 1.0 0.01
#if defined(VERTEX)
@ -79,7 +82,6 @@ uniform COMPAT_PRECISION vec2 TextureSize;
uniform COMPAT_PRECISION vec2 InputSize;
uniform sampler2D Texture;
COMPAT_VARYING vec4 TEX0;
// in variables go here as COMPAT_VARYING whatever
// compatibility #defines
#define Source Texture
@ -89,10 +91,13 @@ COMPAT_VARYING vec4 TEX0;
#define OutSize vec4(OutputSize, 1.0 / OutputSize)
#ifdef PARAMETER_UNIFORM
uniform COMPAT_PRECISION float temperature, luma_preserve;
uniform COMPAT_PRECISION float temperature, luma_preserve, red, green, blue;
#else
#define temperature 6500.0
#define luma_preserve 1.0
#define red 0.0
#define green 0.0
#define blue 0.0
#endif
// white point adjustment
@ -116,6 +121,9 @@ vec3 wp_adjust(vec3 color){
// clamp and normalize
wp.rgb = clamp(wp.rgb, vec3(0.), vec3(255.)) / vec3(255.);
// this is dumb, but various cores don't always show white as white. Use this to make white white...
wp.rgb += vec3(red, green, blue);
return (color * wp);
}