Shading Terrains?

Blitz3D Forums/Blitz3D Programming/Shading Terrains?

Hey,
I'm still workin on the "visible polys on terrain" project, but i figured out that the function that Stevie if im not wrong, gave me, is not good enough for my needs. So someone there said "why won't you put a spotlight and shade the not visible areas?"

So what i need is a sample of how if at all possible, i can use devils shadow system in order to shadow the not visible areas on the same mesh(i mean the receiver and the caster would be the same mesh so hills would cast on the ground. like creating dynamically a lightmap for the terrain by a given position of the spotlight). the terrain mesh is about 25k polys i think( its not the same mesh all the time), so i might need a function to divide the mesh to blocks.
Thanks in advance

Are we going to break a record? nevermind.
well here is the topic i was talking about:
http://blitzbasic.com/Community/posts.php?topic=77338#865829

Like I said - post or e-mail your code and explain explicitly what you want ( a picture would be a help too ) and I ( and others ) should be able to help.

do you want the whole code? or just a part of it?

EDIT:
nevermind. I didn't want to do that but youve asked for it(muhahahaha), here is my very not organized code:

Graphics3D 1024,768,32,2
SetBuffer BackBuffer()
Include "ScanCodes.bb"
Include "centermesh.bb"
Global touchv#
Global jumpv#

Global RecievedStr$
Global FFt
Global FFx$
Global FFy$
Global FFz$
Global mapcount%=1
Global currentcam=0
; -- Viewport.

Global viewport_center_x = GraphicsWidth () / 2
Global viewport_center_y = GraphicsHeight () / 2
;^^^^^^

;UDP Stream
Global Mystream=CreateUDPStream(3365) 
If Not Mystream Then RuntimeError("Couldn't Create Port To Read From")
Global msg$=""
Global msgdata$=""


; -- User.
Global user_movement_speed# = 4.0 ; The user's movement speed. This produces a movement speed of 4 metres per second.
Global user_camera_pitch#
Global light1=CreateLight()
PositionEntity light1,0,0,0
;^^^^^^

; -- Timing.
Global milli_secs ; Holds the value of the Millisecs() timer. Set at the start of the main loop.
Global old_time ; This must be set to the current 'MilliSecs()' time at the start of a new game and when returning from a pause.
Global game_time ; This holds a relative game time value which is used with timeouts so that they can be paused.
Global Delta_Time# ; Use this as a multiplier for all continuous game world events, to regulate game speed.
;^^^^^^

;collision groups
Global 	PLAYER = 2
Global 	ter = 1

;light
Global light = CreateLight()
	TurnEntity light,45,45,0
;CAMERA PIVOT
Global camera_pivot= CreatePivot()
EntityRadius camera_pivot,2,5
EntityType camera_pivot, PLAYER

;User Sphere
ball1=CreateCone(32,True,camera_pivot)
RotateEntity ball1,0,270,90
ScaleEntity ball1,30,60,30
EntityColor ball1,70,80,190



;Pyramyd FOV
PyFov=CreateCone(32,True,camera_pivot)
RotateEntity PyFov,0,90,90
MoveEntity pyfov,0,-300,0
EntityAlpha(pyfov,0.5)
ScaleEntity pyfov,700,350,700

;CAMERA
Global camera = CreateCamera(camera_pivot)
CameraViewport(camera,0,GraphicsHeight()/2,GraphicsWidth()/2,GraphicsHeight()/2)
CameraRange(camera,1,50000)
CameraZoom(camera,FovToZoom(90))

;Camera 2
Global camera2 = CreateCamera()
CameraViewport(camera2,GraphicsWidth()/2,GraphicsHeight()/2,GraphicsWidth()/2,GraphicsHeight()/2)
PositionEntity camera2,0,300,0
CameraRange(camera2,1,50000)
RotateEntity camera2,90,180,180

;Camera 3
Global camera3 = CreateCamera()
CameraViewport(camera3,GraphicsWidth()/2,0,GraphicsWidth()/2,GraphicsHeight()/2)
PositionEntity camera3,0,6600,0
CameraRange(camera3,1,100000)
RotateEntity camera3,90,180,180


;CAMERA11 PIVOT
Global camera_pivot11= CreatePivot()
EntityRadius camera_pivot11,2,50
EntityType camera_pivot11, PLAYER
;CAMERA12 PIVOT
Global camera_pivot12= CreatePivot()
EntityRadius camera_pivot12,2,50
EntityType camera_pivot12, PLAYER
;CAMERA13 PIVOT
Global camera_pivot13= CreatePivot()
EntityRadius camera_pivot13,2,50
EntityType camera_pivot13, PLAYER
;CAMERA14 PIVOT
Global camera_pivot14= CreatePivot()
EntityRadius camera_pivot14,2,50
EntityType camera_pivot14, PLAYER

;Pyramyd FOV11
PyFov11=CreateCone(32,True,camera_pivot11)
RotateEntity PyFov11,0,90,90
MoveEntity pyfov11,0,-300,0
EntityAlpha(pyfov11,0.5)
ScaleEntity pyfov11,800,400,800
EntityColor(pyfov11,0,255,255)
;Pyramyd FOV12
PyFov12=CreateCone(32,True,camera_pivot12)
RotateEntity PyFov12,0,90,90
MoveEntity pyfov12,0,-300,0
EntityAlpha(pyfov12,0.5)
ScaleEntity pyfov12,800,400,800
EntityColor(pyfov12,155,100,255)
;Pyramyd FOV13
PyFov13=CreateCone(32,True,camera_pivot13)
RotateEntity PyFov13,0,90,90
MoveEntity pyfov13,0,-300,0
EntityAlpha(pyfov13,0.5)
ScaleEntity pyfov13,800,400,800
EntityColor(pyfov13,255,255,0)
;Pyramyd FOV14
PyFov14=CreateCone(32,True,camera_pivot14)
RotateEntity PyFov14,0,90,90
MoveEntity pyfov14,0,-300,0
EntityAlpha(pyfov14,0.5)
ScaleEntity pyfov14,800,400,800
EntityColor(pyfov14,255,0,255)

;Camera 11
Global camera11 = CreateCamera(camera_pivot11)
CameraViewport(camera11,0,0,GraphicsWidth()/4,GraphicsHeight()/4)
CameraRange(camera11,1,50000)
CameraZoom(camera11,FovToZoom(90))


;Camera 12
Global camera12 = CreateCamera(camera_pivot12)
CameraViewport(camera12,GraphicsWidth()/4,0,GraphicsWidth()/4,GraphicsHeight()/4)
CameraRange(camera12,1,50000)
CameraZoom(camera12,FovToZoom(90))

;Camera 13
Global camera13 = CreateCamera(camera_pivot13)
CameraViewport(camera13,GraphicsWidth()/4,GraphicsHeight()/4,GraphicsWidth()/4,GraphicsHeight()/4)
CameraRange(camera13,1,50000)
CameraZoom(camera13,FovToZoom(90))

;Camera 14
Global camera14 = CreateCamera(camera_pivot14)
CameraViewport(camera14,0,GraphicsHeight()/4,GraphicsWidth()/4,GraphicsHeight()/4)
CameraRange(camera14,1,50000)
CameraZoom(camera14,FovToZoom(90))

;cam11 Sphere
ball11=CreateCone(32,True,camera_pivot11)
RotateEntity ball11,0,270,90
ScaleEntity ball11,20,40,20
EntityColor ball11,255,0,0
;cam12 Sphere
ball12=CreateCone(32,True,camera_pivot12)
RotateEntity ball12,0,270,90
ScaleEntity ball12,20,40,20
EntityColor ball12,255,0,0
;cam13 Sphere
ball13=CreateCone(32,True,camera_pivot13)
RotateEntity ball13,0,270,90
ScaleEntity ball13,20,40,20
EntityColor ball13,255,0,0
;cam14 Sphere
ball14=CreateCone(32,True,camera_pivot14)
RotateEntity ball14,0,270,90
ScaleEntity ball14,20,40,20
EntityColor ball14,255,0,0

; Terrain
Terrain1 = LoadMesh("israp1p1.3ds")
EntityType Terrain1,ter
ScaleEntity(terrain1,0.25,1,0.25)
Meshcenter(terrain1)
tex1=LoadBrush("N31E342.jpg")
BrushFX tex1,16
PaintEntity(terrain1,tex1)

;Trees
Tree=LoadMesh("tree1.3ds")
ScaleEntity tree,5,5,5
HideEntity Tree
RndSeed()
EntityPickMode(terrain1,2)
;For i=0 To 30
;	x# = Rand(0,MeshWidth(terrain1))
;	z# = Rand(0,MeshDepth(terrain1))
;	x=x-MeshWidth(terrain1)/2
;	z=z-MeshDepth(terrain1)/2
;	LinePick(x#,20000,z#,x#,-40000,z#)
;	y#=PickedY()
;	tree1=CopyEntity(tree)
;	PositionEntity(tree1,x,y,z)
;Next


;Position the cameras
PositionEntity camera_pivot11,100,300,0
PositionEntity camera_pivot12,0,300,-100
PositionEntity camera_pivot13,-100,300,0
PositionEntity camera_pivot14,0,300,100

RotateEntity camera_pivot11,30,270,0
RotateEntity camera_pivot12,30,180,0
RotateEntity camera_pivot13,30,90,0
RotateEntity camera_pivot14,30,0,0


Collisions PLAYER,ter,2,3
Color(255,0,0)



While Not KeyHit(1)

PositionEntity light1,EntityX(camera_pivot),EntityY(camera_pivot),EntityZ(camera_pivot)
PositionEntity(camera2,EntityX(camera_pivot),1000,EntityZ(camera_pivot))

If EntityX(camera_pivot)>6800 And mapcount>1
	mapcount=mapcount-1
	FreeEntity terrain1
	Terrain1 = LoadMesh("israp1p" +Str(mapcount) + ".3ds")
	EntityType Terrain1,ter
	ScaleEntity(terrain1,0.25,1,0.25)
	Meshcenter(terrain1)
	tex1=LoadBrush("N31E342.jpg")
	BrushFX tex1,16
	PaintEntity(terrain1,tex1)
End If


If EntityX(camera_pivot)<-7250 And mapcount<6
	mapcount=mapcount+1
	FreeEntity terrain1
	Terrain1 = LoadMesh("israp1p" +Str(mapcount) + ".3ds")
	EntityType Terrain1,ter
	ScaleEntity(terrain1,0.25,1,0.25)
	Meshcenter(terrain1)
	tex1=LoadBrush("N31E342.jpg")
	BrushFX tex1,16
	PaintEntity(terrain1,tex1)
End If


ReadStream(mystream)

  If KeyDown(KEY_SPACE) Then jumpv=True
	
  If KeyHit(19) Then
  	MESHnormals(Terrain1)
  	resetpolygons(terrain1)
  	TRIScolor(Terrain1,camera_pivot,6500)
  End If
  
  If KeyHit(key_0)
  	currentcam=0
  	ElseIf  KeyHit(key_1)
  	currentcam=1
	ElseIf  KeyHit(key_2)
	currentcam=2
	ElseIf  KeyHit(key_3)
	currentcam=3
	ElseIf  KeyHit(key_4)
	currentcam=4
  End If
  
CalculateDeltatimeAndGametime()
If currentcam=0
	MoveUser(camera_pivot)
RotateCams(camera_pivot,2)
ElseIf currentcam=1
RotateCams(camera_pivot11,1)
ElseIf currentcam=2
RotateCams(camera_pivot12,1)
ElseIf currentcam=3
RotateCams(camera_pivot13,1)
ElseIf currentcam=4
RotateCams(camera_pivot14,1)
End If

;touchground(camera_pivot)

If jumpv=True jump(camera_pivot)
	HideEntity camera2
	HideEntity camera3
	HideEntity pyfov
	HideEntity pyfov11
	HideEntity pyfov12
	HideEntity pyfov13
	HideEntity pyfov14
	ShowEntity camera11
	ShowEntity camera12
	ShowEntity camera13
	ShowEntity camera14
	ShowEntity camera
	UpdateWorld
	RenderWorld

	HideEntity camera
	HideEntity camera11
	HideEntity camera12
	HideEntity camera13
	HideEntity camera14
	ShowEntity pyfov
	ShowEntity pyfov11
	ShowEntity pyfov12
	ShowEntity pyfov13
	ShowEntity pyfov14
	ShowEntity camera2
	ShowEntity camera3
	RenderWorld
	
	ShowEntity camera
	ShowEntity camera11
	ShowEntity camera12
	ShowEntity camera13
	ShowEntity camera14
	Color 255,255,255
	Text(0,0,"Cam:1")
	Text(0,10,"Pitch(X):" + EntityPitch(camera_pivot11))
	Text(0,20,"Yaw(Y):" + EntityYaw(camera_pivot11))
	
	Text(GraphicsWidth()/4,0,"Cam:2")
	Text(GraphicsWidth()/4,10,"Pitch(X):" + EntityPitch(camera_pivot12))
	Text(GraphicsWidth()/4,20,"Yaw(Y):" + EntityYaw(camera_pivot12))
	
	Text(GraphicsWidth()/4,GraphicsHeight()/4,"Cam:3")
	Text(GraphicsWidth()/4,GraphicsHeight()/4+ 10,"Pitch(X):" + EntityPitch(camera_pivot13))
	Text(GraphicsWidth()/4,GraphicsHeight()/4+20,"Yaw(Y):" + EntityYaw(camera_pivot13))

	Text(0,GraphicsHeight()/4,"Cam:4")
	Text(0,GraphicsHeight()/4+ 10,"Pitch(X):" + EntityPitch(camera_pivot14))
	Text(0,GraphicsHeight()/4+20,"Yaw(Y):" + EntityYaw(camera_pivot14))
	
	CameraProject camera2, EntityX( camera_pivot12 ), EntityY( camera_pivot12 ) , EntityZ( camera_pivot12 )

	If (ProjectedX()>0) And (ProjectedY()>0) Then
Text GraphicsWidth()/2+ProjectedX(), GraphicsHeight()/2+ProjectedY(), "2"
End If

CameraProject camera2, EntityX( camera_pivot11 ), EntityY( camera_pivot11 ) , EntityZ( camera_pivot11 )
If (ProjectedX()>0) And (ProjectedY()>0) Then
Text GraphicsWidth()/2+ProjectedX(), GraphicsHeight()/2+ProjectedY(), "1"
End If
CameraProject camera2, EntityX( camera_pivot13 ), EntityY( camera_pivot13 ) , EntityZ( camera_pivot13 )
If (ProjectedX()>0) And (ProjectedY()>0) Then
Text GraphicsWidth()/2+ProjectedX(), GraphicsHeight()/2+ProjectedY(), "3"
End If

CameraProject camera2, EntityX( camera_pivot14 ), EntityY( camera_pivot14 ) , EntityZ( camera_pivot14 )
If (ProjectedX()>0) And (ProjectedY()>0) Then
Text GraphicsWidth()/2+ProjectedX(), GraphicsHeight()/2+ProjectedY(), "4"


End If
Text 500,600,"X:" + EntityX(camera_pivot) + "y:" + EntityY(camera_pivot) + "z:" + EntityZ(camera_pivot)
	Color 255,0,0
	Line(GraphicsWidth()/4,0,GraphicsWidth()/4,GraphicsHeight()/2)
	Line(0,GraphicsHeight()/4,GraphicsWidth()/2,GraphicsHeight()/4)
	Line(GraphicsWidth()/2,0,GraphicsWidth()/2,GraphicsHeight())
	Line(0,GraphicsHeight()/2,GraphicsWidth(),GraphicsHeight()/2)
Flip
Wend 
;==================================
; ReadStream function
;================================== 
Function ReadStream(serverstream)
msg = RecvUDPMsg(serverstream)
	If Not msg = 0
		MsgData=ReadLine(serverstream)
		If Not Trim(msgdata)=""
		RecievedStr=Trim(msgdata)
		End If
	End If
End Function

;==================================
; RotateCams function
;================================== 
Function RotateCams(CamPiv,MP)
enty=EntityYaw(campiv)
entR=EntityRoll(campiv)
If KeyDown(key_down)
	RotateEntity(campiv,EntityPitch(campiv)+2*MP,EntityYaw(campiv),EntityRoll(campiv))
	ElseIf KeyDown(key_up)
	RotateEntity(campiv,EntityPitch(campiv)-2*MP,EntityYaw(campiv),EntityRoll(campiv))
	ElseIf KeyDown(KEY_left)
	RotateEntity(campiv,EntityPitch(campiv),EntityYaw(campiv)+2*MP,EntityRoll(campiv))
	ElseIf KeyDown(KEY_right)
	RotateEntity(campiv,EntityPitch(campiv),EntityYaw(campiv)-2*MP,EntityRoll(campiv))
End If
If EntityPitch(campiv)>90-2*mp Then RotateEntity(campiv,90-2*mp,enty,entR)
If EntityPitch(campiv)<-(90-2*mp) Then RotateEntity(campiv,-(90-2*mp),enty,entR)
End Function


;==================================
; touchGround function
;================================== 
Function touchground(n$)
If Not EntityCollided(n$,ter)
touchv=touchv-0.5
  MoveEntity (n$,0,touchv,0)
Else
  touchv=0
End If
End Function

;==================================
; Jump function
;================================== 
Function Jump(n$)
If Not EntityCollided(n$,ter)
  MoveEntity (n$,0,10,0)
Else
 jumpv=False
End If
End Function

Function MoveUser(user)
fft=False

	If Left(RecievedStr$,2)="FF"
		fft=True
	End If
	If fft=True 
		ffx = Mid(RecievedStr$,4,1)
		ffy = Mid(RecievedStr$,6,1)
		ffz = Mid(RecievedStr$,8,1)
	End If
	
	If KeyDown( key_d )  Or (fft=True And ffx=1) ; Right. The 'D' and 'CURSOR RIGHT' keys.
		x#=100.0
	Else If KeyDown( key_a )  Or (fft=True And ffx=-1) ; Left. The 'A' and 'CURSOR LEFT' keys.
	x#=-100.0
	EndIf

	If KeyDown( KEY_F ) Or KeyDown( 54 ) Or (fft=True And ffy=1) ; Up. The 'F' and 'RIGHT SHIFT' keys.
		y#=500.0
	Else If KeyDown( key_c ) Or KeyDown( 157 )Or (fft=True And ffy=-1) ; Down. The 'C' and 'RIGHT CONTROL' keys.
		y#=-500.0
	EndIf

	If KeyDown( key_w )  Or (fft=True And ffz=1) ; Right. The 'w' and 'CURSOR RIGHT' keys.
		z#=100.0

	Else If KeyDown( key_s )  Or (fft=True And ffz=-1) ; Left. The 's' and 'CURSOR LEFT' keys.
	z#=-100.0
	EndIf

	MoveEntity user, x# * user_movement_speed# * Delta_Time#, y# * user_movement_speed# * Delta_Time#, z# * user_movement_speed# * Delta_Time# ; Move the user.
If fft=True
	RecievedStr$=""
End If


End Function


Function CalculateDeltatimeAndGametime()
; NOTES:
; The variable 'old_time' must be set to the current millisecs time at the start of a new game and when returning from a pause.

	milli_secs = MilliSecs () ; Store the 'MilliSecs ()' time in the 'milli_secs' variable so that you can use the stored time value without calling 'MilliSecs ()' again in this loop.

	the_time_taken = milli_secs - old_time ; Calculate the time the last loop took to execute.
	If the_time_taken > 100 Then the_time_taken = 100 ; This stop disk accesses And the like from causing jumps in position.
	game_time = game_time + the_time_taken ; Calculate the value for the 'game_time' variable used with timeouts, etc.
	Delta_Time# = the_time_taken / 1000.0 ; Calculate the value for the 'Delta_Time#' variable used to regulate game speed.
	old_time = milli_secs ; Update the 'old_time' variable with the current time.

End Function

Function FovToZoom#(FOV#)
  Return 1.0 / Tan(FOV#/2.0)
End Function

Function ZoomToFov#(Zoom#)
  Return 2*ATan(1.0/Zoom)
End Function


So my need is a function that would be used like that:
spotlight1=createlight(); I guess
positionentity spotlight1,entityx(camera_pivot),entity(camera_pivot),entityz(camera_pivot)
if keyhit(key_r)
shadeterrainacordingtospotlight(terrain1,spotlight1)
end if

or another option is
if keyhit(key_r)
shadeterrainacordingtoposition(terrain1,x,y,z)
end if

so what will come out will be like the function you gave me using line pick on last topic, but it should be much more accurated(the problem with tha function you gave is that it send a linepick to the center of the triangle, but my need is like to send it to every single point on the triangle and even if one is visible then color the triangle(and some why it wasnt accurated and colored some triangle wrong)

When I said post the code - I meant something which I can run without other include files / media etc..

btw. Native spotlights are going to light hidden poly's so this isn't what you want.

The function I gave you could be easily amended to do a check on all 3 vertices of the triangle.

Function TRIScolor( Mesh , Viewer )

	;get viewers direction normal
	TFormNormal 0,0,1,Viewer, 0
	CamNx# = TFormedX()
	CamNy# = TFormedY()
	CamNz# = TFormedZ()

	For su = 1 To CountSurfaces( Mesh )
		s = GetSurface( Mesh , su )
		For t = 0 To CountTriangles( s ) - 1
		
			;get vertices in triangle - normals should be same on each
			v0 = TriangleVertex( s, t, 0 )
			v1 = TriangleVertex( s, t, 1 )
			v2 = TriangleVertex( s, t, 2 )
			
			;get triangle normal in world space coords
			TFormVector VertexNX( s, v0 ), VertexNY( s, v0 ) , VertexNZ( s, v0 ) , Mesh , 0
			TriNx# = TFormedX() 
			TriNy# = TFormedY() 
			TriNz# = TFormedZ() 			 
			
			;compute dot product of camera normal and tri normal
			CdotN# = CamNx * TriNx + CamNY * TriNy + CamNz * TriNz
			
			;default rgb to white
			tR = 255
			tG = 255
			tB = 255
			
			If CdotN <= .000001 Then

				;this triangle is facing camera so check whether any of the vertices are obscured
				For v = v0 To v2
					;get vertex position in world space coords
					TFormPoint VertexX( s, v ) , VertexY( s, v ) , VertexZ( s, v ), mesh, 0
					;get direction vector from vertex position to viewer
					Dx# = TFormedX() - EntityX( viewer, 1 )
					Dy# = TFormedY() - EntityY( viewer, 1 )
					Dz# = TFormedZ() - EntityZ( viewer, 1 )
					;do a linepick from the viewer to the vertex
					Picked = LinePick( EntityX( viewer , 1 ) , EntityY( viewer , 1 ) , EntityZ( viewer , 1 ) , Dx, Dy , Dz )
					;the linepick hit something so this tri is obscured
					If PickedTime() < 1.0
						tR = 255
						tG = 0
						tB = 0
						Exit
					EndIf
				Next					

			EndIf
	
			;color this triangle
			For v = v0 To v2
				VertexColor s, v, tR, tG , tB
			Next

		Next
	Next
	
End Function


Does this work for you?

Stevie

I'm pretty noob in blitz but not that i cant think of doing that for the 3 vertexes. even though when ive done that, it wasn't really accurate(it was even worse when using all the 3 vertexes) and colored wrongly.