Jump to content

help shader dxdrawcircle antialias


iiv03

Recommended Posts

hey guys, I wanna help on shader Im trying to put antialias with borderWidth

circle.fx

float sCircleHeightInPixel = 100;
float sCircleWidthInPixel = 100;
float sBorderWidthInPixel = 10;

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)
float4 PixelShaderFunction(float4 Diffuse : COLOR0, float2 TexCoord : TEXCOORD0) : COLOR0
{
    float2 uv = float2( TexCoord.x, TexCoord.y ) - float2( 0.5, 0.5 );
    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;
}
    float2 vec = normalize( uv );
    float CircleRadiusInPixel = lerp( sCircleWidthInPixel, sCircleHeightInPixel, vec.y * vec.y );
    float borderWidth = sBorderWidthInPixel / CircleRadiusInPixel;
    if ( ( dist > 0.5 ) || ( dist < 0.5 - borderWidth ) )
        return 0;
    else 
        return Diffuse;
}


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

client.Lua

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( "circle.fx" )
local shaderColCache = {}
function dxDrawCircleShader(posX,posY,radius,color1,color2,antialias,borderWidth)
	assert(type(color1) == "number", "Expected number as color argument to dxDrawCircleShader")
	if (not color2) or (color2 == color1) then color2 = "def" end
    borderWidth = borderWidth or 1e9 
	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
			dxSetShaderValue ( shader, "sCircleWidthInPixel", width );
			dxSetShaderValue ( shader, "sCircleHeightInPixel", height );
			dxSetShaderValue ( shader, "sBorderWidthInPixel", borderWidth );
			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
addEventHandler("onClientRender",root,
	function()
	dxDrawCircleShader(500,200,60,tocolor(255,255,255),tocolor(255,255,255),1,1)
	end
)

im not good in shader and i don't know shader. anyone help me please?

actually i wanna do like this but with antialas :'(:

ycwns50iy696.png

 

Edited by liwahadri
Link to comment

MY TRYING EDIT:

shader.fx

float sCircleHeightInPixel = 100;
float sCircleWidthInPixel = 100;
float sBorderWidthInPixel = 10;
float sAngleStart = -3.14;
float sAngleEnd = 3.14;
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;
};


float4 PixelShaderFunction(float4 Diffuse : COLOR0, float2 TexCoord : TEXCOORD0) : COLOR0
{
    float2 uv = float2( TexCoord.x, TexCoord.y ) - float2( 0.5, 0.5 );

    float angle = atan2( -uv.x, uv.y );  // -PI to +PI
    if ( sAngleStart > sAngleEnd )
    {
        if ( angle < sAngleStart && angle > sAngleEnd )
            return 0;
    }
    else
    {
        if ( angle < sAngleStart || angle > sAngleEnd )
            return 0;
    }

    // Calc border width to use
    float2 vec = normalize( uv );
    float CircleRadiusInPixel = lerp( sCircleWidthInPixel, sCircleHeightInPixel, vec.y * vec.y );
    float borderWidth = sBorderWidthInPixel / CircleRadiusInPixel;

    // Check if pixel is inside circle
    float dist =  sqrt( dot( uv, uv ) );
    if ( ( dist > 0.5 ) || ( dist < 0.5 - borderWidth ) )
        return 0;
    else 
        return Diffuse;
		
}

technique tec0
{
    pass P0
    {
        PixelShader = compile ps_2_0 PixelShaderFunction();
    }
}

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

client.Lua


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

function dxDrawShaderCircle( x, y, width, height, color1, color2, angleStart, angleSweep, borderWidth, antialiasing)
local shaderColCache = {}
    height = height or width 
    color = color or tocolor(255,255,255) 
    borderWidth = borderWidth or 1e9 
    angleStart = angleStart or 0 
    angleSweep = angleSweep or 360 - angleStart 
    if ( angleSweep < 360 ) then 
        angleEnd = math.fmod( angleStart + angleSweep, 360 ) + 0 
    else 
        angleStart = 0 
        angleEnd = 360 
    end 
    x = x - width / 2 
    y = y - height / 2 
    if not circleShader then 
        circleShader = dxCreateShader ( "circle.fx" ) 
    end 
	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
    dxSetShaderValue ( circleShader, "sCircleWidthInPixel", width ); 
    dxSetShaderValue ( circleShader, "sCircleHeightInPixel", height ); 
    dxSetShaderValue ( circleShader, "sBorderWidthInPixel", borderWidth ); 
    dxSetShaderValue ( circleShader, "sAngleStart", math.rad( angleStart ) - math.pi ); 
    dxSetShaderValue ( circleShader, "sAngleEnd", math.rad( angleEnd ) - math.pi ); 
    dxDrawImage( x, y, width, height, circleShader, 0, 0, 0, color ) 
end 


addEventHandler("onClientRender",root,
	function()
	dxDrawShaderCircle(500,400,100,height,tocolor(0,0,255),tocolor(0,0,255),0,360,3,1) 
	end
)

not work why? help guys please :'(

 

Link to comment
  • IIYAMA locked this topic
Guest
This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...