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