Reputation: 9260
Good day my dear community.
I'm working on dynamic shadows for a game I shall work on, but as it usually happens I bring you a problem, in hope (I'm certain actually) that someone will help.
This is where I am right now:
Notice the red square, I want it to gradually fade away as the light source moves out of the sight. I do check if a point of a polygon is inside circle's radius, but that of course doesn't solve it; as I said I want it to fade gradually until it completely blacks out If the light is too far away.
There's one idea on my mind but I hope for a better one. I will not talk about it since it's really the last option and I find it to be a 'brute force' technique.
This is how I render my light:
glBegin(GL_TRIANGLE_FAN);
{
Graphics::Instance()->SetColor(r_,g_,b_,intensity_);
glVertex2f(posX_,posY_);
glColor4f(0.f, 0.f, 0.f, 0.0f);
for (angle_=0.0; angle_<=3.14159265*2; angle_+=((3.14159265*2)/64.0f) )
{
glVertex2f(range_*(float)cos(angle_) + posX_,
range_*(float)sin(angle_) + posY_);
}
glVertex2f(posX_+range_, posY_);
}
And this is how I blend it:
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
l0->Render();
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
l0->ProjectShadow(*mmm);
l0->ProjectShadow(*bb);
That is all. If I didn't made myself clear or If I missed to post relevant code, please do say so and don't downvote.
Upvotes: 2
Views: 727
Reputation: 37490
How about calculating the range to the center of your red square from the light sources center? Normalise that value to a suitable range and adjust the transparency or colour of the red square? Something like this:
double Range(double x1, double y1, double x2, double y2)
{
double xDist = x1-x2;
double yDist = y1-y2;
return math::sqrt(xDist*xDist+yDist*yDist);
}
double CalcIntensity(double lightX, double lightY, double lightRadius, double objectX, double objectY)
{
double range = Range(lightX, lightY, objectX, objectY);
double intensity;
if( range > lightRadius )
{
intensity = 0.0;
}
else
{
intensity = range/lightRadius;
}
return intensity;
}
Then just call CalcIntensity
and feed in the reletive positions of the light and the square and the radius of the light.
[Edit] ...or this would be a slightly more optomised version if you're not pre-checking it's within the lights radius:
double CalcIntensity(double lightX, double lightY, double lightRadius, double objectX, double objectY)
{
double intensity = 0.0;
double xDist = lightX-objectX;
if( xDist < lightRadius )
{
yDist = lightY-objectY;
if( yDist < lightRadius )
{
double range = math::sqrt(xDist*xDist+yDist*yDist);
intensity = range/lightRadius;
}
}
return intensity;
}
Upvotes: 3
Reputation: 4482
Well the light is at full brightness at posX,posY
and fully "depleted" (i.e. black) at range
. The values between are interpolated linearly. Therefore a point at any position with distance d
from the light source is lit by rgb * (d/range)
.
If you now calculate the distances d_i
of each vertex v_i
of your red square, you can apply shadowing to each vertex color c_i
by multiplying (d_i/range)
to it. If you want the whole square to appear in the same color regardless of further-away vertices just use the distance of its center for every vertex, that is set the color only once before you draw the square.
Upvotes: 1