port from perforce

This commit is contained in:
2026-04-18 22:31:51 +02:00
commit 8d0ab5b7cc
8409 changed files with 3972376 additions and 0 deletions

200
hgplus/particles/test.hlsl Normal file
View File

@@ -0,0 +1,200 @@
#define ParticleType_Dead 0
#define ParticleType_Emitter 1
#define ParticleType_Point 2
struct ParticleState
{
int type;
float3 oldPosition;
float3 currentPosition;
float3 direction;
float creationTime;
float mass;
};//48 bytes
#define PI 3.14159265
float hash(float n) { return frac(sin(n)*43758.5453123); }
cbuffer _0 : register(b0)
{
float demoTime;
float deltaTime;
float dummy1;
float dummy2;
};
static const float emitRate = 0.00001f; //delay in seconds between each particle spawn
static const float lifeTime = 1.0f; //particle lifetime in seconds
ConsumeStructuredBuffer<ParticleState> particles:register(u0);
AppendStructuredBuffer<ParticleState> writeParticles:register(u1);
StructuredBuffer<ParticleState> readParticles:register(t0);
void emit(int type, float3 oldPosition, float3 position, float3 direction, float time)
{
ParticleState emittedParticle;
emittedParticle.type = type;
emittedParticle.oldPosition = position;
emittedParticle.currentPosition = position;
emittedParticle.creationTime = time;
emittedParticle.direction = direction;
emittedParticle.mass = 1;
writeParticles.Append(emittedParticle); // emit new particle
}
void recycle(ParticleState particle)
{
ParticleState newParticle;
newParticle.type = particle.type;
newParticle.oldPosition = particle.currentPosition;
newParticle.currentPosition = particle.currentPosition + particle.direction * deltaTime;
newParticle.creationTime = particle.creationTime;
newParticle.direction = particle.direction;
if (particle.type == ParticleType_Point)
newParticle.direction += float3(0, -10, 0) * deltaTime;
newParticle.mass = particle.mass;
writeParticles.Append(newParticle);
}
[numthreads(1, 1, 1)]
void init(int3 id:SV_DispatchThreadID)
{
emit(ParticleType_Emitter, float3(0, 0, 0), float3(0, 0, 0), float3(0, 0, 0), demoTime);
}
float3 project(float3 v)
{
return float3(v.x, v.y, (1 - v.z) / 10.0f) / -v.z;
}
float3 h2r(float h, float s, float v){ return lerp(saturate((abs(frac(h + float3(1, 2, 3) / 3) * 6 - 3) - 1)), 1, s)*v; }
[numthreads(1, 1, 1)]
void update(int3 id:SV_DispatchThreadID)
{
float seed = 1024 * id.y + id.x + hash(demoTime) * 1024;
ParticleState particle = particles.Consume();
if (particle.type == ParticleType_Emitter)
{
float t = particle.creationTime;
particle.currentPosition = float3(sin(t * 20), -1, cos(t * 20) - 3) * 0.3;
if (demoTime - particle.creationTime < emitRate)
{
recycle(particle);
}
else
{
while (t <= demoTime)
{
particle.currentPosition = float3(sin(t * 20), -1, cos(t * 20) - 3) * 0.3;
emit(ParticleType_Point, particle.currentPosition, particle.currentPosition, hash(seed++ * demoTime) * 5 * normalize(float3(hash(seed++) * 2 - 1, 10 * hash(seed++ * demoTime * demoTime), hash(seed++ * demoTime * 10) * 2 - 1)), t);
t += emitRate;
}
emit(ParticleType_Emitter, particle.currentPosition, particle.currentPosition, particle.direction, t);
}
}
else if (particle.type == ParticleType_Point)
{
float age = (demoTime - particle.creationTime) / lifeTime;
uint index;
if (age <= 1)
{
recycle(particle);
}
}
}
struct _2
{
float3 pos1 : TEXCOORD0;
float3 pos2 : TEXCOORD1;
float3 dir : TEXCOORD2;
float age : AGE;
int valid : VALID;
};
struct _3
{
float4 pos : SV_POSITION;
float length : LENGTH;
float age : AGE;
};
void pvs(uint id : SV_VertexID, out _2 o)
{
ParticleState particle = readParticles[id];
o.pos1 = particle.oldPosition;
o.pos2 = particle.currentPosition;
o.dir = particle.direction;
o.age = (demoTime - particle.creationTime) / lifeTime;
o.valid = particle.type == ParticleType_Point ? 1 : 0;
}
float particleSize(float z)
{
return 0.0005f / -z;
}
[maxvertexcount(18)]
void pgs(point _2 input[1], inout TriangleStream<_3> o)
{
_2 p = input[0];
if (p.valid == 0)
return;
float s1 = particleSize(p.pos1.z);
float s2 = particleSize(p.pos2.z);
float3 p1 = project(p.pos1);
float3 p2 = project(p.pos2);
float2 d = normalize(p2.xy - p1.xy);
if (length(d) == 0)
d = normalize(project(p.dir).xy);
float2 pr = float2(-d.y, d.x);
p1.xy += d * s1 * 0.5;
p2.xy -= d * s2 * 0.5;
_3 r;
r.length = distance(p1.xy, p2.xy) * 128;
r.age = p.age;
r.pos = float4(p1.xy - d * s1, p1.z, 1.0); o.Append(r);
r.pos = float4(p1.xy + pr * s1, p1.z, 1.0); o.Append(r);
r.pos = float4(p1.xy - pr * s1, p1.z, 1.0); o.Append(r);
o.RestartStrip();
r.pos = float4(p1.xy - pr * s1, p1.z, 1.0); o.Append(r);
r.pos = float4(p1, 1.0); o.Append(r);
r.pos = float4(p2.xy - pr * s2, p2.z, 1.0); o.Append(r);
o.RestartStrip();
r.pos = float4(p1, 1.0); o.Append(r);
r.pos = float4(p2, 1.0); o.Append(r);
r.pos = float4(p2.xy - pr * s2, p2.z, 1.0); o.Append(r);
o.RestartStrip();
r.pos = float4(p1, 1.0); o.Append(r);
r.pos = float4(p2.xy + pr * s2, p2.z, 1.0); o.Append(r);
r.pos = float4(p2, 1.0); o.Append(r);
o.RestartStrip();
r.pos = float4(p1, 1.0); o.Append(r);
r.pos = float4(p1.xy + pr * s1, p1.z, 1.0); o.Append(r);
r.pos = float4(p2.xy + pr * s2, p2.z, 1.0); o.Append(r);
o.RestartStrip();
r.pos = float4(p2.xy + d * s2, p2.z, 1.0); o.Append(r);
r.pos = float4(p2.xy - pr * s2, p2.z, 1.0); o.Append(r);
r.pos = float4(p2.xy + pr * s2, p2.z, 1.0); o.Append(r);
o.RestartStrip();
}
float4 pps(_3 i) : SV_Target
{
float intensity = 1.0 / (i.length + 50);
float3 color = h2r(i.age * 3, 0.2, 1.0);
return float4(color, intensity);
}