Texture2D Texture : register(t0); SamplerState Sampler : register(s0); cbuffer Constants { float4x4 ViewProjection; float2 UnitRange; float screenPixelRange = 2; } struct VS_Input { float2 Position : POSITION; float2 Texcoord : TEXCOORD0; float4x4 Tranform : TRANSFORM; float4 Color : COLOR; float4 UVTransform : TEXCOORD1; }; struct PS_Input { float4 Position : SV_Position; float2 TexCoord : TEXCOORD0; float4 Color : COLOR; }; PS_Input VS(VS_Input input) { PS_Input output; output.Position = mul(ViewProjection, mul(input.Tranform, float4(input.Position, 0.0f, 1.0f))); output.TexCoord = input.UVTransform.xy + input.UVTransform.zw * input.Texcoord; output.Color = input.Color; return output; } /* in vec2 texCoord; out vec4 color; uniform sampler2D msdf; uniform vec4 bgColor; uniform vec4 fgColor; float median(float r, float g, float b) { return max(min(r, g), min(max(r, g), b)); } void main() { vec3 msd = texture(msdf, texCoord).rgb; float sd = median(msd.r, msd.g, msd.b); float screenPxDistance = screenPxRange()*(sd - 0.5); float opacity = clamp(screenPxDistance + 0.5, 0.0, 1.0); color = mix(bgColor, fgColor, opacity); } */ float median(float r, float g, float b) { return max(min(r, g), min(max(r, g), b)); } float ScreenPxRange(float2 texcoord) { float2 screenTexSize = 1.0f / fwidth(texcoord); return max(0.5f * dot(UnitRange, screenTexSize), 1.0f); } float4 PS(PS_Input input) : SV_Target0 { float3 msd = Texture.Sample(Sampler, input.TexCoord); float sd = median(msd.r, msd.g, msd.b); float screenPxDistance = ScreenPxRange(input.TexCoord) * (sd - 0.5); float opacity = clamp(screenPxDistance + 0.5, 0.0, 1.0); return float4(input.Color.rgb, opacity * input.Color.a); } /* // 2D float4 PS(PS_Input input) : SV_Target0 { float3 msd = Texture.Sample(Sampler, input.TexCoord).rgb; float sd = median(msd.r, msd.g, msd.b); float screenPxDistance = screenPixelRange*(sd - 0.5); float opacity = clamp(screenPxDistance + 0.5, 0.0, 1.0); return float4(input.Color.rgb, opacity * input.Color.a); } */ #pragma Effect[VS=VS; PS=PS]