This commit is contained in:
Turanszki Janos
2021-07-02 14:32:16 +02:00
parent cc0c35ac59
commit 6ccd94aac8
3 changed files with 59 additions and 49 deletions
@@ -1,9 +1,9 @@
#include "globals.hlsli"
#include "ShaderInterop_Postprocess.h"
TEXTURE2D(input_normals, float4, TEXSLOT_ONDEMAND0);
TEXTURE2D(input_normals, float4, TEXSLOT_ONDEMAND0); // DXGI_FORMAT_R8G8B8A8_UNORM
RWTEXTURE2D(output_edgeMap, uint4, 0);
RWTEXTURE2D(output_edgeMap, uint4, 0); // DXGI_FORMAT_R32G32B32A32_UINT
static const int2 offsets[3] = {
int2(1, 0),
@@ -11,29 +11,34 @@ static const int2 offsets[3] = {
int2(1, 1),
};
static float detect_edge_threshold = 0.1f; // lower: less chance for detecting edges
static float detect_corner_threshold = 0.8f; // higher: less chance for detecting corners
static float reject_depth_threshold = 0.001f; // depth difference above this will be detected as separate surface without edge
[numthreads(8, 8, 1)]
void main(uint3 DTid : SV_DispatchThreadID)
{
float4 normal = input_normals[DTid.xy];
normal.xyz = normal.xyz * 2 - 1;
normal.xyz = normalize(normal.xyz * 2 - 1);
float lineardepth = texture_lineardepth[DTid.xy];
const float lineardepth = texture_lineardepth[DTid.xy];
float3 edgeNormal = 0;
for (uint i = 0; i < 3; ++i)
{
int2 pixel2 = DTid.xy + offsets[i];
const int2 pixel2 = DTid.xy + offsets[i];
float ld = texture_lineardepth[pixel2];
float diff = abs(lineardepth - ld);
const float ld = texture_lineardepth[pixel2];
const float diff = abs(lineardepth - ld);
if (diff < 0.0001)
if (diff < reject_depth_threshold)
{
float3 n = input_normals[pixel2].xyz * 2 - 1;
const float3 n = input_normals[pixel2].xyz * 2 - 1;
if (abs(dot(normal.xyz, n.xyz)) < 0.5)
if (abs(dot(normal.xyz, n.xyz)) < detect_edge_threshold)
{
edgeNormal = normalize(normal.xyz + n.xyz);
break;
}
}
}
@@ -51,19 +56,19 @@ void main(uint3 DTid : SV_DispatchThreadID)
float3 N = normal.xyz;
float3 NR = input_normals[max(0, min(DTid.xy + int2(1, 0), xPPResolution - 1))].xyz * 2 - 1;
float3 ND = input_normals[max(0, min(DTid.xy + int2(0, 1), xPPResolution - 1))].xyz * 2 - 1;
if (abs(dot(N, cross(NR, ND))) > 0.2f)
if (abs(dot(N, cross(NR, ND))) > detect_corner_threshold)
{
cornerNormal += NR + ND;
}
NR = input_normals[max(0, min(DTid.xy + int2(-1, 0), xPPResolution - 1))].xyz * 2 - 1;
ND = input_normals[max(0, min(DTid.xy + int2(0, 1), xPPResolution - 1))].xyz * 2 - 1;
if (abs(dot(N, cross(NR, ND))) > 0.2f)
if (abs(dot(N, cross(NR, ND))) > detect_corner_threshold)
{
cornerNormal += NR + ND;
}
NR = input_normals[max(0, min(DTid.xy + int2(1, 0), xPPResolution - 1))].xyz * 2 - 1;
ND = input_normals[max(0, min(DTid.xy + int2(0, -1), xPPResolution - 1))].xyz * 2 - 1;
if (abs(dot(N, cross(NR, ND))) > 0.2f)
if (abs(dot(N, cross(NR, ND))) > detect_corner_threshold)
{
cornerNormal += NR + ND;
}
@@ -1,9 +1,9 @@
#include "globals.hlsli"
#include "ShaderInterop_Postprocess.h"
TEXTURE2D(input_edgeMap, uint4, TEXSLOT_ONDEMAND0);
TEXTURE2D(input_edgeMap, uint4, TEXSLOT_ONDEMAND0); // DXGI_FORMAT_R32G32B32A32_UINT
RWTEXTURE2D(output_edgeMap, uint4, 0);
RWTEXTURE2D(output_edgeMap, uint4, 0); // DXGI_FORMAT_R32G32B32A32_UINT
static const int2 offsets[9] = {
int2(-1, -1), int2(-1, 0), int2(-1, 1),
@@ -16,7 +16,7 @@ void main(uint3 DTid : SV_DispatchThreadID)
{
const float2 uv = (DTid.xy + 0.5) * xPPResolution_rcp;
float lineardepth = texture_lineardepth[DTid.xy];
const float lineardepth = texture_lineardepth[DTid.xy];
const float depth = texture_depth[DTid.xy];
const float3 P = reconstructPosition(uv, depth);
@@ -28,18 +28,18 @@ void main(uint3 DTid : SV_DispatchThreadID)
for (uint i = 0; i < 9; ++i)
{
int2 pixel = (int2)DTid.xy + int2(offsets[i] * xPPParams0.x);
uint4 edgeMap = input_edgeMap[pixel];
const int2 pixel = (int2)DTid.xy + int2(offsets[i] * xPPParams0.x);
const uint4 edgeMap = input_edgeMap[pixel];
uint2 edge = edgeMap.xy;
const uint2 edge = edgeMap.xy;
if (edge.x)
{
uint2 edgePixel = unpack_pixel(edge.y);
float2 edgeUV = (edgePixel.xy + 0.5) * xPPResolution_rcp;
const uint2 edgePixel = unpack_pixel(edge.y);
const float2 edgeUV = (edgePixel.xy + 0.5) * xPPResolution_rcp;
const float edgeDepth = texture_depth[edgePixel];
const float3 edgePosition = reconstructPosition(edgeUV, edgeDepth);
float dist = length(edgePosition - P);
const float dist = length(edgePosition - P);
if (dist < bestEdgeDistance)
{
@@ -49,15 +49,15 @@ void main(uint3 DTid : SV_DispatchThreadID)
}
uint2 corner = edgeMap.zw;
const uint2 corner = edgeMap.zw;
if (corner.x)
{
uint2 cornerPixel = unpack_pixel(corner.y);
float2 cornerUV = (cornerPixel.xy + 0.5) * xPPResolution_rcp;
const uint2 cornerPixel = unpack_pixel(corner.y);
const float2 cornerUV = (cornerPixel.xy + 0.5) * xPPResolution_rcp;
const float cornerDepth = texture_depth[cornerPixel];
const float3 cornerPosition = reconstructPosition(cornerUV, cornerDepth);
float dist = length(cornerPosition - P);
const float dist = length(cornerPosition - P);
if (dist < bestCornerDistance)
{
@@ -1,66 +1,71 @@
#include "globals.hlsli"
#include "ShaderInterop_Postprocess.h"
TEXTURE2D(input_edgeMap, uint4, TEXSLOT_ONDEMAND0);
TEXTURE2D(input_edgeMap, uint4, TEXSLOT_ONDEMAND0); // DXGI_FORMAT_R32G32B32A32_UINT
RWTEXTURE2D(input_output_normals, unorm float4, 0);
RWTEXTURE2D(input_output_normals, unorm float4, 0); // DXGI_FORMAT_R8G8B8A8_UNORM
static const float chamfer_edge_radius = 0.05; // radius of the edge chamfering in world space
static const float chamfer_edge_strength = 1; // falloff for edge smoothness (lower: smaller chamfer, higher: stronger chamfer)
static const float chamfer_corner_radius = 0.1; // radius of the corner chamfering in world space
static const float chamfer_corner_strength = 2; // falloff for corner smoothness (lower: smaller chamfer, higher: stronger chamfer)
[numthreads(8, 8, 1)]
void main(uint3 DTid : SV_DispatchThreadID)
{
const float2 uv = (DTid.xy + 0.5f) * xPPResolution_rcp;
const float depth = texture_depth[DTid.xy];
const float3 P = reconstructPosition(uv, depth);
float4 normal = input_output_normals[DTid.xy];
normal.xyz = normal.xyz * 2 - 1;
normal.xyz = normalize(normal.xyz * 2 - 1);
uint4 edgeMap = input_edgeMap[DTid.xy];
const uint4 edgeMap = input_edgeMap[DTid.xy];
// edges:
uint2 closestEdge = edgeMap.xy;
if (closestEdge.x)
{
float3 edgeNormal = unpack_unitvector(closestEdge.x);
uint2 edgePixel = unpack_pixel(closestEdge.y);
float2 edgeUV = (edgePixel.xy + 0.5f) * xPPResolution_rcp;
const float3 edgeNormal = unpack_unitvector(closestEdge.x);
const uint2 edgePixel = unpack_pixel(closestEdge.y);
const float2 edgeUV = (edgePixel.xy + 0.5f) * xPPResolution_rcp;
const float edgeDepth = texture_depth[edgePixel];
const float3 edgePosition = reconstructPosition(edgeUV, edgeDepth);
const float depth = texture_depth[DTid.xy];
const float3 P = reconstructPosition(uv, depth);
float dist = length(edgePosition - P);
const float dist = length(edgePosition - P);
float l = dist * 10;
float l = dist / chamfer_edge_radius;
l = saturate(l);
l = pow(l, chamfer_edge_strength);
normal.xyz = lerp(edgeNormal, normal.xyz, l);
normal.xyz = normalize(normal.xyz);
//output[DTid.xy] = dist * 10;
//input_output_normals[DTid.xy] = dist * 10;
//return;
}
// corners:
closestEdge = edgeMap.zw;
if (closestEdge.x)
{
float3 edgeNormal = unpack_unitvector(closestEdge.x);
uint2 edgePixel = unpack_pixel(closestEdge.y);
float2 edgeUV = (edgePixel.xy + 0.5f) * xPPResolution_rcp;
const float3 edgeNormal = unpack_unitvector(closestEdge.x);
const uint2 edgePixel = unpack_pixel(closestEdge.y);
const float2 edgeUV = (edgePixel.xy + 0.5f) * xPPResolution_rcp;
const float edgeDepth = texture_depth[edgePixel];
const float3 edgePosition = reconstructPosition(edgeUV, edgeDepth);
const float depth = texture_depth[DTid.xy];
const float3 P = reconstructPosition(uv, depth);
const float dist = length(edgePosition - P);
float dist = length(edgePosition - P);
float l = dist * 5;
float l = dist / chamfer_corner_radius;
l = saturate(l);
l = pow(l, 2);
l = pow(l, chamfer_corner_strength);
normal.xyz = lerp(edgeNormal, normal.xyz, l);
normal.xyz = normalize(normal.xyz);
//output[DTid.xy] = dist * 10;
//input_output_normals[DTid.xy] = dist * 10;
//return;
}