Skip to content

Commit

Permalink
D3D12: Add "UI Invert Alpha" option
Browse files Browse the repository at this point in the history
remove unused shader
  • Loading branch information
praydog committed Jan 26, 2025
1 parent ce1d453 commit 25fd056
Show file tree
Hide file tree
Showing 10 changed files with 511 additions and 6 deletions.
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -874,6 +874,12 @@ set_target_properties(uevr PROPERTIES
"${CMAKE_BINARY_DIR}/lib/${CMKR_TARGET}"
)

add_custom_command(
TARGET uevr PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E echo "Compiling shaders for UEVR..."
COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_SOURCE_DIR}/src/mods/vr/shaders ${CMAKE_SOURCE_DIR}/src/mods/vr/shaders/compile_shaders.bat
)

add_custom_command(
TARGET uevr PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E echo "Generating commit hash..."
Expand Down
6 changes: 6 additions & 0 deletions cmake.toml
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,12 @@ link-libraries = [
"uesdk"
]
cmake-after="""
add_custom_command(
TARGET uevr PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E echo "Compiling shaders for UEVR..."
COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_SOURCE_DIR}/src/mods/vr/shaders ${CMAKE_SOURCE_DIR}/src/mods/vr/shaders/compile_shaders.bat
)
add_custom_command(
TARGET uevr PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E echo "Generating commit hash..."
Expand Down
62 changes: 57 additions & 5 deletions src/mods/vr/D3D12Component.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#include <d3dcompiler.h>

#include <openvr.h>
#include <utility/String.hpp>
#include <utility/ScopeGuard.hpp>
Expand All @@ -9,6 +11,9 @@
#include <../../directxtk12-src/Inc/ResourceUploadBatch.h>
#include <../../directxtk12-src/Inc/RenderTargetState.h>

#include "shaders/Compiled/alpha_luminance_sprite_ps_SpritePixelShader.inc"
#include "shaders/Compiled/alpha_luminance_sprite_ps_SpriteVertexShader.inc"

#include "d3d12/DirectXTK.hpp"

#include "D3D12Component.hpp"
Expand Down Expand Up @@ -66,6 +71,8 @@ vr::EVRCompositorError D3D12Component::on_frame(VR* vr) {
return vr::VRCompositorError_None;
}

const auto ui_should_invert_alpha = vr->get_overlay_component().should_invert_ui_alpha();

// Update the UI overlay.
auto runtime = vr->get_runtime();

Expand Down Expand Up @@ -215,6 +222,10 @@ vr::EVRCompositorError D3D12Component::on_frame(VR* vr) {
const auto is_2d_screen = vr->is_using_2d_screen();

auto draw_2d_view = [&](d3d12::CommandContext& commands) {
if (ui_should_invert_alpha && m_game_ui_tex.texture.Get() != nullptr && m_game_ui_tex.srv_heap != nullptr) {
d3d12::render_srv_to_rtv(m_ui_batch_alpha_invert.get(), commands.cmd_list.Get(), m_game_ui_tex, m_game_ui_tex, std::nullopt, ENGINE_SRC_COLOR, ENGINE_SRC_COLOR);
}

draw_spectator_view(commands.cmd_list.Get(), is_right_eye_frame);

if (is_2d_screen && m_game_tex.texture.Get() != nullptr && m_game_tex.srv_heap != nullptr) {
Expand Down Expand Up @@ -276,7 +287,8 @@ vr::EVRCompositorError D3D12Component::on_frame(VR* vr) {

// Draws the spectator view
auto clear_rt = [&](d3d12::CommandContext& commands) {
commands.clear_rtv(m_game_ui_tex, (float*)&clear_color, ENGINE_SRC_COLOR);
const float ui_clear_color[] = { 0.0f, 0.0f, 0.0f, ui_should_invert_alpha ? 1.0f : 0.0f };
commands.clear_rtv(m_game_ui_tex, (float*)&ui_clear_color, ENGINE_SRC_COLOR);
};

if (runtime->is_openvr() && m_openvr.ui_tex.texture.Get() != nullptr) {
Expand Down Expand Up @@ -629,7 +641,12 @@ vr::EVRCompositorError D3D12Component::on_frame(VR* vr) {
return e;
}

std::unique_ptr<DirectX::DX12::SpriteBatch> D3D12Component::setup_sprite_batch_pso(DXGI_FORMAT output_format) {
std::unique_ptr<DirectX::DX12::SpriteBatch> D3D12Component::setup_sprite_batch_pso(
DXGI_FORMAT output_format,
std::span<const uint8_t> ps,
std::span<const uint8_t> vs,
std::optional<DirectX::SpriteBatchPipelineStateDescription> pd)
{
spdlog::info("[D3D12] Setting up sprite batch PSO");

auto& hook = g_framework->get_d3d12_hook();
Expand All @@ -641,10 +658,19 @@ std::unique_ptr<DirectX::DX12::SpriteBatch> D3D12Component::setup_sprite_batch_p
DirectX::ResourceUploadBatch upload{ device };
upload.Begin();

DirectX::RenderTargetState output_state{output_format, DXGI_FORMAT_UNKNOWN};
DirectX::SpriteBatchPipelineStateDescription pd{output_state};
if (!pd) {
pd = DirectX::SpriteBatchPipelineStateDescription{DirectX::RenderTargetState{output_format, DXGI_FORMAT_UNKNOWN}};
}

auto batch = std::make_unique<DirectX::DX12::SpriteBatch>(device, upload, pd);
if (ps.size() > 0) {
pd->customPixelShader = D3D12_SHADER_BYTECODE{ps.data(), ps.size()};
}

if (vs.size() > 0) {
pd->customVertexShader = D3D12_SHADER_BYTECODE{vs.data(), vs.size()};
}

auto batch = std::make_unique<DirectX::DX12::SpriteBatch>(device, upload, *pd);

auto result = upload.End(command_queue);
result.wait();
Expand Down Expand Up @@ -928,6 +954,7 @@ void D3D12Component::on_reset(VR* vr) {
m_game_tex.reset();
m_backbuffer_batch.reset();
m_game_batch.reset();
m_ui_batch_alpha_invert.reset();
m_graphics_memory.reset();

if (runtime->is_openxr() && runtime->loaded) {
Expand Down Expand Up @@ -1144,6 +1171,31 @@ bool D3D12Component::setup() {
m_backbuffer_batch = setup_sprite_batch_pso(real_backbuffer_desc.Format);
m_game_batch = setup_sprite_batch_pso(backbuffer_desc.Format);

// Custom blend state to flip the alpha in-place of the UI texture without an intermediate render target
{
DirectX::SpriteBatchPipelineStateDescription invert_alpha_in_place_pd{DirectX::RenderTargetState{backbuffer_desc.Format, DXGI_FORMAT_UNKNOWN}};

auto& bd = invert_alpha_in_place_pd.blendDesc;
auto& bdrt = bd.RenderTarget[0];
bdrt.BlendEnable = TRUE;

bdrt.SrcBlend = D3D12_BLEND_ONE;
bdrt.DestBlend = D3D12_BLEND_ZERO;
bdrt.BlendOp = D3D12_BLEND_OP_ADD;

bdrt.SrcBlendAlpha = D3D12_BLEND_ONE;
bdrt.DestBlendAlpha = D3D12_BLEND_ZERO;
bdrt.BlendOpAlpha = D3D12_BLEND_OP_ADD;
bdrt.RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;

m_ui_batch_alpha_invert = setup_sprite_batch_pso(
backbuffer_desc.Format,
alpha_luminance_sprite_ps_SpritePixelShader,
alpha_luminance_sprite_ps_SpriteVertexShader,
invert_alpha_in_place_pd
);
}

spdlog::info("[VR] d3d12 textures have been setup");
m_force_reset = false;

Expand Down
10 changes: 9 additions & 1 deletion src/mods/vr/D3D12Component.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once

#include <span>

#include <d3d12.h>
#include <dxgi.h>
#include <mutex>
Expand Down Expand Up @@ -44,7 +46,12 @@ class D3D12Component {

private:
bool setup();
std::unique_ptr<DirectX::DX12::SpriteBatch> setup_sprite_batch_pso(DXGI_FORMAT output_format);
std::unique_ptr<DirectX::DX12::SpriteBatch> setup_sprite_batch_pso(
DXGI_FORMAT output_format,
std::span<const uint8_t> vs = {}, std::span<const uint8_t> ps = {},
std::optional<DirectX::SpriteBatchPipelineStateDescription> pd = std::nullopt
);

void draw_spectator_view(ID3D12GraphicsCommandList* command_list, bool is_right_eye_frame);
void clear_backbuffer();

Expand All @@ -64,6 +71,7 @@ class D3D12Component {
std::unique_ptr<DirectX::DX12::GraphicsMemory> m_graphics_memory{};
std::unique_ptr<DirectX::DX12::SpriteBatch> m_backbuffer_batch{};
std::unique_ptr<DirectX::DX12::SpriteBatch> m_game_batch{};
std::unique_ptr<DirectX::DX12::SpriteBatch> m_ui_batch_alpha_invert{};

ID3D12Resource* m_last_checked_native{nullptr};

Expand Down
2 changes: 2 additions & 0 deletions src/mods/vr/OverlayComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,8 @@ void OverlayComponent::on_draw_ui() {
m_slate_distance->draw("UI Distance");
m_slate_size->draw("UI Size");
m_ui_follows_view->draw("UI Follows View");
ImGui::SameLine();
m_ui_invert_alpha->draw("UI Invert Alpha");

m_framework_distance->draw("Framework Distance");
m_framework_size->draw("Framework Size");
Expand Down
6 changes: 6 additions & 0 deletions src/mods/vr/OverlayComponent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ class OverlayComponent : public ModComponent {
return m_intersect_state;
}

bool should_invert_ui_alpha() const {
return m_ui_invert_alpha->value();
}

private:
// Cached data for imgui VR overlay so we know when we need to update it
// instead of doing it constantly every frame
Expand Down Expand Up @@ -102,6 +106,7 @@ class OverlayComponent : public ModComponent {
const ModSlider::Ptr m_slate_size{ ModSlider::create("UI_Size", 0.5f, 10.0f, 2.0f) };
const ModSlider::Ptr m_slate_cylinder_angle{ ModSlider::create("UI_Cylinder_Angle", 0.0f, 360.0f, 90.0f) };
const ModToggle::Ptr m_ui_follows_view{ ModToggle::create("UI_FollowView", false) };
const ModToggle::Ptr m_ui_invert_alpha{ ModToggle::create("UI_InvertAlpha", false) };

const ModSlider::Ptr m_framework_distance{ ModSlider::create("UI_Framework_Distance", 0.5f, 10.0f, 1.75f) };
const ModSlider::Ptr m_framework_size{ ModSlider::create("UI_Framework_Size", 0.5f, 10.0f, 2.0f) };
Expand All @@ -121,6 +126,7 @@ class OverlayComponent : public ModComponent {
*m_slate_size,
*m_slate_cylinder_angle,
*m_ui_follows_view,
*m_ui_invert_alpha,
*m_framework_distance,
*m_framework_size,
*m_framework_ui_follows_view,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#if 0
//
// Generated by Microsoft (R) D3D Shader Disassembler
//
//
// Input signature:
//
// Name Index Mask Register SysValue Format Used
// -------------------- ----- ------ -------- -------- ------- ------
// COLOR 0 xyzw 0 NONE float xyzw
// TEXCOORD 0 xy 1 NONE float xy
//
//
// Output signature:
//
// Name Index Mask Register SysValue Format Used
// -------------------- ----- ------ -------- -------- ------- ------
// SV_Target 0 xyzw 0 TARGET float xyzw
//
ps_5_0
dcl_globalFlags refactoringAllowed
dcl_sampler s0, mode_default
dcl_resource_texture2d (float,float,float,float) t0
dcl_input_ps linear v0.xyzw
dcl_input_ps linear v1.xy
dcl_output o0.xyzw
dcl_temps 1
sample_indexable(texture2d)(float,float,float,float) r0.xyzw, v1.xyxx, t0.xyzw, s0
mad r0.xyzw, r0.xyzw, l(1.000000, 1.000000, 1.000000, -1.000000), l(0.000000, 0.000000, 0.000000, 1.000000)
mul o0.xyzw, r0.xyzw, v0.xyzw
ret
// Approximately 0 instruction slots used
#endif

const BYTE alpha_luminance_sprite_ps_SpritePixelShader[] =
{
68, 88, 66, 67, 132, 97,
102, 125, 147, 134, 128, 67,
189, 46, 21, 225, 135, 134,
209, 134, 1, 0, 0, 0,
48, 2, 0, 0, 4, 0,
0, 0, 48, 0, 0, 0,
128, 0, 0, 0, 180, 0,
0, 0, 152, 1, 0, 0,
73, 83, 71, 78, 72, 0,
0, 0, 2, 0, 0, 0,
8, 0, 0, 0, 56, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 3, 0,
0, 0, 0, 0, 0, 0,
15, 15, 0, 0, 62, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 3, 0,
0, 0, 1, 0, 0, 0,
3, 3, 0, 0, 67, 79,
76, 79, 82, 0, 84, 69,
88, 67, 79, 79, 82, 68,
0, 171, 79, 83, 71, 78,
44, 0, 0, 0, 1, 0,
0, 0, 8, 0, 0, 0,
32, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
3, 0, 0, 0, 0, 0,
0, 0, 15, 0, 0, 0,
83, 86, 95, 84, 97, 114,
103, 101, 116, 0, 171, 171,
83, 72, 69, 88, 220, 0,
0, 0, 80, 0, 0, 0,
55, 0, 0, 0, 106, 8,
0, 1, 90, 0, 0, 3,
0, 96, 16, 0, 0, 0,
0, 0, 88, 24, 0, 4,
0, 112, 16, 0, 0, 0,
0, 0, 85, 85, 0, 0,
98, 16, 0, 3, 242, 16,
16, 0, 0, 0, 0, 0,
98, 16, 0, 3, 50, 16,
16, 0, 1, 0, 0, 0,
101, 0, 0, 3, 242, 32,
16, 0, 0, 0, 0, 0,
104, 0, 0, 2, 1, 0,
0, 0, 69, 0, 0, 139,
194, 0, 0, 128, 67, 85,
21, 0, 242, 0, 16, 0,
0, 0, 0, 0, 70, 16,
16, 0, 1, 0, 0, 0,
70, 126, 16, 0, 0, 0,
0, 0, 0, 96, 16, 0,
0, 0, 0, 0, 50, 0,
0, 15, 242, 0, 16, 0,
0, 0, 0, 0, 70, 14,
16, 0, 0, 0, 0, 0,
2, 64, 0, 0, 0, 0,
128, 63, 0, 0, 128, 63,
0, 0, 128, 63, 0, 0,
128, 191, 2, 64, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 128, 63, 56, 0,
0, 7, 242, 32, 16, 0,
0, 0, 0, 0, 70, 14,
16, 0, 0, 0, 0, 0,
70, 30, 16, 0, 0, 0,
0, 0, 62, 0, 0, 1,
82, 84, 83, 48, 144, 0,
0, 0, 2, 0, 0, 0,
2, 0, 0, 0, 24, 0,
0, 0, 1, 0, 0, 0,
92, 0, 0, 0, 29, 0,
0, 0, 0, 0, 0, 0,
5, 0, 0, 0, 48, 0,
0, 0, 2, 0, 0, 0,
0, 0, 0, 0, 80, 0,
0, 0, 1, 0, 0, 0,
56, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
255, 255, 255, 255, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 21, 0,
0, 0, 3, 0, 0, 0,
3, 0, 0, 0, 3, 0,
0, 0, 0, 0, 0, 0,
16, 0, 0, 0, 4, 0,
0, 0, 2, 0, 0, 0,
0, 0, 0, 0, 255, 255,
127, 127, 0, 0, 0, 0,
0, 0, 0, 0, 5, 0,
0, 0
};
Loading

0 comments on commit 25fd056

Please sign in to comment.