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
// copyright-holders:Ryan Holtz,ImJezze
// copyright-holders:ImJezze
//-----------------------------------------------------------------------------
// Effect File Variables
// Distortion Effect
//-----------------------------------------------------------------------------
texture DiffuseTexture;
@ -21,16 +21,16 @@ sampler DiffuseSampler = sampler_state
// Vertex Definitions
//-----------------------------------------------------------------------------
struct VS_OUTPUT
struct VS_INPUT
{
float4 Position : POSITION;
float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0;
};
struct VS_INPUT
struct VS_OUTPUT
{
float3 Position : POSITION;
float4 Position : POSITION;
float4 Color : COLOR0;
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)
{
@ -57,37 +58,40 @@ VS_OUTPUT vs_main(VS_INPUT Input)
Output.Position.xy -= 0.5f; // center
Output.Position.xy *= 2.0f; // zoom
Output.TexCoord = Input.Position.xy / ScreenDims;
Output.Color = Input.Color;
Output.TexCoord = Input.Position.xy / ScreenDims;
Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9)
return Output;
}
//-----------------------------------------------------------------------------
// Simple Pixel Shader
// Post-Processing Pixel Shader
//-----------------------------------------------------------------------------
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
{
Lighting = FALSE;
Sampler[0] = <DiffuseSampler>;
VertexShader = compile vs_2_0 vs_main();
PixelShader = compile ps_2_0 ps_main();
VertexShader = compile vs_3_0 vs_main();
PixelShader = compile ps_3_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;
};
//-----------------------------------------------------------------------------
// 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
//-----------------------------------------------------------------------------
uniform float2 ScreenDims;
uniform float2 Prescale = float2(8.0f, 8.0f);
uniform float2 TargetDims;
uniform float4 Level01Size;
uniform float4 Level23Size;
@ -186,43 +206,28 @@ uniform float4 Level67Size;
uniform float4 Level89Size;
uniform float2 LevelASize;
uniform bool PrepareVector = false;
VS_OUTPUT vs_main(VS_INPUT Input)
{
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.xy /= ScreenDims;
Output.Position.y = 1.0f - Output.Position.y;
Output.Position.xy -= 0.5f;
Output.Position.xy *= 2.0f;
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;
// Vector graphics is not prescaled it has the size of the screen
if (PrepareVector)
{
Output.TexCoord01 = Input.Position.xyxy / ScreenDims.xyxy + 1.0f / Level01Size;
Output.TexCoord23 = Input.Position.xyxy / ScreenDims.xyxy + 1.0f / Level23Size;
Output.TexCoord45 = Input.Position.xyxy / ScreenDims.xyxy + 1.0f / Level45Size;
Output.TexCoord67 = Input.Position.xyxy / ScreenDims.xyxy + 1.0f / Level67Size;
Output.TexCoord89 = Input.Position.xyxy / ScreenDims.xyxy + 1.0f / Level89Size;
Output.TexCoordA = Input.Position.xy / ScreenDims.xy + 1.0f / 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;
}
float2 TexCoord = Input.Position.xy / ScreenDims;
TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9)
Output.TexCoord01.xy = TexCoord.xy;
Output.TexCoord01.zw = TexCoord.xy + 0.5f / Level01Size.zw;
Output.TexCoord23 = TexCoord.xyxy + 0.5f / Level23Size;
Output.TexCoord45 = TexCoord.xyxy + 0.5f / Level45Size;
Output.TexCoord67 = TexCoord.xyxy + 0.5f / Level67Size;
Output.TexCoord89 = TexCoord.xyxy + 0.5f / Level89Size;
Output.TexCoordA = TexCoord.xy + 0.5f / LevelASize;
return Output;
}
@ -235,6 +240,14 @@ uniform float4 Level0123Weight;
uniform float4 Level4567Weight;
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
{
float3 texel0 = tex2D(DiffuseSampler0, Input.TexCoord01.xy).rgb;
@ -261,23 +274,35 @@ float4 ps_main(PS_INPUT Input) : COLOR
texel9 = texel9 * Level89AWeight.y;
texelA = texelA * Level89AWeight.z;
float4 sum = float4(
texel0 +
texel1 +
texel2 +
texel3 +
float3 bloom = float3(
texel1 +
texel2 +
texel3 +
texel4 +
texel5 +
texel6 +
texel7 +
texel8 +
texel9 +
texelA, 1.0f);
return sum;
texel5 +
texel6 +
texel7 +
texel8 +
texel9 +
texelA);
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

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 TargetSize;
uniform float2 TargetDims;
uniform float2 Prescale = float2(8.0f, 8.0f);
uniform float BloomRescale;
uniform bool PrepareVector = false;
uniform bool PrepareVector;
VS_OUTPUT vs_main(VS_INPUT Input)
{
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.xy /= ScreenDims;
Output.Position.y = 1.0f - Output.Position.y;
Output.Position.xy -= 0.5f;
Output.Position.xy *= 2.0f;
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;
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
if (PrepareVector)
{
Output.TexCoord01.xy = TexCoord + float2(-0.5f, -0.5f) * TargetTexelSize;
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;
}
Output.TexCoord01.xy = TexCoord + float2(-0.5f, -0.5f) * TargetTexelDims;
Output.TexCoord01.zw = TexCoord + float2( 0.5f, -0.5f) * TargetTexelDims;
Output.TexCoord23.xy = TexCoord + float2(-0.5f, 0.5f) * TargetTexelDims;
Output.TexCoord23.zw = TexCoord + float2( 0.5f, 0.5f) * TargetTexelDims;
return Output;
}
@ -102,7 +90,7 @@ float4 ps_main(PS_INPUT Input) : COLOR
float4 texel2 = tex2D(DiffuseSampler, Input.TexCoord23.xy);
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);
}

View File

@ -40,7 +40,6 @@ struct VS_INPUT
float3 Position : POSITION;
float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0;
float2 Unused : TEXCOORD1;
};
struct PS_INPUT
@ -61,12 +60,10 @@ struct PS_INPUT
//-----------------------------------------------------------------------------
uniform float2 ScreenDims;
uniform float2 TargetDims;
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 Coord2Offset = float2( 0.4f, -0.4f);
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.xy /= ScreenDims;
Output.Position.y = 1.0f - Output.Position.y;
Output.Position.xy -= 0.5f;
Output.Position.xy *= 2.0f;
Output.Position.y = 1.0f - Output.Position.y; // flip y
Output.Position.xy -= 0.5f; // center
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;
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.TexCoord2 = TexCoord + Coord2Offset * 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 blurred = (d0.rgb + d1 + d2 + d3 + d4 + d5 + d6 + d7) / 8.0f;
blurred = lerp(d0.rgb, blurred, 1.0f);
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;
float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0;
float2 Unused : TEXCOORD1;
};
struct PS_INPUT
@ -62,25 +61,27 @@ struct PS_INPUT
//-----------------------------------------------------------------------------
uniform float2 ScreenDims;
uniform float2 TargetDims;
uniform float Passthrough;
uniform bool Passthrough;
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;
Output.Position.xy -= 0.5f;
Output.Position *= float4(2.0f, 2.0f, 1.0f, 1.0f);
Output.Color = Input.Color;
Output.TexCoord = Input.TexCoord + 0.5f / TargetDims;
Output.Position.y = 1.0f - Output.Position.y; // flip y
Output.Position.xy -= 0.5f; // center
Output.Position.xy *= 2.0f; // zoom
Output.TexCoord = Input.TexCoord;
Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9)
Output.PrevCoord = Output.TexCoord;
Output.Color = Input.Color;
return Output;
}
@ -94,12 +95,14 @@ float4 ps_main(PS_INPUT Input) : COLOR
{
float4 CurrPix = tex2D(DiffuseSampler, Input.TexCoord);
float3 PrevPix = tex2D(PreviousSampler, Input.PrevCoord).rgb * float3(Phosphor.r, Phosphor.g, Phosphor.b);
float RedMax = max(CurrPix.r, PrevPix.r);
float GreenMax = max(CurrPix.g, PrevPix.g);
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;
};
//-----------------------------------------------------------------------------
// Constants
//-----------------------------------------------------------------------------
static const float PI = 3.1415927f;
//-----------------------------------------------------------------------------
// Functions
//-----------------------------------------------------------------------------
bool xor(bool a, bool 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 ScreenRatio = float2(1.0f, 3.0f / 4.0f);
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 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 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 Output = (VS_OUTPUT)0;
float4 Position = Input.Position;
Position.xy *= (ScreenDims + 1.0f) / ScreenDims;
Position.xy -= 0.5f / ScreenDims;
float2 shadowUVOffset = ShadowUVOffset;
shadowUVOffset = xor(OrientationSwapXY, RotationSwapXY)
? shadowUVOffset.yx
: shadowUVOffset.xy;
// todo: calculate offset
float2 ScreenCoordPrescaleOffset = 0.0f;
ScreenCoordPrescaleOffset += shadowUVOffset;
float2 ScreenCoordOffset = 0.0f;
ScreenCoordOffset += shadowUVOffset;
Output.ScreenCoord = Position.xy;
Output.ScreenCoord += ScreenCoordPrescaleOffset;
Output.ScreenCoord = Input.Position.xy;
Output.ScreenCoord += ScreenCoordOffset;
Output.Position = float4(Position.xyz, 1.0f);
Output.Position = float4(Input.Position.xyz, 1.0f);
Output.Position.xy /= ScreenDims;
Output.Position.y = 1.0f - Output.Position.y; // flip y
Output.Position.xy -= 0.5f; // center
Output.Position.xy *= 2.0f; // zoom
Output.TexCoord = Input.TexCoord;
Output.TexCoord = PrepareVector
? Input.Position.xy / ScreenDims
: Input.TexCoord;
Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9)
Output.Color = Input.Color;
@ -124,11 +130,6 @@ uniform float ScanlineBrightOffset = 1.0f;
uniform float ScanlineOffset = 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 float2 ShadowCount = float2(6.0f, 6.0f);
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 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
{
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;
ScreenCoord -= HalfSourceRect;
ScreenCoord *= CurvatureZoom; // zoom
ScreenCoord += HalfSourceRect;
ScreenCoord += CurvatureCurve; // distortion
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);
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)
if (!PrepareBloom)
{
@ -365,40 +204,24 @@ float4 ps_main(PS_INPUT Input) : COLOR
// Scanline Simulation (may not affect bloom)
if (!PrepareBloom)
{
// todo: there is an offset which can be noticed at lower prescale in high-resolution
float2 ScanlinePrescaleOffset = 0.0f;
// 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);
float InnerSine = BaseCoordCentered.y * ScanlineScale * SourceDims.y;
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;
BaseColor.rgb *= ScanColor;
}
}
// 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;
// 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;
}
@ -412,7 +235,7 @@ technique ScanMaskTechnique
{
Lighting = FALSE;
//Sampler[0] = <DiffuseSampler>;
Sampler[0] = <DiffuseSampler>;
VertexShader = compile vs_3_0 vs_main();
PixelShader = compile ps_3_0 ps_main();

View File

@ -33,7 +33,6 @@ struct VS_INPUT
float3 Position : POSITION;
float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0;
float2 Unused : TEXCOORD1;
};
struct PS_INPUT
@ -46,22 +45,35 @@ struct PS_INPUT
// Simple Vertex Shader
//-----------------------------------------------------------------------------
static const float Epsilon = 1.0e-7f;
uniform float2 ScreenDims;
uniform float PostPass;
uniform float FixedAlpha;
uniform float2 TargetDims;
uniform bool PostPass;
uniform float Brighten;
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;
Output.Position.xy -= 0.5f;
Output.Position *= float4(2.0f, 2.0f, 1.0f, 1.0f);
Output.Position.y = 1.0f - Output.Position.y; // flip y
Output.Position.xy -= 0.5f; // center
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.TexCoord = lerp(Input.TexCoord, Input.Position.xy / ScreenDims, PostPass);
return Output;
}
@ -73,7 +85,9 @@ VS_OUTPUT vs_main(VS_INPUT Input)
float4 ps_main(PS_INPUT Input) : COLOR
{
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;
//Sampler[0] = <DiffuseSampler>;
Sampler[0] = <DiffuseSampler>;
VertexShader = compile vs_2_0 vs_main();
PixelShader = compile ps_2_0 ps_main();

View File

@ -443,17 +443,29 @@ void emu_options::parse_standard_inis(std::string &error_string)
parse_one_ini("computer", OPTION_PRIORITY_SYSTYPE_INI, &error_string);
else if (cursystem->flags & MACHINE_TYPE_OTHER)
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);
screen_device_iterator iter(config.root_device());
for (const screen_device *device = iter.first(); device != NULL; device = iter.next())
if (device->screen_type() == SCREEN_TYPE_VECTOR)
{
parse_one_ini("vector", OPTION_PRIORITY_VECTOR_INI, &error_string);
break;
}
// parse "raster.ini" for raster games
if (device->screen_type() == SCREEN_TYPE_RASTER)
{
parse_one_ini("raster", OPTION_PRIORITY_SCREEN_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

View File

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

View File

@ -605,6 +605,7 @@ public:
float max_update_rate() const { return m_max_refresh; }
int orientation() const { return m_orientation; }
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); }
bool hidden() const { return ((m_flags & RENDER_CREATE_HIDDEN) != 0); }
bool is_ui_target() const;

View File

@ -239,6 +239,8 @@ public:
layout_view *next() const { return m_next; }
item *first_item(item_layer layer) const;
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; }
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_SOURCE_DIMS,
CU_SOURCE_RECT,
CU_TARGET_DIMS,
CU_QUAD_DIMS,
CU_NTSC_CCFREQ,
CU_NTSC_A,
@ -77,6 +79,7 @@ public:
CU_POST_VIGNETTING,
CU_POST_CURVATURE,
CU_POST_ROUND_CORNER,
CU_POST_SMOOTH_BORDER,
CU_POST_REFLECTION,
CU_POST_SHADOW_ALPHA,
CU_POST_SHADOW_COUNT,
@ -192,6 +195,7 @@ struct hlsl_options
float shadow_mask_v_offset;
float curvature;
float round_corner;
float smooth_border;
float reflection;
float vignetting;
float scanline_alpha;
@ -234,8 +238,8 @@ struct hlsl_options
float vector_length_ratio;
// Bloom
float vector_bloom_scale;
float raster_bloom_scale;
float bloom_scale;
float bloom_overdrive[3];
float bloom_level0_weight;
float bloom_level1_weight;
float bloom_level2_weight;
@ -314,8 +318,7 @@ public:
};
private:
void blit(surface *dst, texture *src, surface *new_dst,
D3DPRIMITIVETYPE prim_type, UINT32 prim_index, UINT32 prim_count);
void blit(surface *dst, bool clear_dst, D3DPRIMITIVETYPE prim_type, UINT32 prim_index, UINT32 prim_count);
void enumerate_screens();
void end_avi_recording();
@ -328,15 +331,20 @@ private:
void remove_cache_target(cache_target *cache);
// Shader passes
void ntsc_pass(render_target *rt, vec2f &texsize, vec2f &delta);
void color_convolution_pass(render_target *rt, vec2f &texsize, vec2f &sourcedims);
void prescale_pass(render_target *rt, vec2f &texsize, vec2f &sourcedims);
void deconverge_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec2f &sourcedims);
void defocus_pass(render_target *rt, vec2f &texsize);
void phosphor_pass(render_target *rt, cache_target *ct, vec2f &texsize, bool focus_enable);
void post_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec2f &sourcedims, poly_info *poly, int vertnum, bool prepare_bloom);
void bloom_pass(render_target *rt, vec2f &texsize, vec2f &delta, poly_info *poly, int vertnum);
void screen_pass(render_target *rt, vec2f &texsize, vec2f &delta, poly_info *poly, int vertnum);
int ntsc_pass(render_target *rt, int source_index, poly_info *poly, int vertnum);
int color_convolution_pass(render_target *rt, int source_index, poly_info *poly, int vertnum);
int prescale_pass(render_target *rt, int source_index, poly_info *poly, int vertnum);
int deconverge_pass(render_target *rt, int source_index, poly_info *poly, int vertnum);
int defocus_pass(render_target *rt, int source_index, poly_info *poly, int vertnum);
int phosphor_pass(render_target *rt, cache_target *ct, int source_index, poly_info *poly, int vertnum);
int post_pass(render_target *rt, int source_index, poly_info *poly, int vertnum, bool prepare_bloom);
int downsample_pass(render_target *rt, int source_index, 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
@ -358,6 +366,8 @@ private:
int prescale_size_y; // prescale size y
int hlsl_prescale_x; // hlsl prescale x
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
bitmap_argb32 shadow_bitmap; // shadow mask bitmap 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
effect * curr_effect; // pointer to the currently active 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 * 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 * phosphor_effect; // pointer to the phosphor-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
texture_info * curr_texture;
bool phosphor_passthrough;
render_target * curr_render_target;
poly_info * curr_poly;
public:
render_target * targethead;

View File

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

View File

@ -67,6 +67,7 @@ public:
~render_target();
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_height;
@ -80,12 +81,10 @@ public:
int screen_index;
int page_index;
surface *prescaletarget;
texture *prescaletexture;
surface *smalltarget;
texture *smalltexture;
surface *target[5];
texture *render_texture[5];
surface *prescale_target[2];
texture *prescale_texture[2];
surface *native_target[2];
texture *native_texture[2];
render_target *next;
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_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_CURVATURE";fs_curv(0.0-1.0)", "0.03", OPTION_FLOAT, "screen curvature amount" },
{ WINOPTION_ROUND_CORNER";fs_rndc(0.0-1.0)", "0.03", OPTION_FLOAT, "screen round corner amount" },
{ WINOPTION_REFLECTION";fs_ref(0.0-1.0)", "0.03", OPTION_FLOAT, "screen reflection amount" },
{ WINOPTION_VIGNETTING";fs_vig(0.0-1.0)", "0.03", OPTION_FLOAT, "image vignetting 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.0", OPTION_FLOAT, "screen round corner amount" },
{ WINOPTION_SMOOTH_BORDER";fs_smob(0.0-1.0)", "0.0", OPTION_FLOAT, "screen smooth border 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*/
{ 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" },
@ -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.)" },
/* Bloom below this line */
{ NULL, NULL, OPTION_HEADER, "BLOOM POST-PROCESSING OPTIONS" },
{ WINOPTION_VECTOR_BLOOM_SCALE, "0.3", OPTION_FLOAT, "Intensity factor for vector bloom" },
{ WINOPTION_RASTER_BLOOM_SCALE, "0.225", OPTION_FLOAT, "Intensity factor for raster bloom" },
{ WINOPTION_BLOOM_SCALE, "0.25", OPTION_FLOAT, "Intensity factor for 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_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" },

View File

@ -48,6 +48,7 @@
#define WINOPTION_REFLECTION "reflection"
#define WINOPTION_CURVATURE "curvature"
#define WINOPTION_ROUND_CORNER "round_corner"
#define WINOPTION_SMOOTH_BORDER "smooth_border"
#define WINOPTION_VIGNETTING "vignetting"
#define WINOPTION_SCANLINE_AMOUNT "scanline_alpha"
#define WINOPTION_SCANLINE_SCALE "scanline_size"
@ -83,9 +84,9 @@
#define WINOPTION_YIQ_PHASE_COUNT "yiq_phase_count"
#define WINOPTION_VECTOR_LENGTH_SCALE "vector_length_scale"
#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_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_LEVEL1_WEIGHT "bloom_lvl1_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_curvature() const { return float_value(WINOPTION_CURVATURE); }
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); }
const char *screen_defocus() const { return value(WINOPTION_DEFOCUS); }
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); }
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_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_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_lvl1_weight() const { return float_value(WINOPTION_BLOOM_LEVEL1_WEIGHT); }
float screen_bloom_lvl2_weight() const { return float_value(WINOPTION_BLOOM_LEVEL2_WEIGHT); }