Skip to content

Instantly share code, notes, and snippets.

@forkerer
Created August 19, 2018 13:50
Show Gist options
  • Save forkerer/bf81c026b19bf9ac12f86e8fc8e310d1 to your computer and use it in GitHub Desktop.
Save forkerer/bf81c026b19bf9ac12f86e8fc8e310d1 to your computer and use it in GitHub Desktop.
Faster shader based dxDrawCircle
float4x4 gWorldViewProjection : WORLDVIEWPROJECTION;
struct VSInput
{
float3 Position : POSITION0;
float4 Diffuse : COLOR0;
float2 TexCoord : TEXCOORD0;
};
struct PSInput
{
float4 Position : POSITION0;
float4 Diffuse : COLOR0;
float4 Diffuse2 : COLOR1;
float2 TexCoord : TEXCOORD0;
float2 Settings : TEXCOORD1;
};
PSInput VertexShaderFunction(VSInput VS)
{
PSInput PS = (PSInput)0;
PS.Position = mul(float4(VS.Position, 1), gWorldViewProjection);
int bAntialias = floor(VS.Diffuse.a*255+0.5)%2;
int bTwoColors = floor(VS.Diffuse.a*127+0.5)%2;
[branch] if(bTwoColors == 1){
float aComp = floor(VS.Diffuse.a*63+0.5)%64;;
PS.Diffuse = float4((floor(VS.Diffuse.rgb*15+0.5)%16)/15, (aComp%8)/7);
PS.Diffuse2 = float4(floor((VS.Diffuse.rgb*255+0.5)%16)/15, ((aComp/8)%8)/7);
} else {
PS.Diffuse = float4(VS.Diffuse.rgb, floor(VS.Diffuse.a*63+0.5)%64/63);
PS.Diffuse2 = PS.Diffuse;
}
PS.TexCoord = VS.TexCoord;
PS.Settings = float2(bTwoColors,bAntialias);
return PS;
}
float4 PixelShaderFunction(PSInput PS) : COLOR0
{
const float dist = length(PS.TexCoord*2-1);
float4 color = PS.Settings.x > 0.5 ? lerp(PS.Diffuse, PS.Diffuse2, dist) : PS.Diffuse;
if (PS.Settings.y < 0.5){
return dist <= 1 ? color : float4(0,0,0,0);
}
return float4(color.rgb, smoothstep(1, 1 - fwidth(dist) * 2, dist)*color.a);
}
technique Technique1
{
pass Pass1
{
SrcBlend = SrcAlpha;
DestBlend = InvSrcAlpha;
VertexShader = compile vs_3_0 VertexShaderFunction();
PixelShader = compile ps_3_0 PixelShaderFunction();
}
}
local floor = math.floor
function fromColor(col)
local r,g,b,a
b = col%256
g = floor(col/0x100)%256
r = floor(col/0x10000)%256
a = floor(col/0x1000000)%256
return r,g,b,a
end
local shader = dxCreateShader( "dxDrawCircle.fx" )
local shaderColCache = {}
--dxDrawCircleShader(posX, posY, radius, innerColor, outerColor, antialiasing)
function dxDrawCircleShader(posX,posY,radius,color1,color2,antialias)
assert(type(color1) == "number", "Expected number as color argument to dxDrawCircleShader")
if (not color2) or (color2 == color1) then color2 = "def" end
local finColor
local col1 = shaderColCache[color1]
if col1 then
local col2 = col1[color2]
if col2 then
finColor = col2
end
end
if not finColor then
shaderColCache[color1] = shaderColCache[color1] or {}
local twoColors = (color2 ~= "def")
if twoColors then
local r1,g1,b1,a1 = fromColor(color1)
local r2,g2,b2,a2 = fromColor(color2)
local finR = floor((r1/256)*16)*16 + floor((r2/256)*16)
local finG = floor((g1/256)*16)*16 + floor((g2/256)*16)
local finB = floor((b1/256)*16)*16 + floor((b2/256)*16)
local finA = floor((a1/256)*8)*32 + floor((a2/256)*8)*4 + 2
finColor = tocolor( finR, finG, finB, finA )
else
local r,g,b,a = fromColor(color1)
local finA = (floor((a/256)*64)*4)%256
finColor = tocolor( r,g,b, finA )
end
shaderColCache[color1][color2] = finColor
end
local antialiasComp = 16777216
if not antialias then antialiasComp = 0 end
finColor = finColor + antialiasComp
dxDrawImage( posX-radius, posY-radius, radius*2, radius*2, shader, nil, nil, finColor )
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment