Dynamic 2d shadows - Blending issue
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开发者_如何学Python 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.
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;
}
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.
精彩评论