Files
armorpaint/Shaders/painter/hlsl/src/cursor.vert.hlsl
T
2020-02-04 17:26:07 +01:00

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;
}