Merge pull request #4000 from anikom15/scanline

-hlsl,bgfx: Made HLSL scanline shader happen before defocus. [anikom15]
This commit is contained in:
MooglyGuy 2018-09-15 10:51:56 +02:00 committed by GitHub
commit 94d215f4a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 460 additions and 119 deletions

View File

@ -390,6 +390,29 @@
],
"output": "internal"
},
{
"effect": "hlsl/scanline",
"name": "Scanline Pass",
"disablewhen": [
{ "type": "slider", "condition": "equal", "combine": "or", "name": "adjustments", "value": 0 },
{ "type": "slider", "condition": "equal", "combine": "or", "name": "scanline_alpha", "value": 0 }
],
"uniforms": [
{ "uniform": "u_scanline_alpha", "slider": "scanline_alpha" },
{ "uniform": "u_scanline_scale", "slider": "scanline_scale" },
{ "uniform": "u_scanline_bright_scale", "slider": "scanline_bright_scale" },
{ "uniform": "u_scanline_bright_offset", "slider": "scanline_bright_offset" },
{ "uniform": "u_scanline_height", "slider": "scanline_height" },
{ "uniform": "u_scanline_variation", "slider": "scanline_variation" },
{ "uniform": "u_scanline_jitter", "slider": "scanline_jitter_amount" },
{ "uniform": "u_jitter_amount", "parameter": "jitter" },
{ "uniform": "u_time", "parameter": "time" }
],
"input": [
{ "sampler": "s_tex", "target": "internal" }
],
"output": "internal"
},
{ "effect": "hlsl/defocus",
"name": "Defocus Pass",
"disablewhen": [
@ -440,19 +463,12 @@
"name": "Non-Bloom Post Pass",
"disablewhen": [
{ "type": "slider", "condition": "equal", "combine": "or", "name": "adjustments", "value": 0 },
{ "type": "slider", "condition": "equal", "combine": "and", "name": "scanline_alpha", "value": 0.0 },
{ "type": "slider", "condition": "equal", "combine": "and", "name": "shadow_alpha", "value": 0.0 },
{ "type": "slider", "condition": "equal", "combine": "and", "name": "humbar_alpha", "value": 0.0 },
{ "type": "slider", "condition": "equal", "combine": "and", "name": "floor", "value": [ 0, 0, 0 ] },
{ "type": "slider", "condition": "equal", "combine": "and", "name": "power", "value": [ 0, 0, 0 ] }
],
"uniforms": [
{ "uniform": "u_scanline_alpha", "slider": "scanline_alpha" },
{ "uniform": "u_scanline_scale", "slider": "scanline_scale" },
{ "uniform": "u_scanline_bright_scale", "slider": "scanline_bright_scale" },
{ "uniform": "u_scanline_bright_offset", "slider": "scanline_bright_offset" },
{ "uniform": "u_scanline_height", "slider": "scanline_height" },
{ "uniform": "u_scanline_variation", "slider": "scanline_variation" },
{ "uniform": "u_shadow_tile_mode", "slider": "shadow_tile_mode" },
{ "uniform": "u_shadow_alpha", "slider": "shadow_alpha" },
{ "uniform": "u_shadow_count", "slider": "shadow_uv_count" },
@ -462,8 +478,6 @@
{ "uniform": "u_humbar_hertz_rate", "slider": "humbar_hertz_rate" },
{ "uniform": "u_floor", "slider": "floor" },
{ "uniform": "u_power", "slider": "power" },
{ "uniform": "u_scanline_jitter", "slider": "scanline_jitter_amount" },
{ "uniform": "u_jitter_amount", "parameter": "jitter" },
{ "uniform": "u_time", "parameter": "time" }
],
"input": [

View File

@ -2,7 +2,7 @@
// copyright-holders:Ryan Holtz,ImJezze
//============================================================
//
// post.json: Scanline, hum-bar, shadow-mask, and final
// post.json: Hum-bar, shadow-mask, and final
// color convolution shader for CRT simulation.
//
//============================================================
@ -31,21 +31,12 @@
{ "name": "u_source_dims", "type": "vec4", "values": [ 256.0, 256.0, 0.0, 0.0 ] },
{ "name": "u_target_dims", "type": "vec4", "values": [ 256.0, 256.0, 0.0, 0.0 ] },
{ "name": "u_target_scale", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] },
{ "name": "u_quad_dims", "type": "vec4", "values": [ 256.0, 256.0, 0.0, 0.0 ] },
{ "name": "u_humbar_hertz_rate", "type": "vec4", "values": [ 0.001, 0.0, 0.0, 0.0 ] },
{ "name": "u_humbar_alpha", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_time", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_screen_scale", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] },
{ "name": "u_screen_offset", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_shadow_tile_mode", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_scanline_alpha", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_scanline_scale", "type": "vec4", "values": [ 1.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_scanline_bright_scale", "type": "vec4", "values": [ 1.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_scanline_bright_offset", "type": "vec4", "values": [ 1.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_scanline_jitter", "type": "vec4", "values": [ 1.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_scanline_height", "type": "vec4", "values": [ 1.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_scanline_variation", "type": "vec4", "values": [ 1.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_jitter_amount", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_shadow_alpha", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_shadow_count", "type": "vec4", "values": [ 12.0, 12.0, 0.0, 0.0 ] },
{ "name": "u_shadow_uv", "type": "vec4", "values": [ 0.25, 0.25, 0.0, 0.0 ] },

View File

@ -0,0 +1,44 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz,ImJezze
//============================================================
//
// scanline.json: Scanline shader for CRT simulation.
//
//============================================================
{
"blend": {
"equation": "add",
"srcColor": "srcalpha",
"dstColor": "1-srcalpha",
"srcAlpha": "srcalpha",
"dstAlpha": "1-srcalpha"
},
"depth": {
"function": "always"
},
"cull": { "mode": "none" },
"write": {
"rgb": true,
"alpha": true
},
"vertex": "chains/hlsl/vs_scanline",
"fragment": "chains/hlsl/fs_scanline",
"uniforms": [
{ "name": "s_tex", "type": "int", "values": [ 0.0 ] },
{ "name": "u_swap_xy", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_source_dims", "type": "vec4", "values": [ 256.0, 256.0, 0.0, 0.0 ] },
{ "name": "u_target_dims", "type": "vec4", "values": [ 256.0, 256.0, 0.0, 0.0 ] },
{ "name": "u_quad_dims", "type": "vec4", "values": [ 256.0, 256.0, 0.0, 0.0 ] },
{ "name": "u_time", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_screen_scale", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] },
{ "name": "u_screen_offset", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_scanline_alpha", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_scanline_scale", "type": "vec4", "values": [ 1.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_scanline_bright_scale", "type": "vec4", "values": [ 1.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_scanline_bright_offset", "type": "vec4", "values": [ 1.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_scanline_jitter", "type": "vec4", "values": [ 1.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_scanline_height", "type": "vec4", "values": [ 1.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_scanline_variation", "type": "vec4", "values": [ 1.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_jitter_amount", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] }
]
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,7 +1,7 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz,ImJezze
//-----------------------------------------------------------------------------
// Scanline & Shadowmask Effect
// Shadowmask Effect
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
@ -68,7 +68,7 @@ static const float PI = 3.1415927f;
static const float HalfPI = PI * 0.5f;
//-----------------------------------------------------------------------------
// Scanline & Shadowmask Vertex Shader
// Shadowmask Vertex Shader
//-----------------------------------------------------------------------------
uniform float2 ScreenDims;
@ -108,7 +108,7 @@ VS_OUTPUT vs_main(VS_INPUT Input)
}
//-----------------------------------------------------------------------------
// Scanline & Shadowmask Pixel Shader
// Shadowmask Pixel Shader
//-----------------------------------------------------------------------------
uniform float HumBarDesync = 60.0f / 59.94f - 1.0f; // difference between the 59.94 Hz field rate and 60 Hz line frequency (NTSC)
@ -119,14 +119,6 @@ uniform float TimeMilliseconds = 0.0f;
uniform float2 ScreenScale = float2(1.0f, 1.0f);
uniform float2 ScreenOffset = float2(0.0f, 0.0f);
uniform float ScanlineAlpha = 0.0f;
uniform float ScanlineScale = 1.0f;
uniform float ScanlineHeight = 1.0f;
uniform float ScanlineVariation = 1.0f;
uniform float ScanlineOffset = 1.0f;
uniform float ScanlineBrightScale = 1.0f;
uniform float ScanlineBrightOffset = 1.0f;
uniform float3 BackColor = float3(0.0f, 0.0f, 0.0f);
uniform int ShadowTileMode = 0; // 0 based on screen (quad) dimension, 1 based on source dimension
@ -247,34 +239,6 @@ float4 ps_main(PS_INPUT Input) : COLOR
// Scanline Simulation (may not affect bloom)
if (!PrepareBloom)
{
// Scanline Simulation (may not affect vector screen)
if (!VectorScreen && ScanlineAlpha > 0.0f)
{
float BrightnessOffset = (ScanlineBrightOffset * ScanlineAlpha);
float BrightnessScale = (ScanlineBrightScale * ScanlineAlpha) + (1.0f - ScanlineAlpha);
float ColorBrightness = 0.299f * BaseColor.r + 0.587f * BaseColor.g + 0.114 * BaseColor.b;
float ScanlineCoord = BaseCoord.y;
ScanlineCoord += SwapXY
? QuadDims.x <= SourceDims.x * 2.0f
? 0.5f / QuadDims.x // uncenter scanlines if the quad is less than twice the size of the source
: 0.0f
: QuadDims.y <= SourceDims.y * 2.0f
? 0.5f / QuadDims.y // uncenter scanlines if the quad is less than twice the size of the source
: 0.0f;
ScanlineCoord *= SourceDims.y * ScanlineScale * PI;
float ScanlineCoordJitter = ScanlineOffset * HalfPI;
float ScanlineSine = sin(ScanlineCoord + ScanlineCoordJitter);
float ScanlineWide = ScanlineHeight + ScanlineVariation * max(1.0f, ScanlineHeight) * (1.0f - ColorBrightness);
float ScanlineAmount = pow(ScanlineSine * ScanlineSine, ScanlineWide);
float ScanlineBrightness = ScanlineAmount * BrightnessScale + BrightnessOffset * BrightnessScale;
BaseColor.rgb *= lerp(1.0f, ScanlineBrightness, ScanlineAlpha);
}
// Hum Bar Simulation (may not affect vector screen)
if (!VectorScreen && HumBarAlpha > 0.0f)
{
@ -288,7 +252,7 @@ float4 ps_main(PS_INPUT Input) : COLOR
}
//-----------------------------------------------------------------------------
// Scanline & Shadowmask Technique
// Shadowmask Technique
//-----------------------------------------------------------------------------
technique DefaultTechnique

172
hlsl/scanline.fx Normal file
View File

@ -0,0 +1,172 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz,ImJezze
//-----------------------------------------------------------------------------
// Scanline Effect
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Sampler Definitions
//-----------------------------------------------------------------------------
texture Diffuse;
sampler DiffuseSampler = sampler_state
{
Texture = <Diffuse>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
AddressU = CLAMP;
AddressV = CLAMP;
AddressW = CLAMP;
};
//-----------------------------------------------------------------------------
// Vertex Definitions
//-----------------------------------------------------------------------------
struct VS_INPUT
{
float4 Position : POSITION;
float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0;
};
struct VS_OUTPUT
{
float4 Position : POSITION;
float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0;
};
struct PS_INPUT
{
float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0;
};
//-----------------------------------------------------------------------------
// Constants
//-----------------------------------------------------------------------------
static const float PI = 3.1415927f;
static const float HalfPI = PI * 0.5f;
//-----------------------------------------------------------------------------
// Scanline Vertex Shader
//-----------------------------------------------------------------------------
uniform float2 ScreenDims;
uniform float2 SourceDims;
uniform float2 TargetDims;
uniform float2 QuadDims;
uniform bool SwapXY = false;
VS_OUTPUT vs_main(VS_INPUT Input)
{
VS_OUTPUT Output = (VS_OUTPUT)0;
Output.Position = float4(Input.Position.xyz, 1.0f);
Output.Position.xy /= ScreenDims;
Output.Position.y = 1.0f - Output.Position.y; // flip y
Output.Position.xy -= 0.5f; // center
Output.Position.xy *= 2.0f; // zoom
Output.TexCoord = Input.TexCoord;
Output.TexCoord += 0.5f / TargetDims; // fix half texel offset (DX9)
Output.Color = Input.Color;
return Output;
}
//-----------------------------------------------------------------------------
// Scanline Pixel Shader
//-----------------------------------------------------------------------------
uniform float2 ScreenScale = float2(1.0f, 1.0f);
uniform float2 ScreenOffset = float2(0.0f, 0.0f);
uniform float ScanlineAlpha = 0.0f;
uniform float ScanlineScale = 1.0f;
uniform float ScanlineHeight = 1.0f;
uniform float ScanlineVariation = 1.0f;
uniform float ScanlineOffset = 1.0f;
uniform float ScanlineBrightScale = 1.0f;
uniform float ScanlineBrightOffset = 1.0f;
float2 GetAdjustedCoords(float2 coord)
{
// center coordinates
coord -= 0.5f;
// apply screen scale
coord *= ScreenScale;
// un-center coordinates
coord += 0.5f;
// apply screen offset
coord += ScreenOffset;
return coord;
}
float4 ps_main(PS_INPUT Input) : COLOR
{
float2 BaseCoord = GetAdjustedCoords(Input.TexCoord);
// Color
float4 BaseColor = tex2D(DiffuseSampler, BaseCoord);
BaseColor.a = 1.0f;
// clip border
if (BaseCoord.x < 0.0f || BaseCoord.y < 0.0f ||
BaseCoord.x > 1.0f || BaseCoord.y > 1.0f)
{
// we don't use the clip function, because we don't clear the render target before
return float4(0.0f, 0.0f, 0.0f, 1.0f);
}
float BrightnessOffset = (ScanlineBrightOffset * ScanlineAlpha);
float BrightnessScale = (ScanlineBrightScale * ScanlineAlpha) + (1.0f - ScanlineAlpha);
float ColorBrightness = 0.299f * BaseColor.r + 0.587f * BaseColor.g + 0.114 * BaseColor.b;
float ScanlineCoord = BaseCoord.y;
ScanlineCoord += SwapXY
? QuadDims.x <= SourceDims.x * 2.0f
? 0.5f / QuadDims.x // uncenter scanlines if the quad is less than twice the size of the source
: 0.0f
: QuadDims.y <= SourceDims.y * 2.0f
? 0.5f / QuadDims.y // uncenter scanlines if the quad is less than twice the size of the source
: 0.0f;
ScanlineCoord *= SourceDims.y * ScanlineScale * PI;
float ScanlineCoordJitter = ScanlineOffset * HalfPI;
float ScanlineSine = sin(ScanlineCoord + ScanlineCoordJitter);
float ScanlineWide = ScanlineHeight + ScanlineVariation * max(1.0f, ScanlineHeight) * (1.0f - ColorBrightness);
float ScanlineAmount = pow(ScanlineSine * ScanlineSine, ScanlineWide);
float ScanlineBrightness = ScanlineAmount * BrightnessScale + BrightnessOffset * BrightnessScale;
BaseColor.rgb *= lerp(1.0f, ScanlineBrightness, ScanlineAlpha);
return BaseColor;
}
//-----------------------------------------------------------------------------
// Scanline & Shadowmask Technique
//-----------------------------------------------------------------------------
technique DefaultTechnique
{
pass Pass0
{
Lighting = FALSE;
VertexShader = compile vs_3_0 vs_main();
PixelShader = compile ps_3_0 ps_main();
}
}

View File

@ -13,19 +13,11 @@ uniform vec4 u_swap_xy;
uniform vec4 u_source_dims; // size of the guest machine
uniform vec4 u_target_dims;
uniform vec4 u_target_scale;
uniform vec4 u_quad_dims;
uniform vec4 u_screen_scale;
uniform vec4 u_screen_offset;
// uniform vec4 u_back_color; // TODO
// User-supplied
uniform vec4 u_scanline_alpha;
uniform vec4 u_scanline_scale;
uniform vec4 u_scanline_bright_scale;
uniform vec4 u_scanline_bright_offset;
uniform vec4 u_scanline_jitter;
uniform vec4 u_scanline_height;
uniform vec4 u_scanline_variation;
uniform vec4 u_shadow_tile_mode;
uniform vec4 u_shadow_alpha;
uniform vec4 u_shadow_count;
@ -38,14 +30,13 @@ uniform vec4 u_floor;
// Parametric
uniform vec4 u_time; // milliseconds
uniform vec4 u_jitter_amount;
// Samplers
SAMPLER2D(s_tex, 0);
SAMPLER2D(s_shadow, 1);
//-----------------------------------------------------------------------------
// Scanline & Shadowmask Pixel Shader
// Shadowmask Pixel Shader
//-----------------------------------------------------------------------------
vec2 GetAdjustedCoords(vec2 coord)
@ -148,34 +139,6 @@ void main()
BaseColor.g = pow(BaseColor.g, u_power.g);
BaseColor.b = pow(BaseColor.b, u_power.b);
// Scanline Simulation
if (u_scanline_alpha.x > 0.0f)
{
float BrightnessOffset = (u_scanline_bright_offset.x * u_scanline_alpha.x);
float BrightnessScale = (u_scanline_bright_scale.x * u_scanline_alpha.x) + (1.0 - u_scanline_alpha.x);
float ColorBrightness = 0.299 * BaseColor.r + 0.587 * BaseColor.g + 0.114 * BaseColor.b;
float ScanCoord = BaseCoord.y;
ScanCoord += u_swap_xy.x > 0.0
? u_quad_dims.x <= u_source_dims.x * 2.0
? 0.5 / u_quad_dims.x // uncenter scanlines if the quad is less than twice the size of the source
: 0.0
: u_quad_dims.y <= u_source_dims.y * 2.0
? 0.5 / u_quad_dims.y // uncenter scanlines if the quad is less than twice the size of the source
: 0.0;
ScanCoord *= u_source_dims.y * u_scanline_scale.x * 3.1415927; // PI
float ScanCoordJitter = u_scanline_jitter.x * u_jitter_amount.x * 1.5707963; // half PI
float ScanSine = sin(ScanCoord + ScanCoordJitter);
float ScanlineWide = u_scanline_height.x + u_scanline_variation.x * max(1.0, u_scanline_height.x) * (1.0 - ColorBrightness);
float ScanSineScaled = pow(ScanSine * ScanSine, ScanlineWide);
float ScanBrightness = ScanSineScaled * BrightnessScale + BrightnessOffset * BrightnessScale;
BaseColor.rgb *= mix(vec3(1.0, 1.0, 1.0), vec3(ScanBrightness, ScanBrightness, ScanBrightness), u_scanline_alpha.xxx);
}
// Hum Bar Simulation
if (u_humbar_alpha.x > 0.0f)
{

View File

@ -0,0 +1,101 @@
$input v_color0, v_texcoord0
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz,ImJezze
//-----------------------------------------------------------------------------
// Scanline Effect
//-----------------------------------------------------------------------------
#include "common.sh"
// Autos
uniform vec4 u_swap_xy;
uniform vec4 u_source_dims; // size of the guest machine
uniform vec4 u_target_dims;
uniform vec4 u_quad_dims;
uniform vec4 u_screen_scale;
uniform vec4 u_screen_offset;
// User-supplied
uniform vec4 u_scanline_alpha;
uniform vec4 u_scanline_scale;
uniform vec4 u_scanline_bright_scale;
uniform vec4 u_scanline_bright_offset;
uniform vec4 u_scanline_jitter;
uniform vec4 u_scanline_height;
uniform vec4 u_scanline_variation;
// Parametric
uniform vec4 u_time; // milliseconds
uniform vec4 u_jitter_amount;
// Samplers
SAMPLER2D(s_tex, 0);
SAMPLER2D(s_shadow, 1);
//-----------------------------------------------------------------------------
// Scanline Pixel Shader
//-----------------------------------------------------------------------------
vec2 GetAdjustedCoords(vec2 coord)
{
// center coordinates
coord -= 0.5;
// apply screen scale
coord *= u_screen_scale.xy;
// un-center coordinates
coord += 0.5;
// apply screen offset
coord += u_screen_offset.xy;
return coord;
}
void main()
{
vec2 BaseCoord = GetAdjustedCoords(v_texcoord0);
// Color
vec4 BaseColor = texture2D(s_tex, BaseCoord);
// Clamp
if (BaseCoord.x < 0.0 || BaseCoord.y < 0.0 || BaseCoord.x > 1.0 || BaseCoord.y > 1.0)
{
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
}
else
{
// Scanline Simulation
if (u_scanline_alpha.x > 0.0f)
{
float BrightnessOffset = (u_scanline_bright_offset.x * u_scanline_alpha.x);
float BrightnessScale = (u_scanline_bright_scale.x * u_scanline_alpha.x) + (1.0 - u_scanline_alpha.x);
float ColorBrightness = 0.299 * BaseColor.r + 0.587 * BaseColor.g + 0.114 * BaseColor.b;
float ScanCoord = BaseCoord.y;
ScanCoord += u_swap_xy.x > 0.0
? u_quad_dims.x <= u_source_dims.x * 2.0
? 0.5 / u_quad_dims.x // uncenter scanlines if the quad is less than twice the size of the source
: 0.0
: u_quad_dims.y <= u_source_dims.y * 2.0
? 0.5 / u_quad_dims.y // uncenter scanlines if the quad is less than twice the size of the source
: 0.0;
ScanCoord *= u_source_dims.y * u_scanline_scale.x * 3.1415927; // PI
float ScanCoordJitter = u_scanline_jitter.x * u_jitter_amount.x * 1.5707963; // half PI
float ScanSine = sin(ScanCoord + ScanCoordJitter);
float ScanlineWide = u_scanline_height.x + u_scanline_variation.x * max(1.0, u_scanline_height.x) * (1.0 - ColorBrightness);
float ScanSineScaled = pow(ScanSine * ScanSine, ScanlineWide);
float ScanBrightness = ScanSineScaled * BrightnessScale + BrightnessOffset * BrightnessScale;
BaseColor.rgb *= mix(vec3(1.0, 1.0, 1.0), vec3(ScanBrightness, ScanBrightness, ScanBrightness), u_scanline_alpha.xxx);
}
gl_FragColor = vec4(BaseColor.rgb * v_color0.rgb, BaseColor.a);
}
}

View File

@ -0,0 +1,14 @@
$input a_position, a_texcoord0, a_color0
$output v_texcoord0, v_color0
// license:BSD-3-Clause
// copyright-holders:Dario Manesku
#include "common.sh"
void main()
{
gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0));
v_texcoord0 = a_texcoord0;
v_color0 = a_color0;
}

View File

@ -161,15 +161,46 @@ private:
//============================================================
shaders::shaders() :
d3dintf(nullptr), machine(nullptr), d3d(nullptr), post_fx_enable(false), oversampling_enable(false),
num_screens(0), curr_screen(0), acc_t(0), delta_t(0), shadow_texture(nullptr), options(nullptr),
black_surface(nullptr), black_texture(nullptr), recording_movie(false), render_snap(false),
snap_copy_target(nullptr), snap_copy_texture(nullptr), snap_target(nullptr), snap_texture(nullptr),
snap_width(0), snap_height(0), initialized(false), backbuffer(nullptr), curr_effect(nullptr),
default_effect(nullptr), prescale_effect(nullptr), post_effect(nullptr), distortion_effect(nullptr),
focus_effect(nullptr), phosphor_effect(nullptr), deconverge_effect(nullptr), color_effect(nullptr),
ntsc_effect(nullptr), bloom_effect(nullptr), downsample_effect(nullptr), vector_effect(nullptr),
curr_texture(nullptr), curr_render_target(nullptr), curr_poly(nullptr),
d3dintf(nullptr),
machine(nullptr),
d3d(nullptr),
post_fx_enable(false),
oversampling_enable(false),
num_screens(0),
curr_screen(0),
acc_t(0),
delta_t(0),
shadow_texture(nullptr),
options(nullptr),
black_surface(nullptr),
black_texture(nullptr),
recording_movie(false),
render_snap(false),
snap_copy_target(nullptr),
snap_copy_texture(nullptr),
snap_target(nullptr),
snap_texture(nullptr),
snap_width(0),
snap_height(0),
initialized(false),
backbuffer(nullptr),
curr_effect(nullptr),
default_effect(nullptr),
prescale_effect(nullptr),
post_effect(nullptr),
distortion_effect(nullptr),
scanline_effect(nullptr),
focus_effect(nullptr),
phosphor_effect(nullptr),
deconverge_effect(nullptr),
color_effect(nullptr),
ntsc_effect(nullptr),
bloom_effect(nullptr),
downsample_effect(nullptr),
vector_effect(nullptr),
curr_texture(nullptr),
curr_render_target(nullptr),
curr_poly(nullptr),
d3dx_create_effect_from_file_ptr(nullptr)
{
}
@ -705,6 +736,7 @@ int shaders::create_resources()
prescale_effect = new effect(this, d3d->get_device(), "prescale.fx", fx_dir);
phosphor_effect = new effect(this, d3d->get_device(), "phosphor.fx", fx_dir);
focus_effect = new effect(this, d3d->get_device(), "focus.fx", fx_dir);
scanline_effect = new effect(this, d3d->get_device(), "scanline.fx", fx_dir);
deconverge_effect = new effect(this, d3d->get_device(), "deconverge.fx", fx_dir);
color_effect = new effect(this, d3d->get_device(), "color.fx", fx_dir);
ntsc_effect = new effect(this, d3d->get_device(), "ntsc.fx", fx_dir);
@ -718,6 +750,7 @@ int shaders::create_resources()
!prescale_effect->is_valid() ||
!phosphor_effect->is_valid() ||
!focus_effect->is_valid() ||
!scanline_effect->is_valid() ||
!deconverge_effect->is_valid() ||
!color_effect->is_valid() ||
!ntsc_effect->is_valid() ||
@ -728,13 +761,16 @@ int shaders::create_resources()
return 1;
}
effect *effects[13] = {
const int EFFECT_COUNT = 14;
effect *effects[EFFECT_COUNT] = {
default_effect,
post_effect,
distortion_effect,
prescale_effect,
phosphor_effect,
focus_effect,
scanline_effect,
deconverge_effect,
color_effect,
ntsc_effect,
@ -779,21 +815,22 @@ int shaders::create_resources()
deconverge_effect->add_uniform("RadialConvergeX", uniform::UT_VEC3, uniform::CU_CONVERGE_RADIAL_X);
deconverge_effect->add_uniform("RadialConvergeY", uniform::UT_VEC3, uniform::CU_CONVERGE_RADIAL_Y);
scanline_effect->add_uniform("ScanlineAlpha", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_ALPHA);
scanline_effect->add_uniform("ScanlineScale", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_SCALE);
scanline_effect->add_uniform("ScanlineHeight", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_HEIGHT);
scanline_effect->add_uniform("ScanlineVariation", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_VARIATION);
scanline_effect->add_uniform("ScanlineBrightScale", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_BRIGHT_SCALE);
scanline_effect->add_uniform("ScanlineBrightOffset", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_BRIGHT_OFFSET);
focus_effect->add_uniform("Defocus", uniform::UT_VEC2, uniform::CU_FOCUS_SIZE);
phosphor_effect->add_uniform("Phosphor", uniform::UT_VEC3, uniform::CU_PHOSPHOR_LIFE);
post_effect->add_uniform("ShadowAlpha", uniform::UT_FLOAT, uniform::CU_POST_SHADOW_ALPHA);
post_effect->add_uniform("ShadowAlpha", uniform::UT_FLOAT, uniform::CU_POST_SHADOW_ALPHA);
post_effect->add_uniform("ShadowCount", uniform::UT_VEC2, uniform::CU_POST_SHADOW_COUNT);
post_effect->add_uniform("ShadowUV", uniform::UT_VEC2, uniform::CU_POST_SHADOW_UV);
post_effect->add_uniform("ShadowUVOffset", uniform::UT_VEC2, uniform::CU_POST_SHADOW_UV_OFFSET);
post_effect->add_uniform("ShadowDims", uniform::UT_VEC2, uniform::CU_POST_SHADOW_DIMS);
post_effect->add_uniform("ScanlineAlpha", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_ALPHA);
post_effect->add_uniform("ScanlineScale", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_SCALE);
post_effect->add_uniform("ScanlineHeight", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_HEIGHT);
post_effect->add_uniform("ScanlineVariation", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_VARIATION);
post_effect->add_uniform("ScanlineBrightScale", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_BRIGHT_SCALE);
post_effect->add_uniform("ScanlineBrightOffset", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_BRIGHT_OFFSET);
post_effect->add_uniform("ShadowDims", uniform::UT_VEC2, uniform::CU_POST_SHADOW_DIMS);
post_effect->add_uniform("Power", uniform::UT_VEC3, uniform::CU_POST_POWER);
post_effect->add_uniform("Floor", uniform::UT_VEC3, uniform::CU_POST_FLOOR);
@ -835,6 +872,7 @@ void shaders::begin_draw()
prescale_effect->set_technique("DefaultTechnique");
phosphor_effect->set_technique("DefaultTechnique");
focus_effect->set_technique("DefaultTechnique");
scanline_effect->set_technique("DefaultTechnique");
deconverge_effect->set_technique("DefaultTechnique");
color_effect->set_technique("DefaultTechnique");
ntsc_effect->set_technique("DefaultTechnique");
@ -1040,6 +1078,38 @@ int shaders::deconverge_pass(d3d_render_target *rt, int source_index, poly_info
return next_index;
}
int shaders::scanline_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum)
{
int next_index = source_index;
// skip scanline if alpha is 0
if (options->scanline_alpha == 0.0f)
return next_index;
auto win = d3d->assert_window();
screen_device_iterator screen_iterator(machine->root_device());
screen_device *screen = screen_iterator.byindex(curr_screen);
render_container &screen_container = screen->container();
float xscale = 1.0f / screen_container.xscale();
float yscale = 1.0f / screen_container.yscale();
float xoffset = -screen_container.xoffset();
float yoffset = -screen_container.yoffset();
float screen_scale[] = { xscale, yscale };
float screen_offset[] = { xoffset, yoffset };
curr_effect = scanline_effect;
curr_effect->update_uniforms();
curr_effect->set_texture("Diffuse", rt->target_texture[next_index]);
curr_effect->set_vector("ScreenScale", 2, screen_scale);
curr_effect->set_vector("ScreenOffset", 2, screen_offset);
curr_effect->set_float("ScanlineOffset",
curr_texture->get_cur_frame() == 0 ?
0.0f : options->scanline_jitter);
next_index = rt->next_index(next_index);
blit(rt->target_surface[next_index], false, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
int shaders::defocus_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum)
{
int next_index = source_index;
@ -1353,10 +1423,11 @@ void shaders::render_quad(poly_info *poly, int vertnum)
int next_index = 0;
next_index = ntsc_pass(rt, next_index, poly, vertnum); // handled in bgfx
next_index = color_convolution_pass(rt, next_index, poly, vertnum); // handled in bgfx
next_index = prescale_pass(rt, next_index, poly, vertnum); // handled in bgfx
next_index = deconverge_pass(rt, next_index, poly, vertnum); // handled in bgfx
next_index = ntsc_pass(rt, next_index, poly, vertnum);
next_index = color_convolution_pass(rt, next_index, poly, vertnum);
next_index = prescale_pass(rt, next_index, poly, vertnum);
next_index = deconverge_pass(rt, next_index, poly, vertnum);
next_index = scanline_pass(rt, next_index, poly, vertnum);
next_index = defocus_pass(rt, next_index, poly, vertnum);
next_index = phosphor_pass(rt, next_index, poly, vertnum);
@ -1735,6 +1806,11 @@ void shaders::delete_resources()
delete focus_effect;
focus_effect = nullptr;
}
if (scanline_effect != nullptr)
{
delete scanline_effect;
scanline_effect = nullptr;
}
if (deconverge_effect != nullptr)
{
delete deconverge_effect;

View File

@ -332,6 +332,7 @@ private:
int color_convolution_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum);
int prescale_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum);
int deconverge_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum);
int scanline_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum);
int defocus_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum);
int phosphor_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum);
int post_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum, bool prepare_bloom);
@ -381,6 +382,7 @@ private:
effect * prescale_effect; // pointer to the prescale-effect object
effect * post_effect; // pointer to the post-effect object
effect * distortion_effect; // pointer to the distortion-effect object
effect * scanline_effect;
effect * focus_effect; // pointer to the focus-effect object
effect * phosphor_effect; // pointer to the phosphor-effect object
effect * deconverge_effect; // pointer to the deconvergence-effect object