[Closed] intensity of light
is it possible via maxscript to find out the cumalative intensity of light at a given vertex of a geometry object (lights include spot lights, direct lights etc… which are attenuated and decayed and usually have greater falloff value than hotspot value) it would be great if indirect light sources could also be included in the calculation (but i doubt that is possible), also if a solution exists is it possible to extend it to particles? (i.e selecting particles based on the intensity of light incident on them)
thanks!
there are several ways:
- use VertexPaint modifier to bake lighting – THE EASIEST
- use Render to Texture to bake lighting element – THE MOST ACCURATE
- calculate yourself by sending rays and checking dot product of vertex normal and direction of light – GUARANTEES A LOT OF FUN
- use Render to Texture to bake lighting element – THE MOST ACCURATE
yea that is the best. its a bit painful to use with V-ray but once i baked in the V-Ray lighting i used a speed by surface operator with speed by material option checked this way particles at high intensity areas got more speed than particles at low intensity areas. But if i make slight adjustments to the lights i have to bake the lighting again and this is a really painful process with v-ray
- calculate yourself by sending rays and checking dot product of vertex normal and direction of light
i thought about that too but its a lot of code and very very slow one and GUARANTEES A LOT OF PAIN
thanks!
thanks for the posts!
NO PAIN NO GAIN
cliche.
This made me LOL
here is my attempt (it calculates intensity at a particle due to all spotlights in a scene, particle-geometry occlusion is taken into consideration, but not particle particle occlusion, it computes loss of intensity due to angle difference between the normal and the light vector, (distance, angle) attenuation and decay)
i am shooting a ray from the particle towards the light instead of the other way around, this approach works only for direct lighting and cannot be extended to indirect lights (in latter case a hemisphere of rays is shot from the source of light), the problem with computing indirect lighting is
a) computing angle of reflection, refraction based on the material of the object
b) interpolating between rays to check existence of particle, obviously i cannot shoot infinite rays and by shooting limited rays i am bound to miss particles (because the rays may pass through the gaps between the particles)
fn computeIntensityAt point nV spotLight =
(
flag = 1
-- compute light vector
lV = normalize (spotLight.pos - point)
-- ray cast from particle to light, blocked by geometry object?
lightRay = ray point lv
for o in geometry do (if ((intersectray o lightRay) != undefined) do (flag = 0))
-- if not blocked by any geometry object then compute the intensity else set it to 0.0
if flag == 1 then
(
--normal vector of the particle, assumed as Z vector, used to compute loss in intensity due to angle between the light and the point normal
lossDueToAngle = dot lV nv
attenuatedIntensity = spotLight.multiplier * lossDueToAngle
--compute loss of intensity due to angle attenuation (in falloff areas)
spotLightDV = normalize (spotLight.pos - spotLight.target.pos)
attenuationAngle = acos (dot spotLightDV lv)
if ((attenuationAngle > (spotLight.hotspot/2)) and (attenuationAngle <= (spotLight.falloff/2))) then
(
diff = (attenuationAngle - (spotLight.hotspot/2))
attenuatedIntensity -= diff * (spotLight.multiplier / (spotLight.falloff - spotLight.hotspot))
)
else if attenuationAngle > (spotLight.falloff/2) do
attenuatedIntensity = 0
--compute loss of intensity due to near distance Attenuation
if spotLight.useNearAtten == on do
(
if ((distance spotLight.pos point) <= spotLight.nearAttenStart) then
attenuatedIntensity = 0
else if ((distance spotLight.pos point) > spotLight.nearAttenStart) and ((distance spotLight.pos point) <= spotLight.nearAttenEnd) do
(
attenuatedIntensity -= ((distance spotLight.pos point) - spotLight.nearAttenStart) * (spotLight.multiplier / (spotLight.nearAttenEnd - spotLight.nearAttenStart))
)
)
--compute loss of intensity due to far distance Attenuation
if spotLight.useFarAtten == on do
(
if ((distance spotLight.pos point) > spotLight.farAttenEnd) then
attenuatedIntensity = 0
else if ((distance spotLight.pos point) > spotLight.farAttenStart) and ((distance spotLight.pos point) <= spotLight.farAttenEnd) do
(
attenuatedIntensity -= ((distance spotLight.pos point) - spotLight.farAttenStart) * (spotLight.multiplier / (spotLight.farAttenEnd - spotLight.farAttenStart))
)
)
-- compute loss of intensity due to decay
case spotLight.attenDecay of
(
1: intensityAtPoint = attenuatedIntensity
2: if ((distance spotLight.pos point) > spotLight.decayRadius) then
(
pointOfDecay = (normalize spotLight.pos)* ((length spotLight.pos)-spotLight.decayRadius)
intensityAtPoint = 1/(distance pointOfDecay point)*attenuatedIntensity
)
else
intensityAtPoint = attenuatedIntensity
3: if ((distance spotLight.pos point) > spotLight.decayRadius) then
(
pointOfDecay = (normalize spotLight.pos)* ((length spotLight.pos)-spotLight.decayRadius)
intensityAtPoint = 1/((distance pointOfDecay point)^2)*attenuatedIntensity
)
else
intensityAtPoint = attenuatedIntensity
)
)
else
intensityAtPoint = 0.0
)
for i = 1 to pcont.numparticles() do
(
CI = 0
pcont.particleindex = i
particlePosition = pCont.particlePosition
particleNormal = pCont.particleTM.row3
for sl in lights do
(
if (classof sl == targetSpot) do
CI += (computeIntensityAt particlePosition particleNormal sl)
)
if CI <= 0 then
pcont.particleteststatus = true
else
pcont.setparticlemapping i 0 ([1,0,0]*CI)
)
let me know if there is a mistake with the computation of intensity in the script. (seems to work fine in the viewport and render only i have to play with the light multiplier a bit, but i can live with that)
thanks!