Skip to content

Commit

Permalink
Editor outline
Browse files Browse the repository at this point in the history
+ fix multithread crash in picking + fix crash when UIText containing '%' is edited
  • Loading branch information
Benualdo committed Jan 6, 2025
1 parent 1c3cdd1 commit f6bc286
Show file tree
Hide file tree
Showing 55 changed files with 473 additions and 110 deletions.
2 changes: 1 addition & 1 deletion Editor.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,6 @@
</Object>
</Property>
<Property type="EnumFlagsU32" name="m_consoleOptions.m_levels" value="Warning|Error"/>
<Property type="EnumFlagsU64" name="m_debugFlags" value=""/>
<Property type="EnumFlagsU64" name="m_debugFlags" value="Culling"/>
</Object>
</Root>
91 changes: 80 additions & 11 deletions data/Shaders/default/default.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,8 @@
#include "system/lighting.hlsli"
#include "system/debugdisplay.hlsli"
#include "system/instancedata.hlsli"

#if _ALPHABLEND
#include "system/transparentPass.hlsli"
#endif
#include "system/outlinemask.hlsli"

#include "default.hlsli"

Expand All @@ -22,6 +20,28 @@
#define EXPORT_VPOS 0
#endif

// TODO: move to transparentPass.hlsli?
void applyDepthTransparency(inout float _alpha, float2 _screenPos, float4 _vpos, float _invDepthFade)
{
TransparentPassConstants transparentPassConstants;
transparentPassConstants.Load(getBuffer(RESERVEDSLOT_BUFSRV_TRANSPARENTPASS));

float linearDepthBuffer = getTexture2D(transparentPassConstants.getLinearDepth()).SampleLevel(nearestClamp, _screenPos.xy, 0).y;
float linearZ = -_vpos.z;
float alpha = saturate((linearDepthBuffer - linearZ) * _invDepthFade );
_alpha *= alpha;
}

bool linearDepthTest(float2 _screenPos, float4 _vpos)
{
TransparentPassConstants transparentPassConstants;
transparentPassConstants.Load(getBuffer(RESERVEDSLOT_BUFSRV_TRANSPARENTPASS));

float linearDepthBuffer = getTexture2D(transparentPassConstants.getLinearDepth()).SampleLevel(nearestClamp, _screenPos.xy, 0).y;
float linearZ = -_vpos.z;
return linearZ < linearDepthBuffer + 0.01;
}

struct VS_Output
{
float4 pos : Position;
Expand Down Expand Up @@ -49,7 +69,6 @@ VS_Output VS_Forward(uint _vertexID : VertexID)

Vertex vert;
vert.Load(getBuffer(rootConstants3D.getVertexBufferHandle()), rootConstants3D.getVertexFormat(), _vertexID, rootConstants3D.getVertexBufferOffset());
//vert.Load(getBuffer(instanceData.getVertexBufferHandle()), instanceData.getVertexFormat(), _vertexID, instanceData.getVertexBufferOffset());

ViewConstants viewConstants;
viewConstants.Load(getBuffer(RESERVEDSLOT_BUFSRV_VIEWCONSTANTS));
Expand Down Expand Up @@ -177,13 +196,7 @@ PS_Output PS_Forward(VS_Output _input)
#endif

#if _ALPHABLEND
TransparentPassConstants transparentPassConstants;
transparentPassConstants.Load(getBuffer(RESERVEDSLOT_BUFSRV_TRANSPARENTPASS));

float linearDepthBuffer = getTexture2D(transparentPassConstants.getLinearDepth()).SampleLevel(nearestClamp, screenPos.xy, 0).y;
float linearZ = -_input.vpos.z;
float alpha = saturate((linearDepthBuffer - linearZ) * materialData.getInvDepthFade());
output.color0.a *= alpha;
applyDepthTransparency(output.color0.a, screenPos.xy, _input.vpos, materialData.getInvDepthFade());
#endif

#if _TOOLMODE && !_ZONLY
Expand Down Expand Up @@ -340,4 +353,60 @@ PS_OutputDeferred PS_Deferred(VS_Output _input)
#else
return output;
#endif
}

struct VS_Output_Outline
{
float4 pos : Position;
float4 vpos : ViewPos;
};

//--------------------------------------------------------------------------------------
VS_Output_Outline VS_Outline(uint _vertexID : VertexID)
{
VS_Output_Outline output;

uint instanceDataOffset = rootConstants3D.getGPUInstanceDataOffset();
GPUInstanceData instanceData = getBuffer(RESERVEDSLOT_BUFSRV_INSTANCEDATA).Load<GPUInstanceData>(instanceDataOffset);

Vertex vert;
vert.Load(getBuffer(rootConstants3D.getVertexBufferHandle()), rootConstants3D.getVertexFormat(), _vertexID, rootConstants3D.getVertexBufferOffset());

ViewConstants viewConstants;
viewConstants.Load(getBuffer(RESERVEDSLOT_BUFSRV_VIEWCONSTANTS));

float4x4 view = viewConstants.getView();
float4x4 proj = viewConstants.getProj();

float3 modelPos = vert.getPos();
float3 worldPos = mul(float4(modelPos.xyz, 1.0f), rootConstants3D.getWorldMatrix()).xyz;
float4 viewPos = mul(float4(worldPos.xyz, 1.0f), view);

viewPos.z += WIREFRAME_DEPTHBIAS;
output.vpos = viewPos;
output.pos = mul(viewPos, proj);

return output;
}

struct PS_Output_Outline
{
uint4 id : Color0;
};

PS_Output_Outline PS_Outline(VS_Output_Outline _input)
{
ViewConstants viewConstants;
viewConstants.Load(getBuffer(RESERVEDSLOT_BUFSRV_VIEWCONSTANTS));

uint2 screenSize = viewConstants.getScreenSize();
float3 screenPos = _input.pos.xyz / float3(screenSize.xy, 1);

PS_Output_Outline output = (PS_Output_Outline)0;
output.id = rootConstants3D.getPickingID();

if (!linearDepthTest(screenPos.xy, _input.vpos))
output.id |= (uint)OutlineMaskFlags::DepthFail;

return output;
}
6 changes: 6 additions & 0 deletions data/Shaders/default/default.hlsl.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ namespace vg::gfx
deferred.vs = declVS("VS_Deferred");
deferred.ps = declPS("PS_Deferred");
}

auto & outline = declTechnique("Outline");
{
outline.vs = declVS("VS_Outline");
outline.ps = declPS("PS_Outline");
}
}
};
}
54 changes: 54 additions & 0 deletions data/Shaders/postprocess/postprocess.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "system/msaa.hlsli"
#include "system/instancedata.hlsli"
#include "system/gamma.hlsli"
#include "system/outlinemask.hlsli"

#if _FXAA
#include "FXAA.hlsli"
Expand Down Expand Up @@ -405,6 +406,49 @@ void CS_PostProcessMain(int2 dispatchThreadID : SV_DispatchThreadID)
color = DebugRayTracing(color, uv, screenSize, viewConstants);
#endif

// outline
{

float2 pcf = (float2)0.0f;
for (int jj = -1; jj < 1; ++jj)
{
for (int ii = -1; ii < 1; ++ii)
{
uint4 center = getTexture2D_UInt4(postProcessConstants.getOutlineMask()).Load(int3(coords.x + ii, coords.y + jj, 0));

bool visibleOutline = false;
bool hiddenOutline = false;

for (int j = -1; j <= 1; ++j)
{
for (int i = -1; i <= 1; ++i)
{
uint4 sample = getTexture2D_UInt4(postProcessConstants.getOutlineMask()).Load(int3(coords.x + ii + i, coords.y + jj + j,0));

if ((sample.a & ~(uint)OutlineMaskFlags::DepthFail) != (center.a & ~(uint)OutlineMaskFlags::DepthFail))
{
if (0 != sample.a)
{
if (sample.a & (uint)OutlineMaskFlags::DepthFail)
hiddenOutline = true;
else
visibleOutline = true;
}
}
}
}

if (visibleOutline)
pcf += 1;

if (hiddenOutline)
pcf.y += 0.325;
}
}

color.rgb = lerp(color.rgb, float3(0,1,0), saturate((pcf.x + pcf.y) / 4.0f));
}

switch(viewConstants.getDisplayMode())
{
default:
Expand Down Expand Up @@ -452,6 +496,16 @@ void CS_PostProcessMain(int2 dispatchThreadID : SV_DispatchThreadID)
case DisplayMode::Lighting_EnvironmentSpecularBRDF:
color.rgb = getTexture2D(viewConstants.getSpecularBRDF()).SampleLevel(nearestClamp, uv, 0).rgb;
break;

case DisplayMode::PostProcess_OutlineMask:
{
uint sample = getTexture2D_UInt4(postProcessConstants.getOutlineMask()).Load(int3(coords,0)).a;
uint id = sample & (uint)~0x80000000;
float alpha = (sample & 0x80000000) ? 0.5 : 1.0;
color.rgb = (0 != id.x) ? frac(float3(id.x * 31.0, id.x * 17.0, id.x * 59.0) / 255.0) : float3(0,0,0);
color.rgb *= alpha;
}
break;
}

#endif // _TOOLMODE
Expand Down
40 changes: 23 additions & 17 deletions data/Shaders/postprocess/postprocess.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -11,39 +11,45 @@ struct PostProcessConstants
#ifdef __cplusplus
PostProcessConstants()
{
m_data = (uint4)0;

setScreenSize(uint2(0,0));
setSource(BINDLESS_TEXTURE_INVALID);
setRWBufferOut(BINDLESS_RWTEXTURE_INVALID);
setDepth(BINDLESS_TEXTURE_INVALID);
setStencil(BINDLESS_TEXTURE_INVALID);
setLinearDepth(BINDLESS_TEXTURE_INVALID);
setOutlineMask(BINDLESS_TEXTURE_INVALID);
}
#endif

void setScreenSize (uint2 _size) { m_data.x = packUint16(_size.xy);}
uint2 getScreenSize () { return unpackUint16(m_data.x); }
void setScreenSize (uint2 _size) { m_screensize = packUint16(_size.xy);}
uint2 getScreenSize () { return unpackUint16(m_screensize); }

void setSource (uint _color) { m_src_dst = packUint16low(m_src_dst, _color); }
uint getSource () { return unpackUint16low(m_src_dst); }

void setSource (uint _color) { m_data.y = packUint16low(m_data.y, _color); }
uint getSource () { return unpackUint16low(m_data.y); }
void setRWBufferOut (uint _rwbuffer){ m_src_dst = packUint16high(m_src_dst, _rwbuffer); }
uint getRWBufferOut () { return unpackUint16high(m_src_dst); }

void setRWBufferOut (uint _rwbuffer){ m_data.y = packUint16high(m_data.y, _rwbuffer); }
uint getRWBufferOut () { return unpackUint16high(m_data.y); }
void setDepth (uint _depth) { m_depth_stencil = packUint16low(m_depth_stencil, _depth); }
uint getDepth () { return unpackUint16low(m_depth_stencil); }

void setDepth (uint _depth) { m_data.z = packUint16low(m_data.z, _depth); }
uint getDepth () { return unpackUint16low(m_data.z); }
void setStencil (uint _stencil) { m_depth_stencil = packUint16high(m_depth_stencil, _stencil); }
uint getStencil () { return unpackUint16high(m_depth_stencil); }

void setStencil (uint _stencil) { m_data.z = packUint16high(m_data.z, _stencil); }
uint getStencil () { return unpackUint16high(m_data.z); }
void setLinearDepth (uint _linearZ) { m_depth_temp = packUint16low(m_depth_temp, _linearZ); }
uint getLinearDepth () { return unpackUint16low(m_depth_temp); }

void setLinearDepth (uint _linearZ) { m_data.w = packUint16low(m_data.w, _linearZ); }
uint getLinearDepth () { return unpackUint16low(m_data.w); }
void setTemp (uint _temp) { m_depth_temp = packUint16high(m_depth_temp, _temp); }
uint getTemp () { return unpackUint16high(m_depth_temp); }

void setTemp (uint _temp) { m_data.w = packUint16high(m_data.w, _temp); }
uint getTemp () { return unpackUint16high(m_data.w); }
void setOutlineMask (uint _outline) { m_outline_unused = packUint16low(m_outline_unused, _outline); }
uint getOutlineMask () { return unpackUint16low(m_outline_unused); }

uint4 m_data;
uint m_screensize;
uint m_src_dst;
uint m_depth_stencil;
uint m_depth_temp;
uint m_outline_unused;
};

#define PostProcessConstantsCount sizeof(PostProcessConstants)/sizeof(u32)
Expand Down
4 changes: 4 additions & 0 deletions data/Shaders/system/bindless.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ DECL_DESCRIPTOR_RANGE_RO(Texture1D, g_Texture1D, BIND
DECL_DESCRIPTOR_RANGE_RO(Texture2D, g_Texture2D, BINDLESS_TEXTURE_BINDING_2D, BINDLESS_TEXTURE_START);
DECL_DESCRIPTOR_RANGE_RO(TextureCube, g_TextureCube, BINDLESS_TEXTURE_BINDING_CUBE, BINDLESS_TEXTURE_START);
DECL_DESCRIPTOR_RANGE_RO(Texture2DMS<float4>, g_Texture2DMS, BINDLESS_TEXTURE_BINDING_2DMS, BINDLESS_TEXTURE_START);
DECL_DESCRIPTOR_RANGE_RO(Texture2D<uint>, g_Texture2D_UInt, BINDLESS_TEXTURE_BINDING_2D_UINT, BINDLESS_TEXTURE_START);
DECL_DESCRIPTOR_RANGE_RO(Texture2D<uint2>, g_Texture2D_UInt2, BINDLESS_TEXTURE_BINDING_2D_UINT2, BINDLESS_TEXTURE_START);
DECL_DESCRIPTOR_RANGE_RO(Texture2D<uint4>, g_Texture2D_UInt4, BINDLESS_TEXTURE_BINDING_2D_UINT4, BINDLESS_TEXTURE_START);
DECL_DESCRIPTOR_RANGE_RO(Texture2DMS<uint2>, g_Texture2DMS_UInt2, BINDLESS_TEXTURE_BINDING_2DMS_UINT2, BINDLESS_TEXTURE_START);
DECL_DESCRIPTOR_RANGE_RO(Texture3D, g_Texture3D, BINDLESS_TEXTURE_BINDING_3D, BINDLESS_TEXTURE_START);

Expand Down Expand Up @@ -52,7 +54,9 @@ DECL_DESCRIPTOR_RANGE_RO(RaytracingAccelerationStructure, g_TLAS, BINDLESS_TLAS_
#define getNonUniformTexture2D(_handle) (g_Texture2D[NonUniformResourceIndex(_handle - BINDLESS_TEXTURE_START)])
#define getTextureCube(_handle) (g_TextureCube[_handle - BINDLESS_TEXTURE_START])
#define getTexture2DMS(_handle) (g_Texture2DMS[_handle - BINDLESS_TEXTURE_START])
#define getTexture2D_UInt(_handle) (g_Texture2D_UInt[_handle - BINDLESS_TEXTURE_START])
#define getTexture2D_UInt2(_handle) (g_Texture2D_UInt2[_handle - BINDLESS_TEXTURE_START])
#define getTexture2D_UInt4(_handle) (g_Texture2D_UInt4[_handle - BINDLESS_TEXTURE_START])
#define getTexture2DMS_UInt2(_handle) (g_Texture2DMS_UInt2[_handle - BINDLESS_TEXTURE_START])
#define getTexture3D(_handle) (g_Texture3D[_handle - BINDLESS_TEXTURE_START])

Expand Down
3 changes: 2 additions & 1 deletion data/Shaders/system/displaymodes.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ vg_enum_class(DisplayMode, uint,
PostProcess_LinearDepth,
PostProcess_DepthOfField,
PostProcess_FXAAEdges,
PostProcess_WorldPos
PostProcess_WorldPos,
PostProcess_OutlineMask
);

vg_enum(DisplayFlags, uint,
Expand Down
29 changes: 29 additions & 0 deletions data/Shaders/system/editorpass.hlsli
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//#ifndef _EDITOR_PASS__HLSLI_
//#define _EDITOR_PASS__HLSLI_
//
//#include "types.hlsli"
//#include "packing.hlsli"
//#include "displaymodes.hlsli"
//
//struct EditorPassConstants
//{
// #ifdef __cplusplus
// EditorPassConstants()
// {
// m_data = 0;
// setOutlineMask(BINDLESS_TEXTURE_INVALID);
// }
// #else
// void Load(ByteAddressBuffer _buffer, uint _offset = 0)
// {
// m_data = _buffer.Load<EditorPassConstants>(_offset).m_data;
// }
// #endif
//
// uint m_data;
//
// void setOutlineMask (uint _outlineMask) { m_data = packUint16low(m_data, _outlineMask); }
// uint getOutlineMask () { return unpackUint16low(m_data); }
//};
//
//#endif // _EDITOR_PASS__HLSLI_
10 changes: 10 additions & 0 deletions data/Shaders/system/outlinemask.hlsli
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#ifndef _OUTLINEMASK__HLSLI_
#define _OUTLINEMASK__HLSLI_

#include "types.hlsli"

vg_enum_class(OutlineMaskFlags, uint,
DepthFail = 0x8000
);

#endif // _OUTLINEMASK__HLSLI_
11 changes: 8 additions & 3 deletions data/Shaders/system/table.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ vg_enum_class(ReservedSlot, uint,
LastTexture = InvalidTexture2D,

// Buffer
EditorPassBufSrv = BINDLESS_BUFFER_INVALID - 7,
TransparentPassBufSrv = BINDLESS_BUFFER_INVALID - 6,
MaterialDataBufSrv = BINDLESS_BUFFER_INVALID - 5,
InstanceDataBufSrv = BINDLESS_BUFFER_INVALID - 4,
Expand Down Expand Up @@ -101,9 +102,11 @@ vg_enum_class(ReservedSlot, uint,
#define BINDLESS_TEXTURE_BINDING_1D 10
#define BINDLESS_TEXTURE_BINDING_2D 20
#define BINDLESS_TEXTURE_BINDING_2DMS 21
#define BINDLESS_TEXTURE_BINDING_2D_UINT2 22
#define BINDLESS_TEXTURE_BINDING_2DMS_UINT2 23
#define BINDLESS_TEXTURE_BINDING_CUBE 24
#define BINDLESS_TEXTURE_BINDING_2D_UINT 22
#define BINDLESS_TEXTURE_BINDING_2D_UINT2 23
#define BINDLESS_TEXTURE_BINDING_2D_UINT4 24
#define BINDLESS_TEXTURE_BINDING_2DMS_UINT2 25
#define BINDLESS_TEXTURE_BINDING_CUBE 26
#define BINDLESS_TEXTURE_BINDING_3D 30

#define BINDLESS_RWTEXTURE_BINDING_1D 210
Expand All @@ -118,7 +121,9 @@ vg_enum_class(ReservedSlot, uint,
#define BINDLESS_TEXTURE_BINDING_2D 0
#define BINDLESS_TEXTURE_BINDING_CUBE 0
#define BINDLESS_TEXTURE_BINDING_2DMS 0
#define BINDLESS_TEXTURE_BINDING_2D_UINT 0
#define BINDLESS_TEXTURE_BINDING_2D_UINT2 0
#define BINDLESS_TEXTURE_BINDING_2D_UINT4 0
#define BINDLESS_TEXTURE_BINDING_2DMS_UINT2 0
#define BINDLESS_TEXTURE_BINDING_3D 0

Expand Down
Loading

0 comments on commit f6bc286

Please sign in to comment.