Merge pull request #409 from ImJezze/master

-Unified HLSL render pipline for raster and vector graphics [ImJezze]
  * simplified draw call of render pass functions
  * reduced number of used render targets from 7 to 4 (2 native and 2 pre-scaled)
  * made render pass functions (nearly) independent from each other
  * unified render pipeline for raster and vector graphics, which means that all effects are now also available for vector graphics (except scan-lines)
  * removed/replaced simple.fx by primary.fx
  * removed CU_PHOSPHOR_IGNORE uniform, which was only used in phosphor pass function and is now directly set
  * added CU_TARGET_DIMS uniform based on the current render target
  * added CU_QUAD_DIMS uniform based on the current full screen polygon quad
  * removed pre-scale knowledge from shaders
  * fixed DX9 related half pixel offset in most shaders
  * reduced shadow mask color bleeding
  * fixed defocus strength with different pre-scales
  * added slight noise to bloom effect to reduce the color banding of lower bloom levels
  * fixed position of reflection effect when screen is rotated or flipped
  * fixed roundness and size of rounded corners in any aspect ratio
  * added distortion pass, which is applied after the bloom pass and moved curvature, vignetting, rounded corners and reflection effect to this pass
  * fixed bloom stair-step artifacts when screen is curved
  * added smooth border effect and option, its amount is limited by the amount of rounded corners
  * added bloom overdrive effect and options, this effect allows to overdrive pure colors like red, green and blue to become more brighter
  * merged vector and raster bloom options, use vector.ini or raster.ini to distinguish
  * added raster.ini and lcd.ini to parse_standard_inis()
  * added bounds() and screen_bounds() getter to layout_view
  * added current_view() getter to render_target
  * many other small changes and refactoring
This commit is contained in:
Miodrag Milanović 2015-10-24 08:38:42 +02:00
commit afbed222b0
19 changed files with 1822 additions and 1201 deletions

View File

@ -1,7 +1,7 @@
// license:BSD-3-Clause // license:BSD-3-Clause
// copyright-holders:Ryan Holtz,ImJezze // copyright-holders:ImJezze
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Effect File Variables // Distortion Effect
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
texture DiffuseTexture; texture DiffuseTexture;
@ -21,16 +21,16 @@ sampler DiffuseSampler = sampler_state
// Vertex Definitions // Vertex Definitions
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
struct VS_OUTPUT struct VS_INPUT
{ {
float4 Position : POSITION; float4 Position : POSITION;
float4 Color : COLOR0; float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0; float2 TexCoord : TEXCOORD0;
}; };
struct VS_INPUT struct VS_OUTPUT
{ {
float3 Position : POSITION; float4 Position : POSITION;
float4 Color : COLOR0; float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0; float2 TexCoord : TEXCOORD0;
}; };
@ -42,10 +42,11 @@ struct PS_INPUT
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Simple Vertex Shader // Distortion Vertex Shader
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
uniform float2 ScreenDims; uniform float2 ScreenDims; // size of the window or fullscreen
uniform float2 TargetDims;
VS_OUTPUT vs_main(VS_INPUT Input) VS_OUTPUT vs_main(VS_INPUT Input)
{ {
@ -57,37 +58,40 @@ VS_OUTPUT vs_main(VS_INPUT Input)
Output.Position.xy -= 0.5f; // center Output.Position.xy -= 0.5f; // center
Output.Position.xy *= 2.0f; // zoom Output.Position.xy *= 2.0f; // zoom
Output.TexCoord = Input.Position.xy / ScreenDims;
Output.Color = Input.Color; Output.Color = Input.Color;
Output.TexCoord = Input.Position.xy / ScreenDims;
Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9)
return Output; return Output;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Simple Pixel Shader // Post-Processing Pixel Shader
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
float4 ps_main(PS_INPUT Input) : COLOR float4 ps_main(PS_INPUT Input) : COLOR
{ {
float4 texel = tex2D(DiffuseSampler, Input.TexCoord); float2 BaseCoord = Input.TexCoord;
return float4(texel.rgb, 1.0f); // Color
float4 BaseColor = tex2D(DiffuseSampler, BaseCoord);
BaseColor.a = 1.0f;
return BaseColor;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Simple Effect // Distortion Effect
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
technique TestTechnique technique DistortionTechnique
{ {
pass Pass0 pass Pass0
{ {
Lighting = FALSE; Lighting = FALSE;
Sampler[0] = <DiffuseSampler>; VertexShader = compile vs_3_0 vs_main();
PixelShader = compile ps_3_0 ps_main();
VertexShader = compile vs_2_0 vs_main();
PixelShader = compile ps_2_0 ps_main();
} }
} }

View File

@ -0,0 +1,477 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz,ImJezze
//-----------------------------------------------------------------------------
// Scanline & Shadowmask Effect
//-----------------------------------------------------------------------------
texture DiffuseTexture;
sampler DiffuseSampler = sampler_state
{
Texture = <DiffuseTexture>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
AddressU = CLAMP;
AddressV = CLAMP;
AddressW = CLAMP;
};
texture ShadowTexture;
sampler ShadowSampler = sampler_state
{
Texture = <ShadowTexture>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
AddressU = WRAP;
AddressV = WRAP;
AddressW = WRAP;
};
//-----------------------------------------------------------------------------
// 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;
float2 ScreenCoord : TEXCOORD1;
};
struct PS_INPUT
{
float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0;
float2 ScreenCoord : TEXCOORD1;
};
//-----------------------------------------------------------------------------
// Constants
//-----------------------------------------------------------------------------
static const float Epsilon = 1.0e-7f;
static const float PI = 3.1415927f;
static const float E = 2.7182817f;
static const float Gelfond = 23.140692f; // e^pi (Gelfond constant)
static const float GelfondSchneider = 2.6651442f; // 2^sqrt(2) (Gelfond-Schneider constant)
//-----------------------------------------------------------------------------
// Functions
//-----------------------------------------------------------------------------
bool xor(bool a, bool b)
{
return (a || b) && !(a && b);
}
// www.stackoverflow.com/questions/5149544/can-i-generate-a-random-number-inside-a-pixel-shader/
float random(float2 seed)
{
// irrationals for pseudo randomness
float2 i = float2(Gelfond, GelfondSchneider);
return frac(cos(dot(seed, i)) * 123456.0f);
}
// www.dinodini.wordpress.com/2010/04/05/normalized-tunable-sigmoid-functions/
float normalizedSigmoid(float n, float k)
{
// valid for n and k in range of -1.0 and 1.0
return (n - n * k) / (k - abs(n) * 2.0f * k + 1);
}
// www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
float roundBox(float2 p, float2 b, float r)
{
return length(max(abs(p) - b + r, 0.0f)) - r;
}
//-----------------------------------------------------------------------------
// Scanline & Shadowmask Vertex Shader
//-----------------------------------------------------------------------------
uniform float2 ScreenDims; // size of the window or fullscreen
uniform float2 SourceDims; // size of the texture in power-of-two size
uniform float2 SourceRect; // size of the uv rectangle
uniform float2 TargetDims; // size of the target surface
uniform float2 QuadDims; // size of the screen quad
uniform float2 ShadowDims = float2(32.0f, 32.0f); // size of the shadow texture (extended to power-of-two size)
uniform float2 ShadowUVOffset = float2(0.0f, 0.0f);
uniform bool OrientationSwapXY = false; // false landscape, true portrait for default screen orientation
uniform bool RotationSwapXY = false; // swapped default screen orientation due to screen rotation
uniform int RotationType = 0; // 0 = 0°, 1 = 90°, 2 = 180°, 3 = 270°
uniform bool PrepareBloom = false; // disables some effects for rendering bloom textures
uniform bool PrepareVector = false;
VS_OUTPUT vs_main(VS_INPUT Input)
{
VS_OUTPUT Output = (VS_OUTPUT)0;
float2 shadowUVOffset = ShadowUVOffset;
shadowUVOffset = xor(OrientationSwapXY, RotationSwapXY)
? shadowUVOffset.yx
: shadowUVOffset.xy;
float2 ScreenCoordOffset = 0.0f;
ScreenCoordOffset += shadowUVOffset;
Output.ScreenCoord = Input.Position.xy;
Output.ScreenCoord += ScreenCoordOffset;
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 = PrepareVector
? Input.Position.xy / ScreenDims
: Input.TexCoord;
Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9)
Output.Color = Input.Color;
return Output;
}
//-----------------------------------------------------------------------------
// Post-Processing Pixel Shader
//-----------------------------------------------------------------------------
uniform float ScanlineAlpha = 1.0f;
uniform float ScanlineScale = 1.0f;
uniform float ScanlineBrightScale = 1.0f;
uniform float ScanlineBrightOffset = 1.0f;
uniform float ScanlineOffset = 1.0f;
uniform float ScanlineHeight = 1.0f;
uniform float CurvatureAmount = 1.0f;
uniform float RoundCornerAmount = 0.0f;
uniform float SmoothBorderAmount = 0.0f;
uniform float VignettingAmount = 0.0f;
uniform float ReflectionAmount = 0.0f;
uniform float ShadowAlpha = 0.0f;
uniform float2 ShadowCount = float2(6.0f, 6.0f);
uniform float2 ShadowUV = float2(0.25f, 0.25f);
uniform float3 Power = float3(1.0f, 1.0f, 1.0f);
uniform float3 Floor = float3(0.0f, 0.0f, 0.0f);
float2 GetRatioCorrection()
{
if (PrepareVector)
{
float ScreenRatio = ScreenDims.x / ScreenDims.y;
float QuadRatio = QuadDims.x / QuadDims.y;
float ScreenQuadRatio = QuadRatio / ScreenRatio;
return ScreenQuadRatio > 1.0f
? float2(1.0, 1.0f / ScreenQuadRatio)
: float2(ScreenQuadRatio, 1.0);
}
else
{
return SourceRect;
}
}
float GetNoiseFactor(float n, float random)
{
// smaller n become more noisy
return 1.0f + random * max(0.0f, 0.25f * pow(E, -8 * n));
}
float GetVignetteFactor(float2 coord, float amount)
{
float2 VignetteCoord = coord;
float VignetteLength = length(VignetteCoord);
float VignetteBlur = (amount * 0.75f) + 0.25;
// 0.5 full screen fitting circle
float VignetteRadius = 1.0f - (amount * 0.25f);
float Vignette = smoothstep(VignetteRadius, VignetteRadius - VignetteBlur, VignetteLength);
return saturate(Vignette);
}
float GetSpotAddend(float2 coord, float amount)
{
float2 RatioCorrection = GetRatioCorrection();
// normalized screen canvas ratio
float2 CanvasRatio = PrepareVector
? float2(1.0f, QuadDims.y / QuadDims.x)
: float2(1.0f, xor(OrientationSwapXY, RotationSwapXY)
? QuadDims.x / QuadDims.y
: QuadDims.y / QuadDims.x);
// upper right quadrant
float2 spotOffset = PrepareVector
? RotationType == 1 // 90°
? float2(-0.25f, -0.25f)
: RotationType == 2 // 180°
? float2(0.25f, -0.25f)
: RotationType == 3 // 270°
? float2(0.25f, 0.25f)
: float2(-0.25f, 0.25f)
: OrientationSwapXY
? float2(0.25f, 0.25f)
: float2(-0.25f, 0.25f);
float2 SpotCoord = coord;
SpotCoord += spotOffset * RatioCorrection;
SpotCoord *= CanvasRatio;
SpotCoord /= RatioCorrection;
float SpotBlur = amount;
// 0.5 full screen fitting circle
float SpotRadius = amount * 0.75f;
float Spot = smoothstep(SpotRadius, SpotRadius - SpotBlur, length(SpotCoord));
float SigmoidSpot = normalizedSigmoid(Spot, 0.75) * amount;
// increase strength by 100%
SigmoidSpot = SigmoidSpot * 2.0f;
return saturate(SigmoidSpot);
}
float GetRoundCornerFactor(float2 coord, float radiusAmount, float smoothAmount)
{
float2 RatioCorrection = GetRatioCorrection();
// reduce smooth amount down to radius amount
smoothAmount = min(smoothAmount, radiusAmount);
float2 CanvasDims = PrepareVector
? ScreenDims
: xor(OrientationSwapXY, RotationSwapXY)
? QuadDims.yx / SourceRect
: QuadDims.xy / SourceRect;
coord = PrepareVector
? coord
: coord - 1.0f / SourceDims; // alignment correction (raster graphics)
float range = min(QuadDims.x, QuadDims.y) * 0.5;
float radius = range * max(radiusAmount, 0.0025f);
float smooth = 1.0 / (range * max(smoothAmount, 0.0025f));
// compute box
float box = roundBox(CanvasDims * (coord * 2.0f), CanvasDims * RatioCorrection, radius);
// apply smooth
box *= smooth;
box += 1.0f - pow(smooth * 0.5f, 0.5f);
float border = smoothstep(1.0f, 0.0f, box);
return saturate(border);
}
// www.francois-tarlier.com/blog/cubic-lens-distortion-shader/
float2 GetDistortedCoords(float2 centerCoord, float amount)
{
amount *= 0.25f; // reduced amount
// lens distortion coefficient
float k = amount;
// cubic distortion value
float kcube = amount * 2.0f;
// compute cubic distortion factor
float r2 = centerCoord.x * centerCoord.x + centerCoord.y * centerCoord.y;
float f = kcube == 0.0f
? 1.0f + r2 * k
: 1.0f + r2 * (k + kcube * sqrt(r2));
// fit screen bounds
f /= 1.0f + amount * 0.5f;
// apply cubic distortion factor
centerCoord *= f;
return centerCoord;
}
float2 GetCoords(float2 coord, float2 centerOffset, float distortionAmount)
{
float2 RatioCorrection = GetRatioCorrection();
// center coordinates
coord -= centerOffset;
// apply ratio difference between screen and quad
coord /= RatioCorrection;
// distort coordinates
coord = GetDistortedCoords(coord, distortionAmount);
// revert ratio difference between screen and quad
coord *= RatioCorrection;
// un-center coordinates
coord += centerOffset;
return coord;
}
float4 ps_main(PS_INPUT Input) : COLOR
{
float2 ScreenTexelDims = 1.0f / ScreenDims;
float2 HalfSourceRect = PrepareVector
? float2(0.5f, 0.5f)
: SourceRect * 0.5f;
float2 ScreenCoord = Input.ScreenCoord / ScreenDims;
ScreenCoord = GetCoords(ScreenCoord, float2(0.5f, 0.5f), CurvatureAmount);
float2 BaseCoord = Input.TexCoord;
BaseCoord = GetCoords(BaseCoord, HalfSourceRect, CurvatureAmount);
float2 BaseCoordCentered = BaseCoord;
BaseCoordCentered -= HalfSourceRect;
float4 BaseColor = tex2D(DiffuseSampler, BaseCoord);
BaseColor.a = 1.0f;
// Mask Simulation (may not affect bloom)
if (!PrepareBloom)
{
float2 shadowDims = ShadowDims;
shadowDims = xor(OrientationSwapXY, RotationSwapXY)
? shadowDims.yx
: shadowDims.xy;
float2 shadowUV = ShadowUV;
// shadowUV = xor(OrientationSwapXY, RotationSwapXY)
// ? shadowUV.yx
// : shadowUV.xy;
float2 screenCoord = ScreenCoord;
screenCoord = xor(OrientationSwapXY, RotationSwapXY)
? screenCoord.yx
: screenCoord.xy;
float2 shadowCount = ShadowCount;
shadowCount = xor(OrientationSwapXY, RotationSwapXY)
? shadowCount.yx
: shadowCount.xy;
float2 shadowTile = (ScreenTexelDims * shadowCount);
shadowTile = xor(OrientationSwapXY, RotationSwapXY)
? shadowTile.yx
: shadowTile.xy;
float2 ShadowFrac = frac(screenCoord / shadowTile);
float2 ShadowCoord = (ShadowFrac * shadowUV);
ShadowCoord += 0.5f / shadowDims; // half texel offset
// ShadowCoord = xor(OrientationSwapXY, RotationSwapXY)
// ? ShadowCoord.yx
// : ShadowCoord.xy;
float3 ShadowColor = tex2D(ShadowSampler, ShadowCoord).rgb;
ShadowColor = lerp(1.0f, ShadowColor, ShadowAlpha);
BaseColor.rgb *= ShadowColor;
}
// Color Compression (may not affect bloom)
if (!PrepareBloom)
{
// increasing the floor of the signal without affecting the ceiling
BaseColor.rgb = Floor + (1.0f - Floor) * BaseColor.rgb;
}
// Color Power (may affect bloom)
BaseColor.r = pow(BaseColor.r, Power.r);
BaseColor.g = pow(BaseColor.g, Power.g);
BaseColor.b = pow(BaseColor.b, Power.b);
// Scanline Simulation (may not affect bloom)
if (!PrepareBloom)
{
// Scanline Simulation (disabled for vector)
if (!PrepareVector)
{
float InnerSine = BaseCoord.y * ScanlineScale * SourceDims.y;
float ScanJitter = ScanlineOffset * SourceDims.y;
float ScanBrightMod = sin(InnerSine * PI + ScanJitter);
float3 ScanColor = lerp(1.0f, (pow(ScanBrightMod * ScanBrightMod, ScanlineHeight) * ScanlineBrightScale + 1.0f + ScanlineBrightOffset) * 0.5f, ScanlineAlpha);
BaseColor.rgb *= ScanColor;
}
}
// Output
float4 Output = PrepareVector
? BaseColor * (Input.Color + float4(1.0f, 1.0f, 1.0f, 0.0f))
: BaseColor * Input.Color;
Output.a = 1.0f;
// Vignetting Simulation (may not affect bloom)
if (!PrepareBloom)
{
float2 VignetteCoord = BaseCoordCentered;
float VignetteFactor = GetVignetteFactor(VignetteCoord, VignettingAmount);
Output.rgb *= VignetteFactor;
}
// Light Reflection Simulation (may not affect bloom)
if (!PrepareBloom)
{
float3 LightColor = float3(1.0f, 0.90f, 0.80f);
float2 SpotCoord = BaseCoordCentered;
float2 NoiseCoord = BaseCoordCentered;
float SpotAddend = GetSpotAddend(SpotCoord, ReflectionAmount);
float NoiseFactor = GetNoiseFactor(SpotAddend, random(NoiseCoord));
Output.rgb += SpotAddend * NoiseFactor * LightColor;
}
// Round Corners Simulation (may affect bloom)
float2 RoundCornerCoord = BaseCoordCentered;
float roundCornerFactor = GetRoundCornerFactor(RoundCornerCoord, RoundCornerAmount, SmoothBorderAmount);
Output.rgb *= roundCornerFactor;
return Output;
}
//-----------------------------------------------------------------------------
// Scanline & Shadowmask Effect
//-----------------------------------------------------------------------------
technique ScanMaskTechnique
{
pass Pass0
{
Lighting = FALSE;
//Sampler[0] = <DiffuseSampler>;
VertexShader = compile vs_3_0 vs_main();
PixelShader = compile ps_3_0 ps_main();
}
}

View File

@ -171,13 +171,33 @@ struct PS_INPUT
float2 TexCoordA : TEXCOORD5; float2 TexCoordA : TEXCOORD5;
}; };
//-----------------------------------------------------------------------------
// Constants
//-----------------------------------------------------------------------------
static const float E = 2.7182817f;
static const float Gelfond = 23.140692f; // e^pi (Gelfond constant)
static const float GelfondSchneider = 2.6651442f; // 2^sqrt(2) (Gelfond-Schneider constant)
//-----------------------------------------------------------------------------
// Funcions
//-----------------------------------------------------------------------------
// www.stackoverflow.com/questions/5149544/can-i-generate-a-random-number-inside-a-pixel-shader/
float random(float2 seed)
{
// irrationals for pseudo randomness
float2 i = float2(Gelfond, GelfondSchneider);
return frac(cos(dot(seed, i)) * 123456.0f);
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Bloom Vertex Shader // Bloom Vertex Shader
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
uniform float2 ScreenDims; uniform float2 ScreenDims;
uniform float2 TargetDims;
uniform float2 Prescale = float2(8.0f, 8.0f);
uniform float4 Level01Size; uniform float4 Level01Size;
uniform float4 Level23Size; uniform float4 Level23Size;
@ -186,43 +206,28 @@ uniform float4 Level67Size;
uniform float4 Level89Size; uniform float4 Level89Size;
uniform float2 LevelASize; uniform float2 LevelASize;
uniform bool PrepareVector = false;
VS_OUTPUT vs_main(VS_INPUT Input) VS_OUTPUT vs_main(VS_INPUT Input)
{ {
VS_OUTPUT Output = (VS_OUTPUT)0; VS_OUTPUT Output = (VS_OUTPUT)0;
float2 ScreenDimsTexel = 1.0f / ScreenDims;
float2 HalfPrescale = Prescale * 0.5f;
Output.Position = float4(Input.Position.xyz, 1.0f); Output.Position = float4(Input.Position.xyz, 1.0f);
Output.Position.xy /= ScreenDims; Output.Position.xy /= ScreenDims;
Output.Position.y = 1.0f - Output.Position.y; Output.Position.y = 1.0f - Output.Position.y; // flip y
Output.Position.xy -= 0.5f; Output.Position.xy -= 0.5f; // center
Output.Position.xy *= 2.0f; Output.Position.xy *= 2.0f; // zoom
Output.Color = Input.Color; Output.Color = Input.Color;
// Vector graphics is not prescaled it has the size of the screen float2 TexCoord = Input.Position.xy / ScreenDims;
if (PrepareVector) TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9)
{
Output.TexCoord01 = Input.Position.xyxy / ScreenDims.xyxy + 1.0f / Level01Size; Output.TexCoord01.xy = TexCoord.xy;
Output.TexCoord23 = Input.Position.xyxy / ScreenDims.xyxy + 1.0f / Level23Size; Output.TexCoord01.zw = TexCoord.xy + 0.5f / Level01Size.zw;
Output.TexCoord45 = Input.Position.xyxy / ScreenDims.xyxy + 1.0f / Level45Size; Output.TexCoord23 = TexCoord.xyxy + 0.5f / Level23Size;
Output.TexCoord67 = Input.Position.xyxy / ScreenDims.xyxy + 1.0f / Level67Size; Output.TexCoord45 = TexCoord.xyxy + 0.5f / Level45Size;
Output.TexCoord89 = Input.Position.xyxy / ScreenDims.xyxy + 1.0f / Level89Size; Output.TexCoord67 = TexCoord.xyxy + 0.5f / Level67Size;
Output.TexCoordA = Input.Position.xy / ScreenDims.xy + 1.0f / LevelASize; Output.TexCoord89 = TexCoord.xyxy + 0.5f / Level89Size;
} Output.TexCoordA = TexCoord.xy + 0.5f / LevelASize;
else
{
Output.TexCoord01 = Input.Position.xyxy / ScreenDims.xyxy + HalfPrescale.xyxy / Level01Size;
Output.TexCoord23 = Input.Position.xyxy / ScreenDims.xyxy + HalfPrescale.xyxy / Level23Size;
Output.TexCoord45 = Input.Position.xyxy / ScreenDims.xyxy + HalfPrescale.xyxy / Level45Size;
Output.TexCoord67 = Input.Position.xyxy / ScreenDims.xyxy + HalfPrescale.xyxy / Level67Size;
Output.TexCoord89 = Input.Position.xyxy / ScreenDims.xyxy + HalfPrescale.xyxy / Level89Size;
Output.TexCoordA = Input.Position.xy / ScreenDims.xy + HalfPrescale.xy / LevelASize;
}
return Output; return Output;
} }
@ -235,6 +240,14 @@ uniform float4 Level0123Weight;
uniform float4 Level4567Weight; uniform float4 Level4567Weight;
uniform float3 Level89AWeight; uniform float3 Level89AWeight;
uniform float3 OverdriveWeight;
float3 GetNoiseFactor(float3 n, float random)
{
// smaller n become more noisy
return 1.0f + random * max(0.0f, 0.25f * pow(E, -8 * n));
}
float4 ps_main(PS_INPUT Input) : COLOR float4 ps_main(PS_INPUT Input) : COLOR
{ {
float3 texel0 = tex2D(DiffuseSampler0, Input.TexCoord01.xy).rgb; float3 texel0 = tex2D(DiffuseSampler0, Input.TexCoord01.xy).rgb;
@ -261,8 +274,7 @@ float4 ps_main(PS_INPUT Input) : COLOR
texel9 = texel9 * Level89AWeight.y; texel9 = texel9 * Level89AWeight.y;
texelA = texelA * Level89AWeight.z; texelA = texelA * Level89AWeight.z;
float4 sum = float4( float3 bloom = float3(
texel0 +
texel1 + texel1 +
texel2 + texel2 +
texel3 + texel3 +
@ -272,12 +284,25 @@ float4 ps_main(PS_INPUT Input) : COLOR
texel7 + texel7 +
texel8 + texel8 +
texel9 + texel9 +
texelA, 1.0f); texelA);
return sum;
float3 bloomOverdrive = max(0.0f, texel0 + bloom - 1.0f) * OverdriveWeight;
bloom.r += bloomOverdrive.g * 0.5f;
bloom.r += bloomOverdrive.b * 0.5f;
bloom.g += bloomOverdrive.r * 0.5f;
bloom.g += bloomOverdrive.b * 0.5f;
bloom.b += bloomOverdrive.r * 0.5f;
bloom.b += bloomOverdrive.g * 0.5f;
float2 NoiseCoord = Input.TexCoord01.xy;
float3 NoiseFactor = GetNoiseFactor(bloom, random(NoiseCoord));
return float4(texel0 + bloom * NoiseFactor, 1.0f);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Downsample Effect // Bloom Effect
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
technique TestTechnique technique TestTechnique

316
hlsl/distortion.fx Normal file
View File

@ -0,0 +1,316 @@
// license:BSD-3-Clause
// copyright-holders:ImJezze
//-----------------------------------------------------------------------------
// Distortion Effect
//-----------------------------------------------------------------------------
texture DiffuseTexture;
sampler DiffuseSampler = sampler_state
{
Texture = <DiffuseTexture>;
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 Epsilon = 1.0e-7f;
static const float PI = 3.1415927f;
static const float E = 2.7182817f;
static const float Gelfond = 23.140692f; // e^pi (Gelfond constant)
static const float GelfondSchneider = 2.6651442f; // 2^sqrt(2) (Gelfond-Schneider constant)
//-----------------------------------------------------------------------------
// Functions
//-----------------------------------------------------------------------------
bool xor(bool a, bool b)
{
return (a || b) && !(a && b);
}
// www.stackoverflow.com/questions/5149544/can-i-generate-a-random-number-inside-a-pixel-shader/
float random(float2 seed)
{
// irrationals for pseudo randomness
float2 i = float2(Gelfond, GelfondSchneider);
return frac(cos(dot(seed, i)) * 123456.0f);
}
// www.dinodini.wordpress.com/2010/04/05/normalized-tunable-sigmoid-functions/
float normalizedSigmoid(float n, float k)
{
// valid for n and k in range of -1.0 and 1.0
return (n - n * k) / (k - abs(n) * 2.0f * k + 1);
}
// www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
float roundBox(float2 p, float2 b, float r)
{
return length(max(abs(p) - b + r, 0.0f)) - r;
}
//-----------------------------------------------------------------------------
// Distortion Vertex Shader
//-----------------------------------------------------------------------------
uniform float2 ScreenDims; // size of the window or fullscreen
uniform float2 TargetDims; // size of the target surface
uniform float2 QuadDims; // size of the screen quad
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.Color = Input.Color;
Output.TexCoord = Input.Position.xy / ScreenDims;
Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9)
return Output;
}
//-----------------------------------------------------------------------------
// Post-Processing Pixel Shader
//-----------------------------------------------------------------------------
uniform float CurvatureAmount = 0.0f;
uniform float RoundCornerAmount = 0.0f;
uniform float SmoothBorderAmount = 0.0f;
uniform float VignettingAmount = 0.0f;
uniform float ReflectionAmount = 0.0f;
uniform bool OrientationSwapXY = false; // false landscape, true portrait for default screen orientation
uniform bool RotationSwapXY = false; // swapped default screen orientation due to screen rotation
uniform int RotationType = 0; // 0 = 0°, 1 = 90°, 2 = 180°, 3 = 270°
float2 GetRatioCorrection()
{
float ScreenRatio = ScreenDims.x / ScreenDims.y;
float QuadRatio = QuadDims.x / QuadDims.y;
float ScreenQuadRatio = QuadRatio / ScreenRatio;
return ScreenQuadRatio > 1.0f
? float2(1.0, 1.0f / ScreenQuadRatio)
: float2(ScreenQuadRatio, 1.0);
}
float GetNoiseFactor(float3 n, float random)
{
// smaller n become more noisy
return 1.0f + random * max(0.0f, 0.25f * pow(E, -8 * n));
}
float GetVignetteFactor(float2 coord, float amount)
{
float2 VignetteCoord = coord;
float VignetteLength = length(VignetteCoord);
float VignetteBlur = (amount * 0.75f) + 0.25;
// 0.5 full screen fitting circle
float VignetteRadius = 1.0f - (amount * 0.25f);
float Vignette = smoothstep(VignetteRadius, VignetteRadius - VignetteBlur, VignetteLength);
return saturate(Vignette);
}
float GetSpotAddend(float2 coord, float amount)
{
float2 RatioCorrection = GetRatioCorrection();
// normalized screen quad ratio
float2 QuadRatio = float2 (1.0f, QuadDims.y / QuadDims.x);
// upper right quadrant
float2 spotOffset =
RotationType == 1 // 90°
? float2(-0.25f, -0.25f)
: RotationType == 2 // 180°
? float2(0.25f, -0.25f)
: RotationType == 3 // 270°
? float2(0.25f, 0.25f)
: float2(-0.25f, 0.25f);
float2 SpotCoord = coord;
SpotCoord += spotOffset * RatioCorrection;
SpotCoord *= QuadRatio;
SpotCoord /= RatioCorrection;
float SpotBlur = amount;
// 0.5 full screen fitting circle
float SpotRadius = amount * 0.75f;
float Spot = smoothstep(SpotRadius, SpotRadius - SpotBlur, length(SpotCoord));
float SigmoidSpot = normalizedSigmoid(Spot, 0.75) * amount;
// increase strength by 100%
SigmoidSpot = SigmoidSpot * 2.0f;
return saturate(SigmoidSpot);
}
float GetRoundCornerFactor(float2 coord, float radiusAmount, float smoothAmount)
{
float2 RatioCorrection = GetRatioCorrection();
// reduce smooth amount down to radius amount
smoothAmount = min(smoothAmount, radiusAmount);
float range = min(QuadDims.x, QuadDims.y) * 0.5;
float radius = range * max(radiusAmount, 0.0025f);
float smooth = 1.0 / (range * max(smoothAmount, 0.0025f));
// compute box
float box = roundBox(ScreenDims * (coord * 2.0f), ScreenDims * RatioCorrection, radius);
// apply smooth
box *= smooth;
box += 1.0f - pow(smooth * 0.5f, 0.5f);
float border = smoothstep(1.0f, 0.0f, box);
return saturate(border);
}
// www.francois-tarlier.com/blog/cubic-lens-distortion-shader/
float2 GetDistortedCoords(float2 centerCoord, float amount)
{
amount *= 0.25f; // reduced amount
// lens distortion coefficient
float k = amount;
// cubic distortion value
float kcube = amount * 2.0f;
// compute cubic distortion factor
float r2 = centerCoord.x * centerCoord.x + centerCoord.y * centerCoord.y;
float f = kcube == 0.0f
? 1.0f + r2 * k
: 1.0f + r2 * (k + kcube * sqrt(r2));
// fit screen bounds
f /= 1.0f + amount * 0.5f;
// apply cubic distortion factor
centerCoord *= f;
return centerCoord;
}
float2 GetCoords(float2 coord, float distortionAmount)
{
float2 RatioCorrection = GetRatioCorrection();
// center coordinates
coord -= 0.5f;
// apply ratio difference between screen and quad
coord /= RatioCorrection;
// distort coordinates
coord = GetDistortedCoords(coord, distortionAmount);
// revert ratio difference between screen and quad
coord *= RatioCorrection;
// un-center coordinates
coord += 0.5f;
return coord;
}
float4 ps_main(PS_INPUT Input) : COLOR
{
float2 TexCoord = Input.TexCoord;
float2 BaseCoord = TexCoord;
// Screen Curvature
BaseCoord = GetCoords(BaseCoord, CurvatureAmount);
float2 BaseCoordCentered = BaseCoord;
BaseCoordCentered -= 0.5f;
// Color
float4 BaseColor = tex2D(DiffuseSampler, BaseCoord);
BaseColor.a = 1.0f;
// Vignetting Simulation
float2 VignetteCoord = BaseCoordCentered;
float VignetteFactor = GetVignetteFactor(VignetteCoord, VignettingAmount);
BaseColor.rgb *= VignetteFactor;
// Light Reflection Simulation
float3 LightColor = float3(1.0f, 0.90f, 0.80f); // color temperature 5.000 Kelvin
float2 SpotCoord = BaseCoordCentered;
float2 NoiseCoord = BaseCoordCentered;
float SpotAddend = GetSpotAddend(SpotCoord, ReflectionAmount);
float NoiseFactor = GetNoiseFactor(SpotAddend, random(NoiseCoord));
BaseColor.rgb += SpotAddend * NoiseFactor * LightColor;
// Round Corners Simulation
float2 RoundCornerCoord = BaseCoordCentered;
float roundCornerFactor = GetRoundCornerFactor(RoundCornerCoord, RoundCornerAmount, SmoothBorderAmount);
BaseColor.rgb *= roundCornerFactor;
return BaseColor;
}
//-----------------------------------------------------------------------------
// Distortion Effect
//-----------------------------------------------------------------------------
technique DistortionTechnique
{
pass Pass0
{
Lighting = FALSE;
VertexShader = compile vs_3_0 vs_main();
PixelShader = compile ps_3_0 ps_main();
}
}

View File

@ -48,45 +48,33 @@ struct PS_INPUT
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
uniform float2 ScreenDims; uniform float2 ScreenDims;
uniform float2 TargetSize; uniform float2 TargetDims;
uniform float2 Prescale = float2(8.0f, 8.0f); uniform bool PrepareVector;
uniform float BloomRescale;
uniform bool PrepareVector = false;
VS_OUTPUT vs_main(VS_INPUT Input) VS_OUTPUT vs_main(VS_INPUT Input)
{ {
VS_OUTPUT Output = (VS_OUTPUT)0; VS_OUTPUT Output = (VS_OUTPUT)0;
float2 TargetTexelSize = 1.0f / TargetSize; float2 TargetTexelDims = 1.0f / TargetDims;
Output.Position = float4(Input.Position.xyz, 1.0f); Output.Position = float4(Input.Position.xyz, 1.0f);
Output.Position.xy /= ScreenDims; Output.Position.xy /= ScreenDims;
Output.Position.y = 1.0f - Output.Position.y; Output.Position.y = 1.0f - Output.Position.y; // flip y
Output.Position.xy -= 0.5f; Output.Position.xy -= 0.5f; // center
Output.Position.xy *= 2.0f; Output.Position.xy *= 2.0f; // zoom
Output.Color = Input.Color; Output.Color = Input.Color;
float2 TexCoord = Input.Position.xy / ScreenDims; float2 TexCoord = Input.Position.xy / ScreenDims;
TexCoord += PrepareVector
? 0.5f / TargetDims // half texel offset correction (DX9)
: 0.0f;
// Vector graphics is not prescaled it has the size of the screen Output.TexCoord01.xy = TexCoord + float2(-0.5f, -0.5f) * TargetTexelDims;
if (PrepareVector) Output.TexCoord01.zw = TexCoord + float2( 0.5f, -0.5f) * TargetTexelDims;
{ Output.TexCoord23.xy = TexCoord + float2(-0.5f, 0.5f) * TargetTexelDims;
Output.TexCoord01.xy = TexCoord + float2(-0.5f, -0.5f) * TargetTexelSize; Output.TexCoord23.zw = TexCoord + float2( 0.5f, 0.5f) * TargetTexelDims;
Output.TexCoord01.zw = TexCoord + float2( 0.5f, -0.5f) * TargetTexelSize;
Output.TexCoord23.xy = TexCoord + float2(-0.5f, 0.5f) * TargetTexelSize;
Output.TexCoord23.zw = TexCoord + float2( 0.5f, 0.5f) * TargetTexelSize;
}
else
{
Output.TexCoord01.xy = TexCoord + float2(-0.5f, -0.5f) * TargetTexelSize * Prescale;
Output.TexCoord01.zw = TexCoord + float2( 0.5f, -0.5f) * TargetTexelSize * Prescale;
Output.TexCoord23.xy = TexCoord + float2(-0.5f, 0.5f) * TargetTexelSize * Prescale;
Output.TexCoord23.zw = TexCoord + float2( 0.5f, 0.5f) * TargetTexelSize * Prescale;
}
return Output; return Output;
} }
@ -102,7 +90,7 @@ float4 ps_main(PS_INPUT Input) : COLOR
float4 texel2 = tex2D(DiffuseSampler, Input.TexCoord23.xy); float4 texel2 = tex2D(DiffuseSampler, Input.TexCoord23.xy);
float4 texel3 = tex2D(DiffuseSampler, Input.TexCoord23.zw); float4 texel3 = tex2D(DiffuseSampler, Input.TexCoord23.zw);
float4 outTexel = (texel0 + texel1 + texel2 + texel3) / 4.0 * BloomRescale; float4 outTexel = (texel0 + texel1 + texel2 + texel3) / 4.0;
return float4(outTexel.rgb, 1.0f); return float4(outTexel.rgb, 1.0f);
} }

View File

@ -40,7 +40,6 @@ struct VS_INPUT
float3 Position : POSITION; float3 Position : POSITION;
float4 Color : COLOR0; float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0; float2 TexCoord : TEXCOORD0;
float2 Unused : TEXCOORD1;
}; };
struct PS_INPUT struct PS_INPUT
@ -61,12 +60,10 @@ struct PS_INPUT
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
uniform float2 ScreenDims; uniform float2 ScreenDims;
uniform float2 TargetDims;
uniform float2 Defocus = float2(0.0f, 0.0f); uniform float2 Defocus = float2(0.0f, 0.0f);
uniform float2 Prescale = float2(8.0f, 8.0f);
float2 Coord0Offset = float2( 0.0f, 0.0f);
float2 Coord1Offset = float2(-0.2f, -0.6f); float2 Coord1Offset = float2(-0.2f, -0.6f);
float2 Coord2Offset = float2( 0.4f, -0.4f); float2 Coord2Offset = float2( 0.4f, -0.4f);
float2 Coord3Offset = float2( 0.6f, 0.2f); float2 Coord3Offset = float2( 0.6f, 0.2f);
@ -83,17 +80,14 @@ VS_OUTPUT vs_main(VS_INPUT Input)
Output.Position = float4(Input.Position.xyz, 1.0f); Output.Position = float4(Input.Position.xyz, 1.0f);
Output.Position.xy /= ScreenDims; Output.Position.xy /= ScreenDims;
Output.Position.y = 1.0f - Output.Position.y; Output.Position.y = 1.0f - Output.Position.y; // flip y
Output.Position.xy -= 0.5f; Output.Position.xy -= 0.5f; // center
Output.Position.xy *= 2.0f; Output.Position.xy *= 2.0f; // zoom
// todo: there is an offset which can be noticed at lower prescale in high-resolution
float2 FocusPrescaleOffset = ScreenTexelDims / Prescale;
float2 TexCoord = Input.TexCoord; float2 TexCoord = Input.TexCoord;
TexCoord += FocusPrescaleOffset; TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9)
Output.TexCoord0 = TexCoord + Coord0Offset * ScreenTexelDims * Defocus; Output.TexCoord0 = TexCoord;
Output.TexCoord1 = TexCoord + Coord1Offset * ScreenTexelDims * Defocus; Output.TexCoord1 = TexCoord + Coord1Offset * ScreenTexelDims * Defocus;
Output.TexCoord2 = TexCoord + Coord2Offset * ScreenTexelDims * Defocus; Output.TexCoord2 = TexCoord + Coord2Offset * ScreenTexelDims * Defocus;
Output.TexCoord3 = TexCoord + Coord3Offset * ScreenTexelDims * Defocus; Output.TexCoord3 = TexCoord + Coord3Offset * ScreenTexelDims * Defocus;
@ -123,13 +117,9 @@ float4 ps_main(PS_INPUT Input) : COLOR
float3 d7 = tex2D(DiffuseSampler, Input.TexCoord7).rgb; float3 d7 = tex2D(DiffuseSampler, Input.TexCoord7).rgb;
float3 blurred = (d0.rgb + d1 + d2 + d3 + d4 + d5 + d6 + d7) / 8.0f; float3 blurred = (d0.rgb + d1 + d2 + d3 + d4 + d5 + d6 + d7) / 8.0f;
blurred = lerp(d0.rgb, blurred, 1.0f); blurred = lerp(d0.rgb, blurred, 1.0f);
return float4(blurred, d0.a); return float4(blurred, d0.a);
// float4 texel = tex2D(DiffuseSampler, Input.TexCoord0);
// return float4(texel.rgb, 1.0f);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -47,7 +47,6 @@ struct VS_INPUT
float3 Position : POSITION; float3 Position : POSITION;
float4 Color : COLOR0; float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0; float2 TexCoord : TEXCOORD0;
float2 Unused : TEXCOORD1;
}; };
struct PS_INPUT struct PS_INPUT
@ -62,10 +61,9 @@ struct PS_INPUT
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
uniform float2 ScreenDims; uniform float2 ScreenDims;
uniform float2 TargetDims; uniform float2 TargetDims;
uniform float Passthrough; uniform bool Passthrough;
VS_OUTPUT vs_main(VS_INPUT Input) VS_OUTPUT vs_main(VS_INPUT Input)
{ {
@ -73,14 +71,17 @@ VS_OUTPUT vs_main(VS_INPUT Input)
Output.Position = float4(Input.Position.xyz, 1.0f); Output.Position = float4(Input.Position.xyz, 1.0f);
Output.Position.xy /= ScreenDims; Output.Position.xy /= ScreenDims;
Output.Position.y = 1.0f - Output.Position.y; Output.Position.y = 1.0f - Output.Position.y; // flip y
Output.Position.xy -= 0.5f; Output.Position.xy -= 0.5f; // center
Output.Position *= float4(2.0f, 2.0f, 1.0f, 1.0f); Output.Position.xy *= 2.0f; // zoom
Output.Color = Input.Color;
Output.TexCoord = Input.TexCoord;
Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9)
Output.TexCoord = Input.TexCoord + 0.5f / TargetDims;
Output.PrevCoord = Output.TexCoord; Output.PrevCoord = Output.TexCoord;
Output.Color = Input.Color;
return Output; return Output;
} }
@ -99,7 +100,9 @@ float4 ps_main(PS_INPUT Input) : COLOR
float GreenMax = max(CurrPix.g, PrevPix.g); float GreenMax = max(CurrPix.g, PrevPix.g);
float BlueMax = max(CurrPix.b, PrevPix.b); float BlueMax = max(CurrPix.b, PrevPix.b);
return lerp(float4(RedMax, GreenMax, BlueMax, CurrPix.a), CurrPix, Passthrough); return Passthrough
? CurrPix
: float4(RedMax, GreenMax, BlueMax, CurrPix.a);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -56,6 +56,16 @@ struct PS_INPUT
float2 ScreenCoord : TEXCOORD1; float2 ScreenCoord : TEXCOORD1;
}; };
//-----------------------------------------------------------------------------
// Constants
//-----------------------------------------------------------------------------
static const float PI = 3.1415927f;
//-----------------------------------------------------------------------------
// Functions
//-----------------------------------------------------------------------------
bool xor(bool a, bool b) bool xor(bool a, bool b)
{ {
return (a || b) && !(a && b); return (a || b) && !(a && b);
@ -66,47 +76,43 @@ bool xor(bool a, bool b)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
uniform float2 ScreenDims; // size of the window or fullscreen uniform float2 ScreenDims; // size of the window or fullscreen
uniform float2 ScreenRatio = float2(1.0f, 3.0f / 4.0f);
uniform float2 SourceDims; // size of the texture in power-of-two size uniform float2 SourceDims; // size of the texture in power-of-two size
uniform float2 SourceRect; // size of the uv rectangle uniform float2 TargetDims; // size of the target surface
uniform float2 ShadowDims = float2(32.0f, 32.0f); // size of the shadow texture (extended to power-of-two size) uniform float2 ShadowDims = float2(32.0f, 32.0f); // size of the shadow texture (extended to power-of-two size)
uniform float2 ShadowUVOffset = float2(0.0f, 0.0f); uniform float2 ShadowUVOffset = float2(0.0f, 0.0f);
uniform float2 Prescale = float2(8.0f, 8.0f);
uniform bool OrientationSwapXY = false; // false landscape, true portrait for default screen orientation uniform bool OrientationSwapXY = false; // false landscape, true portrait for default screen orientation
uniform bool RotationSwapXY = false; // swapped default screen orientation due to screen rotation uniform bool RotationSwapXY = false; // swapped default screen orientation due to screen rotation
uniform bool PrepareBloom = false; // disables some effects for rendering bloom textures uniform bool PrepareBloom = false; // disables some effects for rendering bloom textures
uniform bool PrepareVector = false;
VS_OUTPUT vs_main(VS_INPUT Input) VS_OUTPUT vs_main(VS_INPUT Input)
{ {
VS_OUTPUT Output = (VS_OUTPUT)0; VS_OUTPUT Output = (VS_OUTPUT)0;
float4 Position = Input.Position;
Position.xy *= (ScreenDims + 1.0f) / ScreenDims;
Position.xy -= 0.5f / ScreenDims;
float2 shadowUVOffset = ShadowUVOffset; float2 shadowUVOffset = ShadowUVOffset;
shadowUVOffset = xor(OrientationSwapXY, RotationSwapXY) shadowUVOffset = xor(OrientationSwapXY, RotationSwapXY)
? shadowUVOffset.yx ? shadowUVOffset.yx
: shadowUVOffset.xy; : shadowUVOffset.xy;
// todo: calculate offset float2 ScreenCoordOffset = 0.0f;
float2 ScreenCoordPrescaleOffset = 0.0f; ScreenCoordOffset += shadowUVOffset;
ScreenCoordPrescaleOffset += shadowUVOffset;
Output.ScreenCoord = Position.xy; Output.ScreenCoord = Input.Position.xy;
Output.ScreenCoord += ScreenCoordPrescaleOffset; Output.ScreenCoord += ScreenCoordOffset;
Output.Position = float4(Position.xyz, 1.0f); Output.Position = float4(Input.Position.xyz, 1.0f);
Output.Position.xy /= ScreenDims; Output.Position.xy /= ScreenDims;
Output.Position.y = 1.0f - Output.Position.y; // flip y Output.Position.y = 1.0f - Output.Position.y; // flip y
Output.Position.xy -= 0.5f; // center Output.Position.xy -= 0.5f; // center
Output.Position.xy *= 2.0f; // zoom Output.Position.xy *= 2.0f; // zoom
Output.TexCoord = Input.TexCoord; Output.TexCoord = PrepareVector
? Input.Position.xy / ScreenDims
: Input.TexCoord;
Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9)
Output.Color = Input.Color; Output.Color = Input.Color;
@ -124,11 +130,6 @@ uniform float ScanlineBrightOffset = 1.0f;
uniform float ScanlineOffset = 1.0f; uniform float ScanlineOffset = 1.0f;
uniform float ScanlineHeight = 1.0f; uniform float ScanlineHeight = 1.0f;
uniform float CurvatureAmount = 0.0f;
uniform float RoundCornerAmount = 0.0f;
uniform float VignettingAmount = 0.0f;
uniform float ReflectionAmount = 0.0f;
uniform float ShadowAlpha = 0.0f; uniform float ShadowAlpha = 0.0f;
uniform float2 ShadowCount = float2(6.0f, 6.0f); uniform float2 ShadowCount = float2(6.0f, 6.0f);
uniform float2 ShadowUV = float2(0.25f, 0.25f); uniform float2 ShadowUV = float2(0.25f, 0.25f);
@ -136,179 +137,17 @@ uniform float2 ShadowUV = float2(0.25f, 0.25f);
uniform float3 Power = float3(1.0f, 1.0f, 1.0f); uniform float3 Power = float3(1.0f, 1.0f, 1.0f);
uniform float3 Floor = float3(0.0f, 0.0f, 0.0f); uniform float3 Floor = float3(0.0f, 0.0f, 0.0f);
static const float Epsilon = 1.0e-7f;
static const float PI = 3.1415927f;
static const float E = 2.7182817f;
static const float Gelfond = 23.140692f; // e^pi (Gelfond constant)
static const float GelfondSchneider = 2.6651442f; // 2^sqrt(2) (GelfondSchneider constant)
float nextPowerOfTwo(float n)
{
return pow(2, floor(log2(n) / log2(2)) + 1);
}
// www.stackoverflow.com/questions/5149544/can-i-generate-a-random-number-inside-a-pixel-shader/
float random(float2 seed)
{
// irrationals for pseudo randomness
float2 i = float2(Gelfond, GelfondSchneider);
return frac(cos(dot(seed, i)) * 123456.0f);
}
// www.dinodini.wordpress.com/2010/04/05/normalized-tunable-sigmoid-functions/
float normalizedSigmoid(float n, float k)
{
// valid for n and k in range of -1.0 and 1.0
return (n - n * k) / (k - abs(n) * 2.0f * k + 1);
}
float GetNoiseFactor(float n, float random)
{
// smaller n become more noisy
return 1.0f + random * max(0.0f, 0.25f * pow(E, -4 * n));
}
float GetVignetteFactor(float2 coord, float amount)
{
float2 VignetteCoord = coord;
float VignetteLength = length(VignetteCoord);
float VignetteBlur = (amount * 0.75f) + 0.25;
// 0.5 full screen fitting circle
float VignetteRadius = 1.0f - (amount * 0.25f);
float Vignette = smoothstep(VignetteRadius, VignetteRadius - VignetteBlur, VignetteLength);
return saturate(Vignette);
}
float GetSpotAddend(float2 coord, float amount)
{
float2 SpotCoord = coord;
SpotCoord += OrientationSwapXY
? float2(-0.25f, -0.25f) * ScreenRatio // upper right quadrant
: float2(-0.25f, 0.25f) * ScreenRatio; // upper right quadrant
float SpotBlur = amount;
// 0.5 full screen fitting circle
float SpotRadius = amount * 0.75f;
float Spot = smoothstep(SpotRadius, SpotRadius - SpotBlur, length(SpotCoord));
float SigmoidSpot = normalizedSigmoid(Spot, 0.75) * amount;
// increase strength by 100%
SigmoidSpot = SigmoidSpot * 2.0f;
return saturate(SigmoidSpot);
}
// www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
float RoundBox(float2 p, float2 b, float r)
{
return length(max(abs(p) - b + r, 0.0f)) - r;
}
float GetRoundCornerFactor(float2 coord, float amount)
{
float2 SourceArea = 1.0f / SourceRect;
float2 SourceRes = SourceDims * SourceRect;
float2 SourceRatio = float2(1.0f, SourceRes.y / SourceRes.x);
float2 SourceTexelDims = 1.0f / SourceDims;
// base on the default ratio of 4:3
float2 RoundCoordScale = (SourceDims / SourceArea / SourceRatio) * ScreenRatio;
float2 RoundCoord = coord;
// hint: alignment correction
RoundCoord -= SourceTexelDims * SourceArea;
RoundCoord *= SourceTexelDims * SourceArea + 1.0f;
// hint: roundness correction
RoundCoord *= RoundCoordScale;
float radius = amount * 50.0f;
// compute box (base on the default ratio of 4:3)
float box = RoundBox(RoundCoord.xy, (RoundCoordScale * 0.5f), radius);
// // apply blur
// float blurAmount = 1.0f / max(1.0f, amount * 25.0f);
// float blueOffset = 1.0f - pow(blurAmount * 0.5f, 0.5f);
// box *= blurAmount;
// box += blueOffset;
float border = smoothstep(1.0f, 0.5f, box);
return saturate(border);
}
float4 ps_main(PS_INPUT Input) : COLOR float4 ps_main(PS_INPUT Input) : COLOR
{ {
float2 ScreenTexelDims = 1.0f / ScreenDims; float2 ScreenTexelDims = 1.0f / ScreenDims;
float2 SourceTexelDims = 1.0f / SourceDims;
float2 SourceArea = 1.0f / SourceRect;
float2 HalfSourceRect = SourceRect * 0.5f;
// Screen Curvature
float2 CurvatureUnitCoord =
Input.TexCoord
* SourceArea * 2.0f -
1.0f;
float2 CurvatureCurve =
CurvatureUnitCoord
* pow(length(CurvatureUnitCoord), 2.0f)
/ pow(length(SourceArea), 2.0f)
* CurvatureAmount * 0.25f; // reduced curvature
float2 CurvatureZoom =
1.0f -
SourceArea * 2.0f
/ pow(length(SourceArea), 2.0f)
* CurvatureAmount * 0.25f; // reduced curvature
float2 ScreenCoord = Input.ScreenCoord / ScreenDims; float2 ScreenCoord = Input.ScreenCoord / ScreenDims;
ScreenCoord -= HalfSourceRect;
ScreenCoord *= CurvatureZoom; // zoom
ScreenCoord += HalfSourceRect;
ScreenCoord += CurvatureCurve; // distortion
float2 BaseCoord = Input.TexCoord; float2 BaseCoord = Input.TexCoord;
BaseCoord -= HalfSourceRect;
BaseCoord *= CurvatureZoom; // zoom
BaseCoord += HalfSourceRect;
BaseCoord += CurvatureCurve; // distortion
float2 BaseCoordCentered = Input.TexCoord;
BaseCoordCentered -= HalfSourceRect;
BaseCoordCentered *= CurvatureZoom; // zoom
BaseCoordCentered += CurvatureCurve; // distortion
float2 BaseAreaCoord = BaseCoord;
BaseAreaCoord *= SourceArea;
float2 BaseAreaCoordCentered = BaseCoordCentered;
BaseAreaCoordCentered *= SourceArea;
float2 BaseAreaRatioCoord = BaseAreaCoord;
BaseAreaRatioCoord *= ScreenRatio;
float2 BaseAreaRatioCoordCentered = BaseAreaCoordCentered;
BaseAreaRatioCoordCentered *= ScreenRatio;
// // Alpha Clipping (round corners applies smoother clipping when screen is curved)
// clip((BaseCoord < SourceTexelDims) ? -1 : 1);
// clip((BaseCoord > SourceRect + SourceTexelDims) ? -1 : 1);
// Color
float4 BaseColor = tex2D(DiffuseSampler, BaseCoord); float4 BaseColor = tex2D(DiffuseSampler, BaseCoord);
BaseColor.a = 1.0f; BaseColor.a = 1.0f;
// Vignetting Simulation (may affect bloom)
float2 VignetteCoord = BaseAreaCoordCentered;
float VignetteFactor = GetVignetteFactor(VignetteCoord, VignettingAmount);
BaseColor.rgb *= VignetteFactor;
// Mask Simulation (may not affect bloom) // Mask Simulation (may not affect bloom)
if (!PrepareBloom) if (!PrepareBloom)
{ {
@ -365,40 +204,24 @@ float4 ps_main(PS_INPUT Input) : COLOR
// Scanline Simulation (may not affect bloom) // Scanline Simulation (may not affect bloom)
if (!PrepareBloom) if (!PrepareBloom)
{ {
// todo: there is an offset which can be noticed at lower prescale in high-resolution // Scanline Simulation (disabled for vector)
float2 ScanlinePrescaleOffset = 0.0f; if (!PrepareVector)
{
float InnerSine = BaseCoord.y * ScanlineScale * SourceDims.y;
float ScanJitter = ScanlineOffset * SourceDims.y;
float ScanBrightMod = sin(InnerSine * PI + ScanJitter);
float3 ScanColor = lerp(1.0f, (pow(ScanBrightMod * ScanBrightMod, ScanlineHeight) * ScanlineBrightScale + 1.0f + ScanlineBrightOffset) * 0.5f, ScanlineAlpha);
float InnerSine = BaseCoordCentered.y * ScanlineScale * SourceDims.y; BaseColor.rgb *= ScanColor;
float ScanJitter = ScanlineOffset * SourceDims.y; }
float ScanBrightMod = sin(InnerSine * PI + ScanJitter + ScanlinePrescaleOffset);
float3 ScanColor = lerp(1.0f, (pow(ScanBrightMod * ScanBrightMod, ScanlineHeight) * ScanlineBrightScale + 1.0f + ScanlineBrightOffset) * 0.5f, ScanlineAlpha);
BaseColor.rgb *= ScanColor;
} }
// Output // Output
float4 Output = BaseColor * Input.Color; float4 Output = PrepareVector
? BaseColor * (Input.Color + float4(1.0f, 1.0f, 1.0f, 0.0f))
: BaseColor * Input.Color;
Output.a = 1.0f; Output.a = 1.0f;
// Light Reflection Simulation (may not affect bloom)
if (!PrepareBloom)
{
float3 LightColor = float3(1.0f, 0.90f, 0.80f);
float2 SpotCoord = BaseAreaRatioCoordCentered;
float2 NoiseCoord = BaseAreaRatioCoordCentered;
float SpotAddend = GetSpotAddend(SpotCoord, ReflectionAmount);
float NoiseFactor = GetNoiseFactor(SpotAddend, random(NoiseCoord));
Output.rgb += SpotAddend * NoiseFactor * LightColor;
}
// Round Corners Simulation (may affect bloom)
float2 RoundCornerCoord = BaseAreaCoordCentered;
float roundCornerFactor = GetRoundCornerFactor(RoundCornerCoord, RoundCornerAmount);
Output.rgb *= roundCornerFactor;
return Output; return Output;
} }
@ -412,7 +235,7 @@ technique ScanMaskTechnique
{ {
Lighting = FALSE; Lighting = FALSE;
//Sampler[0] = <DiffuseSampler>; Sampler[0] = <DiffuseSampler>;
VertexShader = compile vs_3_0 vs_main(); VertexShader = compile vs_3_0 vs_main();
PixelShader = compile ps_3_0 ps_main(); PixelShader = compile ps_3_0 ps_main();

View File

@ -33,7 +33,6 @@ struct VS_INPUT
float3 Position : POSITION; float3 Position : POSITION;
float4 Color : COLOR0; float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0; float2 TexCoord : TEXCOORD0;
float2 Unused : TEXCOORD1;
}; };
struct PS_INPUT struct PS_INPUT
@ -46,9 +45,13 @@ struct PS_INPUT
// Simple Vertex Shader // Simple Vertex Shader
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static const float Epsilon = 1.0e-7f;
uniform float2 ScreenDims; uniform float2 ScreenDims;
uniform float PostPass; uniform float2 TargetDims;
uniform float FixedAlpha;
uniform bool PostPass;
uniform float Brighten; uniform float Brighten;
VS_OUTPUT vs_main(VS_INPUT Input) VS_OUTPUT vs_main(VS_INPUT Input)
@ -57,11 +60,20 @@ VS_OUTPUT vs_main(VS_INPUT Input)
Output.Position = float4(Input.Position.xyz, 1.0f); Output.Position = float4(Input.Position.xyz, 1.0f);
Output.Position.xy /= ScreenDims; Output.Position.xy /= ScreenDims;
Output.Position.y = 1.0f - Output.Position.y; Output.Position.y = 1.0f - Output.Position.y; // flip y
Output.Position.xy -= 0.5f; Output.Position.xy -= 0.5f; // center
Output.Position *= float4(2.0f, 2.0f, 1.0f, 1.0f); Output.Position.xy *= 2.0f; // zoom
float2 targetDims = TargetDims + Epsilon; // bug: with exact target dimensions the font disappears
Output.TexCoord = PostPass
? Input.Position.xy / ScreenDims
: Input.TexCoord;
Output.TexCoord += PostPass
? 0.5f / targetDims // half texel offset correction (DX9)
: 0.0f;
Output.Color = Input.Color; Output.Color = Input.Color;
Output.TexCoord = lerp(Input.TexCoord, Input.Position.xy / ScreenDims, PostPass);
return Output; return Output;
} }
@ -73,7 +85,9 @@ VS_OUTPUT vs_main(VS_INPUT Input)
float4 ps_main(PS_INPUT Input) : COLOR float4 ps_main(PS_INPUT Input) : COLOR
{ {
float4 BaseTexel = tex2D(DiffuseSampler, Input.TexCoord); float4 BaseTexel = tex2D(DiffuseSampler, Input.TexCoord);
return BaseTexel * (Input.Color + float4(Brighten, Brighten, Brighten, 0.0f)); BaseTexel *= Input.Color + float4(Brighten, Brighten, Brighten, 0.0f);
return BaseTexel;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -86,7 +100,7 @@ technique TestTechnique
{ {
Lighting = FALSE; Lighting = FALSE;
//Sampler[0] = <DiffuseSampler>; Sampler[0] = <DiffuseSampler>;
VertexShader = compile vs_2_0 vs_main(); VertexShader = compile vs_2_0 vs_main();
PixelShader = compile ps_2_0 ps_main(); PixelShader = compile ps_2_0 ps_main();

View File

@ -444,16 +444,28 @@ void emu_options::parse_standard_inis(std::string &error_string)
else if (cursystem->flags & MACHINE_TYPE_OTHER) else if (cursystem->flags & MACHINE_TYPE_OTHER)
parse_one_ini("othersys", OPTION_PRIORITY_SYSTYPE_INI, &error_string); parse_one_ini("othersys", OPTION_PRIORITY_SYSTYPE_INI, &error_string);
// parse "vector.ini" for vector games machine_config config(*cursystem, *this);
screen_device_iterator iter(config.root_device());
for (const screen_device *device = iter.first(); device != NULL; device = iter.next())
{ {
machine_config config(*cursystem, *this); // parse "raster.ini" for raster games
screen_device_iterator iter(config.root_device()); if (device->screen_type() == SCREEN_TYPE_RASTER)
for (const screen_device *device = iter.first(); device != NULL; device = iter.next()) {
if (device->screen_type() == SCREEN_TYPE_VECTOR) parse_one_ini("raster", OPTION_PRIORITY_SCREEN_INI, &error_string);
{ break;
parse_one_ini("vector", OPTION_PRIORITY_VECTOR_INI, &error_string); }
break; // parse "vector.ini" for vector games
} if (device->screen_type() == SCREEN_TYPE_VECTOR)
{
parse_one_ini("vector", OPTION_PRIORITY_SCREEN_INI, &error_string);
break;
}
// parse "lcd.ini" for lcd games
if (device->screen_type() == SCREEN_TYPE_LCD)
{
parse_one_ini("lcd", OPTION_PRIORITY_SCREEN_INI, &error_string);
break;
}
} }
// next parse "source/<sourcefile>.ini"; if that doesn't exist, try <sourcefile>.ini // next parse "source/<sourcefile>.ini"; if that doesn't exist, try <sourcefile>.ini

View File

@ -31,7 +31,7 @@ enum
OPTION_PRIORITY_DEBUG_INI, OPTION_PRIORITY_DEBUG_INI,
OPTION_PRIORITY_ORIENTATION_INI, OPTION_PRIORITY_ORIENTATION_INI,
OPTION_PRIORITY_SYSTYPE_INI, OPTION_PRIORITY_SYSTYPE_INI,
OPTION_PRIORITY_VECTOR_INI, OPTION_PRIORITY_SCREEN_INI,
OPTION_PRIORITY_SOURCE_INI, OPTION_PRIORITY_SOURCE_INI,
OPTION_PRIORITY_GPARENT_INI, OPTION_PRIORITY_GPARENT_INI,
OPTION_PRIORITY_PARENT_INI, OPTION_PRIORITY_PARENT_INI,

View File

@ -605,6 +605,7 @@ public:
float max_update_rate() const { return m_max_refresh; } float max_update_rate() const { return m_max_refresh; }
int orientation() const { return m_orientation; } int orientation() const { return m_orientation; }
render_layer_config layer_config() const { return m_layerconfig; } render_layer_config layer_config() const { return m_layerconfig; }
layout_view *current_view() const { return m_curview; }
int view() const { return view_index(*m_curview); } int view() const { return view_index(*m_curview); }
bool hidden() const { return ((m_flags & RENDER_CREATE_HIDDEN) != 0); } bool hidden() const { return ((m_flags & RENDER_CREATE_HIDDEN) != 0); }
bool is_ui_target() const; bool is_ui_target() const;

View File

@ -239,6 +239,8 @@ public:
layout_view *next() const { return m_next; } layout_view *next() const { return m_next; }
item *first_item(item_layer layer) const; item *first_item(item_layer layer) const;
const char *name() const { return m_name.c_str(); } const char *name() const { return m_name.c_str(); }
const render_bounds &bounds() const { return m_bounds; }
const render_bounds &screen_bounds() const { return m_scrbounds; }
const render_screen_list &screens() const { return m_screens; } const render_screen_list &screens() const { return m_screens; }
bool layer_enabled(item_layer layer) const { return m_layenabled[layer]; } bool layer_enabled(item_layer layer) const { return m_layenabled[layer]; }

File diff suppressed because it is too large Load Diff

View File

@ -44,6 +44,8 @@ public:
CU_SCREEN_DIMS = 0, CU_SCREEN_DIMS = 0,
CU_SOURCE_DIMS, CU_SOURCE_DIMS,
CU_SOURCE_RECT, CU_SOURCE_RECT,
CU_TARGET_DIMS,
CU_QUAD_DIMS,
CU_NTSC_CCFREQ, CU_NTSC_CCFREQ,
CU_NTSC_A, CU_NTSC_A,
@ -77,6 +79,7 @@ public:
CU_POST_VIGNETTING, CU_POST_VIGNETTING,
CU_POST_CURVATURE, CU_POST_CURVATURE,
CU_POST_ROUND_CORNER, CU_POST_ROUND_CORNER,
CU_POST_SMOOTH_BORDER,
CU_POST_REFLECTION, CU_POST_REFLECTION,
CU_POST_SHADOW_ALPHA, CU_POST_SHADOW_ALPHA,
CU_POST_SHADOW_COUNT, CU_POST_SHADOW_COUNT,
@ -192,6 +195,7 @@ struct hlsl_options
float shadow_mask_v_offset; float shadow_mask_v_offset;
float curvature; float curvature;
float round_corner; float round_corner;
float smooth_border;
float reflection; float reflection;
float vignetting; float vignetting;
float scanline_alpha; float scanline_alpha;
@ -234,8 +238,8 @@ struct hlsl_options
float vector_length_ratio; float vector_length_ratio;
// Bloom // Bloom
float vector_bloom_scale; float bloom_scale;
float raster_bloom_scale; float bloom_overdrive[3];
float bloom_level0_weight; float bloom_level0_weight;
float bloom_level1_weight; float bloom_level1_weight;
float bloom_level2_weight; float bloom_level2_weight;
@ -314,8 +318,7 @@ public:
}; };
private: private:
void blit(surface *dst, texture *src, surface *new_dst, void blit(surface *dst, bool clear_dst, D3DPRIMITIVETYPE prim_type, UINT32 prim_index, UINT32 prim_count);
D3DPRIMITIVETYPE prim_type, UINT32 prim_index, UINT32 prim_count);
void enumerate_screens(); void enumerate_screens();
void end_avi_recording(); void end_avi_recording();
@ -328,15 +331,20 @@ private:
void remove_cache_target(cache_target *cache); void remove_cache_target(cache_target *cache);
// Shader passes // Shader passes
void ntsc_pass(render_target *rt, vec2f &texsize, vec2f &delta); int ntsc_pass(render_target *rt, int source_index, poly_info *poly, int vertnum);
void color_convolution_pass(render_target *rt, vec2f &texsize, vec2f &sourcedims); int color_convolution_pass(render_target *rt, int source_index, poly_info *poly, int vertnum);
void prescale_pass(render_target *rt, vec2f &texsize, vec2f &sourcedims); int prescale_pass(render_target *rt, int source_index, poly_info *poly, int vertnum);
void deconverge_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec2f &sourcedims); int deconverge_pass(render_target *rt, int source_index, poly_info *poly, int vertnum);
void defocus_pass(render_target *rt, vec2f &texsize); int defocus_pass(render_target *rt, int source_index, poly_info *poly, int vertnum);
void phosphor_pass(render_target *rt, cache_target *ct, vec2f &texsize, bool focus_enable); int phosphor_pass(render_target *rt, cache_target *ct, int source_index, poly_info *poly, int vertnum);
void post_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec2f &sourcedims, poly_info *poly, int vertnum, bool prepare_bloom); int post_pass(render_target *rt, int source_index, poly_info *poly, int vertnum, bool prepare_bloom);
void bloom_pass(render_target *rt, vec2f &texsize, vec2f &delta, poly_info *poly, int vertnum); int downsample_pass(render_target *rt, int source_index, poly_info *poly, int vertnum);
void screen_pass(render_target *rt, vec2f &texsize, vec2f &delta, poly_info *poly, int vertnum); int bloom_pass(render_target *rt, int source_index, poly_info *poly, int vertnum);
int distortion_pass(render_target *rt, int source_index, poly_info *poly, int vertnum);
int vector_pass(render_target *rt, int source_index, poly_info *poly, int vertnum);
int vector_buffer_pass(render_target *rt, int source_index, poly_info *poly, int vertnum);
int screen_pass(render_target *rt, int source_index, poly_info *poly, int vertnum);
void menu_pass(poly_info *poly, int vertnum);
base * d3dintf; // D3D interface base * d3dintf; // D3D interface
@ -358,6 +366,8 @@ private:
int prescale_size_y; // prescale size y int prescale_size_y; // prescale size y
int hlsl_prescale_x; // hlsl prescale x int hlsl_prescale_x; // hlsl prescale x
int hlsl_prescale_y; // hlsl prescale y int hlsl_prescale_y; // hlsl prescale y
float bloom_dims[11][2]; // bloom texture dimensions
int bloom_count; // count of used bloom textures
int preset; // preset, if relevant int preset; // preset, if relevant
bitmap_argb32 shadow_bitmap; // shadow mask bitmap for post-processing shader bitmap_argb32 shadow_bitmap; // shadow mask bitmap for post-processing shader
texture_info * shadow_texture; // shadow mask texture for post-processing shader texture_info * shadow_texture; // shadow mask texture for post-processing shader
@ -395,9 +405,9 @@ private:
surface * backbuffer; // pointer to our device's backbuffer surface * backbuffer; // pointer to our device's backbuffer
effect * curr_effect; // pointer to the currently active effect object effect * curr_effect; // pointer to the currently active effect object
effect * default_effect; // pointer to the primary-effect object effect * default_effect; // pointer to the primary-effect object
effect * simple_effect; // pointer to the simple-effect object
effect * prescale_effect; // pointer to the prescale-effect object effect * prescale_effect; // pointer to the prescale-effect object
effect * post_effect; // pointer to the post-effect object effect * post_effect; // pointer to the post-effect object
effect * distortion_effect; // pointer to the distortion-effect object
effect * focus_effect; // pointer to the focus-effect object effect * focus_effect; // pointer to the focus-effect object
effect * phosphor_effect; // pointer to the phosphor-effect object effect * phosphor_effect; // pointer to the phosphor-effect object
effect * deconverge_effect; // pointer to the deconvergence-effect object effect * deconverge_effect; // pointer to the deconvergence-effect object
@ -410,7 +420,8 @@ private:
vertex * fsfx_vertices; // pointer to our full-screen-quad object vertex * fsfx_vertices; // pointer to our full-screen-quad object
texture_info * curr_texture; texture_info * curr_texture;
bool phosphor_passthrough; render_target * curr_render_target;
poly_info * curr_poly;
public: public:
render_target * targethead; render_target * targethead;

View File

@ -44,7 +44,6 @@
#include "drawd3d.h" #include "drawd3d.h"
//============================================================ //============================================================
// DEBUGGING // DEBUGGING
//============================================================ //============================================================
@ -52,7 +51,6 @@
extern void mtlog_add(const char *event); extern void mtlog_add(const char *event);
//============================================================ //============================================================
// CONSTANTS // CONSTANTS
//============================================================ //============================================================
@ -67,7 +65,6 @@ enum
}; };
//============================================================ //============================================================
// MACROS // MACROS
//============================================================ //============================================================
@ -75,7 +72,6 @@ enum
#define FSWAP(var1, var2) do { float temp = var1; var1 = var2; var2 = temp; } while (0) #define FSWAP(var1, var2) do { float temp = var1; var1 = var2; var2 = temp; } while (0)
//============================================================ //============================================================
// GLOBALS // GLOBALS
//============================================================ //============================================================
@ -95,6 +91,7 @@ static const line_aa_step line_aa_4step[] =
{ 0 } { 0 }
}; };
//============================================================ //============================================================
// INLINES // INLINES
//============================================================ //============================================================
@ -167,12 +164,14 @@ INLINE UINT32 ycc_to_rgb(UINT8 y, UINT8 cb, UINT8 cr)
return rgb_t(0xff, r, g, b); return rgb_t(0xff, r, g, b);
} }
//============================================================ //============================================================
// drawd3d_init // drawd3d_init
//============================================================ //============================================================
static d3d::base * d3dintf; // FIX ME static d3d::base * d3dintf; // FIX ME
//============================================================ //============================================================
// PROTOTYPES // PROTOTYPES
//============================================================ //============================================================
@ -180,6 +179,7 @@ static d3d::base * d3dintf; // FIX ME
// core functions // core functions
static void drawd3d_exit(void); static void drawd3d_exit(void);
//============================================================ //============================================================
// drawd3d_window_init // drawd3d_window_init
//============================================================ //============================================================
@ -196,6 +196,7 @@ int d3d::renderer::create()
return 0; return 0;
} }
//============================================================ //============================================================
// drawd3d_exit // drawd3d_exit
//============================================================ //============================================================
@ -222,7 +223,6 @@ void d3d::renderer::save()
} }
//============================================================ //============================================================
// drawd3d_window_destroy // drawd3d_window_destroy
//============================================================ //============================================================
@ -235,7 +235,6 @@ void d3d::renderer::destroy()
} }
//============================================================ //============================================================
// drawd3d_window_get_primitives // drawd3d_window_get_primitives
//============================================================ //============================================================
@ -253,6 +252,7 @@ render_primitive_list *d3d::renderer::get_primitives()
return &window().target()->get_primitives(); return &window().target()->get_primitives();
} }
//============================================================ //============================================================
// drawnone_create // drawnone_create
//============================================================ //============================================================
@ -283,6 +283,7 @@ int drawd3d_init(running_machine &machine, osd_draw_callbacks *callbacks)
return 0; return 0;
} }
//============================================================ //============================================================
// drawd3d_window_draw // drawd3d_window_draw
//============================================================ //============================================================
@ -314,7 +315,6 @@ void renderer::set_texture(texture_info *texture)
} }
} }
void renderer::set_filter(int filter) void renderer::set_filter(int filter)
{ {
if (filter != m_last_filter) if (filter != m_last_filter)
@ -331,7 +331,6 @@ void renderer::set_filter(int filter)
} }
} }
void renderer::set_wrap(D3DTEXTUREADDRESS wrap) void renderer::set_wrap(D3DTEXTUREADDRESS wrap)
{ {
if (wrap != m_last_wrap) if (wrap != m_last_wrap)
@ -348,7 +347,6 @@ void renderer::set_wrap(D3DTEXTUREADDRESS wrap)
} }
} }
void renderer::set_modmode(DWORD modmode) void renderer::set_modmode(DWORD modmode)
{ {
if (modmode != m_last_modmode) if (modmode != m_last_modmode)
@ -361,7 +359,6 @@ void renderer::set_modmode(DWORD modmode)
} }
} }
void renderer::set_blendmode(int blendmode) void renderer::set_blendmode(int blendmode)
{ {
int blendenable; int blendenable;
@ -409,7 +406,6 @@ void renderer::set_blendmode(int blendmode)
} }
} }
void renderer::reset_render_states() void renderer::reset_render_states()
{ {
// this ensures subsequent calls to the above setters will force-update the data // this ensures subsequent calls to the above setters will force-update the data
@ -422,8 +418,6 @@ void renderer::reset_render_states()
m_last_wrap = (D3DTEXTUREADDRESS)-1; m_last_wrap = (D3DTEXTUREADDRESS)-1;
} }
texture_manager::texture_manager(renderer *d3d) texture_manager::texture_manager(renderer *d3d)
{ {
m_renderer = d3d; m_renderer = d3d;
@ -737,7 +731,7 @@ void renderer::begin_frame()
m_texture_manager->update_textures(); m_texture_manager->update_textures();
// begin the scene // begin the scene
mtlog_add("drawd3d_window_draw: begin_scene"); mtlog_add("drawd3d_window_draw: begin_scene");
result = (*d3dintf->device.begin_scene)(m_device); result = (*d3dintf->device.begin_scene)(m_device);
if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device begin_scene call\n", (int)result); if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device begin_scene call\n", (int)result);
@ -934,7 +928,6 @@ try_again:
} }
//============================================================ //============================================================
// device_create_resources // device_create_resources
//============================================================ //============================================================
@ -1000,7 +993,6 @@ int renderer::device_create_resources()
} }
//============================================================ //============================================================
// device_delete // device_delete
//============================================================ //============================================================
@ -1039,6 +1031,7 @@ void renderer::device_delete()
m_device = NULL; m_device = NULL;
} }
//============================================================ //============================================================
// device_delete_resources // device_delete_resources
//============================================================ //============================================================
@ -1054,7 +1047,6 @@ void renderer::device_delete_resources()
} }
//============================================================ //============================================================
// device_verify_caps // device_verify_caps
//============================================================ //============================================================
@ -1125,7 +1117,6 @@ int renderer::device_verify_caps()
} }
//============================================================ //============================================================
// device_test_cooperative // device_test_cooperative
//============================================================ //============================================================
@ -1174,7 +1165,6 @@ int renderer::device_test_cooperative()
} }
//============================================================ //============================================================
// config_adapter_mode // config_adapter_mode
//============================================================ //============================================================
@ -1250,7 +1240,6 @@ int renderer::config_adapter_mode()
} }
//============================================================ //============================================================
// get_adapter_for_monitor // get_adapter_for_monitor
//============================================================ //============================================================
@ -1277,7 +1266,6 @@ int renderer::get_adapter_for_monitor()
} }
//============================================================ //============================================================
// pick_best_mode // pick_best_mode
//============================================================ //============================================================
@ -1366,7 +1354,6 @@ void renderer::pick_best_mode()
} }
//============================================================ //============================================================
// update_window_size // update_window_size
//============================================================ //============================================================
@ -1401,6 +1388,7 @@ int renderer::update_window_size()
return TRUE; return TRUE;
} }
//============================================================ //============================================================
// batch_vectors // batch_vectors
//============================================================ //============================================================
@ -1554,6 +1542,7 @@ void renderer::batch_vector(const render_primitive *prim, float line_time)
} }
} }
//============================================================ //============================================================
// draw_line // draw_line
//============================================================ //============================================================
@ -1638,7 +1627,6 @@ void renderer::draw_line(const render_primitive *prim)
} }
//============================================================ //============================================================
// draw_quad // draw_quad
//============================================================ //============================================================
@ -1752,6 +1740,7 @@ void poly_info::init(D3DPRIMITIVETYPE type, UINT32 count, UINT32 numverts,
m_prim_height = prim_height; m_prim_height = prim_height;
} }
//============================================================ //============================================================
// primitive_alloc // primitive_alloc
//============================================================ //============================================================
@ -1791,7 +1780,6 @@ vertex *renderer::mesh_alloc(int numverts)
} }
//============================================================ //============================================================
// primitive_flush_pending // primitive_flush_pending
//============================================================ //============================================================
@ -1877,6 +1865,7 @@ void renderer::primitive_flush_pending()
m_numpolys = 0; m_numpolys = 0;
} }
//============================================================ //============================================================
// texture_info destructor // texture_info destructor
//============================================================ //============================================================
@ -1904,6 +1893,7 @@ texture_info::~texture_info()
} }
} }
//============================================================ //============================================================
// texture_info constructor // texture_info constructor
//============================================================ //============================================================
@ -2080,7 +2070,6 @@ error:
} }
//============================================================ //============================================================
// texture_info::compute_size_subroutine // texture_info::compute_size_subroutine
//============================================================ //============================================================
@ -2137,6 +2126,7 @@ void texture_info::compute_size_subroutine(int texwidth, int texheight, int* p_w
*p_height = finalheight; *p_height = finalheight;
} }
//============================================================ //============================================================
// texture_info::compute_size // texture_info::compute_size
//============================================================ //============================================================
@ -2195,7 +2185,6 @@ void texture_info::compute_size(int texwidth, int texheight)
} }
//============================================================ //============================================================
// copyline_palette16 // copyline_palette16
//============================================================ //============================================================
@ -2214,7 +2203,6 @@ INLINE void copyline_palette16(UINT32 *dst, const UINT16 *src, int width, const
} }
//============================================================ //============================================================
// copyline_palettea16 // copyline_palettea16
//============================================================ //============================================================
@ -2233,7 +2221,6 @@ INLINE void copyline_palettea16(UINT32 *dst, const UINT16 *src, int width, const
} }
//============================================================ //============================================================
// copyline_rgb32 // copyline_rgb32
//============================================================ //============================================================
@ -2277,7 +2264,6 @@ INLINE void copyline_rgb32(UINT32 *dst, const UINT32 *src, int width, const rgb_
} }
//============================================================ //============================================================
// copyline_argb32 // copyline_argb32
//============================================================ //============================================================
@ -2321,7 +2307,6 @@ INLINE void copyline_argb32(UINT32 *dst, const UINT32 *src, int width, const rgb
} }
//============================================================ //============================================================
// copyline_yuy16_to_yuy2 // copyline_yuy16_to_yuy2
//============================================================ //============================================================
@ -2387,7 +2372,6 @@ INLINE void copyline_yuy16_to_yuy2(UINT16 *dst, const UINT16 *src, int width, co
} }
//============================================================ //============================================================
// copyline_yuy16_to_uyvy // copyline_yuy16_to_uyvy
//============================================================ //============================================================
@ -2451,7 +2435,6 @@ INLINE void copyline_yuy16_to_uyvy(UINT16 *dst, const UINT16 *src, int width, co
} }
//============================================================ //============================================================
// copyline_yuy16_to_argb // copyline_yuy16_to_argb
//============================================================ //============================================================
@ -2529,7 +2512,6 @@ INLINE void copyline_yuy16_to_argb(UINT32 *dst, const UINT16 *src, int width, co
} }
//============================================================ //============================================================
// texture_set_data // texture_set_data
//============================================================ //============================================================
@ -2612,7 +2594,6 @@ void texture_info::set_data(const render_texinfo *texsource, UINT32 flags)
} }
//============================================================ //============================================================
// texture_info::prescale // texture_info::prescale
//============================================================ //============================================================
@ -2776,26 +2757,30 @@ cache_target::~cache_target()
bool cache_target::init(renderer *d3d, base *d3dintf, int width, int height, int prescale_x, int prescale_y) bool cache_target::init(renderer *d3d, base *d3dintf, int width, int height, int prescale_x, int prescale_y)
{ {
int bloom_size = (width < height) ? width : height;
int bloom_index = 0; int bloom_index = 0;
int bloom_size = (width < height) ? width : height;
int bloom_width = width; int bloom_width = width;
int bloom_height = height; int bloom_height = height;
for (; bloom_size >= 2 && bloom_index < 11; bloom_size >>= 1) for (; bloom_size >= 2 && bloom_index < 11; bloom_size >>= 1)
{ {
bloom_width >>= 1; bloom_width >>= 1;
bloom_height >>= 1; bloom_height >>= 1;
HRESULT result = (*d3dintf->device.create_texture)(d3d->get_device(), bloom_width, bloom_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &bloom_texture[bloom_index]); HRESULT result = (*d3dintf->device.create_texture)(d3d->get_device(), bloom_width, bloom_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &bloom_texture[bloom_index]);
if (result != D3D_OK) if (result != D3D_OK)
{ {
return false; return false;
} }
(*d3dintf->texture.get_surface_level)(bloom_texture[bloom_index], 0, &bloom_target[bloom_index]); (*d3dintf->texture.get_surface_level)(bloom_texture[bloom_index], 0, &bloom_target[bloom_index]);
bloom_index++; bloom_index++;
} }
HRESULT result = (*d3dintf->device.create_texture)(d3d->get_device(), width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &last_texture); HRESULT result = (*d3dintf->device.create_texture)(d3d->get_device(), width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &last_texture);
if (result != D3D_OK) if (result != D3D_OK)
{
return false; return false;
}
(*d3dintf->texture.get_surface_level)(last_texture, 0, &last_target); (*d3dintf->texture.get_surface_level)(last_texture, 0, &last_target);
target_width = width * prescale_x; target_width = width * prescale_x;
@ -2804,6 +2789,7 @@ bool cache_target::init(renderer *d3d, base *d3dintf, int width, int height, int
return true; return true;
} }
//============================================================ //============================================================
// render_target::~render_target // render_target::~render_target
//============================================================ //============================================================
@ -2824,40 +2810,28 @@ render_target::~render_target()
} }
} }
for (int index = 0; index < 5; index++) for (int index = 0; index < 2; index++)
{ {
if (render_texture[index] != NULL) if (native_texture[index] != NULL)
{ {
(*d3dintf->texture.release)(render_texture[index]); (*d3dintf->texture.release)(native_texture[index]);
render_texture[index] = NULL; native_texture[index] = NULL;
} }
if (target[index] != NULL) if (native_target[index] != NULL)
{ {
(*d3dintf->surface.release)(target[index]); (*d3dintf->surface.release)(native_target[index]);
target[index] = NULL; native_target[index] = NULL;
}
if (prescale_texture[index] != NULL)
{
(*d3dintf->texture.release)(prescale_texture[index]);
prescale_texture[index] = NULL;
}
if (prescale_target[index] != NULL)
{
(*d3dintf->surface.release)(prescale_target[index]);
prescale_target[index] = NULL;
} }
}
if (prescaletexture != NULL)
{
(*d3dintf->texture.release)(prescaletexture);
prescaletexture = NULL;
}
if (prescaletarget != NULL)
{
(*d3dintf->surface.release)(prescaletarget);
prescaletarget = NULL;
}
if (smalltexture != NULL)
{
(*d3dintf->texture.release)(smalltexture);
smalltexture = NULL;
}
if (smalltarget != NULL)
{
(*d3dintf->surface.release)(smalltarget);
smalltarget = NULL;
} }
} }
@ -2868,55 +2842,41 @@ render_target::~render_target()
bool render_target::init(renderer *d3d, base *d3dintf, int width, int height, int prescale_x, int prescale_y) bool render_target::init(renderer *d3d, base *d3dintf, int width, int height, int prescale_x, int prescale_y)
{ {
D3DFORMAT format = D3DFMT_A8R8G8B8; HRESULT result;
HRESULT result = (*d3dintf->device.create_texture)(d3d->get_device(), width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &render_texture[0]); for (int index = 0; index < 2; index++)
if (result != D3D_OK) {
return false; result = (*d3dintf->device.create_texture)(d3d->get_device(), width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &native_texture[index]);
(*d3dintf->texture.get_surface_level)(render_texture[0], 0, &target[0]); if (result != D3D_OK)
{
return false;
}
(*d3dintf->texture.get_surface_level)(native_texture[index], 0, &native_target[index]);
result = (*d3dintf->device.create_texture)(d3d->get_device(), width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &render_texture[1]); result = (*d3dintf->device.create_texture)(d3d->get_device(), width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &prescale_texture[index]);
if (result != D3D_OK) if (result != D3D_OK)
return false; {
(*d3dintf->texture.get_surface_level)(render_texture[1], 0, &target[1]); return false;
}
(*d3dintf->texture.get_surface_level)(prescale_texture[index], 0, &prescale_target[index]);
}
result = (*d3dintf->device.create_texture)(d3d->get_device(), width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &render_texture[2]);
if (result != D3D_OK)
return false;
(*d3dintf->texture.get_surface_level)(render_texture[2], 0, &target[2]);
result = (*d3dintf->device.create_texture)(d3d->get_device(), width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &render_texture[3]);
if (result != D3D_OK)
return false;
(*d3dintf->texture.get_surface_level)(render_texture[3], 0, &target[3]);
result = (*d3dintf->device.create_texture)(d3d->get_device(), width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &render_texture[4]);
if (result != D3D_OK)
return false;
(*d3dintf->texture.get_surface_level)(render_texture[4], 0, &target[4]);
result = (*d3dintf->device.create_texture)(d3d->get_device(), width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &smalltexture);
if (result != D3D_OK)
return false;
(*d3dintf->texture.get_surface_level)(smalltexture, 0, &smalltarget);
result = (*d3dintf->device.create_texture)(d3d->get_device(), width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &prescaletexture);
if (result != D3D_OK)
return false;
(*d3dintf->texture.get_surface_level)(prescaletexture, 0, &prescaletarget);
float bloom_size = (d3d->get_width() < d3d->get_height()) ? d3d->get_width() : d3d->get_height();
int bloom_index = 0; int bloom_index = 0;
float bloom_size = (d3d->get_width() < d3d->get_height()) ? d3d->get_width() : d3d->get_height();
float bloom_width = d3d->get_width(); float bloom_width = d3d->get_width();
float bloom_height = d3d->get_height(); float bloom_height = d3d->get_height();
for (; bloom_size >= 2.0f && bloom_index < 11; bloom_size *= 0.5f) for (; bloom_size >= 2.0f && bloom_index < 11; bloom_size *= 0.5f)
{ {
bloom_width *= 0.5f; bloom_width *= 0.5f;
bloom_height *= 0.5f; bloom_height *= 0.5f;
result = (*d3dintf->device.create_texture)(d3d->get_device(), (int)bloom_width, (int)bloom_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &bloom_texture[bloom_index]); result = (*d3dintf->device.create_texture)(d3d->get_device(), (int)bloom_width, (int)bloom_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &bloom_texture[bloom_index]);
if (result != D3D_OK) if (result != D3D_OK)
{
return false; return false;
}
(*d3dintf->texture.get_surface_level)(bloom_texture[bloom_index], 0, &bloom_target[bloom_index]); (*d3dintf->texture.get_surface_level)(bloom_texture[bloom_index], 0, &bloom_target[bloom_index]);
bloom_index++; bloom_index++;
} }

View File

@ -67,6 +67,7 @@ public:
~render_target(); ~render_target();
bool init(renderer *d3d, base *d3dintf, int width, int height, int prescale_x, int prescale_y); bool init(renderer *d3d, base *d3dintf, int width, int height, int prescale_x, int prescale_y);
int next_index(int index) { return ++index > 1 ? 0 : index; }
int target_width; int target_width;
int target_height; int target_height;
@ -80,12 +81,10 @@ public:
int screen_index; int screen_index;
int page_index; int page_index;
surface *prescaletarget; surface *prescale_target[2];
texture *prescaletexture; texture *prescale_texture[2];
surface *smalltarget; surface *native_target[2];
texture *smalltexture; texture *native_texture[2];
surface *target[5];
texture *render_texture[5];
render_target *next; render_target *next;
render_target *prev; render_target *prev;

View File

@ -302,10 +302,11 @@ const options_entry windows_options::s_option_entries[] =
{ WINOPTION_SHADOW_MASK_VSIZE";fs_shadwv(0.0-1.0)", "0.1875", OPTION_FLOAT, "shadow mask texture size in V direction" }, { WINOPTION_SHADOW_MASK_VSIZE";fs_shadwv(0.0-1.0)", "0.1875", OPTION_FLOAT, "shadow mask texture size in V direction" },
{ WINOPTION_SHADOW_MASK_UOFFSET";fs_shadwou(-1.0-1.0)", "0.0", OPTION_FLOAT, "shadow mask texture offset in U direction" }, { WINOPTION_SHADOW_MASK_UOFFSET";fs_shadwou(-1.0-1.0)", "0.0", OPTION_FLOAT, "shadow mask texture offset in U direction" },
{ WINOPTION_SHADOW_MASK_VOFFSET";fs_shadwov(-1.0-1.0)", "0.0", OPTION_FLOAT, "shadow mask texture offset in V direction" }, { WINOPTION_SHADOW_MASK_VOFFSET";fs_shadwov(-1.0-1.0)", "0.0", OPTION_FLOAT, "shadow mask texture offset in V direction" },
{ WINOPTION_CURVATURE";fs_curv(0.0-1.0)", "0.03", OPTION_FLOAT, "screen curvature amount" }, { WINOPTION_CURVATURE";fs_curv(0.0-1.0)", "0.0", OPTION_FLOAT, "screen curvature amount" },
{ WINOPTION_ROUND_CORNER";fs_rndc(0.0-1.0)", "0.03", OPTION_FLOAT, "screen round corner amount" }, { WINOPTION_ROUND_CORNER";fs_rndc(0.0-1.0)", "0.0", OPTION_FLOAT, "screen round corner amount" },
{ WINOPTION_REFLECTION";fs_ref(0.0-1.0)", "0.03", OPTION_FLOAT, "screen reflection amount" }, { WINOPTION_SMOOTH_BORDER";fs_smob(0.0-1.0)", "0.0", OPTION_FLOAT, "screen smooth border amount" },
{ WINOPTION_VIGNETTING";fs_vig(0.0-1.0)", "0.03", OPTION_FLOAT, "image vignetting amount" }, { WINOPTION_REFLECTION";fs_ref(0.0-1.0)", "0.0", OPTION_FLOAT, "screen reflection amount" },
{ WINOPTION_VIGNETTING";fs_vig(0.0-1.0)", "0.0", OPTION_FLOAT, "image vignetting amount" },
/* Beam-related values below this line*/ /* Beam-related values below this line*/
{ WINOPTION_SCANLINE_AMOUNT";fs_scanam(0.0-4.0)", "1.0", OPTION_FLOAT, "overall alpha scaling value for scanlines" }, { WINOPTION_SCANLINE_AMOUNT";fs_scanam(0.0-4.0)", "1.0", OPTION_FLOAT, "overall alpha scaling value for scanlines" },
{ WINOPTION_SCANLINE_SCALE";fs_scansc(0.0-4.0)", "1.0", OPTION_FLOAT, "overall height scaling value for scanlines" }, { WINOPTION_SCANLINE_SCALE";fs_scansc(0.0-4.0)", "1.0", OPTION_FLOAT, "overall height scaling value for scanlines" },
@ -350,8 +351,8 @@ const options_entry windows_options::s_option_entries[] =
{ WINOPTION_VECTOR_LENGTH_RATIO";vecsize", "500.0", OPTION_FLOAT, "Vector fade length (4.0 - vectors fade the most at and above 4 pixels, etc.)" }, { WINOPTION_VECTOR_LENGTH_RATIO";vecsize", "500.0", OPTION_FLOAT, "Vector fade length (4.0 - vectors fade the most at and above 4 pixels, etc.)" },
/* Bloom below this line */ /* Bloom below this line */
{ NULL, NULL, OPTION_HEADER, "BLOOM POST-PROCESSING OPTIONS" }, { NULL, NULL, OPTION_HEADER, "BLOOM POST-PROCESSING OPTIONS" },
{ WINOPTION_VECTOR_BLOOM_SCALE, "0.3", OPTION_FLOAT, "Intensity factor for vector bloom" }, { WINOPTION_BLOOM_SCALE, "0.25", OPTION_FLOAT, "Intensity factor for bloom" },
{ WINOPTION_RASTER_BLOOM_SCALE, "0.225", OPTION_FLOAT, "Intensity factor for raster bloom" }, { WINOPTION_BLOOM_OVERDRIVE, "0.0,0.0,0.0",OPTION_STRING, "Overdrive factor for bloom" },
{ WINOPTION_BLOOM_LEVEL0_WEIGHT, "1.0", OPTION_FLOAT, "Bloom level 0 (full-size target) weight" }, { WINOPTION_BLOOM_LEVEL0_WEIGHT, "1.0", OPTION_FLOAT, "Bloom level 0 (full-size target) weight" },
{ WINOPTION_BLOOM_LEVEL1_WEIGHT, "0.21", OPTION_FLOAT, "Bloom level 1 (half-size target) weight" }, { WINOPTION_BLOOM_LEVEL1_WEIGHT, "0.21", OPTION_FLOAT, "Bloom level 1 (half-size target) weight" },
{ WINOPTION_BLOOM_LEVEL2_WEIGHT, "0.19", OPTION_FLOAT, "Bloom level 2 (quarter-size target) weight" }, { WINOPTION_BLOOM_LEVEL2_WEIGHT, "0.19", OPTION_FLOAT, "Bloom level 2 (quarter-size target) weight" },

View File

@ -48,6 +48,7 @@
#define WINOPTION_REFLECTION "reflection" #define WINOPTION_REFLECTION "reflection"
#define WINOPTION_CURVATURE "curvature" #define WINOPTION_CURVATURE "curvature"
#define WINOPTION_ROUND_CORNER "round_corner" #define WINOPTION_ROUND_CORNER "round_corner"
#define WINOPTION_SMOOTH_BORDER "smooth_border"
#define WINOPTION_VIGNETTING "vignetting" #define WINOPTION_VIGNETTING "vignetting"
#define WINOPTION_SCANLINE_AMOUNT "scanline_alpha" #define WINOPTION_SCANLINE_AMOUNT "scanline_alpha"
#define WINOPTION_SCANLINE_SCALE "scanline_size" #define WINOPTION_SCANLINE_SCALE "scanline_size"
@ -83,9 +84,9 @@
#define WINOPTION_YIQ_PHASE_COUNT "yiq_phase_count" #define WINOPTION_YIQ_PHASE_COUNT "yiq_phase_count"
#define WINOPTION_VECTOR_LENGTH_SCALE "vector_length_scale" #define WINOPTION_VECTOR_LENGTH_SCALE "vector_length_scale"
#define WINOPTION_VECTOR_LENGTH_RATIO "vector_length_ratio" #define WINOPTION_VECTOR_LENGTH_RATIO "vector_length_ratio"
#define WINOPTION_VECTOR_BLOOM_SCALE "vector_bloom_scale"
#define WINOPTION_VECTOR_TIME_PERIOD "vector_time_period" #define WINOPTION_VECTOR_TIME_PERIOD "vector_time_period"
#define WINOPTION_RASTER_BLOOM_SCALE "raster_bloom_scale" #define WINOPTION_BLOOM_SCALE "bloom_scale"
#define WINOPTION_BLOOM_OVERDRIVE "bloom_overdrive"
#define WINOPTION_BLOOM_LEVEL0_WEIGHT "bloom_lvl0_weight" #define WINOPTION_BLOOM_LEVEL0_WEIGHT "bloom_lvl0_weight"
#define WINOPTION_BLOOM_LEVEL1_WEIGHT "bloom_lvl1_weight" #define WINOPTION_BLOOM_LEVEL1_WEIGHT "bloom_lvl1_weight"
#define WINOPTION_BLOOM_LEVEL2_WEIGHT "bloom_lvl2_weight" #define WINOPTION_BLOOM_LEVEL2_WEIGHT "bloom_lvl2_weight"
@ -156,6 +157,7 @@ public:
float screen_reflection() const { return float_value(WINOPTION_REFLECTION); } float screen_reflection() const { return float_value(WINOPTION_REFLECTION); }
float screen_curvature() const { return float_value(WINOPTION_CURVATURE); } float screen_curvature() const { return float_value(WINOPTION_CURVATURE); }
float screen_round_corner() const { return float_value(WINOPTION_ROUND_CORNER); } float screen_round_corner() const { return float_value(WINOPTION_ROUND_CORNER); }
float screen_smooth_border() const { return float_value(WINOPTION_SMOOTH_BORDER); }
float screen_vignetting() const { return float_value(WINOPTION_VIGNETTING); } float screen_vignetting() const { return float_value(WINOPTION_VIGNETTING); }
const char *screen_defocus() const { return value(WINOPTION_DEFOCUS); } const char *screen_defocus() const { return value(WINOPTION_DEFOCUS); }
const char *screen_converge_x() const { return value(WINOPTION_CONVERGE_X); } const char *screen_converge_x() const { return value(WINOPTION_CONVERGE_X); }
@ -179,9 +181,9 @@ public:
int screen_yiq_phase_count() const { return int_value(WINOPTION_YIQ_PHASE_COUNT); } int screen_yiq_phase_count() const { return int_value(WINOPTION_YIQ_PHASE_COUNT); }
float screen_vector_length_scale() const { return float_value(WINOPTION_VECTOR_LENGTH_SCALE); } float screen_vector_length_scale() const { return float_value(WINOPTION_VECTOR_LENGTH_SCALE); }
float screen_vector_length_ratio() const { return float_value(WINOPTION_VECTOR_LENGTH_RATIO); } float screen_vector_length_ratio() const { return float_value(WINOPTION_VECTOR_LENGTH_RATIO); }
float screen_vector_bloom_scale() const { return float_value(WINOPTION_VECTOR_BLOOM_SCALE); }
float screen_vector_time_period() const { return float_value(WINOPTION_VECTOR_TIME_PERIOD); } float screen_vector_time_period() const { return float_value(WINOPTION_VECTOR_TIME_PERIOD); }
float screen_raster_bloom_scale() const { return float_value(WINOPTION_RASTER_BLOOM_SCALE); } float screen_bloom_scale() const { return float_value(WINOPTION_BLOOM_SCALE); }
const char *screen_bloom_overdrive() const { return value(WINOPTION_BLOOM_OVERDRIVE); }
float screen_bloom_lvl0_weight() const { return float_value(WINOPTION_BLOOM_LEVEL0_WEIGHT); } float screen_bloom_lvl0_weight() const { return float_value(WINOPTION_BLOOM_LEVEL0_WEIGHT); }
float screen_bloom_lvl1_weight() const { return float_value(WINOPTION_BLOOM_LEVEL1_WEIGHT); } float screen_bloom_lvl1_weight() const { return float_value(WINOPTION_BLOOM_LEVEL1_WEIGHT); }
float screen_bloom_lvl2_weight() const { return float_value(WINOPTION_BLOOM_LEVEL2_WEIGHT); } float screen_bloom_lvl2_weight() const { return float_value(WINOPTION_BLOOM_LEVEL2_WEIGHT); }