Jump to content

Recommended Posts

I didn't "kinda made it work", I made it work how I wanted it to :) .

 

As I said, it was a balancing act. Snow density and spread vs time between emitter spawning vs radius vs chance of seeing snow in buildings vs CPU overhead

 

Fiddle the settings to see if you get something that suits you better. Or not. Or wait for killzone.

 

_snowEmitter setParticleRandom [0, [4,4,4], [0, 0, 0], 0, 0.01, [0, 0, 0, 0.1], 0, 0];
_snowEmitter setDropInterval 0.01; 
_rad = 12; // spawn emitters further away if under cover
		} else
sleep 0.1;

 

Share this post


Link to post
Share on other sites
Spoiler
On 16. 1. 2017 at 10:12 AM, tpw said:

Blatant promotion: TPW MODS (TPW FOG) has a snow function which spawns snowflakes around the player as long as the player is not in a building.  

 

Here's modified version which doesn't rely on the other variables in TPW FOG. 



//SNOW FX    
tpw_fog_fnc_snow =
    {
    private ["_pos","_highpos","_snowemitter"];    
    while {true} do
        {
        if (overcast > 0.4 && alive player) then 
            {
            0 setrain 0;
            _pos = eyepos player;
            _highpos = [_pos select 0,_pos select 1,(_pos select 2) + 10];
            if (!(lineintersects [_pos,_highpos]) || vehicle player != player || (eyepos player) select 2 < 0) then 
                {
                _snowEmitter = "#particlesource" createVehicleLocal getpos player;
                _snowEmitter setParticleCircle [0.0, [0, 0, 0]];
                _snowEmitter setParticleRandom [0, [10, 10, 7], [0, 0, 0], 0, 0.01, [0, 0, 0, 0.1], 0, 0];
                _snowEmitter setParticleParams [["\A3\data_f\ParticleEffects\Universal\Universal", 16, 12, 13,1], "","Billboard", 1, 7, [0,0,0], [0,0,0], 1, 0.0000001, 0.000, 1.7,[0.07],[[1,1,1,1]],[0,1], 0.2, 1.2, "", "", vehicle player];
                _snowEmitter setDropInterval 0.001;  
                _snowEmitter attachto [vehicle player,[0,0,8]];
                sleep 2;
                deletevehicle _snowemitter;
                };
            };
        sleep 1;    
        };    
    };

Hope this helps.

A particle newbie here, why do you continuously delete and respawn the particle emitter? Why not just move it with the player and check for conditions?

Share this post


Link to post
Share on other sites
7 hours ago, theend3r said:
  Reveal hidden contents

A particle newbie here, why do you continuously delete and respawn the particle emitter? Why not just move it with the player and check for conditions?

 

Emitters can't be switched on/off or have their parameters changed once they're created, they have to be deleted and created with new parameters. It's not possible to create a snow emitter which dynamically changes the amount of snow it creates in response to the environmental conditions for instance.

 

I indeed used to just use a single large emitter attached to the player, checked if the player was under cover, and deleted the emitter if so. This prevented snow from falling inside, but also prevented snow from falling outside when the player was inside.

 

Continuously spawning/despawning small snow emitters randomly around the player gives the same illusion of snow around the player, but allows the determination of whether a given position is under cover and should have snow or not. So a player won't see snow inside, but can look out the window and see snow outside.

Share this post


Link to post
Share on other sites
31 minutes ago, tpw said:

 

Emitters can't be switched on/off or have their parameters changed once they're created, they have to be deleted and created with new parameters. It's not possible to create a snow emitter which dynamically changes the amount of snow it creates in response to the environmental conditions for instance.

 

I indeed used to just use a single large emitter attached to the player, checked if the player was under cover, and deleted the emitter if so. This prevented snow from falling inside, but also prevented snow from falling outside when the player was inside.

 

Continuously spawning/despawning small snow emitters randomly around the player gives the same illusion of snow around the player, but allows the determination of whether a given position is under cover and should have snow or not. So a player won't see snow inside, but can look out the window and see snow outside.

That's the same thing, just checking if the player is inside and spawning emitters around the bounding box of the model one time and not continually seems more intuitive.

Share this post


Link to post
Share on other sites

Guys, guys! You are doing it the wrong way. Here is an algorithm:


1. Generate random position for 1 particle spawn around player
2. Find distance for the nearest surface underneath it
3. Calculate TTL - time to live for the particle based on the distance and speed of falling, so that when it near surface it is deleted
4. Obviously you dont need to bother if surface is ground
5. use "drop" command in a loop to generate snow with dynamic params

That's all. Then there is tonnes of tweaks to make it work good. I don't have time to finish my script, and I do not share work in progress. But this tip should be enough to get you started on the right path.

  • Like 2

Share this post


Link to post
Share on other sites
19 minutes ago, killzone_kid said:

Guys, guys! You are doing it the wrong way. Here is an algorithm:


1. Generate random position for 1 particle spawn around player
2. Find distance for the nearest surface underneath it
3. Calculate TTL - time to live for the particle based on the distance and speed of falling, so that when it near surface it is deleted
4. Obviously you dont need to bother if surface is ground
5. use "drop" command in a loop to generate snow with dynamic params

That's all. Then there is tonnes of tweaks to make it work good. I don't have time to finish my script, and I do not share work in progress. But this tip should be enough to get you started on the right path.

There he is :D Too bad you don't have time for it.. But if anyone else knows how to do this that would be awesome.

Share this post


Link to post
Share on other sites

There you all go then, there are multiple ways to approach the problem, whodathunkit. None of them is more correct than the others. Pick the one that suits you.

Share this post


Link to post
Share on other sites

Impressive !!

 

Do you know if it's possible to get a white sky ? May be with some heavy fog 200m above the players ?

Share this post


Link to post
Share on other sites

Thanks to KK for the steer. Here's my proof of concept code. Put it in the debug console and hit local exec. This isn't optimized and not an MP thing, please don't use this in a mission :). It currently relies on zero wind (so the snow falls directly downwards), it really needs the checks to compensate for wind vector (if anyone fancies working that out :)).

Play around with snowFidelity (spacing of particle emitters), snowIntensity (amount of snow) and snowMaxDistance (maximum distance snow is spawned from player).
 

Spoiler

1 setOvercast 0.7;
1 setFog 0.5;
snow = true;
snowIntensity = 400;
snowVelocity = 1;
snowFidelity = 5;
snowMaxDistance = 25;
setViewDistance 500;
 
0 = [] spawn {  
  while {true} do {  
    private _a = 0;  
    while {snow && _a < snowIntensity} do {  
      private _vel = snowVelocity;  
      private _fi = snowFidelity;  
      private _max = snowMaxDistance;   
      for "_i" from _fi to _max step _fi do {  
        private _pos = getposASL player;
        setWind [0,0,true];
        0 setRain 0;  
       _d = _i;  
        private _dpos = [((_pos select 0) + (_d - (random (2*_d))) + ((velocity vehicle player select 0)*1)),((_pos select 1) + (_d - (random (2*_d))) + ((velocity vehicle player select 0)*1)),(_pos select 2) + ((_max + _fi) - _i)];  
 
        private _hdpos = [_dpos select 0, _dpos select 1, (_dpos select 2) + 25];  
        private _ldpos = [(_dpos select 0), (_dpos select 1), _pos select 2];  
 
        if !(lineIntersects [_ldpos, _hdpos]) then {  
          private _surfheight = _ldpos select 2;  
          private _dist = (_dpos select 2) - (_ldpos select 2);  
          if (lineIntersects [_dpos, _ldpos]) then {  
            _surfHeight = (((lineIntersectsSurfaces [_dpos,_ldpos,player,player,true,1] select 0) select 0) select 2);  
            _dist = (_dpos select 2) - _surfHeight;  
          };  
          private _ttl = (_dist / _vel) * 0.6;  
 
          drop ["\ca\data\cl_water", "", "Billboard", 1, _ttl, ASLToATL _dpos, [0,0, 0 - _vel], 1, 0.0000001, 0.000, 0.7, [0.07], [[1,1,1,0], [1,1,1,1], [1,1,1,1], [1,1,1,1]], [0,0], 0.2, 1, "", "", ""];  
        };  
        _a = _a + 1;  
      };  
    };  
    sleep 0.3;  
  };  
 
};

 

 

  • Like 1

Share this post


Link to post
Share on other sites

Runs very smooth and it spawns in very nice and subtly.

I would like to see it with other snow flakes (i know its just a concept). Also, the snow gets pretty intense if you quickly look back after you have ran for a bit (don't know if that's a standard problem or difficult to fix).

I also noticed that some flakes disappears before reaching the ground (again, dont know if its an easy fix or not).

If the snow could be affected by the wind that would be VERY cool if anyone knows how to do that.

I see what you mean about MP. Tried taking control of an ugv and the snow apparently only falls around the player, also when seen from the ugv's perspective. But it seems to work very nicely with driving (you can't drive past the snow or something like that)

Btw is 400 the highest value for snow intensity? (i'm trying out more distance)

Share this post


Link to post
Share on other sites

18000 I think is the intensity limit (number of particles per emitter). The more distance, the more spread out the emitters will be. maxDistance in theory should cover the largest building size, so when indoors, its snowing all around. I think maxDistance of 35-50 is probably ok, but snow starts to thin out even at max intensity. This is just prototype code as a test :)

Share this post


Link to post
Share on other sites

You probably can do with just lineIntersectsSurfaces as it has everything. Also no need to calculate ttl when there is only ground, again lineIntersectsSurfaces can tell you that.

 

Share this post


Link to post
Share on other sites

Wasn't sure how expensive lineIntersectsSurfaces was compared to lineIntersects. Guess it saves two checks though :)

Share this post


Link to post
Share on other sites
2 minutes ago, tupolov said:

Wasn't sure how expensive lineIntersectsSurfaces was compared to lineIntersects. Guess it saves two checks though :)


Ironically, it is the fastest of them all I think

Share this post


Link to post
Share on other sites

Ok, updated it a little. Still not perfect though and stil needs updating to handle wind etc.

 

Spoiler

1 setFog 0.6;  
snow = true;   
snowIntensity = 700;  
snowTempIntensity = 700;   
snowVelocity = 1;   
snowFidelity = 7;   
snowMaxDistance = 35;  
setViewDistance 500;   
   
0 = [] spawn {    
 
    while {true} do {    
 
        private _a = 0;    
        while {snow && _a < snowIntensity} do {    
 
            private _vel = snowVelocity;    
            private _fi = snowFidelity;    
            private _max = snowMaxDistance;   
 
            if (vehicle player != player) then {  
                _max = _max * 2; 
                smowTempIntensity = snowIntensity;  
                snowIntensity = snowIntensity * 9;  
            } else {  
                snowIntensity = snowTempIntensity; 
            };    
 
            for "_d" from _fi to _max step _fi do { 
 
                private _pos = getposASL player; 
 
                setWind [0,0,true];  
                0 setRain 0;    
                 
                private _height = (_max - _d + 2) min 12; 
                if (speed player > 30) then {_height = 8;}; 
 
                private _dpos = [ 
                    ((_pos select 0) + (_d - (random (2*_d))) + ((velocity vehicle player select 1)*1)), 
                    ((_pos select 1) + (_d - (random (2*_d))) + ((velocity vehicle player select 0)*1)), 
                    (_pos select 2) + _height 
                ];    
 
                private _hdpos = [_dpos select 0, _dpos select 1, (_dpos select 2) + 20];    
                private _ldpos =+ _dpos; _ldpos = ASLtoATL _ldpos; _ldpos set [2,0.3]; _ldpos = ATLtoASL _ldpos;    
                 
                if !(lineIntersects [_ldpos, _hdpos]) then {   
 
                    private _ttl = (_height/2);  
                    private _surfaces = lineIntersectsSurfaces [_dpos,_ldpos,player,player,true,1];  
 
                    if (count _surfaces > 0) then { 
 
                        _surfHeight = _surfaces select 0 select 0 select 2; 
                        private _dist = (_dpos select 2) - _surfHeight; 
                        _ttl = ((_dist / _vel) * 0.5) min (_height/2);                         
 
                    };  

                    private _snowDrop = selectRandom [                  
                        ["a3\data_f\ParticleEffects\Universal\Universal.p3d",16,12,(1 + ceil(random 7)),0],
                        "\ca\data\cl_water",
                        ["a3\data_f\ParticleEffects\Universal\Universal.p3d",16,12,13,0],                   
                        ["a3\data_f\ParticleEffects\Universal\Universal.p3d",16,12,(1 + ceil(random 7)),0],
                        ["a3\data_f\ParticleEffects\Universal\Universal.p3d",16,12,16,0],
                        "\ca\data\cl_water",                             
                        ["a3\data_f\ParticleEffects\Universal\Universal.p3d",16,12,(1 + ceil(random 7)),0]
                    ];

                    drop [_snowDrop, "", "Billboard", 1, _ttl, ASLToATL _dpos, [0,0, 0 - _vel], 1, 0.0000001, 0.000, 0.7, [(0.02 + (random 0.06))], [[1,1,1,0], [1,1,1,1], [1,1,1,1], [1,1,1,1]], [0,0], 0.2, 0.7, "", "", ""];    
                };   
                _a = _a + 1;    
            };               
        };  
        sleep 0.2;       
    };    
};

 

 

  • Like 1

Share this post


Link to post
Share on other sites

You need to remove the comments if running it in the debug console.

  • Like 1

Share this post


Link to post
Share on other sites

Very nice. You changed the height so that the snow doesn't swarm the sky when setting up the distance. Could you by any chance make an option for that (how high the snow falls)?

Share this post


Link to post
Share on other sites

Just change the value 12 to whatever max height you would like.

private _height = (_max - _d + 2) min 12;

 

  • Like 1

Share this post


Link to post
Share on other sites

Nice. I really think this has potential. Looking forward to trying it out with other snow flakes (presuming that you are going to finish it).

Share this post


Link to post
Share on other sites
2 hours ago, neetch said:

Nice. I really think this has potential. Looking forward to trying it out with other snow flakes (presuming that you are going to finish it).

Added random snowflakes in new edited code above

  • Like 1

Share this post


Link to post
Share on other sites

Verrry nice! This almost begins to feel complete.

Is there a setting that you can set how much the flakes are being changed? I'd like to have none of the flakes to be completely snowball round.

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×