diff --git a/Content/Editor/MaterialTemplates/PostProcess.shader b/Content/Editor/MaterialTemplates/PostProcess.shader
index f20bdc610..927d63c8c 100644
--- a/Content/Editor/MaterialTemplates/PostProcess.shader
+++ b/Content/Editor/MaterialTemplates/PostProcess.shader
@@ -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)
{
diff --git a/Source/Engine/Graphics/Materials/MaterialInfo.h b/Source/Engine/Graphics/Materials/MaterialInfo.h
index 876246e0c..dfdcdc9be 100644
--- a/Source/Engine/Graphics/Materials/MaterialInfo.h
+++ b/Source/Engine/Graphics/Materials/MaterialInfo.h
@@ -435,6 +435,11 @@ API_ENUM() enum class MaterialSceneTextures
/// The material shading mode.
///
ShadingModel = 10,
+
+ ///
+ /// The scene world-space position (relative to the render view origin).
+ ///
+ WorldPosition = 11,
};
///
diff --git a/Source/Engine/Graphics/Materials/MaterialParams.cpp b/Source/Engine/Graphics/Materials/MaterialParams.cpp
index 7c3e9d2d0..50ac1f8bb 100644
--- a/Source/Engine/Graphics/Materials/MaterialParams.cpp
+++ b/Source/Engine/Graphics/Materials/MaterialParams.cpp
@@ -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()
diff --git a/Source/Engine/Graphics/Materials/MaterialShader.h b/Source/Engine/Graphics/Materials/MaterialShader.h
index 3c8bf37bf..c7249b2ab 100644
--- a/Source/Engine/Graphics/Materials/MaterialShader.h
+++ b/Source/Engine/Graphics/Materials/MaterialShader.h
@@ -10,7 +10,7 @@
///
/// Current materials shader version.
///
-#define MATERIAL_GRAPH_VERSION 156
+#define MATERIAL_GRAPH_VERSION 157
class Material;
class GPUShader;
diff --git a/Source/Engine/Graphics/Materials/PostFxMaterialShader.cpp b/Source/Engine/Graphics/Materials/PostFxMaterialShader.cpp
index 4c2caec84..ff1ff3fb6 100644
--- a/Source/Engine/Graphics/Materials/PostFxMaterialShader.cpp
+++ b/Source/Engine/Graphics/Materials/PostFxMaterialShader.cpp
@@ -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;
diff --git a/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.Textures.cpp b/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.Textures.cpp
index 823ddbccd..05059f05e 100644
--- a/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.Textures.cpp
+++ b/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.Textures.cpp
@@ -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
diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Textures.cpp b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Textures.cpp
index cc5130d44..d6ae2719f 100644
--- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Textures.cpp
+++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Textures.cpp
@@ -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>();
+ 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