mirror of
https://github.com/holub/mame
synced 2025-04-26 18:23:08 +03:00
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:
commit
afbed222b0
@ -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();
|
||||
}
|
||||
}
|
477
hlsl/artwork_support/post.fx
Normal file
477
hlsl/artwork_support/post.fx
Normal 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();
|
||||
}
|
||||
}
|
@ -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,8 +274,7 @@ float4 ps_main(PS_INPUT Input) : COLOR
|
||||
texel9 = texel9 * Level89AWeight.y;
|
||||
texelA = texelA * Level89AWeight.z;
|
||||
|
||||
float4 sum = float4(
|
||||
texel0 +
|
||||
float3 bloom = float3(
|
||||
texel1 +
|
||||
texel2 +
|
||||
texel3 +
|
||||
@ -272,12 +284,25 @@ float4 ps_main(PS_INPUT Input) : COLOR
|
||||
texel7 +
|
||||
texel8 +
|
||||
texel9 +
|
||||
texelA, 1.0f);
|
||||
return sum;
|
||||
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
316
hlsl/distortion.fx
Normal 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();
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
// todo: there is an offset which can be noticed at lower prescale in high-resolution
|
||||
float2 FocusPrescaleOffset = ScreenTexelDims / Prescale;
|
||||
Output.Position.y = 1.0f - Output.Position.y; // flip y
|
||||
Output.Position.xy -= 0.5f; // center
|
||||
Output.Position.xy *= 2.0f; // zoom
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -47,7 +47,6 @@ struct VS_INPUT
|
||||
float3 Position : POSITION;
|
||||
float4 Color : COLOR0;
|
||||
float2 TexCoord : TEXCOORD0;
|
||||
float2 Unused : TEXCOORD1;
|
||||
};
|
||||
|
||||
struct PS_INPUT
|
||||
@ -62,10 +61,9 @@ struct PS_INPUT
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
uniform float2 ScreenDims;
|
||||
|
||||
uniform float2 TargetDims;
|
||||
|
||||
uniform float Passthrough;
|
||||
uniform bool Passthrough;
|
||||
|
||||
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.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.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.TexCoord = Input.TexCoord + 0.5f / TargetDims;
|
||||
Output.PrevCoord = Output.TexCoord;
|
||||
|
||||
Output.Color = Input.Color;
|
||||
|
||||
return Output;
|
||||
}
|
||||
|
||||
@ -99,7 +100,9 @@ float4 ps_main(PS_INPUT Input) : COLOR
|
||||
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);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
245
hlsl/post.fx
245
hlsl/post.fx
@ -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 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) (Gelfond–Schneider 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,39 +204,23 @@ 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;
|
||||
|
||||
float InnerSine = BaseCoordCentered.y * ScanlineScale * SourceDims.y;
|
||||
// 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 + ScanlinePrescaleOffset);
|
||||
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 = 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;
|
||||
// Output
|
||||
float4 Output = PrepareVector
|
||||
? BaseColor * (Input.Color + float4(1.0f, 1.0f, 1.0f, 0.0f))
|
||||
: BaseColor * Input.Color;
|
||||
Output.a = 1.0f;
|
||||
|
||||
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();
|
||||
|
@ -33,7 +33,6 @@ struct VS_INPUT
|
||||
float3 Position : POSITION;
|
||||
float4 Color : COLOR0;
|
||||
float2 TexCoord : TEXCOORD0;
|
||||
float2 Unused : TEXCOORD1;
|
||||
};
|
||||
|
||||
struct PS_INPUT
|
||||
@ -46,9 +45,13 @@ 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)
|
||||
@ -57,11 +60,20 @@ 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 *= 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();
|
||||
|
@ -444,14 +444,26 @@ void emu_options::parse_standard_inis(std::string &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())
|
||||
{
|
||||
// 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_VECTOR_INI, &error_string);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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
@ -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;
|
||||
|
@ -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 (prescaletexture != NULL)
|
||||
if (prescale_texture[index] != NULL)
|
||||
{
|
||||
(*d3dintf->texture.release)(prescaletexture);
|
||||
prescaletexture = NULL;
|
||||
(*d3dintf->texture.release)(prescale_texture[index]);
|
||||
prescale_texture[index] = NULL;
|
||||
}
|
||||
if (prescaletarget != NULL)
|
||||
if (prescale_target[index] != NULL)
|
||||
{
|
||||
(*d3dintf->surface.release)(prescaletarget);
|
||||
prescaletarget = NULL;
|
||||
(*d3dintf->surface.release)(prescale_target[index]);
|
||||
prescale_target[index] = 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]);
|
||||
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)(render_texture[0], 0, &target[0]);
|
||||
}
|
||||
(*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)
|
||||
{
|
||||
return false;
|
||||
(*d3dintf->texture.get_surface_level)(render_texture[1], 0, &target[1]);
|
||||
}
|
||||
(*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++;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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" },
|
||||
|
@ -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); }
|
||||
|
Loading…
Reference in New Issue
Block a user