smoothing out results from gui shaders

roundedRectangle and circle drawing now smooth out their results
This commit is contained in:
marauder2k7 2024-03-07 09:47:18 +00:00
parent 2dc623df7e
commit 0d448ad761
6 changed files with 57 additions and 52 deletions

View file

@ -627,6 +627,11 @@ void GFXDrawUtil::drawRoundedRect(const F32& cornerRadius,
Point2F rectCenter((F32)(topLeftCorner.x + (size.x / 2.0)), (F32)(topLeftCorner.y + (size.y / 2.0))); Point2F rectCenter((F32)(topLeftCorner.x + (size.x / 2.0)), (F32)(topLeftCorner.y + (size.y / 2.0)));
mRoundRectangleShaderConsts->setSafe(mRoundRectangleShader->getShaderConstHandle("$rectCenter"), rectCenter); mRoundRectangleShaderConsts->setSafe(mRoundRectangleShader->getShaderConstHandle("$rectCenter"), rectCenter);
const Point2I& resolution = GFX->getActiveRenderTarget()->getSize();
Point2F TargetSize(1.0 / (F32)resolution.x, 1.0 / (F32)resolution.y);
mRoundRectangleShaderConsts->setSafe(mRoundRectangleShader->getShaderConstHandle("$oneOverViewport"), TargetSize);
mDevice->drawPrimitive(GFXTriangleStrip, 0, 2); mDevice->drawPrimitive(GFXTriangleStrip, 0, 2);
} }

View file

@ -31,12 +31,12 @@
#include "math/mPolyhedron.h" #include "math/mPolyhedron.h"
#endif #endif
class FontRenderBatcher; class FontRenderBatcher;
class Frustum; class Frustum;
/// Helper class containing utility functions for useful drawing routines /// Helper class containing utility functions for useful drawing routines
/// (line, box, rect, billboard, text). /// (line, box, rect, billboard, text).
class GFXDrawUtil class GFXDrawUtil

View file

@ -271,19 +271,26 @@ void GuiShaderEditor::onRender(Point2I offset, const RectI& updateRect)
{ {
// for temp connetion, nodeA is always the first node selected. // for temp connetion, nodeA is always the first node selected.
Point2I start(Point2I::Zero); Point2I start(Point2I::Zero);
ColorI color(ColorI::WHITE);
if (mTempConnection->inSocket != NULL) if (mTempConnection->inSocket != NULL)
{
start = mTempConnection->nodeA->localToGlobalCoord(mTempConnection->inSocket->pos) + offset; start = mTempConnection->nodeA->localToGlobalCoord(mTempConnection->inSocket->pos) + offset;
else if(mTempConnection->outSocket != NULL) color = mTempConnection->inSocket->col;
}
else if (mTempConnection->outSocket != NULL)
{
start = mTempConnection->nodeA->localToGlobalCoord(mTempConnection->outSocket->pos) + offset; start = mTempConnection->nodeA->localToGlobalCoord(mTempConnection->outSocket->pos) + offset;
color = mTempConnection->outSocket->col;
}
RectI sockActive(start, Point2I(mNodeSize, mNodeSize)); RectI sockActive(start, Point2I(mNodeSize, mNodeSize));
start += Point2I(mNodeSize / 2, mNodeSize / 2); start += Point2I(mNodeSize / 2, mNodeSize / 2);
drawer->drawThickLine(start, mLastMousePos + offset, ColorI(255, 255, 255, 255), (F32)mNodeSize / 3); drawer->drawThickLine(start, mLastMousePos + offset, color, (F32)mNodeSize / 3);
// draw socket overlay over the top of the line. // draw socket overlay over the top of the line.
sockActive.inset(1, 1); sockActive.inset(1, 1);
drawer->drawCircleFill(sockActive, ColorI(255, 255, 255), mNodeSize / 2); drawer->drawCircleFill(sockActive, color, mNodeSize / 2);
} }
} }
// Draw selection rectangle last so it is rendered on top. // Draw selection rectangle last so it is rendered on top.

View file

@ -73,22 +73,22 @@ struct NodeSocket
switch (inDim) switch (inDim)
{ {
case DataDimensions::Dynamic: case DataDimensions::Dynamic:
col = ColorI(200, 200, 200, 200); col = ColorI(200, 200, 200, 128);
break; break;
case DataDimensions::Scalar: case DataDimensions::Scalar:
col = ColorI(210, 105, 30, 200); col = ColorI(210, 105, 30, 128);
break; break;
case DataDimensions::Vector2: case DataDimensions::Vector2:
col = ColorI(152, 251,152, 200); col = ColorI(152, 251,152, 128);
break; break;
case DataDimensions::Vector3: case DataDimensions::Vector3:
col = ColorI(127, 255, 212, 200); col = ColorI(127, 255, 212, 128);
break; break;
case DataDimensions::Vector4: case DataDimensions::Vector4:
col = ColorI(100, 149, 237, 200); col = ColorI(100, 149, 237, 128);
break; break;
case DataDimensions::Mat4x4: case DataDimensions::Mat4x4:
col = ColorI(153, 50, 204, 200); col = ColorI(153, 50, 204, 128);
break; break;
default: default:
break; break;

View file

@ -34,33 +34,33 @@ uniform float2 rectCenter;
uniform float borderSize; uniform float borderSize;
uniform float4 borderCol; uniform float4 borderCol;
float circle(float2 p, float radius) float circle(float2 p, float2 center, float r)
{ {
float dist = length(p - float2(0.5,0.5)); return length(p - center);
return 1.0 - smoothstep(radius - (radius*0.01),
radius + (radius*0.01),
dot(dist,dist) * 4.0);
} }
float4 main(Conn IN) : TORQUE_TARGET0 float4 main(Conn IN) : TORQUE_TARGET0
{ {
float distance = length(IN.HPOS.xy - rectCenter); float distance = circle(IN.HPOS.xy, rectCenter, radius);
if(distance > radius)
{ float4 fromColor = borderCol;
discard; float4 toColor = float4(0.0, 0.0, 0.0, 0.0);
}
if(distance < radius) if(distance < radius)
{ {
if(distance < (radius - borderSize)) distance = abs(distance) - radius;
if(distance < (radius - (borderSize * 0.5)))
{ {
return IN.color; toColor = IN.color;
} distance = abs(distance) - (borderSize * 0.5);
else
{
return borderCol;
} }
float blend = smoothstep(0.0, 1.0, distance);
return lerp(fromColor, toColor, blend);
} }
return IN.color; distance = abs(distance) - radius;
float blend = smoothstep(0.0, 1.0, distance);
return lerp(fromColor, toColor, blend);
} }

View file

@ -30,19 +30,18 @@ struct Conn
uniform float2 sizeUni; uniform float2 sizeUni;
uniform float2 rectCenter; uniform float2 rectCenter;
uniform float2 oneOverViewport;
uniform float radius; uniform float radius;
uniform float borderSize; uniform float borderSize;
uniform float4 borderCol; uniform float4 borderCol;
float RoundedRectSDF(float2 p, float2 size, float radius) float RoundedRectSDF(float2 p, float2 size, float radius)
{ {
float2 halfSize = size / 2.0;
// Calculate distance to each side of the rectangle // Calculate distance to each side of the rectangle
float2 dist = abs(p) - halfSize + radius; float2 dist = abs(p) - size + float2(radius, radius);
// Compute the distance to the rounded corners // Compute the distance to the rounded corners
float cornerDist = length(max(abs(p) - (halfSize - float2(radius, radius)), 0.0)); float cornerDist = length(max(dist, 0.0));
// Return the minimum distance (negative inside, positive outside) // Return the minimum distance (negative inside, positive outside)
return min(max(dist.x, dist.y), 0.0) + cornerDist - radius; return min(max(dist.x, dist.y), 0.0) + cornerDist - radius;
@ -51,13 +50,13 @@ float RoundedRectSDF(float2 p, float2 size, float radius)
float4 main(Conn IN) : TORQUE_TARGET0 float4 main(Conn IN) : TORQUE_TARGET0
{ {
float2 p = IN.HPOS.xy; float2 p = IN.HPOS.xy;
float2 halfSize = sizeUni * 0.5;
float halfBorder = borderSize * 0.5;
float halfBorder = borderSize * 0.5;
float2 halfSize = sizeUni * 0.5;
p -= rectCenter; p -= rectCenter;
// Calculate signed distance field for rounded rectangle // Calculate signed distance field for rounded rectangle
float4 fromColor = IN.color; float4 fromColor = borderCol;
// alpha // alpha
float4 toColor = float4(0.0, 0.0, 0.0, 0.0); float4 toColor = float4(0.0, 0.0, 0.0, 0.0);
@ -73,9 +72,7 @@ float4 main(Conn IN) : TORQUE_TARGET0
if(cornerRadius > 0.0 || halfBorder > 0.0) if(cornerRadius > 0.0 || halfBorder > 0.0)
{ {
float sdf = RoundedRectSDF(p, sizeUni, cornerRadius - halfBorder); float sdf = RoundedRectSDF(p, halfSize, cornerRadius - halfBorder);
clip(0.01 - sdf);
if(halfBorder > 0.0) if(halfBorder > 0.0)
{ {
@ -87,20 +84,16 @@ float4 main(Conn IN) : TORQUE_TARGET0
// (p.x >= halfSize.x - radius + halfBorder && p.x <= halfSize.x + radius - halfBorder) ) { // right border // (p.x >= halfSize.x - radius + halfBorder && p.x <= halfSize.x + radius - halfBorder) ) { // right border
// } // }
toColor = IN.color;
toColor = borderCol;
} }
sdf = abs(sdf) - halfBorder; sdf = abs(sdf) - halfBorder;
}
// Apply smoothing to create rounded effect else{
float blending = smoothstep(1.0, -1.0, sdf); fromColor = IN.color;
return lerp(fromColor, toColor, blending);
} }
float alpha = smoothstep(1.0, 0.0, sdf); float alpha = smoothstep(-1.0, 1.0, sdf);
return float4(IN.color.rgb, IN.color.a * alpha); return lerp(fromColor, toColor, alpha);
} }
else else
{ {