Add WorldPosition to postfx material scene textures for world-space position sampling at uv

This commit is contained in:
Wojtek Figat
2022-11-21 23:45:13 +01:00
parent 99c296ff3a
commit c55d38534d
7 changed files with 38 additions and 1 deletions

View File

@@ -18,6 +18,7 @@ float TimeParam;
float4 ViewInfo;
float4 ScreenSize;
float4 TemporalAAJitter;
float4x4 InverseViewProjectionMatrix;
@1META_CB_END
// Shader resources
@@ -62,6 +63,14 @@ MaterialInput GetMaterialInput(PixelInput input)
return result;
}
// Gets world space position at given pixel coordinate with given device depth
float3 GetWorldPos(float2 uv, float deviceDepth)
{
float4 clipPos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), deviceDepth, 1.0);
float4 wsPos = mul(clipPos, InverseViewProjectionMatrix);
return wsPos.xyz / wsPos.w;
}
// Transforms a vector from tangent space to world space
float3 TransformTangentVectorToWorld(MaterialInput input, float3 tangentVector)
{

View File

@@ -435,6 +435,11 @@ API_ENUM() enum class MaterialSceneTextures
/// The material shading mode.
/// </summary>
ShadingModel = 10,
/// <summary>
/// The scene world-space position (relative to the render view origin).
/// </summary>
WorldPosition = 11,
};
/// <summary>

View File

@@ -439,6 +439,7 @@ void MaterialParameter::Bind(BindMeta& meta) const
switch (type)
{
case MaterialSceneTextures::SceneDepth:
case MaterialSceneTextures::WorldPosition:
view = meta.CanSampleDepth
? meta.Buffers->DepthBuffer->GetDescription().Flags & GPUTextureFlags::ReadOnlyDepthView
? meta.Buffers->DepthBuffer->ViewReadOnlyDepth()

View File

@@ -10,7 +10,7 @@
/// <summary>
/// Current materials shader version.
/// </summary>
#define MATERIAL_GRAPH_VERSION 156
#define MATERIAL_GRAPH_VERSION 157
class Material;
class GPUShader;

View File

@@ -18,6 +18,7 @@ PACK_STRUCT(struct PostFxMaterialShaderData {
Float4 ViewInfo;
Float4 ScreenSize;
Float4 TemporalAAJitter;
Matrix InverseViewProjectionMatrix;
});
void PostFxMaterialShader::Bind(BindParameters& params)
@@ -44,6 +45,7 @@ void PostFxMaterialShader::Bind(BindParameters& params)
// Setup material constants
{
Matrix::Transpose(view.View, materialData->ViewMatrix);
Matrix::Transpose(view.IVP, materialData->InverseViewProjectionMatrix);
materialData->ViewPos = view.Position;
materialData->ViewFar = view.Far;
materialData->ViewDir = view.Direction;

View File

@@ -245,6 +245,9 @@ void ParticleEmitterGPUGenerator::ProcessGroupTextures(Box* box, Node* node, Val
value = writeLocal(VariantType::Int, String::Format(TEXT("(int)({0}.a * 3.999)"), gBuffer1Sample.Value), node);
break;
}
case MaterialSceneTextures::WorldPosition:
value = Value::Zero; // Not implemented
break;
default:
{
// Sample single texture

View File

@@ -416,6 +416,23 @@ void MaterialGenerator::ProcessGroupTextures(Box* box, Node* node, Value& value)
value = writeLocal(VariantType::Int, String::Format(TEXT("(int)({0}.a * 3.999)"), gBuffer1Sample->Value), node);
break;
}
case MaterialSceneTextures::WorldPosition:
{
auto depthParam = findOrAddSceneTexture(MaterialSceneTextures::SceneDepth);
auto depthSample = sampleTextureRaw(node, value, box, &depthParam);
if (depthSample == nullptr)
break;
const auto parent = box->GetParent<ShaderGraphNode<>>();
MaterialGraphBox* uvBox = parent->GetBox(0);
bool useCustomUVs = uvBox->HasConnection();
String uv;
if (useCustomUVs)
uv = MaterialValue::Cast(tryGetValue(uvBox, getUVs), VariantType::Float2).Value;
else
uv = TEXT("input.TexCoord.xy");
value = writeLocal(VariantType::Float3, String::Format(TEXT("GetWorldPos({1}, {0}.rgb)"), depthSample->Value, uv), node);
break;
}
default:
{
// Sample single texture