54 lines
2.0 KiB
HLSL
54 lines
2.0 KiB
HLSL
uniform float4x4 VP;
|
|
uniform float4x4 invVP;
|
|
uniform float2 mouse;
|
|
uniform float2 texStep;
|
|
uniform float radius;
|
|
Texture2D<float4> texa; // direct3d12 unit align
|
|
SamplerState _texa_sampler; // direct3d12 unit align
|
|
Texture2D<float4> gbufferD;
|
|
SamplerState _gbufferD_sampler;
|
|
float3x3 rotAxis(float3 axis, float a) {
|
|
float c = cos(a);
|
|
float3 as = axis * sin(a).xxx;
|
|
float3x3 p = float3x3(axis.xxx * axis, axis.yyy * axis, axis.zzz * axis);
|
|
float3x3 q = float3x3(c, -as.z, as.y, as.z, c, -as.x, -as.y, as.x, c);
|
|
return p * (1.0 - c) + q;
|
|
}
|
|
float3 getPos(float2 uv) {
|
|
float2 uvinv = float2(uv.x, 1.0 - uv.y);
|
|
float depth = gbufferD.SampleLevel(_gbufferD_sampler, uvinv, 0).r;
|
|
float4 wpos = float4(uv * 2.0 - 1.0, depth * 2.0 - 1.0, 1.0);
|
|
wpos = mul(wpos, invVP);
|
|
return wpos.xyz / wpos.w;
|
|
}
|
|
float3 getNormal(float3 p0, float2 uv) {
|
|
float3 p1 = getPos(uv + float2(texStep.x, 0));
|
|
float3 p2 = getPos(uv + float2(0, texStep.y));
|
|
return normalize(cross(p2 - p0, p1 - p0));
|
|
}
|
|
struct SPIRV_Cross_Output { float2 texCoord : TEXCOORD0; float4 gl_Position : SV_Position; };
|
|
SPIRV_Cross_Output main(float2 nor : TEXCOORD0, float4 pos : TEXCOORD1, float2 tex : TEXCOORD2) {
|
|
SPIRV_Cross_Output stage_output;
|
|
stage_output.texCoord = tex;
|
|
float3 wpos = getPos(mouse);
|
|
float2 uv1 = mouse + texStep * 4;
|
|
float2 uv2 = mouse - texStep * 4;
|
|
float3 wpos1 = getPos(uv1);
|
|
float3 wpos2 = getPos(uv2);
|
|
float keep = texa.SampleLevel(_texa_sampler, mouse, 0).r; // direct3d12 unit align
|
|
wpos.x += keep * 0.0000001; // direct3d12 unit align;
|
|
float3 n = normalize(
|
|
getNormal(wpos, mouse) +
|
|
getNormal(wpos1, uv1) +
|
|
getNormal(wpos2, uv2)
|
|
);
|
|
float ax = acos(dot(float3(1,0,0), float3(n.x,0,0)));
|
|
float az = acos(dot(float3(0,0,1), float3(0,0,n.z)));
|
|
float sy = -sign(n.y);
|
|
wpos += mul(mul(pos.xyz * radius.xxx, rotAxis(float3(0,0,1), ax + 3.14/2)),
|
|
rotAxis(float3(1,0,0), -az * sy + 3.14/2));
|
|
stage_output.gl_Position = mul(float4(wpos, 1.0), VP);
|
|
stage_output.gl_Position.z = (stage_output.gl_Position.z + stage_output.gl_Position.w) * 0.5;
|
|
return stage_output;
|
|
}
|