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

150 lines
4.4 KiB
HLSL

cbuffer ParamConstants : register(b0)
{
float4x4 TransformMatrix;
float4 LineColor;
float4 BackgroundColor;
}
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 Params : register(b2)
{
/*{FLOAT_PARAMS}*/
}
struct vsOutput
{
float4 position : SV_POSITION;
float2 texCoord : TEXCOORD;
float3 posInWorld : POSITION;
float distToCamera : DEPTH;
};
static const float3 Quad[] =
{
float3(-1, -1, 0),
float3(1, -1, 0),
float3(1, 1, 0),
float3(1, 1, 0),
float3(-1, 1, 0),
float3(-1, -1, 0),
};
vsOutput vsMain4(uint vertexId : SV_VertexID)
{
vsOutput output;
float2 quadVertex = Quad[vertexId].xy;
float2 quadVertexInObject = quadVertex;
float4 posInObj = mul(float4(quadVertexInObject, 0, 1), TransformMatrix);
output.position = mul(posInObj, ObjectToClipSpace);
output.posInWorld = mul(posInObj, ObjectToWorld).xyz;
output.texCoord = quadVertex * float2(0.5, -0.5) + 0.5;
return output;
}
sampler ClampedSampler : register(s0);
sampler WrappedSampler : register(s1);
//=== Resources =====================================================
/*{RESOURCES(t0)}*/
//=== Globals =======================================================
/*{GLOBALS}*/
//=== Field functions ===============================================
/*{FIELD_FUNCTIONS}*/
//-------------------------------------------------------------------
float4 GetField(float4 p)
{
p.xyz = mul(float4(p.xyz, 1), WorldToObject).xyz;
float4 f = 1;
/*{FIELD_CALL}*/
return f;
}
float GetDistance(float3 p3)
{
return GetField(float4(p3.xyz, 0)).w;
}
//===================================================================
const static float NormalSamplingDistance = 0.01;
float3 GetNormalNonNormalized(float3 p)
{
// return normalize(
return GetDistance(p + float3(NormalSamplingDistance, -NormalSamplingDistance, -NormalSamplingDistance)) * float3(1, -1, -1) +
GetDistance(p + float3(-NormalSamplingDistance, NormalSamplingDistance, -NormalSamplingDistance)) * float3(-1, 1, -1) +
GetDistance(p + float3(-NormalSamplingDistance, -NormalSamplingDistance, NormalSamplingDistance)) * float3(-1, -1, 1) +
GetDistance(p + float3(NormalSamplingDistance, NormalSamplingDistance, NormalSamplingDistance)) * float3(1, 1, 1);
//);
}
#define PI acos(-1.)
#define INFINITY pow(2., 8.)
float4 DistanceMeter(float dist, float rayLength, float3 rayDir, float camHeight, float horizonFade)
{
float idealGridDistance = camHeight;
float nearestBase = floor(log(idealGridDistance) / log(10.0));
float relativeDist = abs(dist / camHeight);
float largerDistance = pow(10.0, nearestBase + 1.0);
float smallerDistance = pow(10.0, nearestBase);
float3 col = 1;
col = max(float3(0.0, 0.0, 0.0), col);
if (sign(dist) < 0.0)
{
// col = col.grb * 0.1;
}
float l0 = pow(0.5 + 0.5 * cos(dist * 3.14159265359 * 2.0 * smallerDistance), 20.0);
float l1 = pow(0.5 + 0.5 * cos(dist * 3.14159265359 * 2.0 * largerDistance), 5.0);
float l = log(idealGridDistance) / log(10.0);
float x = frac(l);
l0 = lerp(l0, 0.0, smoothstep(0.4, 1.0, x));
l1 = lerp(0.0, l1, smoothstep(0.0, 0.4, x));
float lines = pow(1 - (0.01 + 0.99 * (1.0 - l0) * (1.0 - l1)), 20);
float cutline = pow(1 - clamp(abs(dist), 0, 1) + 0.01 / camHeight, 20);
float inside = sign(dist) < 0 ? 0.3 : 0;
float lineAlpha = (lines * 0.7 + cutline + inside) * horizonFade;
return lerp(BackgroundColor, LineColor, lineAlpha);
}
float4 psMain(vsOutput input) : SV_TARGET
{
float dist = GetDistance(input.posInWorld);
float2 s = length(float2(ddy(input.texCoord.x), ddy(input.texCoord.y)));
float3 camPos = mul(float4(0, 0, 0, 1), CameraToWorld).xyz;
float dToCam = length(camPos - input.posInWorld);
float3 ray = float3(0, 0, 1);
float sideView = saturate(max(abs(s.x), abs(s.y)) * 1000);
float lipschitz = pow(length(GetNormalNonNormalized(input.posInWorld)) - 0.0, 0.5);
// return float4( lipschitz.xxx,1);
return DistanceMeter(dist, 0.1, ray, 15 / dToCam, 1 - sideView);
// + float4( lipschitz.xxx,1);
//+ float4( length(lipschitz).xxx / 3,1);
}