# 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.

## 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 on other sites

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

##### Share on other sites

You can look on some examples on github

##### 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;
//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 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?

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

• 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

×