How to apply gradient to shaped objects?

Hi, I’m a totally beginner of OpenFrameworks.

I’m trying to apply color gradient to objects such as ofCircle, ofRectRounded, ofRect…

I found some example code which I can color pixel by pixel.

So I tried to apply this code to color the shaped object.

in testApp.h, I added

void drawGradient();

ofImage img;

and in testApp.mm,

void testApp::setup() {

img.allocate(100 ,100,OF_IMAGE_COLOR);
drawGradient();

}

void testApp::draw() {

img.draw(100,100);

}

void testApp::drawGradient() {

for (int x=0; x<100; x++) {
    for (int y=0; y<100; y++) {
        img.setColor(x, y, ofColor::fromHsb(255, y, 255));
    }
}
img.update();

}

When I run it, it draws 100 x 100 sized rectangular area that gradient(saturation) is applied.
Is it possible to apply gradient to a shaped object such as ofCircle by using this method?
If so, could anyone please tell me how to do it?

this is the kind of thing shaders (fragment shaders) are particularly good at – you can write code that get executed at the per pixel level, like adding a gradient.

to do a circle in pixels (via an image) you could modify this slightly:

for (int x=0; x<100; x++) {
for (int y=0; y<100; y++) {
float dist = ofDist(50, 50, x,y);
if (dist < 50)
img.setColor(x, y, ofColor::fromHsb(255, y, 255));
} else {
img.setColor(x,y, ofColor::black);
}
}
}
img.update();

essentially turning pixels on or off to make a circle. You might control alpha, for example, instead of making non circular pixels black to make non circle parts transparent.

if you are interested in seeing how to do this via a shader let me know.

Thank you Zach!
I know nothing about shaders yet, but I would appreciate if you can show me how to do it using the shader.

Or is there any simpler way to apply color gradient just within the object?

It would be easier if I can apply this effect regardless of the shape of an object.

How do I make non circle parts transparent??

img.setColor(x,y, ofColor::black);

how do I change this line if I want to change black to transparent??

maybe this could work:

img.setColor(x,y, ofColor(0,0,0,0));

you’d need to allocate the image as OF_IMAGE_COLOR_ALPHA not OF_IMAGE_COLOR

hope this helps,
zach

Thank you Zach!

One more question!
is there anyway to smooth out the circle shape made with ofDist?
It seems like it is not as smooth as ofCircle with high resolution.

you can always color the pixel based on it’s % away from the center, ie:

float dist = ofDist(50, 50, x,y);
float pct = 1.0 - dist / 50.0;
if (pct < 0) pct 0;
img.setColor(x, y, ofColor::fromHsb(255, y, 255, pct * 255));

int this case, you’ve get a smooth gradient from fully opaque in the center, to tansparent on the outside.

if you do this:

float dist = ofDist(50, 50, x,y);
float pct = 1.0 - dist / 50.0;
if (pct < 0) pct 0;  
pct = powf(pct, 0.3);
img.setColor(x, y, ofColor::fromHsb(255, y, 255, pct * 255));

I you can shape the pct, so it’s non linear, and potential get it to be mostly opaue, but with some number of pixels that go transparent. that number 0.3 adjust the curve, if you do 1, you get same behavior as before, if you go < 1 and > 0 you curve in one direction, > 1 curves in the other direction.

hope that helps!