Fix GlobalSDF sampling in materials to properly read far cascades
This commit is contained in:
@@ -463,6 +463,7 @@ void MaterialParameter::Bind(BindMeta& meta) const
|
||||
if (GlobalSignDistanceFieldPass::Instance()->Get(meta.Buffers, bindingData))
|
||||
Platform::MemoryClear(&bindingData, sizeof(bindingData));
|
||||
meta.Context->BindSR(_registerIndex, bindingData.Texture ? bindingData.Texture->ViewVolume() : nullptr);
|
||||
meta.Context->BindSR(_registerIndex + 1, bindingData.TextureMip ? bindingData.TextureMip->ViewVolume() : nullptr);
|
||||
*((GlobalSignDistanceFieldPass::ConstantsData*)(meta.Constants.Get() + _offset)) = bindingData.Constants;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
/// <summary>
|
||||
/// Current materials shader version.
|
||||
/// </summary>
|
||||
#define MATERIAL_GRAPH_VERSION 165
|
||||
#define MATERIAL_GRAPH_VERSION 166
|
||||
|
||||
class Material;
|
||||
class GPUShader;
|
||||
|
||||
@@ -917,6 +917,7 @@ bool GlobalSignDistanceFieldPass::Render(RenderContext& renderContext, GPUContex
|
||||
}
|
||||
result.Constants.Resolution = (float)resolution;
|
||||
result.Constants.CascadesCount = cascadesCount;
|
||||
result.Constants.Padding = Float2::Zero;
|
||||
sdfData.Result = result;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -665,7 +665,7 @@ void MaterialGenerator::ProcessGroupTextures(Box* box, Node* node, Value& value)
|
||||
{
|
||||
auto param = findOrAddGlobalSDF();
|
||||
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 = writeLocal(VariantType::Float, String::Format(TEXT("SampleGlobalSDF({0}, {0}_Tex, {0}_Mip, {1})"), param.ShaderName, worldPosition.Value), node);
|
||||
_includes.Add(TEXT("./Flax/GlobalSignDistanceField.hlsl"));
|
||||
break;
|
||||
}
|
||||
@@ -677,7 +677,7 @@ void MaterialGenerator::ProcessGroupTextures(Box* box, Node* node, Value& value)
|
||||
auto param = findOrAddGlobalSDF();
|
||||
Value worldPosition = tryGetValue(node->GetBox(1), Value(VariantType::Float3, TEXT("input.WorldPosition.xyz"))).Cast(VariantType::Float3);
|
||||
auto distance = writeLocal(VariantType::Float, node);
|
||||
auto gradient = writeLocal(VariantType::Float3, String::Format(TEXT("SampleGlobalSDFGradient({0}, {0}_Tex, {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})"), param.ShaderName, worldPosition.Value, distance.Value), node);
|
||||
_includes.Add(TEXT("./Flax/GlobalSignDistanceField.hlsl"));
|
||||
gradientBox->Cache = gradient;
|
||||
distanceBox->Cache = distance;
|
||||
|
||||
@@ -1206,11 +1206,8 @@ SerializedMaterialParam* ShaderGenerator::findParam(const String& shaderName)
|
||||
{
|
||||
SerializedMaterialParam& param = _parameters[i];
|
||||
if (param.ShaderName == shaderName)
|
||||
{
|
||||
return ¶m;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -1235,9 +1232,7 @@ SerializedMaterialParam ShaderGenerator::findOrAddTexture(const Guid& id)
|
||||
{
|
||||
SerializedMaterialParam& param = _parameters[i];
|
||||
if (!param.IsPublic && param.Type == MaterialParameterType::Texture && param.AsGuid == id)
|
||||
{
|
||||
return param;
|
||||
}
|
||||
}
|
||||
|
||||
// Create
|
||||
@@ -1259,9 +1254,7 @@ SerializedMaterialParam ShaderGenerator::findOrAddNormalMap(const Guid& id)
|
||||
{
|
||||
SerializedMaterialParam& param = _parameters[i];
|
||||
if (!param.IsPublic && param.Type == MaterialParameterType::NormalMap && param.AsGuid == id)
|
||||
{
|
||||
return param;
|
||||
}
|
||||
}
|
||||
|
||||
// Create
|
||||
@@ -1283,9 +1276,7 @@ SerializedMaterialParam ShaderGenerator::findOrAddCubeTexture(const Guid& id)
|
||||
{
|
||||
SerializedMaterialParam& param = _parameters[i];
|
||||
if (!param.IsPublic && param.Type == MaterialParameterType::CubeTexture && param.AsGuid == id)
|
||||
{
|
||||
return param;
|
||||
}
|
||||
}
|
||||
|
||||
// Create
|
||||
@@ -1309,9 +1300,7 @@ SerializedMaterialParam ShaderGenerator::findOrAddSceneTexture(MaterialSceneText
|
||||
{
|
||||
SerializedMaterialParam& param = _parameters[i];
|
||||
if (!param.IsPublic && param.Type == MaterialParameterType::SceneTexture && param.AsInteger == asInt)
|
||||
{
|
||||
return param;
|
||||
}
|
||||
}
|
||||
|
||||
// Create
|
||||
@@ -1333,9 +1322,7 @@ SerializedMaterialParam& ShaderGenerator::findOrAddTextureGroupSampler(int32 ind
|
||||
{
|
||||
SerializedMaterialParam& param = _parameters[i];
|
||||
if (!param.IsPublic && param.Type == MaterialParameterType::TextureGroupSampler && param.AsInteger == index)
|
||||
{
|
||||
return param;
|
||||
}
|
||||
}
|
||||
|
||||
// Create
|
||||
|
||||
@@ -170,8 +170,9 @@ const Char* ShaderGraphUtilities::GenerateShaderResources(TextWriterUnicode& wri
|
||||
format = TEXT("Texture3D {0} : register(t{1});");
|
||||
break;
|
||||
case MaterialParameterType::GlobalSDF:
|
||||
format = TEXT("Texture3D<float> {0}_Tex : register(t{1});");
|
||||
format = TEXT("Texture3D<float> {0}_Tex : register(t{1});\nTexture3D<float> {0}_Mip : register(t{2});");
|
||||
zeroOffset = false;
|
||||
registers = 2;
|
||||
break;
|
||||
}
|
||||
if (format)
|
||||
@@ -179,7 +180,7 @@ const Char* ShaderGraphUtilities::GenerateShaderResources(TextWriterUnicode& wri
|
||||
if (zeroOffset)
|
||||
param.Offset = 0;
|
||||
param.RegisterIndex = (byte)startRegister;
|
||||
writer.WriteLine(format, param.ShaderName, startRegister);
|
||||
writer.WriteLine(format, param.ShaderName, startRegister, startRegister + 1);
|
||||
startRegister += registers;
|
||||
if (param.RegisterIndex >= GPU_MAX_SR_BINDED)
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#define GLOBAL_SDF_RASTERIZE_CHUNK_MARGIN 4
|
||||
#define GLOBAL_SDF_MIP_FLOODS 5
|
||||
#define GLOBAL_SDF_WORLD_SIZE 60000.0f
|
||||
#define GLOBAL_SDF_MIN_VALID 0.9f
|
||||
|
||||
// Global SDF data for a constant buffer
|
||||
struct GlobalSDFData
|
||||
@@ -90,7 +91,7 @@ float SampleGlobalSDFCascade(const GlobalSDFData data, Texture3D<float> tex, flo
|
||||
float3 cascadeUV, textureUV;
|
||||
GetGlobalSDFCascadeUV(data, cascade, worldPosition, cascadeMaxDistance, cascadeUV, textureUV);
|
||||
float cascadeDistance = tex.SampleLevel(SamplerLinearClamp, textureUV, 0);
|
||||
if (cascadeDistance < 1.0f && !any(cascadeUV < 0) && !any(cascadeUV > 1))
|
||||
if (cascadeDistance < GLOBAL_SDF_MIN_VALID && all(cascadeUV > 0) && all(cascadeUV < 1))
|
||||
distance = cascadeDistance * cascadeMaxDistance;
|
||||
return distance;
|
||||
}
|
||||
@@ -107,7 +108,7 @@ float SampleGlobalSDF(const GlobalSDFData data, Texture3D<float> tex, float3 wor
|
||||
float3 cascadeUV, textureUV;
|
||||
GetGlobalSDFCascadeUV(data, cascade, worldPosition, cascadeMaxDistance, cascadeUV, textureUV);
|
||||
float cascadeDistance = tex.SampleLevel(SamplerLinearClamp, textureUV, 0);
|
||||
if (cascadeDistance < 0.9f && !any(cascadeUV < 0) && !any(cascadeUV > 1))
|
||||
if (cascadeDistance < GLOBAL_SDF_MIN_VALID && all(cascadeUV > 0) && all(cascadeUV < 1))
|
||||
{
|
||||
distance = cascadeDistance * cascadeMaxDistance;
|
||||
break;
|
||||
@@ -130,7 +131,7 @@ float SampleGlobalSDF(const GlobalSDFData data, Texture3D<float> tex, Texture3D<
|
||||
float3 cascadeUV, textureUV;
|
||||
GetGlobalSDFCascadeUV(data, cascade, worldPosition, cascadeMaxDistance, cascadeUV, textureUV);
|
||||
float cascadeDistance = mip.SampleLevel(SamplerLinearClamp, textureUV, 0);
|
||||
if (cascadeDistance < chunkSizeDistance && !any(cascadeUV < 0) && !any(cascadeUV > 1))
|
||||
if (cascadeDistance < chunkSizeDistance && all(cascadeUV > 0) && all(cascadeUV < 1))
|
||||
{
|
||||
float cascadeDistanceTex = tex.SampleLevel(SamplerLinearClamp, textureUV, 0);
|
||||
if (cascadeDistanceTex < chunkMarginDistance * 2)
|
||||
@@ -155,7 +156,7 @@ float3 SampleGlobalSDFGradient(const GlobalSDFData data, Texture3D<float> tex, f
|
||||
float3 cascadeUV, textureUV;
|
||||
GetGlobalSDFCascadeUV(data, cascade, worldPosition, cascadeMaxDistance, cascadeUV, textureUV);
|
||||
float cascadeDistance = tex.SampleLevel(SamplerLinearClamp, textureUV, 0);
|
||||
if (cascadeDistance < 0.9f && !any(cascadeUV < 0) && !any(cascadeUV > 1))
|
||||
if (cascadeDistance < GLOBAL_SDF_MIN_VALID && all(cascadeUV > 0) && all(cascadeUV < 1))
|
||||
{
|
||||
float texelOffset = 1.0f / data.Resolution;
|
||||
float xp = tex.SampleLevel(SamplerLinearClamp, float3(textureUV.x + texelOffset, textureUV.y, textureUV.z), 0).x;
|
||||
@@ -187,7 +188,7 @@ float3 SampleGlobalSDFGradient(const GlobalSDFData data, Texture3D<float> tex, T
|
||||
float3 cascadeUV, textureUV;
|
||||
GetGlobalSDFCascadeUV(data, cascade, worldPosition, cascadeMaxDistance, cascadeUV, textureUV);
|
||||
float cascadeDistance = mip.SampleLevel(SamplerLinearClamp, textureUV, 0);
|
||||
if (cascadeDistance < chunkSizeDistance && !any(cascadeUV < 0) && !any(cascadeUV > 1))
|
||||
if (cascadeDistance < chunkSizeDistance && all(cascadeUV > 0) && all(cascadeUV < 1))
|
||||
{
|
||||
float cascadeDistanceTex = tex.SampleLevel(SamplerLinearClamp, textureUV, 0);
|
||||
if (cascadeDistanceTex < chunkMarginDistance * 2)
|
||||
|
||||
Reference in New Issue
Block a user