Notifications
Clear all

[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!

6 Replies

there are several ways:

  1. use VertexPaint modifier to bake lighting – THE EASIEST
  2. use Render to Texture to bake lighting element – THE MOST ACCURATE
  3. calculate yourself by sending rays and checking dot product of vertex normal and direction of light – GUARANTEES A LOT OF FUN
  1. 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

  1. 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!

NO PAIN NO GAIN

1 Reply
(@system)
Joined: 11 months ago

Posts: 0

This made me LOL

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!

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

no pain no gain

really?