mirror of
https://github.com/hedge-dev/UnleashedRecomp.git
synced 2025-04-28 13:27:58 +03:00
Implement aspect ratio adjustments for inspire overlays. (#201)
* Handle texture/movie overlays for original 4:3. * Implement aspect ratio adjustments for texture/movie overlays. * Fix fade scale for original 4:3.
This commit is contained in:
parent
a9573584cd
commit
76ec5f032d
6 changed files with 143 additions and 7 deletions
|
@ -361,6 +361,7 @@ function(compile_pixel_shader FILE_PATH)
|
|||
compile_shader(${FILE_PATH} ps_6_0)
|
||||
endfunction()
|
||||
|
||||
compile_pixel_shader(blend_color_alpha_ps)
|
||||
compile_vertex_shader(copy_vs)
|
||||
compile_pixel_shader(csd_filter_ps)
|
||||
compile_vertex_shader(csd_no_tex_vs)
|
||||
|
|
41
UnleashedRecomp/gpu/shader/blend_color_alpha_ps.hlsl
Normal file
41
UnleashedRecomp/gpu/shader/blend_color_alpha_ps.hlsl
Normal file
|
@ -0,0 +1,41 @@
|
|||
#include "../../../tools/XenosRecomp/XenosRecomp/shader_common.h"
|
||||
|
||||
#ifdef __spirv__
|
||||
|
||||
#define g_SrcAlpha_DestAlpha vk::RawBufferLoad<float4>(g_PushConstants.PixelShaderConstants + 2400, 0x10)
|
||||
#define s0_Texture2DDescriptorIndex vk::RawBufferLoad<uint>(g_PushConstants.SharedConstants + 0)
|
||||
#define s0_SamplerDescriptorIndex vk::RawBufferLoad<uint>(g_PushConstants.SharedConstants + 192)
|
||||
|
||||
#else
|
||||
|
||||
cbuffer PixelShaderConstants : register(b1, space4)
|
||||
{
|
||||
float4 g_SrcAlpha_DestAlpha : packoffset(c150);
|
||||
};
|
||||
|
||||
cbuffer SharedConstants : register(b2, space4)
|
||||
{
|
||||
uint s0_Texture2DDescriptorIndex : packoffset(c0.x);
|
||||
uint s0_SamplerDescriptorIndex : packoffset(c12.x);
|
||||
DEFINE_SHARED_CONSTANTS();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
float4 main(
|
||||
in float4 iPos : SV_Position,
|
||||
in float4 iTexCoord0 : TEXCOORD0) : SV_Target0
|
||||
{
|
||||
Texture2D<float4> texture = g_Texture2DDescriptorHeap[s0_Texture2DDescriptorIndex];
|
||||
SamplerState samplerState = g_SamplerDescriptorHeap[s0_SamplerDescriptorIndex];
|
||||
|
||||
float4 color = texture.Sample(samplerState, iTexCoord0.xy);
|
||||
|
||||
if (any(or(iTexCoord0.xy < 0.0, iTexCoord0.xy > 1.0)))
|
||||
color = float4(0.0, 0.0, 0.0, 1.0);
|
||||
|
||||
color.rgb *= color.a * g_SrcAlpha_DestAlpha.x;
|
||||
color.a = g_SrcAlpha_DestAlpha.y + (1.0 - color.a) * g_SrcAlpha_DestAlpha.x;
|
||||
|
||||
return color;
|
||||
}
|
|
@ -38,7 +38,7 @@ cbuffer SharedConstants : register(b2, space4)
|
|||
|
||||
#endif
|
||||
|
||||
float4 main(in float4 position : SV_Position, in float2 texCoord : TEXCOORD0) : SV_Target
|
||||
float4 main(in float4 position : SV_Position, in float4 texCoord : TEXCOORD0) : SV_Target
|
||||
{
|
||||
Texture2D<float4> sampColor = g_Texture2DDescriptorHeap[sampColor_Texture2DDescriptorIndex];
|
||||
Texture2D<float4> sampVelocityMap = g_Texture2DDescriptorHeap[sampVelocityMap_Texture2DDescriptorIndex];
|
||||
|
@ -48,19 +48,19 @@ float4 main(in float4 position : SV_Position, in float2 texCoord : TEXCOORD0) :
|
|||
SamplerState sampVelocityMap_s = g_SamplerDescriptorHeap[sampVelocityMap_SamplerDescriptorIndex];
|
||||
SamplerState sampZBuffer_s = g_SamplerDescriptorHeap[sampZBuffer_SamplerDescriptorIndex];
|
||||
|
||||
float depth = sampZBuffer.SampleLevel(sampZBuffer_s, texCoord, 0).x;
|
||||
float4 velocityMap = sampVelocityMap.SampleLevel(sampVelocityMap_s, texCoord, 0);
|
||||
float depth = sampZBuffer.SampleLevel(sampZBuffer_s, texCoord.xy, 0).x;
|
||||
float4 velocityMap = sampVelocityMap.SampleLevel(sampVelocityMap_s, texCoord.xy, 0);
|
||||
float2 velocity = (velocityMap.xz + velocityMap.yw / 255.0) * 2.0 - 1.0;
|
||||
|
||||
int sampleCount = min(64, round(length(velocity * g_ViewportSize.xy)));
|
||||
float2 sampleOffset = velocity / (float) sampleCount;
|
||||
|
||||
float3 color = sampColor.SampleLevel(sampColor_s, texCoord, 0).rgb;
|
||||
float3 color = sampColor.SampleLevel(sampColor_s, texCoord.xy, 0).rgb;
|
||||
int count = 1;
|
||||
|
||||
for (int i = 1; i <= sampleCount; i++)
|
||||
{
|
||||
float2 sampleCoord = texCoord + sampleOffset * i;
|
||||
float2 sampleCoord = texCoord.xy + sampleOffset * i;
|
||||
float3 sampleColor = sampColor.SampleLevel(sampColor_s, sampleCoord, 0).rgb;
|
||||
float sampleDepth = sampZBuffer.SampleLevel(sampZBuffer_s, sampleCoord, 0).x;
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "../../tools/XenosRecomp/XenosRecomp/shader_common.h"
|
||||
|
||||
#ifdef UNLEASHED_RECOMP_D3D12
|
||||
#include "shader/blend_color_alpha_ps.hlsl.dxil.h"
|
||||
#include "shader/copy_vs.hlsl.dxil.h"
|
||||
#include "shader/csd_filter_ps.hlsl.dxil.h"
|
||||
#include "shader/csd_no_tex_vs.hlsl.dxil.h"
|
||||
|
@ -56,6 +57,7 @@
|
|||
#include "shader/resolve_msaa_depth_8x.hlsl.dxil.h"
|
||||
#endif
|
||||
|
||||
#include "shader/blend_color_alpha_ps.hlsl.spirv.h"
|
||||
#include "shader/copy_vs.hlsl.spirv.h"
|
||||
#include "shader/csd_filter_ps.hlsl.spirv.h"
|
||||
#include "shader/csd_no_tex_vs.hlsl.spirv.h"
|
||||
|
@ -4233,7 +4235,9 @@ static GuestShader* CreateShader(const be<uint32_t>* function, ResourceType reso
|
|||
{
|
||||
shader = g_userHeap.AllocPhysical<GuestShader>(resourceType);
|
||||
|
||||
if (hash == 0xB1086A4947A797DE)
|
||||
if (hash == 0x85ED723035ECF535)
|
||||
shader->shader = CREATE_SHADER(blend_color_alpha_ps);
|
||||
else if (hash == 0xB1086A4947A797DE)
|
||||
shader->shader = CREATE_SHADER(csd_no_tex_vs);
|
||||
else if (hash == 0xB4CAFC034A37C8A8)
|
||||
shader->shader = CREATE_SHADER(csd_vs);
|
||||
|
|
|
@ -1195,11 +1195,22 @@ void ViewRingXMidAsmHook(PPCRegister& f1, PPCVRegister& v62)
|
|||
}
|
||||
}
|
||||
|
||||
// SWA::Inspire::CLetterbox::CLetterbox
|
||||
PPC_FUNC_IMPL(__imp__sub_82B8A8F8);
|
||||
PPC_FUNC(sub_82B8A8F8)
|
||||
{
|
||||
// Permanently store the letterbox bool instead of letting the game set it to false from widescreen check.
|
||||
bool letterbox = PPC_LOAD_U8(ctx.r4.u32);
|
||||
__imp__sub_82B8A8F8(ctx, base);
|
||||
PPC_STORE_U8(ctx.r3.u32, letterbox);
|
||||
}
|
||||
|
||||
// SWA::Inspire::CLetterbox::Draw
|
||||
PPC_FUNC_IMPL(__imp__sub_82B8AA40);
|
||||
PPC_FUNC(sub_82B8AA40)
|
||||
{
|
||||
bool shouldDrawLetterbox = Config::CutsceneAspectRatio != ECutsceneAspectRatio::Unlocked && g_aspectRatio < WIDE_ASPECT_RATIO;
|
||||
bool letterbox = PPC_LOAD_U8(ctx.r3.u32);
|
||||
bool shouldDrawLetterbox = letterbox && Config::CutsceneAspectRatio != ECutsceneAspectRatio::Unlocked && g_aspectRatio < WIDE_ASPECT_RATIO;
|
||||
|
||||
PPC_STORE_U8(ctx.r3.u32, shouldDrawLetterbox);
|
||||
if (shouldDrawLetterbox)
|
||||
|
@ -1212,7 +1223,11 @@ PPC_FUNC(sub_82B8AA40)
|
|||
PPC_STORE_U32(ctx.r3.u32 + 0x14, (720 - width * 9 / 16) / 2);
|
||||
}
|
||||
|
||||
auto r3 = ctx.r3;
|
||||
__imp__sub_82B8AA40(ctx, base);
|
||||
|
||||
// Restore the original letterbox value.
|
||||
PPC_STORE_U8(r3.u32, letterbox);
|
||||
}
|
||||
|
||||
void InspireLetterboxTopMidAsmHook(PPCRegister& r3)
|
||||
|
@ -1234,3 +1249,64 @@ void InspireSubtitleMidAsmHook(PPCRegister& r3)
|
|||
|
||||
*reinterpret_cast<be<float>*>(g_memory.base + r3.u32 + 0x3C) = NARROW_OFFSET + (WIDE_OFFSET - NARROW_OFFSET) * g_aspectRatioNarrowScale;
|
||||
}
|
||||
|
||||
enum class FadeTextureMode
|
||||
{
|
||||
Unknown,
|
||||
Letterbox,
|
||||
SideCrop
|
||||
};
|
||||
|
||||
static FadeTextureMode g_fadeTextureMode;
|
||||
|
||||
void FxFadePreRenderQuadMidAsmHook(PPCRegister& r31)
|
||||
{
|
||||
g_fadeTextureMode = *(g_memory.base + r31.u32 + 0x44) ? FadeTextureMode::Letterbox : FadeTextureMode::SideCrop;
|
||||
}
|
||||
|
||||
void FxFadePostRenderQuadMidAsmHook()
|
||||
{
|
||||
g_fadeTextureMode = FadeTextureMode::Unknown;
|
||||
}
|
||||
|
||||
void YggdrasillRenderQuadMidAsmHook(PPCRegister& r3, PPCRegister& r6)
|
||||
{
|
||||
if (g_fadeTextureMode != FadeTextureMode::Unknown)
|
||||
{
|
||||
float scaleX = 1.0f;
|
||||
float scaleY = 1.0f;
|
||||
|
||||
// Fade textures are slightly squashed in the original game at 4:3.
|
||||
if (Config::AspectRatio == EAspectRatio::OriginalNarrow)
|
||||
{
|
||||
if (g_fadeTextureMode == FadeTextureMode::Letterbox)
|
||||
scaleY = NARROW_ASPECT_RATIO;
|
||||
else
|
||||
scaleX = 0.8f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (g_fadeTextureMode == FadeTextureMode::Letterbox && g_aspectRatio < WIDE_ASPECT_RATIO)
|
||||
scaleY = WIDE_ASPECT_RATIO / g_aspectRatio;
|
||||
else
|
||||
scaleX = g_aspectRatio / WIDE_ASPECT_RATIO;
|
||||
}
|
||||
|
||||
struct Vertex
|
||||
{
|
||||
be<float> x;
|
||||
be<float> y;
|
||||
be<float> z;
|
||||
be<float> u;
|
||||
be<float> v;
|
||||
};
|
||||
|
||||
auto vertex = reinterpret_cast<Vertex*>(g_memory.base + r6.u32);
|
||||
|
||||
for (size_t i = 0; i < 6; i++)
|
||||
{
|
||||
vertex[i].u = (vertex[i].u - 0.5f) * scaleX + 0.5f;
|
||||
vertex[i].v = (vertex[i].v - 0.5f) * scaleY + 0.5f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -868,3 +868,17 @@ registers = ["r3", "r4"]
|
|||
name = "LoadingRenderMidAsmHook"
|
||||
address = 0x824DB734
|
||||
jump_address_on_true = 0x824DB738
|
||||
|
||||
[[midasm_hook]]
|
||||
name = "FxFadePreRenderQuadMidAsmHook"
|
||||
address = 0x82BA7D3C
|
||||
registers = ["r31"]
|
||||
|
||||
[[midasm_hook]]
|
||||
name = "FxFadePostRenderQuadMidAsmHook"
|
||||
address = 0x82BA7D40
|
||||
|
||||
[[midasm_hook]]
|
||||
name = "YggdrasillRenderQuadMidAsmHook"
|
||||
address = 0x82E9FBA0
|
||||
registers = ["r3", "r6"]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue