Simple feature request that would go a long way...

Blitz3D Forums/Blitz3D Programming/Simple feature request that would go a long way...

JoshK(Posted 2004) [#1]
I would like to request addition of the following feature to Blitz3D.

If there were a command that disable/enabled a light's effect on an entity, it would open up a lot of possibilities. The command would be something like EntityLightEffect( entity, light, disable/enable ). If the command were called, it would make it so the light did not have any effect on the entity during rendering.

What can this be used for?

- Control of lighting as the player moves through the map. Create a light entity wherever there is a light from the lightmap. Then do a visiblity check between the player and the light, and disable or enable the entity/light interaction accordingly. This would make the player lit when he was in bright areas of the map, and darkened when he walks into the shadow. I do this already with vertex colors, but hardware lighting is calculated faster and allows specular highlights. It's not going to draw shadows on the mesh or anything, but it keeps the entity at the same lighting as the surroundings. If you play any FPS game, you'll notice that the characters are either effected by a light or not, based on visibility between the mesh and the light.

-Referenced prefabs are presently pretty much impossible, except in an outdoor scene, because of lighting issues. I can use vertex coloring , but not without making another copy of the mesh in memory. If hardware lights could be disabled and enabled per entity, I could have lights effect only the meshes that are visible from it. This way we could use lots of referenced prefabs, like the Unreal engine does, and they would not get lit by a light that was in another room.

-Outdoor lighting would be more accurate. You could do a visibility check between the entity and the sun once, at load time, and then enable or disable the sun's effect on the tree or rock or whatever, so trees in a mountain's shadow would not be lit by the sun.

-Management of DirectX's 8 lights would be easier. For moving entities, we could calculate the 3 or 4 closest lights, and only enable those lights' effect on the entity.

Please, this would give a lot more control and speed to users, and shouldn't be too difficult to implement. I'll be happy to post some demos showing how to make the most of this feature, if you can make it happen.


Thank you!




(Please.)


Dustin(Posted 2004) [#2]
Count me in! This is an indispensable tool we use in Lightwave (you can selectively exclude lights from hitting objects) and would be a great addition to the next B3D revision.


Matt2222(Posted 2004) [#3]
YES. THIS REALLY NEEDS TO BE DONE!
There would be many abilities granted by the addition of this option.

Please, please, add this in!

-Matt


Matt2222(Posted 2004) [#4]
YES. THIS REALLY NEEDS TO BE DONE!
There would be many abilities granted by the addition of this option.

Please, please, add this in!

-Matt


Bolo_Loco(Posted 2004) [#5]
Yeah,this would be a nice feature !


Kozmi(Posted 2004) [#6]
I cast my vote for it as well! This would be a valued asset towards my egyptian level im' working on! So yes Mark!! Please add this ability to Blitz3D!! This would be GREAT!!! ;)

Thank's for bringing this into focus halo!


Techlord(Posted 2004) [#7]
Can this not be achieved with EntityFX?

EntityFX entity,fx
Parameters:
entity - entity handle

fx -
0: nothing (default)
1: full-bright <-- disable lighting?
2: use vertex colors instead of brush color
4: flatshaded <-- disable lighting?
8: disable fog
16: disable backface culling
32: force alpha-blending
Description:
Sets miscellaneous effects for an entity.



jhocking(Posted 2004) [#8]
That would disable ALL lighting on an object. Halo is talking about disabling select lights, with other lights still affecting the object normally.


skidracer(Posted 2004) [#9]
Sounds like something you could do with a multipass renderer. Create a parent pivot for each lighting rig, parent the entities to which ever rig you want them light by and then perform a multipass render using a simple ShowEntity/RenderWorld/HideEntity (fast) loop through each rig.

EntityOrder may be an even more optimal approach, if blitz lights don't already only affect the entities at the same EntityOrder then they possibly should.


JoshK(Posted 2004) [#10]
So a separate render for each combination of lighting? In a simple demo, it would work fine, but in a full game? That would get really complicated.

EntityOrder would draw objects on top of other objects. Plus, entityorder screws up the Z-order, even in a single mesh. If you draw one mesh in a non-0 order, the triangles will not be ordered themselves, even within this single mesh.


skidracer(Posted 2004) [#11]
There is nothing inherently slow about each pass though, and as I mention above EntityOrder is an internal multi pass system which may be even more suitable...

The only slow down is if you forget to parent some entities to a particular lighting rig then they will get rendered for every pass and it's a bit of a bunt to detect visually...


JoshK(Posted 2004) [#12]
Here's an example. It's rather complicated, and I can't do it quite right, because I don't know the offsets for the CameraCls mode values. An internal command would make it much more accessible, and easier to implement. This makes the difference between lights being totally useless, and being a really cool feature that takes up no extra processing time.

This appends a list of disabled light to any entity. The entity is not rendered during the first pass. Then it goes through and renders specially lit entities with one render per entity. This won't actually run on your machine, because it requires two DLL's, one of which simply wraps the PB memory functions:

Graphics3D 800,600,16,2
SetBuffer BackBuffer()

cam=CreateCamera()

m=CreateSphere()
MoveEntity m,0,0,20

l1=CreateLight(2)
PositionEntity l1,-100,0,0
LightColor l1,255,0,0

l2=CreateLight(2)
PositionEntity l2,100,0,0
LightColor l2,0,0,255

showlight1=True
showlight2=True

While Not KeyHit(1)
	If KeyHit(2)
		showlight1=1-showlight1
		If showlight1 EnableLight l1,m Else DisableLight l1,m
		EndIf
	If KeyHit(3)
		showlight2=1-showlight2
		If showlight2 EnableLight l2,m Else DisableLight l2,m
		EndIf
	render cam
	Flip

Wend
WaitKey
End


Const ENTITY_LIGHTLIST=0
Const ENTITY_LIGHTHIDDEN=4

Function FirstEntity()
p=CreatePivot()
o=p
Repeat
	p=LastEntity(p)
	Until Not LastEntity(p)
FreeEntity o
Return p
End Function

Function EntityBank(entity)
bank=PeekL(entity+240)
If bank=1065353216
	bank=CreateBank()
	PokeL entity+240,bank
	EndIf
Return bank
End Function

Function DisableLight(light,entity)
params=entitybank(entity)
lightbank=safepeekint(params,ENTITY_LIGHTLIST)
If Not lightbank
	lightbank=CreateBank()
	SafePokeInt params,ENTITY_LIGHTLIST,lightbank
	EndIf
For n=0 To BankSize(lightbank)/4-1
	If light=PeekInt(lightbank,n*4) Return
	Next
AppendInt lightbank,light
End Function

Function EnableLight(light,entity)
params=entitybank(entity)
lightbank=safepeekint(params,ENTITY_LIGHTLIST)
If lightbank
	For n=0 To BankSize(lightbank)/4-1
		If light=PeekInt(lightbank,n*4)
			For m=n To BankSize(lightbank)/4-1-1
				PokeInt lightbank,m*4,PeekInt(lightbank,m*4+4)
				Next
			ResizeBank lightbank,BankSize(lightbank)-4
			Return
			EndIf
		Next
	EndIf
End Function

Function SafePokeInt(bank,offset,value)
If BankSize(bank)<offset+4 ResizeBank bank,offset+4
PokeInt bank,offset,value
End Function

Function SafePokeFloat(bank,offset,value#)
If BankSize(bank)<offset+4 ResizeBank bank,offset+4
PokeFloat bank,offset,value
End Function

Function SafePeekInt(bank,offset)
If BankSize(bank)<offset+4 Return
Return PeekInt(bank,offset)
End Function

Function SafePeekFloat#(bank,offset)
If BankSize(bank)<offset+4 Return
Return PeekFloat(bank,offset)
End Function

Function AppendInt(bank,value)
size=BankSize(bank)
ResizeBank bank,size+4
PokeInt bank,size,value
End Function

Function AppendFloat(bank,value#)
size=BankSize(bank)
ResizeBank bank,size+4
PokeFloat bank,size,value#
End Function

Function Render(camera)
;First pass
CameraClsMode camera,1,1
entity=firstentity()
While entity
	bank=entitybank(entity)
	lightbank=safepeekint(bank,ENTITY_LIGHTLIST)
	If lightbank
		If BankSize(lightbank)
			HideEntity entity
			Else
			ShowEntity entity
			EndIf
		Else
		ShowEntity entity
		EndIf
	entity=NextEntity(entity)
	Wend
RenderWorld
;Additional passes
CameraClsMode camera,0,0
entity=firstentity()
While entity
	If EntityClass(entity)<>"Camera" And EntityClass(entity)<>"Light" HideEntity entity Else ShowEntity entity
	entity=NextEntity(entity)
	Wend
entity=firstentity()
While entity
	bank=entitybank(entity)
	lightbank=safepeekint(bank,ENTITY_LIGHTLIST)
	If lightbank
		If BankSize(lightbank)
			ShowEntity entity
			For n=0 To BankSize(lightbank)/4-1
				light=PeekInt(lightbank,n*4)
				HideEntity light
				Next
			RenderWorld
			For n=0 To BankSize(lightbank)/4-1
				light=PeekInt(lightbank,n*4)
				ShowEntity light
				Next
			HideEntity entity
			EndIf
		EndIf
	entity=NextEntity(entity)
	Wend
CameraClsMode camera,1,1
End Function



N(Posted 2004) [#13]
I'd prefer the addition of this feature to a work-around. Good one, halo, wouldn't have thought of something like this myself.


4: flatshaded <-- disable lighting?



No.. that would make the entity's mesh look faceted- rather like the way a diamond would be lit if it didn't refract light.


skidracer(Posted 2004) [#14]
To go back to the original post as I don't feel like pointing out the obvious unlikelihood of Blitz3D "doing it for you on a plate"-

- Control of lighting as the player moves through the map. Create a light entity wherever there is a light from the lightmap. Then do a visiblity check between the player and the light, and disable or enable the entity/light interaction accordingly. This would make the player lit when he was in bright areas of the map, and darkened when he walks into the shadow. I do this already with vertex colors, but hardware lighting is calculated faster and allows specular highlights. It's not going to draw shadows on the mesh or anything, but it keeps the entity at the same lighting as the surroundings. If you play any FPS game, you'll notice that the characters are either effected by a light or not, based on visibility between the mesh and the light.

By space partitioning indoor levels room by room, simply change the parent of the player to the current room. Rooms can easily be entityOrdered, and you get a sensible culling method included.

-Referenced prefabs are presently pretty much impossible, except in an outdoor scene, because of lighting issues. I can use vertex coloring , but not without making another copy of the mesh in memory. If hardware lights could be disabled and enabled per entity, I could have lights effect only the meshes that are visible from it. This way we could use lots of referenced prefabs, like the Unreal engine does, and they would not get lit by a light that was in another room.

Again, along as the prefabs are children of the room just multipass render your indoor stuff room by room.

-Outdoor lighting would be more accurate. You could do a visibility check between the entity and the sun once, at load time, and then enable or disable the sun's effect on the tree or rock or whatever, so trees in a mountain's shadow would not be lit by the sun.

In outdoor scenes you only want to render dynamic geometry, blitz desparately needs a stencil brushmode for decent shadow drawing but in reality it's a binary tree, either an object is in shade or it's not, if it's inbetween it rould be nice to render twice with a stencil mode but we don't seem to be their yet.

-Management of DirectX's 8 lights would be easier. For moving entities, we could calculate the 3 or 4 closest lights, and only enable those lights' effect on the entity.

IMHO hardware lights are pretty ineffective (and becoming completely redundant) compared to generating even extremely simple environment maps.


JoshK(Posted 2004) [#15]
Did you just propose that users order arbitrary rooms depending on camera position? I mean, a "room" is an imaginary convention that doesn't necessarily relate to a bunch of arbitrary geometry.

Or else render a separate cube map per entity, per frame?!

I have a method where I can do this, but no one else will really be able to access it. It just makes more sense to make this internal.


Craig H. Nisbet(Posted 2004) [#16]
I agree, I have a project that would really be helped by this.