add target density option "initial pose"

This commit is contained in:
Lasse Jon Fuglsang Pedersen 2020-12-16 18:00:08 +01:00
Родитель 999e387441
Коммит dd53abc509
7 изменённых файлов: 129 добавлений и 39 удалений

Просмотреть файл

@ -320,6 +320,12 @@ namespace Unity.DemoTeam.Hair
// update volume boundaries
HairSim.UpdateVolumeBoundaries(ref volumeData, volumeSettings, strandBounds);
// update solver data
for (int i = 0; i != solverData.Length; i++)
{
//TODO
}
// pre-step volume if resolution changed
if (HairSim.PrepareVolumeData(ref volumeData, volumeSettings.volumeGridResolution, halfPrecision: false))
{
@ -487,6 +493,7 @@ namespace Unity.DemoTeam.Hair
if (solverData != null && solverData.Length == strandGroups.Length)
return true;
// prep volume data
HairSim.PrepareVolumeData(ref volumeData, volumeSettings.volumeGridResolution, halfPrecision: false);
volumeData.allGroupsMaxParticleInterval = 0.0f;
@ -550,7 +557,7 @@ namespace Unity.DemoTeam.Hair
var strandScale = GetSimulationStrandScale();
var strandTransform = Matrix4x4.TRS(Vector3.zero, GetRootRotation(componentGroups[i]), Vector3.one * strandScale);
HairSim.UpdateSolverData(ref solverData[i], solverSettings, strandTransform, strandScale, 0.0f);
HairSim.UpdateSolverData(ref solverData[i], solverSettings, strandTransform, strandScale, 1.0f);
HairSim.UpdateSolverRoots(cmd, rootMesh, rootTransform, solverData[i]);
{
HairSim.InitSolverParticles(cmd, solverData[i], strandTransform);
@ -577,6 +584,7 @@ namespace Unity.DemoTeam.Hair
}
}
// ready
return true;
}

Просмотреть файл

@ -293,7 +293,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: da692e001514ec24dbc4cca1949ff7e8, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 9
version: 11
--- !u!114 &6109787261538182768
MonoBehaviour:
m_ObjectHideFlags: 11

Просмотреть файл

@ -49,6 +49,7 @@ namespace Unity.DemoTeam.Hair
public static ProfilingSampler Volume_1_SplatVelocityXYZ;
public static ProfilingSampler Volume_1_SplatByRasterization;
public static ProfilingSampler Volume_1_SplatByRasterizationNoGS;
public static ProfilingSampler Volume_1_SplatInitialPose;
public static ProfilingSampler Volume_2_Resolve;
public static ProfilingSampler Volume_2_ResolveFromRasterization;
public static ProfilingSampler Volume_3_Divergence;
@ -125,6 +126,7 @@ namespace Unity.DemoTeam.Hair
public static int KVolumeSplatVelocityX;
public static int KVolumeSplatVelocityY;
public static int KVolumeSplatVelocityZ;
public static int KVolumeSplatInitialPose;
public static int KVolumeResolve;
public static int KVolumeResolveFromRasterization;
public static int KVolumeDivergence;
@ -619,7 +621,7 @@ namespace Unity.DemoTeam.Hair
keywords.ENABLE_SHAPE_GLOBAL = (solverSettings.shape && solverSettings.shapeStiffness > 0.0f);
}
public static void UpdateVolumeBoundaries(ref VolumeData volumeData, in VolumeSettings volumeSettings, in Bounds overlapBounds)
public static void UpdateVolumeBoundaries(ref VolumeData volumeData, in VolumeSettings volumeSettings, in Bounds volumeBounds)
{
ref var cbuffer = ref volumeData.cbuffer;
@ -638,7 +640,7 @@ namespace Unity.DemoTeam.Hair
if (volumeSettings.boundaryShapes)
{
var result = s_boundariesOverlapResult;
var resultCount = Physics.OverlapBoxNonAlloc(overlapBounds.center, overlapBounds.extents, result, Quaternion.identity);
var resultCount = Physics.OverlapBoxNonAlloc(volumeBounds.center, volumeBounds.extents, result, Quaternion.identity);
for (int i = 0; i != resultCount; i++)
{
@ -1096,6 +1098,21 @@ namespace Unity.DemoTeam.Hair
}
break;
}
// accumulate initial pose
if (volumeSettings.targetDensity == VolumeSettings.TargetDensity.InitialPose)
{
int __numX = (int)solverData.cbuffer._StrandCount / PARTICLE_GROUP_SIZE + Mathf.Min(1, (int)solverData.cbuffer._StrandCount % PARTICLE_GROUP_SIZE);
int __numY = 1;
int __numZ = 1;
using (new ProfilingScope(cmd, MarkersGPU.Volume_1_SplatInitialPose))
{
PushVolumeData(cmd, s_volumeCS, VolumeKernels.KVolumeSplatInitialPose, volumeData);
PushSolverData(cmd, s_volumeCS, VolumeKernels.KVolumeSplatInitialPose, solverData);
cmd.DispatchCompute(s_volumeCS, VolumeKernels.KVolumeSplatInitialPose, __numX, __numY, __numZ);
}
}
}
private static void StepVolumeData_Resolve(CommandBuffer cmd, ref VolumeData volumeData, in VolumeSettings volumeSettings)

Просмотреть файл

@ -92,7 +92,6 @@ float BoundaryDistance(const float3 p)
for (uint i = 0; i != _BoundaryTorusCount; i++)
{
BoundaryTorus torus = _BoundaryTorus[i];
d = min(d, SdTorus(p, torus.center, torus.axis, torus.radiusA, torus.radiusB));
}
}

Просмотреть файл

@ -4,6 +4,7 @@
#pragma kernel KVolumeSplatVelocityX
#pragma kernel KVolumeSplatVelocityY
#pragma kernel KVolumeSplatVelocityZ
#pragma kernel KVolumeSplatInitialPose
#pragma kernel KVolumeResolve
#pragma kernel KVolumeResolveFromRasterization
#pragma kernel KVolumeDivergence
@ -14,6 +15,10 @@
//----------
// features
#pragma multi_compile_local __ LAYOUT_INTERLEAVED
// 0 == particles grouped by strand, i.e. root, root+1, root, root+1
// 1 == particles grouped by index, i.e. root, root, root+1, root+1
#pragma multi_compile_local __ VOLUME_SUPPORT_CONTRACTION
// 0 == pressure is always positive
// 1 == negative pressure causes contraction
@ -52,6 +57,10 @@
#define VOLUME_NUM_Y 8
#define VOLUME_NUM_Z 1
#define STRAND_NUM_X 64
#define STRAND_NUM_Y 1
#define STRAND_NUM_Z 1
#if VOLUME_SUPPORT_CONTRACTION
#define VOLUME_REST_AT_ZERO 0
#define VOLUME_AIR_CELL_ZERO_PRESSURE 0
@ -84,6 +93,22 @@
#define CHECK_PARTICLE_INDEX(x) \
if (x >= _StrandCount * _StrandParticleCount) return;
#if LAYOUT_INTERLEAVED
#define DECLARE_STRAND(x) \
if (x >= _StrandCount) return; \
const uint strandIndex = x; \
const uint strandParticleBegin = strandIndex; \
const uint strandParticleStride = _StrandCount; \
const uint strandParticleEnd = strandParticleBegin + strandParticleStride * _StrandParticleCount;
#else
#define DECLARE_STRAND(x) \
if (x >= _StrandCount) return; \
const uint strandIndex = x; \
const uint strandParticleBegin = strandIndex * _StrandParticleCount; \
const uint strandParticleStride = 1; \
const uint strandParticleEnd = strandParticleBegin + strandParticleStride * _StrandParticleCount;
#endif
//---------
// utility
@ -130,33 +155,33 @@ void InterlockedMaxTrilinear(RWTexture3D<int> volume, float value, uint3 idx0, f
InterlockedMax(volume[idx0 + h.xxx], (int)round(value * w1.x * w1.y * w1.z));
}
void InterlockedAddParticleContribution(uint i, float value, RWTexture3D<int> volume, float3 offset = 0.5)
void InterlockedAddParticleContribution(float3 worldPos, float value, RWTexture3D<int> volume, float3 offset = 0.5)
{
#if SPLAT_TRILINEAR
TrilinearWeights tri = VolumeWorldToCellTrilinear(_ParticlePosition[i].xyz, offset);
TrilinearWeights tri = VolumeWorldToCellTrilinear(worldPos, offset);
InterlockedAddTrilinear(volume, value * (1 << SPLAT_FRACTIONAL_BITS), tri.idx0, tri.w0, tri.w1);
#else
InterlockedAdd(volume[VolumeWorldToIndex(_ParticlePosition[i].xyz)], (int)round(value * (1 << SPLAT_FRACTIONAL_BITS)));
InterlockedAdd(volume[VolumeWorldToIndex(worldPos)], (int)round(value * (1 << SPLAT_FRACTIONAL_BITS)));
#endif
}
void InterlockedAddParticleContributionPackW(uint i, float value, RWTexture3D<int> volume, float3 offset = 0.5)
void InterlockedAddParticleContributionPackW(float3 worldPos, float value, RWTexture3D<int> volume, float3 offset = 0.5)
{
#if SPLAT_TRILINEAR
TrilinearWeights tri = VolumeWorldToCellTrilinear(_ParticlePosition[i].xyz, offset);
TrilinearWeights tri = VolumeWorldToCellTrilinear(worldPos, offset);
InterlockedAddTrilinearPackW(volume, value * (1 << SPLAT_FRACTIONAL_BITS), tri.idx0, tri.w0, tri.w1);
#else
InterlockedAdd(volume[VolumeWorldToIndex(_ParticlePosition[i].xyz)], (int)round(value * (1 << SPLAT_FRACTIONAL_BITS)));
InterlockedAdd(volume[VolumeWorldToIndex(worldPos)], (int)round(value * (1 << SPLAT_FRACTIONAL_BITS)));
#endif
}
void InterlockedMaxParticleContribution(uint i, float value, RWTexture3D<int> volume, float3 offset = 0.5)
void InterlockedMaxParticleContribution(float3 worldPos, float value, RWTexture3D<int> volume, float3 offset = 0.5)
{
#if SPLAT_TRILINEAR
TrilinearWeights tri = VolumeWorldToCellTrilinear(_ParticlePosition[i].xyz, offset);
TrilinearWeights tri = VolumeWorldToCellTrilinear(worldPos, offset);
InterlockedMaxTrilinear(volume, value * (1 << SPLAT_FRACTIONAL_BITS), tri.idx0, tri.w0, tri.w1);
#else
InterlockedMax(volume[VolumeWorldToIndex(_ParticlePosition[i].xyz)], (int)round(value * (1 << SPLAT_FRACTIONAL_BITS)));
InterlockedMax(volume[VolumeWorldToIndex(worldPos)], (int)round(value * (1 << SPLAT_FRACTIONAL_BITS)));
#endif
}
@ -175,9 +200,11 @@ void KVolumeClear(
// SV_GroupIndex thread offset within execution group
{
_AccuWeight[worldIdx] = 0;
#if VOLUME_TARGET_INITIAL_POSE_IN_PARTICLES
#if VOLUME_TARGET_INITIAL_POSE || VOLUME_TARGET_INITIAL_POSE_IN_PARTICLES
_AccuWeight0[worldIdx] = 0;
#endif
_AccuVelocityX[worldIdx] = 0;
_AccuVelocityY[worldIdx] = 0;
_AccuVelocityZ[worldIdx] = 0;
@ -203,21 +230,22 @@ void KVolumeSplat(
//float3 velocityStepLimit = _VolumeWorldMax - _VolumeWorldMin;
//float3 velocityStep = clamp(_ParticleVelocity[worldIdx.x].xyz * _DT, -velocityStepLimit, velocityStepLimit);
const float3 p = _ParticlePosition[worldIdx.x].xyz;
const float4 v = _ParticleVelocity[worldIdx.x];
InterlockedAddParticleContribution(worldIdx.x, (v.w), _AccuWeight);
InterlockedAddParticleContribution(p, (v.w), _AccuWeight);
#if VOLUME_TARGET_INITIAL_POSE_IN_PARTICLES
InterlockedMaxParticleContribution(worldIdx.x, (v.w * _ParticlePosition[worldIdx.x].w), _AccuWeight0);
InterlockedMaxParticleContribution(p, (v.w * _ParticlePosition[worldIdx.x].w), _AccuWeight0);
#endif
#if VOLUME_STAGGERED_GRID
InterlockedAddParticleContributionPackW(worldIdx.x, (v.w * v.x), _AccuVelocityX, float3(0.0, 0.5, 0.5));
InterlockedAddParticleContributionPackW(worldIdx.x, (v.w * v.y), _AccuVelocityY, float3(0.5, 0.0, 0.5));
InterlockedAddParticleContributionPackW(worldIdx.x, (v.w * v.z), _AccuVelocityZ, float3(0.5, 0.5, 0.0));
InterlockedAddParticleContributionPackW(p, (v.w * v.x), _AccuVelocityX, float3(0.0, 0.5, 0.5));
InterlockedAddParticleContributionPackW(p, (v.w * v.y), _AccuVelocityY, float3(0.5, 0.0, 0.5));
InterlockedAddParticleContributionPackW(p, (v.w * v.z), _AccuVelocityZ, float3(0.5, 0.5, 0.0));
#else
InterlockedAddParticleContribution(worldIdx.x, (v.w * v.x), _AccuVelocityX);
InterlockedAddParticleContribution(worldIdx.x, (v.w * v.y), _AccuVelocityY);
InterlockedAddParticleContribution(worldIdx.x, (v.w * v.z), _AccuVelocityZ);
InterlockedAddParticleContribution(p, (v.w * v.x), _AccuVelocityX);
InterlockedAddParticleContribution(p, (v.w * v.y), _AccuVelocityY);
InterlockedAddParticleContribution(p, (v.w * v.z), _AccuVelocityZ);
#endif
}
@ -234,11 +262,12 @@ void KVolumeSplatDensity(
{
CHECK_PARTICLE_INDEX(worldIdx.x);
const float3 p = _ParticlePosition[worldIdx.x].xyz;
const float4 v = _ParticleVelocity[worldIdx.x];
InterlockedAddParticleContribution(worldIdx.x, (v.w), _AccuWeight);
InterlockedAddParticleContribution(p, (v.w), _AccuWeight);
#if VOLUME_TARGET_INITIAL_POSE_IN_PARTICLES
InterlockedMaxParticleContribution(worldIdx.x, (v.w * _ParticlePosition[worldIdx.x].w), _AccuWeight0);
InterlockedMaxParticleContribution(p, (v.w * _ParticlePosition[worldIdx.x].w), _AccuWeight0);
#endif
}
@ -255,12 +284,13 @@ void KVolumeSplatVelocityX(
{
CHECK_PARTICLE_INDEX(worldIdx.x);
const float3 p = _ParticlePosition[worldIdx.x].xyz;
const float4 v = _ParticleVelocity[worldIdx.x];
#if VOLUME_STAGGERED_GRID
InterlockedAddParticleContributionPackW(worldIdx.x, (v.w * v.x), _AccuVelocityX, float3(0.0, 0.5, 0.5));
InterlockedAddParticleContributionPackW(p, (v.w * v.x), _AccuVelocityX, float3(0.0, 0.5, 0.5));
#else
InterlockedAddParticleContribution(worldIdx.x, (v.w * v.x), _AccuVelocityX);
InterlockedAddParticleContribution(p, (v.w * v.x), _AccuVelocityX);
#endif
}
@ -277,12 +307,13 @@ void KVolumeSplatVelocityY(
{
CHECK_PARTICLE_INDEX(worldIdx.x);
const float3 p = _ParticlePosition[worldIdx.x].xyz;
const float4 v = _ParticleVelocity[worldIdx.x];
#if VOLUME_STAGGERED_GRID
InterlockedAddParticleContributionPackW(worldIdx.x, (v.w * v.y), _AccuVelocityY, float3(0.5, 0.0, 0.5));
InterlockedAddParticleContributionPackW(p, (v.w * v.y), _AccuVelocityY, float3(0.5, 0.0, 0.5));
#else
InterlockedAddParticleContribution(worldIdx.x, (v.w * v.y), _AccuVelocityY);
InterlockedAddParticleContribution(p, (v.w * v.y), _AccuVelocityY);
#endif
}
@ -299,15 +330,42 @@ void KVolumeSplatVelocityZ(
{
CHECK_PARTICLE_INDEX(worldIdx.x);
const float3 p = _ParticlePosition[worldIdx.x].xyz;
const float4 v = _ParticleVelocity[worldIdx.x];
#if VOLUME_STAGGERED_GRID
InterlockedAddParticleContributionPackW(worldIdx.x, (v.w * v.z), _AccuVelocityZ, float3(0.5, 0.5, 0.0));
InterlockedAddParticleContributionPackW(p, (v.w * v.z), _AccuVelocityZ, float3(0.5, 0.5, 0.0));
#else
InterlockedAddParticleContribution(worldIdx.x, (v.w * v.z), _AccuVelocityZ);
InterlockedAddParticleContribution(p, (v.w * v.z), _AccuVelocityZ);
#endif
}
[numthreads(STRAND_NUM_X, STRAND_NUM_Y, STRAND_NUM_Z)]
void KVolumeSplatInitialPose(
uint3 groupIdx : SV_GroupID,
uint3 localIdx : SV_GroupThreadID,
uint3 worldIdx : SV_DispatchThreadID,
uint threadIdx : SV_GroupIndex)
// SV_GroupID execution group coords
// SV_GroupThreadID thread coords within execution group
// SV_DispatchThreadID thread coords (global)
// SV_GroupIndex thread offset within execution group
{
DECLARE_STRAND(worldIdx.x);
float3 p0 = _ParticlePosition[strandParticleBegin].xyz;
for (uint i = strandParticleBegin; i != strandParticleEnd; i += strandParticleStride)
{
float3 r = mul(_LocalToWorld, float4(_ParticlePositionPose[i].xyz, 0.0)).xyz;
float3 p = p0 + r;
#if VOLUME_TARGET_INITIAL_POSE
InterlockedAddParticleContribution(p, _ParticleVelocity[i].w, _AccuWeight0);
#endif
}
}
//-----------------
// kernels resolve
@ -334,7 +392,7 @@ void KVolumeResolve(
_VolumeDensity[worldIdx] = rho_particle * accu_w;
#if VOLUME_TARGET_INITIAL_POSE
_VolumeDensity0[worldIdx] = 0.0;//TODO
_VolumeDensity0[worldIdx] = rho_particle * (_AccuWeight0[worldIdx] / (float)(1 << SPLAT_FRACTIONAL_BITS));
#elif VOLUME_TARGET_INITIAL_POSE_IN_PARTICLES
_VolumeDensity0[worldIdx] = rho_particle * (_AccuWeight0[worldIdx] / (float)(1 << SPLAT_FRACTIONAL_BITS));
#endif
@ -372,15 +430,13 @@ void KVolumeResolveFromRasterization(
{
const float4 splat = _VolumeVelocity[worldIdx];
{
const float rho_particle = _ResolveUnitVolume / (1e+9 * VolumeWorldCellVolume());
const float rho_unscaled = splat.w;
#if DEBUG_STRAND_31_32
const float rho = pow(_ResolveUnitDebugWidth, 3.0) * rho_unscaled;
const float rho_particle = pow(_ResolveUnitDebugWidth, 3.0);
#else
const float rho = rho_particle * rho_unscaled;
const float rho_particle = _ResolveUnitVolume / (1e+9 * VolumeWorldCellVolume());
#endif
_VolumeDensity[worldIdx] = rho;
_VolumeDensity[worldIdx] = rho_particle * splat.w;
if (splat.w > 0.0)
_VolumeVelocity[worldIdx] = float4(splat.xyz / splat.w, splat.w);

Просмотреть файл

@ -8,6 +8,10 @@
// 0 == particles grouped by strand, i.e. root, root+1, root, root+1
// 1 == particles grouped by index, i.e. root, root, root+1, root+1
#pragma multi_compile_local __ VOLUME_TARGET_INITIAL_POSE VOLUME_TARGET_INITIAL_POSE_IN_PARTICLES
// 0 == uniform target density
// 1 == non uniform target density
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
@ -147,7 +151,11 @@
}
float volumeDensity = VolumeSampleScalar(_VolumeDensity, uvw);
#if VOLUME_TARGET_INITIAL_POSE || VOLUME_TARGET_INITIAL_POSE_IN_PARTICLES
float volumeDensity0 = VolumeSampleScalar(_VolumeDensity0, uvw);
#else
float volumeDensity0 = 1.0;
#endif
float3 volumeVelocity = VolumeSampleVector(_VolumeVelocity, uvw);
float volumeDivergence = VolumeSampleScalar(_VolumeDivergence, uvw);
float volumePressure = VolumeSampleScalar(_VolumePressure, uvw);
@ -201,7 +209,7 @@
if (x < 1.0)
return float4(ColorDensity(volumeDensity), _DebugSliceOpacity);
else if (x < 2.0)
return float4(ColorDensity(volumeDensity0), _DebugSliceOpacity);
return float4(float3(1.0, 1.0, 0.0) * ColorDensity(volumeDensity0), _DebugSliceOpacity);
else if (x < 3.0)
return float4(ColorVelocity(volumeVelocity), _DebugSliceOpacity);
else if (x < 4.0)

Просмотреть файл

@ -192,6 +192,8 @@ Material:
- _LinkDetailsWithBase: 1
- _MaterialID: 1
- _Metallic: 0
- _MetallicRemapMax: 0
- _MetallicRemapMin: 0
- _NormalMapSpace: 0
- _NormalScale: 1
- _OpaqueCullMode: 2
@ -276,4 +278,4 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: da692e001514ec24dbc4cca1949ff7e8, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 9
version: 11