Merge branch 'master' into 1.1

# Conflicts:
#	Source/Engine/Content/JsonAsset.h
#	Source/Engine/Core/Config/Settings.h
This commit is contained in:
Wojtek Figat
2021-02-15 10:40:59 +01:00
77 changed files with 1111 additions and 531 deletions

View File

@@ -1,98 +0,0 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
#if COMPILE_WITH_PARTICLE_GPU_GRAPH
#include "ParticleEmitterGraph.GPU.h"
void ParticleEmitterGPUGenerator::ProcessGroupParameters(Box* box, Node* node, Value& value)
{
switch (node->TypeID)
{
// Get
case 1:
case 2:
{
// Get parameter
const auto param = findParam((Guid)node->Values[0]);
if (param)
{
switch (param->Type)
{
case MaterialParameterType::Bool:
value = Value(VariantType::Bool, param->ShaderName);
break;
case MaterialParameterType::Integer:
case MaterialParameterType::SceneTexture:
value = Value(VariantType::Int, param->ShaderName);
break;
case MaterialParameterType::Float:
value = Value(VariantType::Float, param->ShaderName);
break;
case MaterialParameterType::Vector2:
case MaterialParameterType::Vector3:
case MaterialParameterType::Vector4:
case MaterialParameterType::Color:
{
// Set result values based on box ID
const Value sample(box->Type.Type, param->ShaderName);
switch (box->ID)
{
case 0:
value = sample;
break;
case 1:
value.Value = sample.Value + _subs[0];
break;
case 2:
value.Value = sample.Value + _subs[1];
break;
case 3:
value.Value = sample.Value + _subs[2];
break;
case 4:
value.Value = sample.Value + _subs[3];
break;
default: CRASH;
break;
}
value.Type = box->Type.Type;
break;
}
case MaterialParameterType::Matrix:
{
value = Value(box->Type.Type, String::Format(TEXT("{0}[{1}]"), param->ShaderName, box->ID));
break;
}
case MaterialParameterType::ChannelMask:
{
const auto input = tryGetValue(node->GetBox(0), Value::Zero);
value = writeLocal(VariantType::Float, String::Format(TEXT("dot({0}, {1})"), input.Value, param->ShaderName), node);
break;
}
case MaterialParameterType::CubeTexture:
case MaterialParameterType::Texture:
case MaterialParameterType::GPUTextureArray:
case MaterialParameterType::GPUTextureCube:
case MaterialParameterType::GPUTextureVolume:
case MaterialParameterType::GPUTexture:
value = Value(VariantType::Object, param->ShaderName);
break;
default:
CRASH;
break;
}
}
else
{
OnError(node, box, String::Format(TEXT("Missing graph parameter {0}."), node->Values[0]));
value = Value::Zero;
}
break;
}
default:
break;
}
}
#endif

View File

@@ -177,7 +177,7 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node)
" {{\n"
" // Linear Drag\n"
" float drag = {2} * {3}.x * {3}.y;\n"
" {0} *= max(0.0f, 1.0f - (drag * DeltaTime) / {1});\n"
" {0} *= max(0.0f, 1.0f - (drag * DeltaTime) / max({1}, PARTICLE_THRESHOLD));\n"
" }}\n"
), velocity.Value, mass.Value, drag.Value, spriteSize.Value);
}
@@ -188,7 +188,7 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node)
" {{\n"
" // Linear Drag\n"
" float drag = {2};\n"
" {0} *= max(0.0f, 1.0f - (drag * DeltaTime) / {1});\n"
" {0} *= max(0.0f, 1.0f - (drag * DeltaTime) / max({1}, PARTICLE_THRESHOLD));\n"
" }}\n"
), velocity.Value, mass.Value, drag.Value);
}
@@ -219,7 +219,7 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node)
" float3 vectorFieldUVW = mul(invFieldTransformMatrix, float4({0}, 1.0f)).xyz;\n"
" float3 force = Noise3D(vectorFieldUVW + 0.5f, {8}, {6});\n"
" force = mul(fieldTransformMatrix, float4(force, 0.0f)).xyz * {7};\n"
" {1} += force * (DeltaTime / {2});\n"
" {1} += force * (DeltaTime / max({2}, PARTICLE_THRESHOLD));\n"
" }}\n"
), position.Value, velocity.Value, mass.Value, fieldPosition.Value, fieldRotation.Value, fieldScale.Value, roughness.Value, intensity.Value, octavesCount.Value);
break;
@@ -486,21 +486,21 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node)
" float3 u = RAND3;\n"
" float sinTheta, cosTheta;\n"
" sincos(u.x * PI * 2.0f, sinTheta, cosTheta);\n"
" float r = saturate((float){4} / {3});\n"
" float2 s1_1 = r * float2( cosTheta, sinTheta) + float2(1, 0);\n"
" float2 s1_2 = r * float2(-cosTheta, sinTheta) + float2(1, 0);\n"
" float w = s1_1.x / (s1_1.x + s1_2.x);\n"
" float r = saturate((float){4} / max({3}, PARTICLE_THRESHOLD));\n"
" float2 s11 = r * float2( cosTheta, sinTheta) + float2(1, 0);\n"
" float2 s12 = r * float2(-cosTheta, sinTheta) + float2(1, 0);\n"
" float w = s11.x / (s11.x + s12.x);\n"
" float3 t;\n"
" float phi;\n"
" if (u.y < w)\n"
" {{\n"
" phi = radians({5}) * u.y / w;\n"
" t = float3(s1_1.x, 0, s1_1.y);\n"
" t = float3(s11.x, 0, s11.y);\n"
" }}\n"
" else\n"
" {{\n"
" phi = radians({5}) * (u.y - w) / (1.0f - w);\n"
" t = float3(s1_2.x, 0, s1_2.y);\n"
" t = float3(s12.x, 0, s12.y);\n"
" }}\n"
" float s, c;\n"
" sincos(phi, c, s);\n"
@@ -693,7 +693,7 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node)
" if ({4} * sqrLength <= {4} * totalRadius * totalRadius)\n"
" {{\n"
" float dist = sqrt(sqrLength);\n"
" float3 n = {4} * dir / dist;\n"
" float3 n = {4} * dir / max(dist, PARTICLE_THRESHOLD);\n"
" {0} -= n * (dist - totalRadius) * {4};\n"
COLLISION_LOGIC()
" }}\n"
@@ -787,7 +787,7 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node)
" collision = abs(dir.y) > halfHeight || sqrLength > cylinderRadiusT * cylinderRadiusT;\n"
" if (collision)\n"
" {{\n"
" float dist = sqrt(sqrLength);\n"
" float dist = max(sqrt(sqrLength), PARTICLE_THRESHOLD);\n"
" float distToCap = {4} * (halfHeight - abs(dir.y));\n"
" float distToSide = {4} * (cylinderRadiusT - dist);\n"
" float3 n = float3(dir.x / dist, sign(dir.y), dir.z / dist) * {4};\n"

View File

@@ -113,6 +113,131 @@ ParticleEmitterGPUGenerator::Value ParticleEmitterGPUGenerator::AccessParticleAt
return value.Variable;
}
void ParticleEmitterGPUGenerator::ProcessGroupParameters(Box* box, Node* node, Value& value)
{
switch (node->TypeID)
{
// Get
case 1:
case 2:
{
// Get parameter
const auto param = findParam((Guid)node->Values[0]);
if (param)
{
switch (param->Type)
{
case MaterialParameterType::Bool:
value = Value(VariantType::Bool, param->ShaderName);
break;
case MaterialParameterType::Integer:
case MaterialParameterType::SceneTexture:
value = Value(VariantType::Int, param->ShaderName);
break;
case MaterialParameterType::Float:
value = Value(VariantType::Float, param->ShaderName);
break;
case MaterialParameterType::Vector2:
case MaterialParameterType::Vector3:
case MaterialParameterType::Vector4:
case MaterialParameterType::Color:
{
// Set result values based on box ID
const Value sample(box->Type.Type, param->ShaderName);
switch (box->ID)
{
case 0:
value = sample;
break;
case 1:
value.Value = sample.Value + _subs[0];
break;
case 2:
value.Value = sample.Value + _subs[1];
break;
case 3:
value.Value = sample.Value + _subs[2];
break;
case 4:
value.Value = sample.Value + _subs[3];
break;
default: CRASH;
break;
}
value.Type = box->Type.Type;
break;
}
case MaterialParameterType::Matrix:
{
value = Value(box->Type.Type, String::Format(TEXT("{0}[{1}]"), param->ShaderName, box->ID));
break;
}
case MaterialParameterType::ChannelMask:
{
const auto input = tryGetValue(node->GetBox(0), Value::Zero);
value = writeLocal(VariantType::Float, String::Format(TEXT("dot({0}, {1})"), input.Value, param->ShaderName), node);
break;
}
case MaterialParameterType::CubeTexture:
case MaterialParameterType::Texture:
case MaterialParameterType::GPUTextureArray:
case MaterialParameterType::GPUTextureCube:
case MaterialParameterType::GPUTextureVolume:
case MaterialParameterType::GPUTexture:
value = Value(VariantType::Object, param->ShaderName);
break;
default:
CRASH;
break;
}
}
else
{
OnError(node, box, String::Format(TEXT("Missing graph parameter {0}."), node->Values[0]));
value = Value::Zero;
}
break;
}
default:
break;
}
}
void ParticleEmitterGPUGenerator::ProcessGroupTools(Box* box, Node* node, Value& value)
{
switch (node->TypeID)
{
// Linearize Depth
case 7:
{
// Get input
const Value depth = tryGetValue(node->GetBox(0), Value::Zero).AsFloat();
// Linearize raw device depth
linearizeSceneDepth(node, depth, value);
break;
}
// Time
case 8:
value = box->ID == 0 ? Value(VariantType::Float, TEXT("Time")) : Value(VariantType::Float, TEXT("DeltaTime"));
break;
// Transform Position To Screen UV
case 9:
{
const Value position = tryGetValue(node->GetBox(0), Value::Zero).AsVector3();
const Value projPos = writeLocal(VariantType::Vector4, String::Format(TEXT("mul(float4({0}, 1.0f), ViewProjectionMatrix)"), position.Value), node);
_writer.Write(TEXT("\t{0}.xy /= {0}.w;\n"), projPos.Value);
_writer.Write(TEXT("\t{0}.xy = {0}.xy * 0.5f + 0.5f;\n"), projPos.Value);
value = Value(VariantType::Vector2, projPos.Value + TEXT(".xy"));
break;
}
default:
ShaderGenerator::ProcessGroupTools(box, node, value);
break;
}
}
void ParticleEmitterGPUGenerator::ProcessGroupParticles(Box* box, Node* node, Value& value)
{
switch (node->TypeID)

View File

@@ -256,10 +256,8 @@ void ParticleEmitterGPUGenerator::ProcessGroupTextures(Box* box, Node* node, Val
}
// Scene Depth
case 8:
{
sampleSceneDepth(node, value, box);
break;
}
// Texture
case 11:
{

View File

@@ -1,43 +0,0 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
#if COMPILE_WITH_PARTICLE_GPU_GRAPH
#include "ParticleEmitterGraph.GPU.h"
void ParticleEmitterGPUGenerator::ProcessGroupTools(Box* box, Node* node, Value& value)
{
switch (node->TypeID)
{
// Linearize Depth
case 7:
{
// Get input
const Value depth = tryGetValue(node->GetBox(0), Value::Zero).AsFloat();
// Linearize raw device depth
linearizeSceneDepth(node, depth, value);
break;
}
// Time
case 8:
{
value = box->ID == 0 ? Value(VariantType::Float, TEXT("Time")) : Value(VariantType::Float, TEXT("DeltaTime"));
break;
}
// Transform Position To Screen UV
case 9:
{
const Value position = tryGetValue(node->GetBox(0), Value::Zero).AsVector3();
const Value projPos = writeLocal(VariantType::Vector4, String::Format(TEXT("mul(float4({0}, 1.0f), ViewProjectionMatrix)"), position.Value), node);
_writer.Write(TEXT("\t{0}.xy /= {0}.w;\n"), projPos.Value);
_writer.Write(TEXT("\t{0}.xy = {0}.xy * 0.5f + 0.5f;\n"), projPos.Value);
value = Value(VariantType::Vector2, projPos.Value + TEXT(".xy"));
break;
}
default:
ShaderGenerator::ProcessGroupTools(box, node, value);
break;
}
}
#endif