Create a debug material type for displaying per-vertex data (#7220)

* Create a debug material type for displaying per-vertex data

Signed-off-by: Tommy Walton <waltont@amazon.com>

* PR feedback. Added color display mode, multiple uv-set support, split tangent/bitangent options into two separate enums, and added a functor for showing only the applicable properties in the UI depending on which vertex stream and uv set are selected.

Signed-off-by: Tommy Walton <waltont@amazon.com>
monroegm-disable-blank-issue-2
Tommy Walton 4 years ago committed by GitHub
parent 122eef2680
commit 837d4fde3e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,154 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <viewsrg.srgi>
#define UvSetCount 2
#include <Atom/RPI/ShaderResourceGroups/DefaultObjectSrg.azsli>
#include <Atom/RPI/ShaderResourceGroups/DefaultDrawSrg.azsli>
#include <Atom/RPI/TangentSpace.azsli>
// These enums need to be kept in sync with the enum values in DebugVertexStreams_IncompatibleEnums.lua
option enum class DebugVertexStream { Normals, Tangents, Bitangents, Uvs, TangentW } o_debugVertexStream = DebugVertexStream::Normals;
option enum class TangentOptions { UseVertexData, UseSurfaceGradient} o_tangentOptions = TangentOptions::UseVertexData;
option enum class BitangentOptions { UseVertexData, UseSurfaceGradient, ReconstructBitangent} o_bitangentOptions = BitangentOptions::UseVertexData;
option enum class ColorDisplayMode {ColorSpace, UnitSpace} o_colorDisplayMode = ColorDisplayMode::ColorSpace;
ShaderResourceGroup MaterialSrg : SRG_PerMaterial
{
uint m_uvIndex;
}
struct VSInput
{
// Base fields (required by the template azsli file)...
float3 m_position : POSITION;
float3 m_normal : NORMAL;
float4 m_tangent : TANGENT;
float3 m_bitangent : BITANGENT;
// Extended fields (only referenced in this azsl file)...
float2 m_uv0 : UV0;
float2 m_uv1 : UV1;
};
struct VSOutput
{
// Base fields (required by the template azsli file)...
// "centroid" is needed for SV_Depth to compile
precise linear centroid float4 m_position : SV_Position;
float3 m_normal: NORMAL;
float4 m_tangent : TANGENT;
float3 m_bitangent : BITANGENT;
float3 m_worldPosition : UV0;
// Extended fields (only referenced in this azsl file)...
float2 m_uv[UvSetCount] : UV1;
};
VSOutput MainVS(VSInput IN)
{
VSOutput OUT;
OUT.m_worldPosition = mul(ObjectSrg::GetWorldMatrix(), float4(IN.m_position, 1.0)).xyz;
OUT.m_position = mul(ViewSrg::m_viewProjectionMatrix, float4(OUT.m_worldPosition, 1.0));
// Only UV0 is supported
OUT.m_uv[0] = IN.m_uv0;
OUT.m_uv[1] = IN.m_uv1;
float4x4 objectToWorld = ObjectSrg::GetWorldMatrix();
float3x3 objectToWorldIT = ObjectSrg::GetWorldMatrixInverseTranspose();
ConstructTBN(IN.m_normal, IN.m_tangent, IN.m_bitangent, objectToWorld, objectToWorldIT, OUT.m_normal, OUT.m_tangent.xyz, OUT.m_bitangent);
OUT.m_tangent.w = IN.m_tangent.w;
return OUT;
}
struct PixelOutput
{
float4 m_color : SV_Target0;
};
float3 OffsetColor(float3 color)
{
if(o_colorDisplayMode == ColorDisplayMode::ColorSpace)
{
// Represent a vector in the (-1, -1, -1) to (1, 1, 1) range as a color in the (0, 0, 0) to (1, 1, 1) range
// Color key
// + x-axis: Light Coral
// - x-axis: Teal
// + y-axis: Bright Green
// - y-axis: Dark Magenta
// + z-axis: Medium Slate Blue
// - z-axis: Olive
return normalize(color) * 0.5 + 0.5;
}
else
{
// Use the normalized color, with any negative values represented as black
// + x-axis: Red
// - x-axis: Black
// + y-axis: Green
// - y-axis: Black
// + z-axis: Blue
// - z-axis: Black
return normalize(color);
}
}
PixelOutput MainPS(VSOutput IN)
{
PixelOutput OUT;
float3 tangents[UvSetCount] = { IN.m_tangent.xyz, IN.m_tangent.xyz };
float3 bitangents[UvSetCount] = { IN.m_bitangent.xyz, IN.m_bitangent.xyz };
if(o_bitangentOptions == BitangentOptions::ReconstructBitangent && MaterialSrg::m_uvIndex == 0)
{
bitangents[MaterialSrg::m_uvIndex] = cross(IN.m_normal.xyz, IN.m_tangent.xyz) * sign(IN.m_tangent.w);
}
else if((o_debugVertexStream == DebugVertexStream::Tangents && o_tangentOptions == TangentOptions::UseSurfaceGradient)
|| (o_debugVertexStream == DebugVertexStream::Bitangents && o_bitangentOptions == BitangentOptions::UseSurfaceGradient)
|| MaterialSrg::m_uvIndex > 0)
{
const bool isBackface = false;
SurfaceGradientNormalMapping_Init(IN.m_normal, IN.m_worldPosition, isBackface);
SurfaceGradientNormalMapping_GenerateTB(IN.m_uv[MaterialSrg::m_uvIndex], tangents[MaterialSrg::m_uvIndex], bitangents[MaterialSrg::m_uvIndex]);
}
float3 outColor = float3(1.0, 1.0, 1.0);
switch(o_debugVertexStream)
{
case DebugVertexStream::Normals:
outColor = OffsetColor(IN.m_normal);
break;
case DebugVertexStream::Tangents:
outColor = OffsetColor(tangents[MaterialSrg::m_uvIndex]);
break;
case DebugVertexStream::Bitangents:
outColor = OffsetColor(bitangents[MaterialSrg::m_uvIndex]);
break;
case DebugVertexStream::Uvs:
// Assume a tiled uv visualization, where anything greater than 1 wraps back around to 0
outColor = float3(frac(IN.m_uv[MaterialSrg::m_uvIndex].x), frac(IN.m_uv[MaterialSrg::m_uvIndex].y), 0.0f);
break;
case DebugVertexStream::TangentW:
float red = IN.m_tangent.w >= 0.0f ? 1.0f : 0.0f;
float green = IN.m_tangent.w <= 0.0f ? 1.0f : 0.0f;
float blue = IN.m_tangent.w == 0.0f ? 1.0f : 0.0f;
outColor = float3(red, green, blue);
break;
}
OUT.m_color.rgb = outColor;
OUT.m_color.a = 1.0;
return OUT;
}

@ -0,0 +1,4 @@
{
"materialType": "Materials/Special/DebugVertexStreams.materialtype",
"materialTypeVersion": 1
}

@ -0,0 +1,94 @@
{
"description": "A simple default base material for Atom testing.",
"version": 1,
"propertyLayout": {
"groups": [
{
"name": "general",
"displayName": "General Settings",
"description": "General settings."
}
],
"properties": {
"general": [
{
"name": "debugVertexStream",
"displayName": "Display Vertex Stream",
"description": "Display vertex stream interpolated over the triangle.",
"type": "Enum",
"defaultValue": "Normals",
"enumValues": [ "Normals", "Tangents", "Bitangents", "Uvs", "TangentW" ],
"connection": {
"type": "ShaderOption",
"name": "o_debugVertexStream"
}
},
{
"name": "tangentOptions",
"displayName": "Tangent Options",
"description": "Use the data from the vertices or use the Surface Gradient technique for calculating tangents.",
"type": "Enum",
"defaultValue": "UseVertexData",
"enumValues": [ "UseVertexData", "UseSurfaceGradient"],
"connection": {
"type": "ShaderOption",
"name": "o_tangentOptions"
}
},
{
"name": "bitangentOptions",
"displayName": "Bitangent Options",
"description": "Use the data from the vertices, use the Surface Gradient technique for calculating bitangents, or use the cross product to reconstruct the bitangents.",
"type": "Enum",
"defaultValue": "UseVertexData",
"enumValues": [ "UseVertexData", "UseSurfaceGradient", "ReconstructBitangent" ],
"connection": {
"type": "ShaderOption",
"name": "o_bitangentOptions"
}
},
{
"name": "colorDisplayMode",
"displayName": "Display Mode",
"description": "Offset the vector into the 0-1 range (ColorSpace), or display the raw unit vector including negative values (UnitSpace)",
"type": "Enum",
"defaultValue": "ColorSpace",
"enumValues": [ "ColorSpace", "UnitSpace"],
"connection": {
"type": "ShaderOption",
"name": "o_colorDisplayMode"
}
},
{
"name": "uvIndex",
"displayName": "UV Index",
"description": "UV set to display and use for tangents/bitangents.",
"type": "Enum",
"enumIsUv": true,
"defaultValue": "Tiled",
"connection": {
"type": "ShaderInput",
"name": "m_uvIndex"
}
}
]
}
},
"shaders": [
{
"file": "Materials/Special/DebugVertexStreams.shader"
}
],
"functors": [
{
"type": "Lua",
"args": {
"file": "DebugVertexStreams_IncompatibleEnums.lua"
}
}
],
"uvNameMap": {
"UV0": "Tiled",
"UV1": "Unwrapped"
}
}

@ -0,0 +1,24 @@
{
"Source" : "DebugVertexStreams.azsl",
"DepthStencilState" : {
"Depth" : { "Enable" : true, "CompareFunc" : "GreaterEqual" }
},
"DrawList" : "auxgeom",
"ProgramSettings":
{
"EntryPoints":
[
{
"name": "MainVS",
"type": "Vertex"
},
{
"name": "MainPS",
"type": "Fragment"
}
]
}
}

@ -0,0 +1,71 @@
--------------------------------------------------------------------------------------
--
-- Copyright (c) Contributors to the Open 3D Engine Project.
-- For complete copyright and license terms please see the LICENSE at the root of this distribution.
--
-- SPDX-License-Identifier: Apache-2.0 OR MIT
--
--
--
----------------------------------------------------------------------------------------------------
DebugVertexStream_Normals = 0
DebugVertexStream_Tangents = 1
DebugVertexStream_Bitangents = 2
DebugVertexStream_Uvs = 3
DebugVertexStream_TangentW = 4
function GetMaterialPropertyDependencies()
return { "general.debugVertexStream", "general.uvIndex"}
end
function ProcessEditor(context)
local vertexStream = context:GetMaterialPropertyValue_enum("general.debugVertexStream");
-- Depending on which vertex stream is being visualized, only certain settings are applicable
if(vertexStream == DebugVertexStream_Normals) then
-- Normals can be viewed as colors using either method
context:SetMaterialPropertyVisibility("general.colorDisplayMode", MaterialPropertyVisibility_Enabled)
-- Uv set and tangent/bitangent options do not impact normals
context:SetMaterialPropertyVisibility("general.tangentOptions", MaterialPropertyVisibility_Hidden)
context:SetMaterialPropertyVisibility("general.bitangentOptions", MaterialPropertyVisibility_Hidden)
context:SetMaterialPropertyVisibility("general.uvIndex", MaterialPropertyVisibility_Hidden)
elseif(vertexStream == DebugVertexStream_Tangents) then
-- Tangents can be viewed using either color display mode, and are affected by tangent options and uv index
context:SetMaterialPropertyVisibility("general.tangentOptions", MaterialPropertyVisibility_Enabled)
context:SetMaterialPropertyVisibility("general.colorDisplayMode", MaterialPropertyVisibility_Enabled)
context:SetMaterialPropertyVisibility("general.uvIndex", MaterialPropertyVisibility_Enabled)
context:SetMaterialPropertyVisibility("general.bitangentOptions", MaterialPropertyVisibility_Hidden)
elseif(vertexStream == DebugVertexStream_Bitangents) then
-- Bitangents can be viewed using either color display mode, and are affected by tangent options and uv index
context:SetMaterialPropertyVisibility("general.bitangentOptions", MaterialPropertyVisibility_Enabled)
context:SetMaterialPropertyVisibility("general.colorDisplayMode", MaterialPropertyVisibility_Enabled)
context:SetMaterialPropertyVisibility("general.uvIndex", MaterialPropertyVisibility_Enabled)
context:SetMaterialPropertyVisibility("general.tangentOptions", MaterialPropertyVisibility_Hidden)
elseif(vertexStream == DebugVertexStream_Uvs) then
-- Uvs are only impacted by uv index
context:SetMaterialPropertyVisibility("general.uvIndex", MaterialPropertyVisibility_Enabled)
context:SetMaterialPropertyVisibility("general.tangentOptions", MaterialPropertyVisibility_Hidden)
context:SetMaterialPropertyVisibility("general.bitangentOptions", MaterialPropertyVisibility_Hidden)
context:SetMaterialPropertyVisibility("general.colorDisplayMode", MaterialPropertyVisibility_Hidden)
elseif(vertexStream == DebugVertexStream_TangentW) then
-- Tangent.w can only use per-vertex data, and only for the first uv set, and is only displayed one way,
-- so it is not impacted by any settings
context:SetMaterialPropertyVisibility("general.tangentOptions", MaterialPropertyVisibility_Hidden)
context:SetMaterialPropertyVisibility("general.bitangentOptions", MaterialPropertyVisibility_Hidden)
context:SetMaterialPropertyVisibility("general.colorDisplayMode", MaterialPropertyVisibility_Hidden)
context:SetMaterialPropertyVisibility("general.uvIndex", MaterialPropertyVisibility_Hidden)
end
-- For the second uv set, only the surface gradient technique is supported for generating tangents and bitangents
local uvSet = context:GetMaterialPropertyValue_enum("general.uvIndex");
if(uvSet > 0) then
context:SetMaterialPropertyVisibility("general.tangentOptions", MaterialPropertyVisibility_Hidden)
context:SetMaterialPropertyVisibility("general.bitangentOptions", MaterialPropertyVisibility_Hidden)
end
end
Loading…
Cancel
Save