Jump to content
• Advertisement

# Ray calculation for volumetric spotlight effect

This topic is 399 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

## Recommended Posts

Hi,

I want to add a volumetric light effect to my spotslights and because of this I want to do raymarching in a cone volume (the spotlight cone). Is there a handy way for me to distribute rays (basically get a list of origins and directions) evenly inside the spotlight cone? Say I start with 5 rays where the algorithm would give me one ray straight forward and four rays at the edge of the cone (up, down, left and right), but if I increase the number of rays the algorithm would give me more and more rays, essentially giving me a higher detail cone volume.

The algorithm would not have to be real-time as I can very well precalculate the rays based on some quality setting at startup but it would still be nice to not have to calculate them by hand. Any tips?

#### Share this post

##### Share on other sites
Advertisement

Lets gor now dont use rotation and translation you define a cone as two functions  that one outputs radius given the height. Consider a spotlight as two points one is the cone top (start pos) second is at the bottom center, the line you define points toward the direction of a spotlight. Given distance function that i talked about earlier, you compute closest point on a segment given actual depth vertex pos, and compare how much actual fragment gets the light

And sorry i didnt even read your question lol

#### Share this post

##### Share on other sites

You can look on some examples on github

#### Share this post

##### Share on other sites
struct SamplePattern
{
std::vector<vec> dir;

// 5 rings: 98 samples
// 4 rings: 66 samples
// 3 rings: 40 samples
// 2 rings: 21 samples
// 1 ring: 8 samples

void Init (const int rings, const float degrees)
{
dir.clear();
if (rings < 1)
{
dir.push_back (vec(0,1,0));
return;
}
float angle = degrees / 180.0f * PI;
float maxRad = sin(angle);
//RenderCircle (maxRad+0.01, vec(0,0,0), vec (0,1,0), 1,0,0);

for (int r=0; r<=rings; r++)
{
float rT = float(r) / float (rings);
//float theta = rT * angle;
//float rad = sin(theta);

float rad = maxRad * rT;
float theta = asin(rad);

float perim = rad * 2.0f * PI;
float numRingSamples = perim * (float (rings) / maxRad);
int num = (int) numRingSamples;
//RenderCircle (rad, vec(0,cos(theta),0), vec (0,1,0), 1,1,1);
//RenderCircle (rad, vec(0,0,0), vec (0,1,0), 0.1,0.1,0.1);

for (int s=0; s<=num; s++)
{

float phi = float(s) / float(1+num) * PI * 2.0f;
phi += PI * rT;
if (r&1) phi += PI;
if (r&2) phi += PI*0.5;

vec d;
d[0] = -sin(theta) * cos(phi);
d[2] = -sin(theta) * sin(phi);
d[1] = cos(theta);
//RenderPoint (3, vec(d[0], 0, d[2]), 1,1,1);
//RenderPoint (3, d, 1,1,1);
dir.push_back (d);
}
}
}
};

I used this code to preprocess meshes, e.g. precompute AO.

I think' its pretty much what you want, but it supports only fixed counts of rays, see comment on top.

Couldn't you just make a ray / cone intersection and use the intersection segment to calculate volume instead generating multiple rays to approximate the cone?

#### Share this post

##### Share on other sites

• Advertisement
• Advertisement

• ### Popular Contributors

1. 1
Rutin
42
2. 2
3. 3
4. 4
5. 5
• Advertisement

• 9
• 27
• 20
• 9
• 20
• ### Forum Statistics

• Total Topics
633395
• Total Posts
3011653
• ### Who's Online (See full list)

There are no registered users currently online

×

## Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!