Files
2026-07-13 13:13:17 +08:00

135 lines
3.5 KiB
HLSL

#include "shared/point.hlsl"
#include "shared/quat-functions.hlsl"
// struct Point
// {
// float3 position;
// float size;
// };
static const float3 Corners[] =
{
float3(0, -1, 0),
float3(1, -1, 0),
float3(1, 1, 0),
float3(1, 1, 0),
float3(0, 1, 0),
float3(0, -1, 0),
};
cbuffer Params : register(b0)
{
float4 Color;
float Size;
float ShrinkWithDistance;
float OffsetU;
float UseWForWidth;
float UseWForU;
float WidthFactor;
};
cbuffer Transforms : register(b1)
{
float4x4 CameraToClipSpace;
float4x4 ClipSpaceToCamera;
float4x4 WorldToCamera;
float4x4 CameraToWorld;
float4x4 WorldToClipSpace;
float4x4 ClipSpaceToWorld;
float4x4 ObjectToWorld;
float4x4 WorldToObject;
float4x4 ObjectToCamera;
float4x4 ObjectToClipSpace;
};
cbuffer FogParams : register(b2)
{
float4 FogColor;
float FogDistance;
float FogBias;
}
struct psInput
{
float4 position : SV_POSITION;
float4 color : COLOR;
float2 texCoord : TEXCOORD;
float fog : FOG;
};
sampler texSampler : register(s0);
StructuredBuffer<Point> Points : t0;
Texture2D<float4> texture2 : register(t1);
psInput vsMain(uint id : SV_VertexID)
{
psInput output;
float discardFactor = 1;
uint SegmentCount, Stride;
Points.GetDimensions(SegmentCount, Stride);
float4 aspect = float4(CameraToClipSpace[1][1] / CameraToClipSpace[0][0], 1, 1, 1);
int quadIndex = id % 6;
uint particleId = id / 6;
float3 cornerFactors = Corners[quadIndex];
float f = cornerFactors.x;
// Point pointAA = Points[ particleId<1 ? 0: particleId-1];
Point pointA = Points[particleId];
Point pointB = Points[particleId + 1];
if (isnan(pointA.Scale.x) || isnan(pointB.Scale.x))
{
output.position = 0;
return output;
}
float4 forward = mul(float4(0, 0, -1, 0), CameraToWorld);
forward = mul(float4(forward.xyz, 0), WorldToObject);
float4 camUpInWorld = mul(float4(0, 1, 0, 0), CameraToWorld);
float4 camUpInObject = mul(camUpInWorld, WorldToObject);
float3 posInObject = f < 0.5 ? pointA.Position : pointB.Position;
float3 posAInCamera = mul(float4(pointA.Position, 1), ObjectToCamera).xyz;
float3 posBInCamera = mul(float4(pointB.Position, 1), ObjectToCamera).xyz;
float4 lineInCamera = float4(posAInCamera - posBInCamera, 1);
float3 forwardInCamera = float3(0, 0, -1);
float3 lineCenterInCamera = lerp(posAInCamera, posBInCamera, 0.5);
float3 sideInCamera = normalize(cross(lineCenterInCamera, lineInCamera.xyz));
output.texCoord = float2(
f,
cornerFactors.y / 2 + 0.5);
float4 posInCamera = mul(float4(posInObject, 1), ObjectToCamera);
float pFx1 = lerp(pointA.FX1, pointB.FX1, f);
float pFx2 = lerp(pointA.FX2, pointB.FX2, f);
float sizeFxFactor = WidthFactor < 0.5 ? 1 : ((WidthFactor < 1.5) ? pFx1 : pFx2);
posInCamera.xyz += sideInCamera * Size * sizeFxFactor / 1000 * cornerFactors.y;
output.position = mul(posInCamera, CameraToClipSpace);
output.fog = pow(saturate(-posInCamera.z / FogDistance), FogBias);
output.color = Color * (f < 0.5 ? pointA.Color : pointB.Color);
return output;
}
float4 psMain(psInput input) : SV_TARGET
{
float4 imgColor = texture2.Sample(texSampler, input.texCoord);
float dFromLineCenter = abs(input.texCoord.y - 0.5) * 2;
float4 col = input.color * imgColor;
col.rgb = lerp(col.rgb, FogColor.rgb, input.fog);
return clamp(col, float4(0, 0, 0, 0), float4(1000, 1000, 1000, 1));
}