Add option to sample Global SDF from higher cascade
This commit is contained in:
@@ -368,11 +368,13 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
Title = "Sample Global SDF",
|
Title = "Sample Global SDF",
|
||||||
Description = "Samples the Global SDF to get the distance to the closest surface (in world-space). Requires models SDF to be generated and checking `Enable Global SDF` in Graphics Settings.",
|
Description = "Samples the Global SDF to get the distance to the closest surface (in world-space). Requires models SDF to be generated and checking `Enable Global SDF` in Graphics Settings.",
|
||||||
Flags = NodeFlags.MaterialGraph | NodeFlags.ParticleEmitterGraph,
|
Flags = NodeFlags.MaterialGraph | NodeFlags.ParticleEmitterGraph,
|
||||||
Size = new Float2(200, 20),
|
Size = new Float2(200, 40),
|
||||||
|
DefaultValues = new object[] { 0 },
|
||||||
Elements = new[]
|
Elements = new[]
|
||||||
{
|
{
|
||||||
NodeElementArchetype.Factory.Output(0, "Distance", typeof(float), 0),
|
NodeElementArchetype.Factory.Output(0, "Distance", typeof(float), 0),
|
||||||
NodeElementArchetype.Factory.Input(0, "World Position", true, typeof(Float3), 1),
|
NodeElementArchetype.Factory.Input(0, "World Position", true, typeof(Float3), 1),
|
||||||
|
NodeElementArchetype.Factory.Input(1, "Start Cascade", true, typeof(int), 2, 0),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new NodeArchetype
|
new NodeArchetype
|
||||||
@@ -382,11 +384,13 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
Description = "Samples the Global SDF to get the gradient and distance to the closest surface (in world-space). Normalize gradient to get SDF surface normal vector. Requires models SDF to be generated and checking `Enable Global SDF` in Graphics Settings.",
|
Description = "Samples the Global SDF to get the gradient and distance to the closest surface (in world-space). Normalize gradient to get SDF surface normal vector. Requires models SDF to be generated and checking `Enable Global SDF` in Graphics Settings.",
|
||||||
Flags = NodeFlags.MaterialGraph | NodeFlags.ParticleEmitterGraph,
|
Flags = NodeFlags.MaterialGraph | NodeFlags.ParticleEmitterGraph,
|
||||||
Size = new Float2(260, 40),
|
Size = new Float2(260, 40),
|
||||||
|
DefaultValues = new object[] { 0 },
|
||||||
Elements = new[]
|
Elements = new[]
|
||||||
{
|
{
|
||||||
NodeElementArchetype.Factory.Output(0, "Gradient", typeof(Float3), 0),
|
NodeElementArchetype.Factory.Output(0, "Gradient", typeof(Float3), 0),
|
||||||
NodeElementArchetype.Factory.Output(1, "Distance", typeof(float), 2),
|
NodeElementArchetype.Factory.Output(1, "Distance", typeof(float), 2),
|
||||||
NodeElementArchetype.Factory.Input(0, "World Position", true, typeof(Float3), 1),
|
NodeElementArchetype.Factory.Input(0, "World Position", true, typeof(Float3), 1),
|
||||||
|
NodeElementArchetype.Factory.Input(1, "Start Cascade", true, typeof(int), 2, 0),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new NodeArchetype
|
new NodeArchetype
|
||||||
|
|||||||
@@ -311,10 +311,27 @@ void ParticleEmitterGPUGenerator::ProcessGroupTextures(Box* box, Node* node, Val
|
|||||||
{
|
{
|
||||||
auto param = findOrAddGlobalSDF();
|
auto param = findOrAddGlobalSDF();
|
||||||
Value worldPosition = tryGetValue(node->GetBox(1), Value(VariantType::Float3, TEXT("input.WorldPosition.xyz"))).Cast(VariantType::Float3);
|
Value worldPosition = tryGetValue(node->GetBox(1), Value(VariantType::Float3, TEXT("input.WorldPosition.xyz"))).Cast(VariantType::Float3);
|
||||||
value = writeLocal(VariantType::Float, String::Format(TEXT("SampleGlobalSDF({0}, {0}_Tex, {1})"), param.ShaderName, worldPosition.Value), node);
|
Value startCascade = tryGetValue(node->GetBox(2), 0, Value::Zero).Cast(VariantType::Uint);
|
||||||
|
value = writeLocal(VariantType::Float, String::Format(TEXT("SampleGlobalSDF({0}, {0}_Tex, {0}_Mip, {1}, {2})"), param.ShaderName, worldPosition.Value, startCascade.Value), node);
|
||||||
_includes.Add(TEXT("./Flax/GlobalSignDistanceField.hlsl"));
|
_includes.Add(TEXT("./Flax/GlobalSignDistanceField.hlsl"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// Sample Global SDF Gradient
|
||||||
|
case 15:
|
||||||
|
{
|
||||||
|
auto gradientBox = node->GetBox(0);
|
||||||
|
auto distanceBox = node->GetBox(2);
|
||||||
|
auto param = findOrAddGlobalSDF();
|
||||||
|
Value worldPosition = tryGetValue(node->GetBox(1), Value(VariantType::Float3, TEXT("input.WorldPosition.xyz"))).Cast(VariantType::Float3);
|
||||||
|
Value startCascade = tryGetValue(node->GetBox(2), 0, Value::Zero).Cast(VariantType::Uint);
|
||||||
|
auto distance = writeLocal(VariantType::Float, node);
|
||||||
|
auto gradient = writeLocal(VariantType::Float3, String::Format(TEXT("SampleGlobalSDFGradient({0}, {0}_Tex, {0}_Mip, {1}, {2}, {3})"), param.ShaderName, worldPosition.Value, distance.Value, startCascade.Value), node);
|
||||||
|
_includes.Add(TEXT("./Flax/GlobalSignDistanceField.hlsl"));
|
||||||
|
gradientBox->Cache = gradient;
|
||||||
|
distanceBox->Cache = distance;
|
||||||
|
value = box == gradientBox ? gradient : distance;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -665,7 +665,8 @@ void MaterialGenerator::ProcessGroupTextures(Box* box, Node* node, Value& value)
|
|||||||
{
|
{
|
||||||
auto param = findOrAddGlobalSDF();
|
auto param = findOrAddGlobalSDF();
|
||||||
Value worldPosition = tryGetValue(node->GetBox(1), Value(VariantType::Float3, TEXT("input.WorldPosition.xyz"))).Cast(VariantType::Float3);
|
Value worldPosition = tryGetValue(node->GetBox(1), Value(VariantType::Float3, TEXT("input.WorldPosition.xyz"))).Cast(VariantType::Float3);
|
||||||
value = writeLocal(VariantType::Float, String::Format(TEXT("SampleGlobalSDF({0}, {0}_Tex, {0}_Mip, {1})"), param.ShaderName, worldPosition.Value), node);
|
Value startCascade = tryGetValue(node->GetBox(2), 0, Value::Zero).Cast(VariantType::Uint);
|
||||||
|
value = writeLocal(VariantType::Float, String::Format(TEXT("SampleGlobalSDF({0}, {0}_Tex, {0}_Mip, {1}, {2})"), param.ShaderName, worldPosition.Value, startCascade.Value), node);
|
||||||
_includes.Add(TEXT("./Flax/GlobalSignDistanceField.hlsl"));
|
_includes.Add(TEXT("./Flax/GlobalSignDistanceField.hlsl"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -676,8 +677,9 @@ void MaterialGenerator::ProcessGroupTextures(Box* box, Node* node, Value& value)
|
|||||||
auto distanceBox = node->GetBox(2);
|
auto distanceBox = node->GetBox(2);
|
||||||
auto param = findOrAddGlobalSDF();
|
auto param = findOrAddGlobalSDF();
|
||||||
Value worldPosition = tryGetValue(node->GetBox(1), Value(VariantType::Float3, TEXT("input.WorldPosition.xyz"))).Cast(VariantType::Float3);
|
Value worldPosition = tryGetValue(node->GetBox(1), Value(VariantType::Float3, TEXT("input.WorldPosition.xyz"))).Cast(VariantType::Float3);
|
||||||
|
Value startCascade = tryGetValue(node->GetBox(2), 0, Value::Zero).Cast(VariantType::Uint);
|
||||||
auto distance = writeLocal(VariantType::Float, node);
|
auto distance = writeLocal(VariantType::Float, node);
|
||||||
auto gradient = writeLocal(VariantType::Float3, String::Format(TEXT("SampleGlobalSDFGradient({0}, {0}_Tex, {0}_Mip, {1}, {2})"), param.ShaderName, worldPosition.Value, distance.Value), node);
|
auto gradient = writeLocal(VariantType::Float3, String::Format(TEXT("SampleGlobalSDFGradient({0}, {0}_Tex, {0}_Mip, {1}, {2}, {3})"), param.ShaderName, worldPosition.Value, distance.Value, startCascade.Value), node);
|
||||||
_includes.Add(TEXT("./Flax/GlobalSignDistanceField.hlsl"));
|
_includes.Add(TEXT("./Flax/GlobalSignDistanceField.hlsl"));
|
||||||
gradientBox->Cache = gradient;
|
gradientBox->Cache = gradient;
|
||||||
distanceBox->Cache = distance;
|
distanceBox->Cache = distance;
|
||||||
|
|||||||
@@ -126,12 +126,13 @@ float SampleGlobalSDF(const GlobalSDFData data, Texture3D<snorm float> tex, floa
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Samples the Global SDF and returns the distance to the closest surface (in world units) at the given world location.
|
// Samples the Global SDF and returns the distance to the closest surface (in world units) at the given world location.
|
||||||
float SampleGlobalSDF(const GlobalSDFData data, Texture3D<snorm float> tex, Texture3D<snorm float> mip, float3 worldPosition)
|
float SampleGlobalSDF(const GlobalSDFData data, Texture3D<snorm float> tex, Texture3D<snorm float> mip, float3 worldPosition, uint startCascade = 0)
|
||||||
{
|
{
|
||||||
float distance = data.CascadePosDistance[3].w * 2.0f;
|
float distance = data.CascadePosDistance[3].w * 2.0f;
|
||||||
if (distance <= 0.0f)
|
if (distance <= 0.0f)
|
||||||
return GLOBAL_SDF_WORLD_SIZE;
|
return GLOBAL_SDF_WORLD_SIZE;
|
||||||
for (uint cascade = 0; cascade < data.CascadesCount; cascade++)
|
startCascade = min(startCascade, data.CascadesCount - 1);
|
||||||
|
for (uint cascade = startCascade; cascade < data.CascadesCount; cascade++)
|
||||||
{
|
{
|
||||||
float3 cascadeUV, textureUV;
|
float3 cascadeUV, textureUV;
|
||||||
GetGlobalSDFCascadeUV(data, cascade, worldPosition, cascadeUV, textureUV);
|
GetGlobalSDFCascadeUV(data, cascade, worldPosition, cascadeUV, textureUV);
|
||||||
@@ -186,13 +187,14 @@ float3 SampleGlobalSDFGradient(const GlobalSDFData data, Texture3D<snorm float>
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Samples the Global SDF and returns the gradient vector (derivative) at the given world location. Normalize it to get normal vector.
|
// Samples the Global SDF and returns the gradient vector (derivative) at the given world location. Normalize it to get normal vector.
|
||||||
float3 SampleGlobalSDFGradient(const GlobalSDFData data, Texture3D<snorm float> tex, Texture3D<snorm float> mip, float3 worldPosition, out float distance)
|
float3 SampleGlobalSDFGradient(const GlobalSDFData data, Texture3D<snorm float> tex, Texture3D<snorm float> mip, float3 worldPosition, out float distance, uint startCascade = 0)
|
||||||
{
|
{
|
||||||
float3 gradient = float3(0, 0.00001f, 0);
|
float3 gradient = float3(0, 0.00001f, 0);
|
||||||
distance = GLOBAL_SDF_WORLD_SIZE;
|
distance = GLOBAL_SDF_WORLD_SIZE;
|
||||||
if (data.CascadePosDistance[3].w <= 0.0f)
|
if (data.CascadePosDistance[3].w <= 0.0f)
|
||||||
return gradient;
|
return gradient;
|
||||||
for (uint cascade = 0; cascade < data.CascadesCount; cascade++)
|
startCascade = min(startCascade, data.CascadesCount - 1);
|
||||||
|
for (uint cascade = startCascade; cascade < data.CascadesCount; cascade++)
|
||||||
{
|
{
|
||||||
float3 cascadeUV, textureUV;
|
float3 cascadeUV, textureUV;
|
||||||
GetGlobalSDFCascadeUV(data, cascade, worldPosition, cascadeUV, textureUV);
|
GetGlobalSDFCascadeUV(data, cascade, worldPosition, cascadeUV, textureUV);
|
||||||
|
|||||||
Reference in New Issue
Block a user