Ambient occlusion code free

Community Forums/Showcase/Ambient occlusion code free

DareDevil(Posted 2009) [#1]
In the code archive i have released the code for generate Vertex ambient Occlusion please test this, and comment.

http://www.blitzbasic.com/codearcs/codearcs.php?code=2517#comments

if you test your scene post the image which result

thanks all


RifRaf(Posted 2009) [#2]
if you test your scene post the image which result

Great job on this, it works very wel.
Could use a savemap() loadmap(Ent) though.

Heres a shot.



DareDevil(Posted 2009) [#3]
the sw not generate texture AO, generate a simple vertex color object is possible save the color vertex ;)

tnks


RifRaf(Posted 2009) [#4]
I knew that devil.. but calculating time being what it is, a save from ent, and load to ent would be useful. Easily added by anyone though


DareDevil(Posted 2009) [#5]
ok thanks :)

you have this function?


RifRaf(Posted 2009) [#6]
ill make a load / save for you.
ill post it here in a few minutes


RifRaf(Posted 2009) [#7]
Ok here you go.. I dont like blend mode 3, so its not in here. but you can change that.

This is the SAVE FUNCTION
Function save_ambient_map(ent,FN$)
 EntityFX ent,2+1
 ;first record the surface count
 scount=CountSurfaces(ENT)
 F=WriteFile(FN$)
 WriteInt f,Scount
  For s=1 To scount 
    surf=GetSurface(ent,s) 
    vcount=CountVertices(surf)-1
     ; surfaces can get rearranged if the model is reexported via differnt modelling apps.. so lets
     ; record the surface info here so we can find the matching surface when we reload the map
     WriteInt f,s
     WriteInt f,vcount
     WriteInt f,CountTriangles(surf) ; just here to help make a surface match in the loader
     For v=0 To vcount
		 ; Now save the vertex data
		 ; since we are not using colored lights, we need only save the red channel
		 ; on reload we apply the red channel to all r,g and b  
    	 WriteInt f,VertexRed(surf,v)
     Next
  Next
CloseFile f
End Function 	                    


and here is the LOAD FUNCTION
Function Load_ambient_map(Ent,fn$)
EntityBlend ent, 1
EntityFX ent,2+1

If FileType(fn$)<>1 Then Return -1
f=OpenFile(fn$)
scount=ReadInt(f)
surfcount=CountSurfaces(ent)
;make sure we have at least the needed suface count
If scount<>surfcount Then 
   CloseFile f
   Return -1
EndIf

For i=1 To scount
;read vert count and tri count
	SurfID=ReadInt(f)
	vcount=ReadInt(f)
	tricount=ReadInt(f)
	;find a matching surface
	match=0


    ;first lets try the surface stored in the save. but because surfaces can get rearranged if a model is reexported
    ;we wont assume its in the same order it was in when we saved the ambient map
    s=GetSurface(ent,surfid)
	If vcount=(CountVertices(s)-1) And tricount=CountTriangles(s) Then
		match=1
		For Vert=0 To vcount
			c=ReadInt(f)
			VertexColor s,vert,c,c,c
		Next
	EndIf


    ; if its not in the right order then match may = 0, if it does 
    ; then we want to search though all the surfaces and find the right one    
    If match=0 Then 
		For getsurf=1 To scount
			s=GetSurface(ent,getsurf)
			If vcount=(CountVertices(s)-1) And tricount=CountTriangles(s) Then
				match=1
				For Vert=0 To vcount
					c=ReadInt(f)
					VertexColor s,vert,c,c,c,VertexAlpha(s,vert)
				Next
			EndIf
 		Next
    EndIf

    ;if match still is 0, it means there was no matching surface and the model has changed its gemoetric properties
	If match=0 Then 
	    CloseFile f
		Return -1 ; did not find a matching surface for this data
	EndIf


Next
CloseFile f
	UpdateNormals ent
Return 1
End Function 



I modified your code a tad bit.. just so that the loadscene returned the receiver object.
;thescene=loadscene()

Function LoadScene()
	;===>
	;===>
	Obj = LoadMesh("DEMOMAP.B3D");CPlane(Segment*2) 
	PositionEntity Obj,0,-5,0
	ScaleEntity Obj, 4, 3, 4
	Return(AO_SetReceiver(Obj))
End Function




and here is everything alltogether so you can test it. I was tweaking the settings some, and removed blend mode3.


EDIT : After fiddling with this a bit, I found blend 3 works pretty well if I turn the ambient light down some.


RifRaf(Posted 2009) [#8]
What would be amazing Devil, is if you used this to compile an ambient volume. Could be made up of many rectangles such as
Type AmbientVolume
field x1#,y1#,z1#
field x2#,y2#,z2#
field x3#,y3#,z3#
field x4#,y4#,z4#
field ambientvalue# (0.0 to 1.0) = 0 to 255
end type

The resolution of the ambient volume should be somthing you can control or modify on export of the volume. having 100k volume rects probably isnt a good idea.



then in a game your could call somthing like this
ColorMultiplier#=CheckAmbientVolume(entityx(player),entityy(player),entityz(player))

EntityColor player,player_red*colormultiplier,player_green*colormultiplier,player_blue*color_multiplier


where the checkambientvolume, checks to see if the coordinates are inside any of the ambient volume 3d rectangles..

Combine this with a few DX or fake DX lights and it would be a very impressive scene for B3D.

can you do this ??????


DareDevil(Posted 2009) [#9]
I think of you! I think it is even easier :)
linepick vertical to entity and get a triangle and take the color of the summit near you :D

this is a idea

bye


DareDevil(Posted 2009) [#10]
hi have update the source code whitch your function look this for news

hi work for new solution request :)

tnk all


RifRaf(Posted 2009) [#11]
I think it is even easier :)
linepick vertical to entity and get a triangle and take the color of the summit near you :D


Easier yes.. and very slow. Imagine many players , many bad guys and more
Linepicks are very slow.

A volume could be more detailed..

Linepick up and see a ceiling that is dark.. but on the ground and around you is light. This would not be a correct method.

precalculate a volume.. then you check if player is in imaginary rectangle, and shade player to rectanges precalculated shade value. You can also get neighbor rectangle values and blend between them very fast since no 3D calculations are required on geometry. When I get more time I may play with some ideas on this.

Here is a visual aid of a single ambient volume block.
The idea is NOT to use entities but just psuedo rectagle values, you could create massive ambient detail in the volume by seperating volumes into blocks and only checking the player is in rectangles belonging to the nearest block