XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
cbuffer Camera : register(b0)
{
    row_major float4x4 World;
    row_major float4x4 ViewProjection;
    float4 Eye;
    float4 HologramColor;
    float4 Detail; // viewport width/height, minimum line length, line opacity
    float4 Sobel; // original distance scale, edge thickness, max distance, power
    float4 TintHigh;
    float4 TintLow;
    float4 Scan; // original UV scale, display exposure, animation time
};
struct VSInput { float3 position : POSITION; float3 normal : NORMAL; };
struct PSInput { float4 position : SV_POSITION; float3 normal : NORMAL; float3 worldPosition : TEXCOORD0; float lineFade : TEXCOORD1; };
PSInput VSMain(VSInput input)
{
    PSInput result;
    float4 world = mul(float4(input.position, 1), World);
    result.position = mul(world, ViewProjection);
    result.worldPosition = world.xyz;
    result.normal = normalize(mul(float4(input.normal, 0), World).xyz);
    result.lineFade = 1;
    return result;
}
float4 PSNormals(PSInput input) : SV_TARGET
{
    return float4(normalize(input.normal), length(Eye.xyz - input.worldPosition));
}
PSInput VSLine(VSInput input)
{
    PSInput result = VSMain(input);
    if (Detail.z > 0)
    {
        float4 end = mul(mul(float4(input.position + input.normal, 1), World), ViewProjection);
        float lengthPixels = length((end.xy / end.w - result.position.xy / result.position.w) * Detail.xy * .5);
        result.lineFade = smoothstep(Detail.z, Detail.z + 5, lengthPixels);
    }
    result.position.z -= .000003 * result.position.w;
    return result;
}
float4 PSLine(PSInput input) : SV_TARGET
{
    float opacity = Detail.w * input.lineFade;
    return float4(HologramColor.rgb * float3(.59, .69, .72) * (opacity / .70), opacity);
}
float4 PSBase(PSInput input) : SV_TARGET { return float4(.008, .021, .033, .10); }
Texture2D<float4> Image : register(t0);
Texture2D<float4> Glow : register(t1);
SamplerState LinearClamp : register(s0);
struct ScreenInput { float4 position : SV_POSITION; float2 uv : TEXCOORD0; };
ScreenInput VSFullscreen(uint id : SV_VertexID)
{
    float2 uv = float2((id << 1) & 2, id & 2);
    ScreenInput result;
    result.position = float4(uv * float2(2, -2) + float2(-1, 1), 0, 1);
    result.uv = uv;
    return result;
}
float4 NormalAt(int2 pixel)
{
    return Image.Load(int3(clamp(pixel, int2(0,0), int2(Detail.xy)-1),0));
}
float4 PSOutline(ScreenInput input) : SV_TARGET
{
    int2 p=int2(input.position.xy);int s=max(1,(int)Sobel.y);
    float4 centre=NormalAt(p);
    if(centre.w<=0)return 0;
    float4 tl=NormalAt(p+int2(-s,-s)),tc=NormalAt(p+int2(0,-s)),tr=NormalAt(p+int2(s,-s));
    float4 ml=NormalAt(p+int2(-s,0)),mr=NormalAt(p+int2(s,0));
    float4 bl=NormalAt(p+int2(-s,s)),bc=NormalAt(p+int2(0,s)),br=NormalAt(p+int2(s,s));
    float3 nx=(tr.rgb+2*mr.rgb+br.rgb)-(tl.rgb+2*ml.rgb+bl.rgb);
    float3 ny=(bl.rgb+2*bc.rgb+br.rgb)-(tl.rgb+2*tc.rgb+tr.rgb);
    float normalEdge=sqrt(dot(nx,nx)+dot(ny,ny))*.25;
    float depthX=(tr.w+2*mr.w+br.w)-(tl.w+2*ml.w+bl.w);
    float depthY=(bl.w+2*bc.w+br.w)-(tl.w+2*tc.w+tr.w);
    float depthEdge=length(float2(depthX,depthY))/max(centre.w,.001)*.25;
    float response=saturate(max(normalEdge*.55,depthEdge)*Sobel.x);
    float edge=pow(response,Sobel.w);
    // The original FGM uses a screen-space scanline texture with this UV scale.
    // Keep the phase in display pixels so a small preview has the same fine raster.
    float scanline=.68+.32*cos(6.2831853*input.position.y*Scan.y*128);
    float3 face=TintLow.rgb*.022*scanline;
    return float4(face+TintHigh.rgb*edge*scanline,1);
}
float4 Blur(float2 uv,float2 step)
{
    float4 color=Image.SampleLevel(LinearClamp,uv,0)*.227027;
    color+=(Image.SampleLevel(LinearClamp,uv+step*1.384615,0)+Image.SampleLevel(LinearClamp,uv-step*1.384615,0))*.316216;
    color+=(Image.SampleLevel(LinearClamp,uv+step*3.230769,0)+Image.SampleLevel(LinearClamp,uv-step*3.230769,0))*.070270;
    return color;
}
float4 PSBlurHorizontal(ScreenInput input):SV_TARGET{return Blur(input.uv,float2(3/Detail.x,0));}
float4 PSBlurVertical(ScreenInput input):SV_TARGET{return Blur(input.uv,float2(0,3/Detail.y));}
float4 PSComposite(ScreenInput input):SV_TARGET
{
    float4 sharp=Image.SampleLevel(LinearClamp,input.uv,0);
    float3 bloom=Glow.SampleLevel(LinearClamp,input.uv,0).rgb;
    float3 radiance=max(0,sharp.rgb+bloom*.38);
    float3 color=pow(1-exp(-radiance*Scan.z),1/2.2);
    float alpha=saturate(max(sharp.a*.94,max(color.r,max(color.g,color.b))));
    return float4(min(color,alpha),alpha);
}