Fog of War

Hi im creating a RTS and Im trying to do the fog of war now. I first tought of creating a spotlight on everything with vision and then i searched and found this topic [url]Best way to implement Fog of War?] i did what was sugested but with the roaming ralph tutorial its not good, 'cause its one texture repeated, so the fog (dark texture) is applied to everyone and then the are of view (the makeSpot) is applied to every ‘tile’ individually.

ps: i dindt tested with a terrain with only one big texture, but I think that

So do you guys have any idea of how could i do a fog of war? or how could I use this idea to a ‘tiled’ terrain (like the roaming ralph)

ps2: sry for my english, its not my main language and im in a hurry ^^


You could cover the terrain with many polys, whcih are textured with a soft black brush and then remove that curtain depending on your units’ positions.

That cover would float above the whole map, but stay under the camera.
Alternatively you could place it at the same height as the terrain and only render it on foreground (you can set the rendering order manually). The latter method would prevent looking under the curtain from smaller camera angles.

Another approach would be a custom vertex shader that paints all geometry under the fog black.

This should be enough to get you started :

from direct.directbase import DirectStart
from pandac.PandaModules import *
import random, sys

terrain = loader.loadModel('../samples/Roaming-Ralph/models/world')

veilColor = .2 # the veil/fog color
imgSize = 32.
img = PNMImage(imgSize,imgSize)
brush = PNMBrush.makeSpot(VBase4D(1),3,True)
painter = PNMPainter(img)
tex = Texture()

minb, maxb = terrain.getTightBounds()
dim = maxb-minb
maxDim = max(dim[0],dim[1])
scale = 1./maxDim
center = (minb+maxb)*.5
veilTS = TextureStage('')
terrain.setTexGen(veilTS, RenderAttrib.MWorldPosition)
terrain.setTexScale(veilTS, scale)
terrain.setTexOffset(veilTS, -.5-center[0]*scale, -.5-center[1]*scale)

# a dummy node to hold size & position of terrain to texture transform  
texOrigin = render.attachNewNode('')
texOrigin.setPos(center[0]-.5*maxDim, center[1]+.5*maxDim, 0)

ls = LineSegs('')
unit = render.attachNewNode(ls.create())

cm = CardMaker('')
card = base.a2dBottomRight.attachNewNode(cm.generate())

def move(task):
    dt = globalClock.getDt()
    task.updateDt += dt
    unit.setH(unit, random.uniform(-15,15))
    unit.setY(unit, 20*dt)
    if not (minb[0]<unit.getX()<maxb[0] and minb[1]<unit.getY()<maxb[1]):
       unit.setY(unit, 40*dt)
    if task.updateDt>.2: # fog update interval, in second
       x = unit.getX(texOrigin)
       y = unit.getY(texOrigin)
       painter.drawPoint(x, y)
    return task.cont
moveTask = taskMgr.add(move,'move')
moveTask.updateDt = 0

camera.setPos(-29.66, -216.88, 255.92)
camera.setHpr(-0.47, -50.13, -0.36)
mat = Mat4(camera.getMat())
base.accept('escape', sys.exit)
base.accept('r', img.fill, [veilColor])

Press R to refill the fog.

Thanks guys.

I just tested your code, its so good. When I get home i’ll do some changes, thx.

This is brilliant. I didn’t even think about that :smiley:

Hello, I’m sorry to bother you. I see that the functionality of your program is great, and it fits exactly into a fog function I’m implementing. However, I am very confused about the setting coordinates and scaling of the virtual nodes in the program, and I found that once modified to other numerical effects, it is not as good as before. So I also want you to help me explain, so as to help me better achieve my own functions. thank you very much!