I wanted to speed up my fog of war code and get it from c++ side to shader code, which is really like drawing alpha on texture. But I have one problem: I can’t really permanently draw on texture, it’s like on every frame shader resets texture and I can only see something in one frame: Video
Im using DiffAlpha technique. My shader code is just modification of LitSolid with added:
if(diffColor.a > 0.01) //check if that part wasn't cleared yet
//if not, then get square of distances
float dX = cUnitPos.x - vTexCoord.x;
float dY = cUnitPos.y - vTexCoord.y;
float sqrD = dX*dX+dY*dY;
float sqrR = 0.01;
float sqrR2 = 0.02;
//if square is smaller than first radius clear fully
if(sqrD < sqrR)
diffColor.a = 0;
else if(sqrD < sqrR2) //otherwise if square is smaller than second radius clear partly
diffColor.a = (sqrD - sqrR)/(sqrR2 - sqrR);
diffColor.a = diffColor.a + ((rand(vTexCoord) / 4.0) * diffColor.a);
I have 1 uniform parameter that describes unit position in current frame. First radius describes range of full clear, second describes partly clear + Im adding some randomity.
From c++ side Im only updating cUnitPos with current mouse position.
I’m not sure, but for some reason I doubt it given the notion of a graphics pipeline. What happens in the shader occurs further down the line as where textures are prepared, I think.
Someone else may be able to confirm or refute this somewhat baseless claim.
I don’t know how could I do this, I remove alpha only when units move, the problem is that in higher resolutions many pixels need to be checked, on 1024x1024 its 25600 pixels to check square distance (I check only a square of fog, that unit can see), and then set pixels alpha to appropriate value, and finally swap texture. That lags my game with every move of unit, so I’m stucked with 512x512 which is smooth yet.
It would probably be faster to draw another texture (similar to the Spot.png, included with the engine) on the fog map than to pixel by pixel calculate a circle each frame.
Of course the texture could be generated at run time, but storing it as such should save some CPU.
If you want to go with updating the texture what I would do is use a texture render target (like the render to texture example) with a render path that does not clear the texture. Clear it once at the beginning, and then after that the only updates are adding/subtracting based on billboards or the like at each of your units (depending on whether 1 or 0 represents fog). This should allow you to relatively easily get your inner and outer radius fading by changing what texture you use as the particle “brush.” (I believe the is basically the approach Modanung is suggesting in his latest reply)
Similar but not identical to what I had in mind. I think my suggestion is closer to what @Taqer already has, whereas thine approach, @SirNate0, would be a more high-level minimap-like solution using existing building blocks. My suggestion did not mean to diverge from the SetData(...) part.