From 67801e993a054d95a2ecda16a5172ddaa22b46ac Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Fri, 29 Jul 2016 07:38:44 -1000 Subject: [PATCH 1/3] Initial space warp filter --- Editor/ViewManager.cpp | 22 +-- Editor/ViewManager.hpp | 2 +- Runtime/Graphics/CBooRenderer.cpp | 57 +++----- Runtime/Graphics/CBooRenderer.hpp | 9 +- Runtime/Graphics/CGraphics.cpp | 4 + Runtime/Graphics/CMakeLists.txt | 1 + Runtime/Graphics/IRenderer.hpp | 4 +- Runtime/Graphics/Shaders/CSpaceWarpFilter.cpp | 133 ++++++++++++++++++ Runtime/Graphics/Shaders/CSpaceWarpFilter.hpp | 47 +++++++ .../Graphics/Shaders/CSpaceWarpFilterGLSL.cpp | 120 ++++++++++++++++ .../Graphics/Shaders/CSpaceWarpFilterHLSL.cpp | 0 .../Shaders/CSpaceWarpFilterMetal.cpp | 0 .../Graphics/Shaders/CThermalColdFilter.cpp | 27 ++-- .../Graphics/Shaders/CThermalColdFilter.hpp | 2 +- Runtime/MP1/MP1.cpp | 3 + 15 files changed, 350 insertions(+), 81 deletions(-) create mode 100644 Runtime/Graphics/Shaders/CSpaceWarpFilter.cpp create mode 100644 Runtime/Graphics/Shaders/CSpaceWarpFilter.hpp create mode 100644 Runtime/Graphics/Shaders/CSpaceWarpFilterGLSL.cpp create mode 100644 Runtime/Graphics/Shaders/CSpaceWarpFilterHLSL.cpp create mode 100644 Runtime/Graphics/Shaders/CSpaceWarpFilterMetal.cpp diff --git a/Editor/ViewManager.cpp b/Editor/ViewManager.cpp index 782d2ffea..bafa36b8f 100644 --- a/Editor/ViewManager.cpp +++ b/Editor/ViewManager.cpp @@ -92,26 +92,7 @@ void ViewManager::ParticleView::draw(boo::IGraphicsCommandQueue *gfxQ) m_vm.m_modelTest->GetInstance().ActivateLights(lights); m_vm.m_modelTest->Draw(flags); - zeus::CColor ctrlCol{0.7f, 0.f, 0.3f, 1.f}; - float fac = 0.0f; - zeus::CColor a = zeus::CColor::lerp(ctrlCol, zeus::CColor::skWhite, fac); - m_thermColdFilter.setColorA(a); - float bFac = 0.f; - float bAlpha = 1.f; - if (fac < 0.5f) - { - bAlpha = fac * 2.f; - bFac = (1.f - bAlpha) / 8.f; - } - zeus::CColor b{bFac, bFac, bFac, bAlpha}; - m_thermColdFilter.setColorB(b); - zeus::CColor c = zeus::CColor::lerp(zeus::CColor::skBlack, zeus::CColor::skWhite, fac * 0.75f + 0.25f); - m_thermColdFilter.setColorC(zeus::CColor::skBlack); - - m_thermColdFilter.setScale(std::sin(m_theta) * 0.5f + 0.5f); - - m_thermColdFilter.setShift(m_random.Next() % 32); - //m_thermColdFilter.draw(); + m_spaceWarpFilter.draw(zeus::CVector2f{0.f, 0.f}); } if (m_vm.m_partGen) { @@ -380,6 +361,7 @@ void ViewManager::stop() m_videoVoice.reset(); m_projManager.shutdown(); TShader::Shutdown(); + TShader::Shutdown(); CElementGen::Shutdown(); CMoviePlayer::Shutdown(); CLineRenderer::Shutdown(); diff --git a/Editor/ViewManager.hpp b/Editor/ViewManager.hpp index f1386fef7..ae97368ff 100644 --- a/Editor/ViewManager.hpp +++ b/Editor/ViewManager.hpp @@ -46,7 +46,7 @@ class ViewManager : public specter::IViewManager class ParticleView : public specter::View { ViewManager& m_vm; - CThermalColdFilter m_thermColdFilter; + CSpaceWarpFilter m_spaceWarpFilter; CRandom16 m_random; float m_theta = 0.f; public: diff --git a/Runtime/Graphics/CBooRenderer.cpp b/Runtime/Graphics/CBooRenderer.cpp index c671c4d89..115dde6c7 100644 --- a/Runtime/Graphics/CBooRenderer.cpp +++ b/Runtime/Graphics/CBooRenderer.cpp @@ -9,7 +9,6 @@ #include "CMetroidModelInstance.hpp" #include "World/CAreaOctTree.hpp" -#define MIRROR_RAMP_RES 32 #define FOGVOL_RAMP_RES 256 #define SPHERE_RAMP_RES 32 @@ -245,26 +244,6 @@ void CBooRenderer::HandleUnsortedModel(CAreaListItem* item, CBooModel& model) } } -void CBooRenderer::GenerateMirrorRampTex(boo::IGraphicsDataFactory::Context& ctx) -{ - u8 data[MIRROR_RAMP_RES][MIRROR_RAMP_RES][4] = {}; - float halfRes = MIRROR_RAMP_RES / 2.f; - for (int y=0 ; y bool { - GenerateMirrorRampTex(ctx); GenerateFogVolumeRampTex(ctx); GenerateSphereRampTex(ctx); return true; @@ -534,10 +512,6 @@ void CBooRenderer::SetWorldViewpoint(const zeus::CTransform& xf) xb0_viewPlane.d = xf.basis[1].dot(xf.origin); } -void CBooRenderer::SetPerspectiveFovScalar(float) -{ -} - void CBooRenderer::SetPerspective(float fovy, float width, float height, float znear, float zfar) { CGraphics::SetPerspective(fovy, width / height, znear, zfar); @@ -548,8 +522,16 @@ void CBooRenderer::SetPerspective(float fovy, float aspect, float znear, float z CGraphics::SetPerspective(fovy, aspect, znear, zfar); } -void CBooRenderer::SetViewportOrtho(bool, float, float) +void CBooRenderer::SetViewportOrtho(bool centered, float znear, float zfar) { + float left = centered ? CGraphics::g_ViewportResolutionHalf.x : 0; + float bottom = centered ? CGraphics::g_ViewportResolutionHalf.y : 0; + float top = centered ? CGraphics::g_ViewportResolutionHalf.y : CGraphics::g_ViewportResolution.y; + float right = centered ? CGraphics::g_ViewportResolutionHalf.x : CGraphics::g_ViewportResolution.x; + + CGraphics::SetOrtho(left, right, top, bottom, znear, zfar); + CGraphics::SetViewPointMatrix(zeus::CTransform::Identity()); + CGraphics::SetModelMatrix(zeus::CTransform::Identity()); } void CBooRenderer::SetClippingPlanes(const zeus::CFrustum& frustum) @@ -557,8 +539,10 @@ void CBooRenderer::SetClippingPlanes(const zeus::CFrustum& frustum) x44_frustumPlanes = frustum; } -void CBooRenderer::SetViewport(int, int, int, int) +void CBooRenderer::SetViewport(int l, int b, int w, int h) { + CGraphics::SetViewport(l, b, w, h); + CGraphics::SetScissor(l, b, w, h); } void CBooRenderer::SetDepthReadWrite(bool, bool) @@ -603,10 +587,15 @@ void CBooRenderer::SetDebugOption(EDebugOption, int) void CBooRenderer::BeginScene() { + CGraphics::SetViewport(0, 0, CGraphics::g_ViewportResolution.x, CGraphics::g_ViewportResolution.y); + CGraphics::SetPerspective(75.f, CGraphics::g_ProjAspect, 1.f, 4096.f); + CGraphics::SetModelMatrix(zeus::CTransform::Identity()); + CGraphics::BeginScene(); } void CBooRenderer::EndScene() { + CGraphics::EndScene(); } void CBooRenderer::BeginPrimitive(EPrimitiveType, int) @@ -653,12 +642,9 @@ void CBooRenderer::EndPrimitive() { } -void CBooRenderer::SetAmbientColor(const zeus::CColor&) -{ -} - -void CBooRenderer::SetStaticWorldAmbientColor(const zeus::CColor&) +void CBooRenderer::SetAmbientColor(const zeus::CColor& color) { + CGraphics::SetAmbientColor(color); } void CBooRenderer::DrawString(const char*, int, int) @@ -670,12 +656,9 @@ u32 CBooRenderer::GetFPS() return 0; } -void CBooRenderer::CacheReflection(TReflectionCallback, void*, bool) +void CBooRenderer::DrawSpaceWarp(const zeus::CVector3f& pt, float) { -} -void CBooRenderer::DrawSpaceWarp(const zeus::CVector3f&, float) -{ } void CBooRenderer::DrawThermalModel(const CModel&, const zeus::CColor&, const zeus::CColor&, const float*, const float*) diff --git a/Runtime/Graphics/CBooRenderer.hpp b/Runtime/Graphics/CBooRenderer.hpp index 10ce85430..0c4165ed6 100644 --- a/Runtime/Graphics/CBooRenderer.hpp +++ b/Runtime/Graphics/CBooRenderer.hpp @@ -6,8 +6,10 @@ #include "CDrawable.hpp" #include "CDrawablePlaneObject.hpp" #include "Shaders/CThermalColdFilter.hpp" +#include "Shaders/CSpaceWarpFilter.hpp" #include "CRandom16.hpp" #include "CPVSVisSet.hpp" +#include "zeus/CRectangle.hpp" namespace urde { @@ -85,7 +87,7 @@ class CBooRenderer : public IRenderer bool xee_24_ : 1; boo::ITextureR* x14c_reflectionTex = nullptr; - boo::ITextureS* x150_mirrorRamp = nullptr; + //boo::ITextureS* x150_mirrorRamp = nullptr; boo::ITextureS* x1b8_fogVolumeRamp = nullptr; boo::ITextureS* x220_sphereRamp = nullptr; TLockedToken m_thermoPaletteTex; @@ -119,7 +121,6 @@ class CBooRenderer : public IRenderer u16 dummy = 0; }; - void GenerateMirrorRampTex(boo::IGraphicsDataFactory::Context& ctx); void GenerateFogVolumeRampTex(boo::IGraphicsDataFactory::Context& ctx); void GenerateSphereRampTex(boo::IGraphicsDataFactory::Context& ctx); void LoadThermoPalette(); @@ -147,7 +148,6 @@ public: void AddDrawable(void const *, const zeus::CVector3f&, const zeus::CAABox&, int, EDrawableSorting); void SetDrawableCallback(TDrawableCallback&&, const void*); void SetWorldViewpoint(const zeus::CTransform&); - void SetPerspectiveFovScalar(float); void SetPerspective(float, float, float, float, float); void SetPerspective(float, float, float, float); void SetViewportOrtho(bool, float, float); @@ -177,10 +177,9 @@ public: void PrimColor(const zeus::CColor&); void EndPrimitive(); void SetAmbientColor(const zeus::CColor&); - void SetStaticWorldAmbientColor(const zeus::CColor&); void DrawString(const char*, int, int); u32 GetFPS(); - void CacheReflection(TReflectionCallback, void*, bool); + //void CacheReflection(TReflectionCallback, void*, bool); void DrawSpaceWarp(const zeus::CVector3f&, float); void DrawThermalModel(const CModel&, const zeus::CColor&, const zeus::CColor&, const float*, const float*); void DrawXRayOutline(const CModel&, const float*, const float*); diff --git a/Runtime/Graphics/CGraphics.cpp b/Runtime/Graphics/CGraphics.cpp index f7b93e6e0..f4a45ca59 100644 --- a/Runtime/Graphics/CGraphics.cpp +++ b/Runtime/Graphics/CGraphics.cpp @@ -79,6 +79,10 @@ void CGraphics::SetCullMode(ERglCullMode) { } +void CGraphics::BeginScene() +{ +} + void CGraphics::EndScene() { /* Spinwait until g_NumBreakpointsWaiting is 0 */ diff --git a/Runtime/Graphics/CMakeLists.txt b/Runtime/Graphics/CMakeLists.txt index 9fcaee9c9..ecf470598 100644 --- a/Runtime/Graphics/CMakeLists.txt +++ b/Runtime/Graphics/CMakeLists.txt @@ -31,6 +31,7 @@ set(GRAPHICS_SOURCES Shaders/CXrayOutlineFilter.hpp Shaders/CXrayOutlineFilter.cpp Shaders/CXrayOutlineFilterGLSL.cpp Shaders/CThermalColdFilter.hpp Shaders/CThermalColdFilter.cpp Shaders/CThermalColdFilterGLSL.cpp Shaders/CThermalHotFilter.hpp Shaders/CThermalHotFilter.cpp Shaders/CThermalHotFilterGLSL.cpp + Shaders/CSpaceWarpFilter.hpp Shaders/CSpaceWarpFilter.cpp Shaders/CSpaceWarpFilterGLSL.cpp ${PLAT_SRCS}) runtime_add_list(Graphics GRAPHICS_SOURCES) diff --git a/Runtime/Graphics/IRenderer.hpp b/Runtime/Graphics/IRenderer.hpp index d8a9dad9f..8c41d7337 100644 --- a/Runtime/Graphics/IRenderer.hpp +++ b/Runtime/Graphics/IRenderer.hpp @@ -54,7 +54,6 @@ public: virtual void AddDrawable(void const *, const zeus::CVector3f&, const zeus::CAABox&, int, EDrawableSorting)=0; virtual void SetDrawableCallback(TDrawableCallback&&, const void*)=0; virtual void SetWorldViewpoint(const zeus::CTransform&)=0; - virtual void SetPerspectiveFovScalar(float)=0; virtual void SetPerspective(float, float, float, float, float)=0; virtual void SetPerspective(float, float, float, float)=0; virtual void SetViewportOrtho(bool, float, float)=0; @@ -84,10 +83,9 @@ public: virtual void PrimColor(const zeus::CColor&)=0; virtual void EndPrimitive()=0; virtual void SetAmbientColor(const zeus::CColor&)=0; - virtual void SetStaticWorldAmbientColor(const zeus::CColor&)=0; virtual void DrawString(const char*, int, int)=0; virtual u32 GetFPS()=0; - virtual void CacheReflection(TReflectionCallback, void*, bool)=0; + //virtual void CacheReflection(TReflectionCallback, void*, bool)=0; virtual void DrawSpaceWarp(const zeus::CVector3f&, float)=0; virtual void DrawThermalModel(const CModel&, const zeus::CColor&, const zeus::CColor&, const float*, const float*)=0; virtual void DrawXRayOutline(const CModel&, const float*, const float*)=0; diff --git a/Runtime/Graphics/Shaders/CSpaceWarpFilter.cpp b/Runtime/Graphics/Shaders/CSpaceWarpFilter.cpp new file mode 100644 index 000000000..7ee3e95f1 --- /dev/null +++ b/Runtime/Graphics/Shaders/CSpaceWarpFilter.cpp @@ -0,0 +1,133 @@ +#include "CSpaceWarpFilter.hpp" +#include "Graphics/CGraphics.hpp" +#include "Graphics/CBooRenderer.hpp" + +#define WARP_RAMP_RES 32 + +namespace urde +{ + +void CSpaceWarpFilter::GenerateWarpRampTex(boo::IGraphicsDataFactory::Context& ctx) +{ + u8 data[WARP_RAMP_RES][WARP_RAMP_RES][4] = {}; + float halfRes = WARP_RAMP_RES / 2.f; + for (int y=0 ; ycommitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool + { + GenerateWarpRampTex(ctx); + struct Vert + { + zeus::CVector2f m_pos; + zeus::CVector2f m_uv; + } verts[4] = + { + {{-1.0, -1.0}, {0.0, 0.0}}, + {{-1.0, 1.0}, {0.0, 1.0}}, + {{ 1.0, -1.0}, {1.0, 0.0}}, + {{ 1.0, 1.0}, {1.0, 1.0}}, + }; + m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts, 32, 4); + m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); + m_dataBind = TShader::BuildShaderDataBinding(ctx, *this); + return true; + }); + + setStrength(1.f); +} + +void CSpaceWarpFilter::draw(const zeus::CVector2f& pt) +{ + /* Indirect coords are full-texture sampling when warp is completely in viewport */ + m_uniform.m_indXf[1][1] = 1.f; + m_uniform.m_indXf[0][0] = 1.f; + m_uniform.m_indXf[3][0] = 0.f; + m_uniform.m_indXf[3][1] = 0.f; + + /* Warp effect is fixed at 192x192 rectangle in original (1/2.5 viewport height) */ + m_uniform.m_matrix[1][1] = 1.f / 2.5f; + m_uniform.m_matrix[0][0] = m_uniform.m_matrix[1][1] / CGraphics::g_ProjAspect; + + SClipScreenRect clipRect = {}; + clipRect.x4_left = ((pt[0] - m_uniform.m_matrix[0][0] / 2.f) / 2.f + 0.5f) * CGraphics::g_ViewportResolution.x; + if (clipRect.x4_left >= CGraphics::g_ViewportResolution.x) + return; + clipRect.x8_top = ((pt[1] - m_uniform.m_matrix[1][1] / 2.f) / 2.f + 0.5f) * CGraphics::g_ViewportResolution.y; + if (clipRect.x8_top >= CGraphics::g_ViewportResolution.y) + return; + clipRect.xc_width = CGraphics::g_ViewportResolution.x * m_uniform.m_matrix[1][1]; + if (clipRect.x4_left + clipRect.xc_width <= 0) + return; + clipRect.x10_height = CGraphics::g_ViewportResolution.y * m_uniform.m_matrix[0][0]; + if (clipRect.x8_top + clipRect.x10_height <= 0) + return; + + if (clipRect.x4_left < 0) + { + float old = clipRect.xc_width; + clipRect.xc_width += clipRect.x4_left; + m_uniform.m_indXf[0][0] = clipRect.xc_width / old; + m_uniform.m_indXf[3][0] = -clipRect.x4_left * m_uniform.m_matrix[0][0]; + clipRect.x4_left = 0; + } + if (clipRect.x8_top < 0) + { + float old = clipRect.x10_height; + clipRect.x10_height += clipRect.x8_top; + m_uniform.m_indXf[1][1] = clipRect.x10_height / old; + m_uniform.m_indXf[3][1] = -clipRect.x8_top * m_uniform.m_matrix[1][1]; + clipRect.x8_top = 0; + } + + float tmp = clipRect.x4_left + clipRect.xc_width; + if (tmp >= CGraphics::g_ViewportResolution.x) + { + float old = clipRect.xc_width; + clipRect.xc_width = CGraphics::g_ViewportResolution.x - clipRect.x4_left; + m_uniform.m_indXf[0][0] *= clipRect.xc_width / old; + } + tmp = clipRect.x8_top + clipRect.x10_height; + if (tmp >= CGraphics::g_ViewportResolution.y) + { + float old = clipRect.x10_height; + clipRect.x10_height = CGraphics::g_ViewportResolution.y - clipRect.x8_top; + m_uniform.m_indXf[1][1] *= clipRect.x10_height / old; + } + CGraphics::ResolveSpareTexture(clipRect); + + /* Transform UV coordinates of rectangle within viewport and sampled scene texels (clamped to viewport bounds) */ + zeus::CVector2f vp{CGraphics::g_ViewportResolution.x, CGraphics::g_ViewportResolution.y}; + zeus::CVector2f center(clipRect.x4_left + clipRect.xc_width / 2.f, clipRect.x8_top + clipRect.x10_height / 2.f); + center /= vp; + center *= zeus::CVector2f{2.f, 2.f}; + center -= zeus::CVector2f{1.f, 1.f}; + m_uniform.m_matrix[0][0] = clipRect.xc_width / vp.x; + m_uniform.m_matrix[1][1] = clipRect.x10_height / vp.y; + m_uniform.m_matrix[3][0] = center.x; + m_uniform.m_matrix[3][1] = center.y; + + m_uniBuf->load(&m_uniform, sizeof(m_uniform)); + + CGraphics::g_BooMainCommandQueue->setShaderDataBinding(m_dataBind); + CGraphics::g_BooMainCommandQueue->draw(0, 4); +} + +URDE_SPECIALIZE_SHADER(CSpaceWarpFilter) + +} diff --git a/Runtime/Graphics/Shaders/CSpaceWarpFilter.hpp b/Runtime/Graphics/Shaders/CSpaceWarpFilter.hpp new file mode 100644 index 000000000..ad912e13f --- /dev/null +++ b/Runtime/Graphics/Shaders/CSpaceWarpFilter.hpp @@ -0,0 +1,47 @@ +#ifndef __URDE_CSPACEWARPFILTER_HPP__ +#define __URDE_CSPACEWARPFILTER_HPP__ + +#include "TShader.hpp" +#include "zeus/CMatrix4f.hpp" +#include "zeus/CColor.hpp" + +namespace urde +{ + +class CSpaceWarpFilter +{ + friend struct CSpaceWarpFilterGLDataBindingFactory; + friend struct CSpaceWarpFilterVulkanDataBindingFactory; + + struct Uniform + { + zeus::CMatrix4f m_matrix; + zeus::CMatrix4f m_indXf; + zeus::CVector3f m_strength; + }; + u8 m_shiftTexture[4][8][4] = {}; + boo::GraphicsDataToken m_token; + boo::ITexture* m_warpTex; + boo::IGraphicsBufferS* m_vbo; + boo::IGraphicsBufferD* m_uniBuf; + boo::IShaderDataBinding* m_dataBind = nullptr; + Uniform m_uniform; + + void GenerateWarpRampTex(boo::IGraphicsDataFactory::Context& ctx); + +public: + CSpaceWarpFilter(); + void setStrength(float scale) + { + m_uniform.m_strength[0] = scale; + m_uniform.m_strength[1] = scale; + } + void draw(const zeus::CVector2f& pt); + + using _CLS = CSpaceWarpFilter; +#include "TShaderDecl.hpp" +}; + +} + +#endif // __URDE_CSPACEWARPFILTER_HPP__ diff --git a/Runtime/Graphics/Shaders/CSpaceWarpFilterGLSL.cpp b/Runtime/Graphics/Shaders/CSpaceWarpFilterGLSL.cpp new file mode 100644 index 000000000..f95836d97 --- /dev/null +++ b/Runtime/Graphics/Shaders/CSpaceWarpFilterGLSL.cpp @@ -0,0 +1,120 @@ +#include "CSpaceWarpFilter.hpp" + +namespace urde +{ + +static const char* VS = +"#version 330\n" +BOO_GLSL_BINDING_HEAD +"layout(location=0) in vec4 posIn;\n" +"layout(location=1) in vec4 uvIn;\n" +"\n" +"UBINDING0 uniform SpaceWarpUniform\n" +"{\n" +" mat4 mainMtx;\n" +" mat4 indMtx;\n" +" vec4 strength;\n" +"};\n" +"\n" +"struct VertToFrag\n" +"{\n" +" vec4 strength;\n" +" vec2 sceneUv;\n" +" vec2 indUv;\n" +"};\n" +"\n" +"SBINDING(0) out VertToFrag vtf;\n" +"void main()\n" +"{\n" +" vtf.strength = strength;\n" +" vtf.sceneUv = (mainMtx * uvIn).xy;\n" +" vtf.indUv = (indMtx * uvIn).xy;\n" +" gl_Position = mainMtx * vec4(posIn.xyz, 1.0);\n" +"}\n"; + +static const char* FS = +"#version 330\n" +BOO_GLSL_BINDING_HEAD +"struct VertToFrag\n" +"{\n" +" vec4 strength;\n" +" vec2 sceneUv;\n" +" vec2 indUv;\n" +"};\n" +"\n" +"SBINDING(0) in VertToFrag vtf;\n" +"layout(location=0) out vec4 colorOut;\n" +"TBINDING0 uniform sampler2D sceneTex;\n" +"TBINDING1 uniform sampler2D indTex;\n" +"void main()\n" +"{\n" +" colorOut = texture(sceneTex, vtf.sceneUv + mix(vtf.indUv, texture(indTex, vtf.indUv).xy, vtf.strength.xy) * vec2(2.0) - vec2(1.0));\n" +"}\n"; + +URDE_DECL_SPECIALIZE_SHADER(CSpaceWarpFilter) + +struct CSpaceWarpFilterGLDataBindingFactory : TShader::IDataBindingFactory +{ + boo::IShaderDataBinding* BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, CSpaceWarpFilter& filter) + { + boo::GLDataFactory::Context& cctx = static_cast(ctx); + + const boo::VertexElementDescriptor VtxVmt[] = + { + {filter.m_vbo, nullptr, boo::VertexSemantic::Position4}, + {filter.m_vbo, nullptr, boo::VertexSemantic::UV4} + }; + boo::IGraphicsBuffer* bufs[] = {filter.m_uniBuf}; + boo::PipelineStage stages[] = {boo::PipelineStage::Vertex}; + boo::ITexture* texs[] = {CGraphics::g_SpareTexture, filter.m_warpTex}; + return cctx.newShaderDataBinding(TShader::m_pipeline, + ctx.newVertexFormat(2, VtxVmt), filter.m_vbo, nullptr, nullptr, + 1, bufs, stages, nullptr, nullptr, 2, texs); + } +}; + +#if BOO_HAS_VULKAN +struct CSpaceWarpFilterVulkanDataBindingFactory : TShader::IDataBindingFactory +{ + boo::IShaderDataBinding* BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, CSpaceWarpFilter& filter) + { + boo::VulkanDataFactory::Context& cctx = static_cast(ctx); + + boo::IGraphicsBuffer* bufs[] = {filter.m_uniBuf}; + boo::ITexture* texs[] = {CGraphics::g_SpareTexture, filter.m_warpTex}; + return cctx.newShaderDataBinding(TShader::m_pipeline, + TShader::m_vtxFmt, + filter.m_vbo, nullptr, nullptr, 1, bufs, + nullptr, nullptr, nullptr, 2, texs); + } +}; +#endif + +TShader::IDataBindingFactory* CSpaceWarpFilter::Initialize(boo::GLDataFactory::Context& ctx, + boo::IShaderPipeline*& pipeOut) +{ + const char* texNames[] = {"sceneTex", "indTex"}; + const char* uniNames[] = {"SpaceWarpUniform"}; + pipeOut = ctx.newShaderPipeline(VS, FS, 2, texNames, 1, uniNames, boo::BlendFactor::One, + boo::BlendFactor::Zero, boo::Primitive::TriStrips, false, false, false); + return new CSpaceWarpFilterGLDataBindingFactory; +} + +#if BOO_HAS_VULKAN +TShader::IDataBindingFactory* CSpaceWarpFilter::Initialize(boo::VulkanDataFactory::Context& ctx, + boo::IShaderPipeline*& pipeOut, + boo::IVertexFormat*& vtxFmtOut) +{ + const boo::VertexElementDescriptor VtxVmt[] = + { + {nullptr, nullptr, boo::VertexSemantic::Position4}, + {nullptr, nullptr, boo::VertexSemantic::UV4} + }; + vtxFmtOut = ctx.newVertexFormat(2, VtxVmt); + pipeOut = ctx.newShaderPipeline(VS, FS, vtxFmtOut, boo::BlendFactor::One, + boo::BlendFactor::Zero, boo::Primitive::TriStrips, false, false, false); + return new CSpaceWarpFilterVulkanDataBindingFactory; +} +#endif + +} diff --git a/Runtime/Graphics/Shaders/CSpaceWarpFilterHLSL.cpp b/Runtime/Graphics/Shaders/CSpaceWarpFilterHLSL.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/Runtime/Graphics/Shaders/CSpaceWarpFilterMetal.cpp b/Runtime/Graphics/Shaders/CSpaceWarpFilterMetal.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/Runtime/Graphics/Shaders/CThermalColdFilter.cpp b/Runtime/Graphics/Shaders/CThermalColdFilter.cpp index a9e64f020..2d5139b89 100644 --- a/Runtime/Graphics/Shaders/CThermalColdFilter.cpp +++ b/Runtime/Graphics/Shaders/CThermalColdFilter.cpp @@ -9,25 +9,24 @@ CThermalColdFilter::CThermalColdFilter() m_token = CGraphics::g_BooFactory->commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool { m_shiftTex = ctx.newDynamicTexture(8, 4, boo::TextureFormat::RGBA8); - m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, 32, 4); + + struct Vert + { + zeus::CVector2f m_pos; + zeus::CVector2f m_uv; + } verts[4] = + { + {{-1.0, -1.0}, {0.0, 0.0}}, + {{-1.0, 1.0}, {0.0, 1.0}}, + {{ 1.0, -1.0}, {1.0, 0.0}}, + {{ 1.0, 1.0}, {1.0, 1.0}}, + }; + m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts, 32, 4); m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); m_dataBind = TShader::BuildShaderDataBinding(ctx, *this); return true; }); - struct Vert - { - zeus::CVector2f m_pos; - zeus::CVector2f m_uv; - } verts[4] = - { - {{-1.0, -1.0}, {0.0, 0.0}}, - {{-1.0, 1.0}, {0.0, 1.0}}, - {{ 1.0, -1.0}, {1.0, 0.0}}, - {{ 1.0, 1.0}, {1.0, 1.0}}, - }; - m_vbo->load(verts, sizeof(verts)); - setShift(0); setScale(0.f); } diff --git a/Runtime/Graphics/Shaders/CThermalColdFilter.hpp b/Runtime/Graphics/Shaders/CThermalColdFilter.hpp index d184bed83..117657d6d 100644 --- a/Runtime/Graphics/Shaders/CThermalColdFilter.hpp +++ b/Runtime/Graphics/Shaders/CThermalColdFilter.hpp @@ -23,7 +23,7 @@ class CThermalColdFilter u8 m_shiftTexture[4][8][4] = {}; boo::GraphicsDataToken m_token; boo::ITextureD* m_shiftTex = nullptr; - boo::IGraphicsBufferD* m_vbo; + boo::IGraphicsBufferS* m_vbo; boo::IGraphicsBufferD* m_uniBuf; boo::IShaderDataBinding* m_dataBind = nullptr; Uniform m_uniform; diff --git a/Runtime/MP1/MP1.cpp b/Runtime/MP1/MP1.cpp index e542efd44..571737963 100644 --- a/Runtime/MP1/MP1.cpp +++ b/Runtime/MP1/MP1.cpp @@ -1,10 +1,12 @@ #include "MP1.hpp" #include "Graphics/Shaders/CModelShaders.hpp" #include "Graphics/Shaders/CThermalColdFilter.hpp" +#include "Graphics/Shaders/CSpaceWarpFilter.hpp" namespace urde { URDE_DECL_SPECIALIZE_SHADER(CThermalColdFilter) +URDE_DECL_SPECIALIZE_SHADER(CSpaceWarpFilter) namespace MP1 { @@ -33,6 +35,7 @@ void CMain::InitializeSubsystems(boo::IGraphicsDataFactory* factory, CGraphics::InitializeBoo(factory, cc, renderTex); CModelShaders::Initialize(storeMgr, factory); TShader::Initialize(); + TShader::Initialize(); CMoviePlayer::Initialize(); CLineRenderer::Initialize(); CElementGen::Initialize(); From 4d018ade1283005940a69ff5f99bacf346b93857 Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Fri, 29 Jul 2016 12:22:17 -1000 Subject: [PATCH 2/3] Working CSpaceWarpFilter --- Editor/ViewManager.cpp | 3 +- Runtime/Graphics/CMakeLists.txt | 11 +++- Runtime/Graphics/Shaders/CSpaceWarpFilter.cpp | 66 +++++++++++-------- Runtime/Graphics/Shaders/CSpaceWarpFilter.hpp | 7 +- .../Graphics/Shaders/CSpaceWarpFilterGLSL.cpp | 17 +++-- .../Shaders/CSpaceWarpFilterMetal.cpp | 13 ++++ 6 files changed, 73 insertions(+), 44 deletions(-) diff --git a/Editor/ViewManager.cpp b/Editor/ViewManager.cpp index bafa36b8f..392386f27 100644 --- a/Editor/ViewManager.cpp +++ b/Editor/ViewManager.cpp @@ -92,6 +92,7 @@ void ViewManager::ParticleView::draw(boo::IGraphicsCommandQueue *gfxQ) m_vm.m_modelTest->GetInstance().ActivateLights(lights); m_vm.m_modelTest->Draw(flags); + m_spaceWarpFilter.setStrength(std::sin(m_theta * 5.f) * 0.5f + 0.5f); m_spaceWarpFilter.draw(zeus::CVector2f{0.f, 0.f}); } if (m_vm.m_partGen) @@ -361,7 +362,7 @@ void ViewManager::stop() m_videoVoice.reset(); m_projManager.shutdown(); TShader::Shutdown(); - TShader::Shutdown(); + TShader::Shutdown(); CElementGen::Shutdown(); CMoviePlayer::Shutdown(); CLineRenderer::Shutdown(); diff --git a/Runtime/Graphics/CMakeLists.txt b/Runtime/Graphics/CMakeLists.txt index ecf470598..9555a261d 100644 --- a/Runtime/Graphics/CMakeLists.txt +++ b/Runtime/Graphics/CMakeLists.txt @@ -1,7 +1,14 @@ if(WIN32) - set(PLAT_SRCS Shaders/CLineRendererShadersHLSL.cpp Shaders/CModelShadersHLSL.cpp Shaders/CThermalColdFilterHLSL.cpp) + set(PLAT_SRCS + Shaders/CLineRendererShadersHLSL.cpp + Shaders/CModelShadersHLSL.cpp + Shaders/CThermalColdFilterHLSL.cpp + Shaders/CSpaceWarpFilterHLSL.cpp) elseif(APPLE) - set(PLAT_SRCS Shaders/CLineRendererShadersMetal.cpp Shaders/CModelShadersMetal.cpp Shaders/CThermalColdFilterMetal.cpp) + set(PLAT_SRCS Shaders/CLineRendererShadersMetal.cpp + Shaders/CModelShadersMetal.cpp + Shaders/CThermalColdFilterMetal.cpp + Shaders/CSpaceWarpFilterMetal.cpp) endif() set(GRAPHICS_SOURCES diff --git a/Runtime/Graphics/Shaders/CSpaceWarpFilter.cpp b/Runtime/Graphics/Shaders/CSpaceWarpFilter.cpp index 7ee3e95f1..1157499e5 100644 --- a/Runtime/Graphics/Shaders/CSpaceWarpFilter.cpp +++ b/Runtime/Graphics/Shaders/CSpaceWarpFilter.cpp @@ -16,10 +16,14 @@ void CSpaceWarpFilter::GenerateWarpRampTex(boo::IGraphicsDataFactory::Context& c for (int x=0 ; x::BuildShaderDataBinding(ctx, *this); return true; }); - - setStrength(1.f); } void CSpaceWarpFilter::draw(const zeus::CVector2f& pt) @@ -57,71 +59,77 @@ void CSpaceWarpFilter::draw(const zeus::CVector2f& pt) /* Indirect coords are full-texture sampling when warp is completely in viewport */ m_uniform.m_indXf[1][1] = 1.f; m_uniform.m_indXf[0][0] = 1.f; - m_uniform.m_indXf[3][0] = 0.f; - m_uniform.m_indXf[3][1] = 0.f; + m_uniform.m_indXf[2][0] = 0.f; + m_uniform.m_indXf[2][1] = 0.f; /* Warp effect is fixed at 192x192 rectangle in original (1/2.5 viewport height) */ m_uniform.m_matrix[1][1] = 1.f / 2.5f; m_uniform.m_matrix[0][0] = m_uniform.m_matrix[1][1] / CGraphics::g_ProjAspect; SClipScreenRect clipRect = {}; - clipRect.x4_left = ((pt[0] - m_uniform.m_matrix[0][0] / 2.f) / 2.f + 0.5f) * CGraphics::g_ViewportResolution.x; + clipRect.x4_left = ((pt[0] - m_uniform.m_matrix[0][0]) / 2.f + 0.5f) * CGraphics::g_ViewportResolution.x; if (clipRect.x4_left >= CGraphics::g_ViewportResolution.x) return; - clipRect.x8_top = ((pt[1] - m_uniform.m_matrix[1][1] / 2.f) / 2.f + 0.5f) * CGraphics::g_ViewportResolution.y; + clipRect.x8_top = ((pt[1] - m_uniform.m_matrix[1][1]) / 2.f + 0.5f) * CGraphics::g_ViewportResolution.y; if (clipRect.x8_top >= CGraphics::g_ViewportResolution.y) return; - clipRect.xc_width = CGraphics::g_ViewportResolution.x * m_uniform.m_matrix[1][1]; + clipRect.xc_width = CGraphics::g_ViewportResolution.x * m_uniform.m_matrix[0][0]; if (clipRect.x4_left + clipRect.xc_width <= 0) return; - clipRect.x10_height = CGraphics::g_ViewportResolution.y * m_uniform.m_matrix[0][0]; + clipRect.x10_height = CGraphics::g_ViewportResolution.y * m_uniform.m_matrix[1][1]; if (clipRect.x8_top + clipRect.x10_height <= 0) return; + float oldW = clipRect.xc_width; if (clipRect.x4_left < 0) { - float old = clipRect.xc_width; clipRect.xc_width += clipRect.x4_left; - m_uniform.m_indXf[0][0] = clipRect.xc_width / old; - m_uniform.m_indXf[3][0] = -clipRect.x4_left * m_uniform.m_matrix[0][0]; + m_uniform.m_indXf[0][0] = clipRect.xc_width / oldW; + m_uniform.m_indXf[2][0] = -clipRect.x4_left / oldW; clipRect.x4_left = 0; } + + float oldH = clipRect.x10_height; if (clipRect.x8_top < 0) { - float old = clipRect.x10_height; clipRect.x10_height += clipRect.x8_top; - m_uniform.m_indXf[1][1] = clipRect.x10_height / old; - m_uniform.m_indXf[3][1] = -clipRect.x8_top * m_uniform.m_matrix[1][1]; + m_uniform.m_indXf[1][1] = clipRect.x10_height / oldH; + m_uniform.m_indXf[2][1] = -clipRect.x8_top / oldH; clipRect.x8_top = 0; } float tmp = clipRect.x4_left + clipRect.xc_width; if (tmp >= CGraphics::g_ViewportResolution.x) { - float old = clipRect.xc_width; clipRect.xc_width = CGraphics::g_ViewportResolution.x - clipRect.x4_left; - m_uniform.m_indXf[0][0] *= clipRect.xc_width / old; + m_uniform.m_indXf[0][0] = clipRect.xc_width / oldW; } + tmp = clipRect.x8_top + clipRect.x10_height; if (tmp >= CGraphics::g_ViewportResolution.y) { - float old = clipRect.x10_height; clipRect.x10_height = CGraphics::g_ViewportResolution.y - clipRect.x8_top; - m_uniform.m_indXf[1][1] *= clipRect.x10_height / old; + m_uniform.m_indXf[1][1] = clipRect.x10_height / oldH; } - CGraphics::ResolveSpareTexture(clipRect); + + SClipScreenRect clipRectDummy = {}; + clipRectDummy.xc_width = CGraphics::g_ViewportResolution.x; + clipRectDummy.x10_height = CGraphics::g_ViewportResolution.y; + CGraphics::ResolveSpareTexture(clipRectDummy); /* Transform UV coordinates of rectangle within viewport and sampled scene texels (clamped to viewport bounds) */ zeus::CVector2f vp{CGraphics::g_ViewportResolution.x, CGraphics::g_ViewportResolution.y}; - zeus::CVector2f center(clipRect.x4_left + clipRect.xc_width / 2.f, clipRect.x8_top + clipRect.x10_height / 2.f); - center /= vp; - center *= zeus::CVector2f{2.f, 2.f}; - center -= zeus::CVector2f{1.f, 1.f}; + //zeus::CVector2f center(clipRect.x4_left + clipRect.xc_width / 2.f, clipRect.x8_top + clipRect.x10_height / 2.f); + //center /= vp; + //center *= zeus::CVector2f{2.f, 2.f}; + //center -= zeus::CVector2f{1.f, 1.f}; m_uniform.m_matrix[0][0] = clipRect.xc_width / vp.x; m_uniform.m_matrix[1][1] = clipRect.x10_height / vp.y; - m_uniform.m_matrix[3][0] = center.x; - m_uniform.m_matrix[3][1] = center.y; - + m_uniform.m_matrix[2][0] = pt.x; + m_uniform.m_matrix[2][1] = pt.y; + + m_uniform.m_strength.x = m_uniform.m_matrix[0][0] * m_strength * 0.5f; + m_uniform.m_strength.y = m_uniform.m_matrix[1][1] * m_strength * 0.5f; m_uniBuf->load(&m_uniform, sizeof(m_uniform)); CGraphics::g_BooMainCommandQueue->setShaderDataBinding(m_dataBind); diff --git a/Runtime/Graphics/Shaders/CSpaceWarpFilter.hpp b/Runtime/Graphics/Shaders/CSpaceWarpFilter.hpp index ad912e13f..eaa0d7214 100644 --- a/Runtime/Graphics/Shaders/CSpaceWarpFilter.hpp +++ b/Runtime/Graphics/Shaders/CSpaceWarpFilter.hpp @@ -26,16 +26,13 @@ class CSpaceWarpFilter boo::IGraphicsBufferD* m_uniBuf; boo::IShaderDataBinding* m_dataBind = nullptr; Uniform m_uniform; + float m_strength = 1.f; void GenerateWarpRampTex(boo::IGraphicsDataFactory::Context& ctx); public: CSpaceWarpFilter(); - void setStrength(float scale) - { - m_uniform.m_strength[0] = scale; - m_uniform.m_strength[1] = scale; - } + void setStrength(float strength) { m_strength = strength; } void draw(const zeus::CVector2f& pt); using _CLS = CSpaceWarpFilter; diff --git a/Runtime/Graphics/Shaders/CSpaceWarpFilterGLSL.cpp b/Runtime/Graphics/Shaders/CSpaceWarpFilterGLSL.cpp index f95836d97..13677915d 100644 --- a/Runtime/Graphics/Shaders/CSpaceWarpFilterGLSL.cpp +++ b/Runtime/Graphics/Shaders/CSpaceWarpFilterGLSL.cpp @@ -18,18 +18,18 @@ BOO_GLSL_BINDING_HEAD "\n" "struct VertToFrag\n" "{\n" -" vec4 strength;\n" " vec2 sceneUv;\n" " vec2 indUv;\n" +" vec2 strength;\n" "};\n" "\n" "SBINDING(0) out VertToFrag vtf;\n" "void main()\n" "{\n" -" vtf.strength = strength;\n" -" vtf.sceneUv = (mainMtx * uvIn).xy;\n" -" vtf.indUv = (indMtx * uvIn).xy;\n" -" gl_Position = mainMtx * vec4(posIn.xyz, 1.0);\n" +" gl_Position = vec4(mat3(mainMtx) * vec3(posIn.xy, 1.0), 1.0);\n" +" vtf.sceneUv = gl_Position.xy * vec2(0.5) + vec2(0.5);\n" +" vtf.indUv = (mat3(indMtx) * vec3(uvIn.xy, 1.0)).xy;\n" +" vtf.strength = strength.xy;\n" "}\n"; static const char* FS = @@ -37,9 +37,9 @@ static const char* FS = BOO_GLSL_BINDING_HEAD "struct VertToFrag\n" "{\n" -" vec4 strength;\n" " vec2 sceneUv;\n" " vec2 indUv;\n" +" vec2 strength;\n" "};\n" "\n" "SBINDING(0) in VertToFrag vtf;\n" @@ -48,7 +48,10 @@ BOO_GLSL_BINDING_HEAD "TBINDING1 uniform sampler2D indTex;\n" "void main()\n" "{\n" -" colorOut = texture(sceneTex, vtf.sceneUv + mix(vtf.indUv, texture(indTex, vtf.indUv).xy, vtf.strength.xy) * vec2(2.0) - vec2(1.0));\n" +" colorOut = texture(sceneTex, vtf.sceneUv + (texture(indTex, vtf.indUv).xy * vec2(2.0) - vec2(1.0)) * vtf.strength.xy);\n" +" //colorOut *= vec4(0.00001);\n" +" //colorOut.rg = texture(indTex, vtf.indUv).xy;\n" +" //colorOut.a = 1.0;\n" "}\n"; URDE_DECL_SPECIALIZE_SHADER(CSpaceWarpFilter) diff --git a/Runtime/Graphics/Shaders/CSpaceWarpFilterMetal.cpp b/Runtime/Graphics/Shaders/CSpaceWarpFilterMetal.cpp index e69de29bb..9a4c3cdda 100644 --- a/Runtime/Graphics/Shaders/CSpaceWarpFilterMetal.cpp +++ b/Runtime/Graphics/Shaders/CSpaceWarpFilterMetal.cpp @@ -0,0 +1,13 @@ +#include "CSpaceWarpFilter.hpp" + +namespace urde +{ + +TShader::IDataBindingFactory* CSpaceWarpFilter::Initialize(boo::MetalDataFactory::Context& ctx, + boo::IShaderPipeline*& pipeOut, + boo::IVertexFormat*& vtxFmtOut) +{ + return nullptr; +} + +} From 0a7e36a1fb70b8880e441f8078d0031c1e6198e0 Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Fri, 29 Jul 2016 12:57:48 -1000 Subject: [PATCH 3/3] Space warp pixel-accuracy fixes --- Editor/ViewManager.cpp | 1 + Runtime/Graphics/Shaders/CSpaceWarpFilter.cpp | 27 +++++++------------ .../Graphics/Shaders/CSpaceWarpFilterGLSL.cpp | 5 +--- 3 files changed, 12 insertions(+), 21 deletions(-) diff --git a/Editor/ViewManager.cpp b/Editor/ViewManager.cpp index 392386f27..ec22a8748 100644 --- a/Editor/ViewManager.cpp +++ b/Editor/ViewManager.cpp @@ -21,6 +21,7 @@ namespace urde { URDE_DECL_SPECIALIZE_SHADER(CThermalColdFilter) +URDE_DECL_SPECIALIZE_SHADER(CSpaceWarpFilter) void ViewManager::BuildTestPART(urde::IObjectStore& objStore) { diff --git a/Runtime/Graphics/Shaders/CSpaceWarpFilter.cpp b/Runtime/Graphics/Shaders/CSpaceWarpFilter.cpp index 1157499e5..862d0da2e 100644 --- a/Runtime/Graphics/Shaders/CSpaceWarpFilter.cpp +++ b/Runtime/Graphics/Shaders/CSpaceWarpFilter.cpp @@ -9,26 +9,26 @@ namespace urde void CSpaceWarpFilter::GenerateWarpRampTex(boo::IGraphicsDataFactory::Context& ctx) { - u8 data[WARP_RAMP_RES][WARP_RAMP_RES][4] = {}; + u8 data[WARP_RAMP_RES+1][WARP_RAMP_RES+1][4] = {}; float halfRes = WARP_RAMP_RES / 2.f; - for (int y=0 ; y