Day/night cycle solution

Grab your favourite IDE and tinker with the innards of game engines

Day/night cycle solution

Postby amdphenom92 on Fri Sep 07, 2012 4:53 pm

Hello!

I've started working on a mod with Source 2007 engine and so far I've managed to implement what I've wanted, but as you've already guessed, I've run into a problem and I need help with some ideeas.
I want to make a day/night cycle and the problem is that light_environment generate lighting and shadows on the map coresponding to the compile inputs and I want to change them during game. I'm interested in changeing: ambient , brightness and pitch yaw roll . I am thinking of three posibilities.

First, I've looked in base.fgd and if you look an the values you will see :

Code: Select all
_light(color255) : "Brightness" : "255 255 255 200"
   _ambient(color255) : "Ambient" : "255 255 255 20"
   _lightHDR(color255) : "BrightnessHDR" : "-1 -1 -1 1"
   _lightscaleHDR(float) : "BrightnessScaleHDR" : "1" : "Amount to scale the light by when compiling for HDR."
   _ambientHDR(color255) : "AmbientHDR" : "-1 -1 -1 1"


I've searched a bit about those values and I found them on : "src/utils/vrad/lightmap.cpp" : (lines 1585-...)

Code: Select all
for (i=0 ; i<(unsigned)num_entities ; i++)
   {
      e = &entities[i];
      name = ValueForKey (e, "classname");
      if (strncmp (name, "light", 5))
         continue;

      // Light_dynamic is actually a real entity; not to be included here...
      if (!strcmp (name, "light_dynamic"))
         continue;

      if (!strcmp (name, "light_spot"))
      {
         ParseLightSpot( e, dl );
      }
      else if (!strcmp(name, "light_environment"))
      {
         ParseLightEnvironment( e, dl );
      }
      else if (!strcmp(name, "light"))
      {
         ParseLightPoint( e, dl );
      }
      else
      {
         qprintf( "unsupported light entity: \"%s\"\n", name );
      }
   }


Looks like at map compiling this loop search through entities. When "light_environment" was found calls ParseLightEnvironment :

Code: Select all
static void ParseLightEnvironment( entity_t* e, directlight_t* dl )
{
   Vector dest;
   GetVectorForKey (e, "origin", dest );
   dl = AllocDLight( dest, false );

   ParseLightGeneric( e, dl );

   char *angle_str=ValueForKeyWithDefault( e, "SunSpreadAngle" );
   if (angle_str)
   {
      g_SunAngularExtent=atof(angle_str);
      g_SunAngularExtent=sin((M_PI/180.0)*g_SunAngularExtent);
      printf("sun extent from map=%f\n",g_SunAngularExtent);
   }
   if ( !gSkyLight )
   {
      // Sky light.
      gSkyLight = dl;
      dl->light.type = emit_skylight;

      // Sky ambient light.
      gAmbient = AllocDLight( dl->light.origin, false );
      gAmbient->light.type = emit_skyambient;
      if( g_bHDR && LightForKey( e, "_ambientHDR", gAmbient->light.intensity ) )
      {
         // we have a valid HDR ambient light value
      }
      else if ( !LightForKey( e, "_ambient", gAmbient->light.intensity ) )
      {
         VectorScale( dl->light.intensity, 0.5, gAmbient->light.intensity );
      }
      if ( g_bHDR )
      {
         VectorScale( gAmbient->light.intensity,
                   FloatForKeyWithDefault( e, "_AmbientScaleHDR", 1.0 ),
                   gAmbient->light.intensity );
      }
      
      BuildVisForLightEnvironment();
 
      // Add sky and sky ambient lights to the list.
      AddDLightToActiveList( gSkyLight );
      AddDLightToActiveList( gAmbient );
   }
}


And the LightForKey and LightForString procedures:

Code: Select all
int LightForKey (entity_t *ent, char *key, Vector& intensity )
{
   char *pLight;

   pLight = ValueForKey( ent, key );

   return LightForString( pLight, intensity );
}

int LightForString( char *pLight, Vector& intensity )
{
   double r, g, b, scaler;
   int argCnt;

   VectorFill( intensity, 0 );

   // scanf into doubles, then assign, so it is vec_t size independent
   r = g = b = scaler = 0;
   double r_hdr,g_hdr,b_hdr,scaler_hdr;
   argCnt = sscanf ( pLight, "%lf %lf %lf %lf %lf %lf %lf %lf",
                 &r, &g, &b, &scaler, &r_hdr,&g_hdr,&b_hdr,&scaler_hdr );

   if (argCnt==8)                                  // 2 4-tuples
   {
      if (g_bHDR)
      {
         r=r_hdr;
         g=g_hdr;
         b=b_hdr;
         scaler=scaler_hdr;
      }
      argCnt=4;
   }

   // make sure light is legal
   if( r < 0.0f || g < 0.0f || b < 0.0f || scaler < 0.0f )
   {
      intensity.Init( 0.0f, 0.0f, 0.0f );
      return false;
   }

   intensity[0] = pow( r / 255.0, 2.2 ) * 255;            // convert to linear
   
   switch( argCnt)
   {
      case 1:
         // The R,G,B values are all equal.
         intensity[1] = intensity[2] = intensity[0];
         break;
         
      case 3:
      case 4:
         // Save the other two G,B values.
         intensity[1] = pow( g / 255.0, 2.2 ) * 255;
         intensity[2] = pow( b / 255.0, 2.2 ) * 255;
         
         // Did we also get an "intensity" scaler value too?
         if ( argCnt == 4 )
         {
            // Scale the normalized 0-255 R,G,B values by the intensity scaler
            VectorScale( intensity, scaler / 255.0, intensity );
         }
         break;

      default:
         printf("unknown light specifier type - %s\n",pLight);
         return false;
   }
   // scale up source lights by scaling factor
   VectorScale( intensity, lightscale, intensity );
   return true;
}


So the ideea is that if I could declare static directlight_t *gAmbient in a header I could include it it my project and start recalculating lighting, but the problem is that lightmap.cpp is not added to the Game Episodic . So my question what does util/vrad project does ? Compiles and make a .dll that is used by hammer at compiling maps ? And how can I make a connection between my project and a way to update the calculations?

The second ideea is that I could disable shadows in light_environment and start thinking of a way implementing a shadow like the shadow_control but applied to world (walls, ground, etc.).

The third ideea is env_global_light . From what I've seen it looks like you could use input to it and change pitch yaw roll. I've started porting it from ASW , no compile error, I've added entity to map, compile, but I can't see a diference with it on. Must be a problem, and I'm going to debug the project and watch what happens with breakpoints.
I need some help with adivces, what solution could work ?

Thanks,
Robert
amdphenom92
Dumpling
Dumpling
 
Joined: Fri Sep 07, 2012 3:55 pm

Re: Day/night cycle solution

Postby fishshapedfish on Fri Sep 07, 2012 6:46 pm

I remember playing the Hostile Planet mod and noticed that it there was a day/night cycle, maybe you should investigate how they did it? Here's a video of it in action:
Check Out the Team's Latest Mod!
WIP Screenshots
Recruiting/Our Goals
User avatar
fishshapedfish
Regular
Regular
 
Joined: Fri Aug 05, 2011 5:44 pm

Re: Day/night cycle solution

Postby amdphenom92 on Fri Sep 07, 2012 7:06 pm

Thanks for reply, fishshapedfish.
I know how to do that day-night cycle from Hostile Planet. They used an input for light_environment , setpattern "string" . Thus the light starts to fade but you can still observe the shadows that they are not moving. The skybox is not a problem, I can make a brush and change index (multiple skyboxes, in Vue Xstream you can change angle of the sun and render skyboxes at different angles). But the problem is that I want to make dynamic shadows casted by light_environment. And also I want to change ambient light because you can see that when night comes out, the world is lighten too much. Adjusting color of the ambient will produce a much more nice effect.

I don't know what to do, continue with env_global_light or try importing that .cpp and force light calculations.
amdphenom92
Dumpling
Dumpling
 
Joined: Fri Sep 07, 2012 3:55 pm

Re: Day/night cycle solution

Postby nub on Fri Sep 07, 2012 7:19 pm

You can't have dynamic lightmaps as far as I know. They're baked into the map during the compile process and are completely static. Your only choice is to use cascade shadow mapping like CSGO has, or Biohazard's deferred rendering system.
User avatar
nub
Veteran
Veteran
 
Joined: Tue Nov 15, 2005 1:11 am
Location: Charlotte, NC, US

Re: Day/night cycle solution

Postby amdphenom92 on Fri Sep 07, 2012 8:57 pm

I've added in my first post the code where is calculated lightning at map compile.
I was wondering, if shadow_control which affects only entities (props, npc, etc.) can accept an input which changes pitch yaw roll and recalculate the shadow direction, why I can't recalculate the shadow and light casted by light_environment ? There is no way that I can get acces to the world brushes and recalculate their shadow ?

You've mentioned two choices, I would use deferred lighting made by Biohazard but I like programming :D and I want to make something myself. About cascade shadow mapping like CSGO did you mean env_global_light and sunlight_shadow_control ?
amdphenom92
Dumpling
Dumpling
 
Joined: Fri Sep 07, 2012 3:55 pm

Re: Day/night cycle solution

Postby SM Sith Lord on Sat Sep 08, 2012 12:58 am

Previous versions of the Source engine had all brush shadows pre-calculated during VRAD. You could compile alternate light maps (such as with pulsing lights), but nothing that would let you implement a good day/night system easily.

Prop shadows are dynamic and calculated in real time in-game, thats why they are able to move.

CSGO has very awesome shadows, a drastic improvement over previous versions. Not sure how they work yet.
SM Sith Lord
Been Here A While
Been Here A While
 
Joined: Sat Nov 25, 2006 4:25 pm
Location: Los Angles, CA

Re: Day/night cycle solution

Postby Gary on Sat Sep 08, 2012 3:03 am

Best you can do is either the fading light_environment with static shadows(light Rad will probably be screwed). Or the much uglier and slower fake CSM(written on my moddb page), which would give you a 100% dynamic per-pixel light and shadow. But the fake CSM is slow(framerate killer) and not very pretty(shadow errors).
Have a question related to modding or something I posted? Something that needs staff attention? I haven't been active lately, but feel free to PM me or message me on Steam(link below)

User avatar
Gary
Interlopers Staff
Interlopers Staff
 
Joined: Wed Dec 16, 2009 12:40 am
Location: USA, FL

Re: Day/night cycle solution

Postby amdphenom92 on Sat Sep 08, 2012 8:49 am

SM Sith Lord, yes I know. How about patches ? Look (everything from lightmap.cpp) :

Code: Select all
unsigned int uiPatchCount = g_Patches.Count();
   for (i=0; i< uiPatchCount; i++)
   {
      p = &g_Patches.Element( i );

      // skip parent patches
      if (p->child1 != g_Patches.InvalidIndex() )
         continue;

      if (p->basearea < 1e-6)
         continue;

      if( VectorAvg( p->baselight ) >= dlight_threshold )
      {
         dl = AllocDLight( p->origin, true );

         dl->light.type = emit_surface;
         VectorCopy (p->normal, dl->light.normal);
         Assert( VectorLength( p->normal ) > 1.0e-20 );
         // scale intensity by number of texture instances
         VectorScale( p->baselight, lightscale * p->area * p->scale[0] * p->scale[1] / p->basearea, dl->light.intensity );

         // scale to a range that results in actual light
         VectorScale( dl->light.intensity, DIRECT_SCALE, dl->light.intensity );
      }
   }


And after patches are calculated, VRAD looks for an entity :

Code: Select all
else if (!strcmp(name, "light_environment"))
      {
         ParseLightEnvironment( e, dl );
      }


After this calculate ambient color, light, etc.
What If I follow this method and add for example an input to light_environment : void InputSetAngles(inputdata_t &param) in which I set up the angles of light_environment (with SetAbsAngles() ) with those from parameter param and then try to recalculate patches, and the other stuff.

Gary, If I can't find a method I'm going to use fading in light_environment and probably a color corection. I looked at your system and the fact that is a framerate killer is a big disadvantage for me. The mod is going to be some kind of FPS RPG and the maps are going to be like those is STALKER, so there's going to be a lot of entities on it. I have a question, you can change angles of your method in game ?
amdphenom92
Dumpling
Dumpling
 
Joined: Fri Sep 07, 2012 3:55 pm

Re: Day/night cycle solution

Postby Gary on Sat Sep 08, 2012 2:47 pm

I'm telling you now, you can not recalculate lightmapped shadows at run time. It's done externally(vrad, so its not even part of the engine, the engine just renders the results) and is the slowest calculation done for the maps. The best you can do is turn their page/light on or off. Or change the intensity.


amdphenom92 wrote:
Gary, If I can't find a method I'm going to use fading in light_environment and probably a color corection. I looked at your system and the fact that is a framerate killer is a big disadvantage for me. The mod is going to be some kind of FPS RPG and the maps are going to be like those is STALKER, so there's going to be a lot of entities on it. I have a question, you can change angles of your method in game ?


Every aspect of the fake CSM can be altered at runtime; angles, position, color, brightness, shadow filter, shadow quality, etc.
Have a question related to modding or something I posted? Something that needs staff attention? I haven't been active lately, but feel free to PM me or message me on Steam(link below)

User avatar
Gary
Interlopers Staff
Interlopers Staff
 
Joined: Wed Dec 16, 2009 12:40 am
Location: USA, FL

Re: Day/night cycle solution

Postby nub on Sat Sep 08, 2012 3:56 pm

I know you like programming and all, but if the day/night cycle system is that important to your mod, I would seriously just consider implementing the deferred rendering system that Biohazard created. It has so much to offer, including day/night cycle (which is just the tip of the iceberg).
User avatar
nub
Veteran
Veteran
 
Joined: Tue Nov 15, 2005 1:11 am
Location: Charlotte, NC, US

Re: Day/night cycle solution

Postby SM Sith Lord on Sat Sep 08, 2012 4:01 pm

nub wrote:I know you like programming and all, but if the day/night cycle system is that important to your mod, I would seriously just consider implementing the deferred rendering system that Biohazard created. It has so much to offer, including day/night cycle (which is just the tip of the iceberg).


Just wanted to say, Biohazzard is the reason I'm even able to make Source mods. Kudos to him.
SM Sith Lord
Been Here A While
Been Here A While
 
Joined: Sat Nov 25, 2006 4:25 pm
Location: Los Angles, CA

Re: Day/night cycle solution

Postby Gary on Sat Sep 08, 2012 4:39 pm

The last time I saw Bio's deferred rendering path, it wasn't ready to be fully utilized. Not saying it's bad, cause it's awesome. Just that it's got a little ways to go. Plus, it's for alienswarm, so it's not convenient if you are using lots of stuff from hl2/src2007.
Have a question related to modding or something I posted? Something that needs staff attention? I haven't been active lately, but feel free to PM me or message me on Steam(link below)

User avatar
Gary
Interlopers Staff
Interlopers Staff
 
Joined: Wed Dec 16, 2009 12:40 am
Location: USA, FL

Re: Day/night cycle solution

Postby amdphenom92 on Sat Sep 08, 2012 9:23 pm

I understand. I looked deeper into code and in order to calculate the environment light it requires to know all clusters, so even if I find out how to implement it, would freeze the game, there's a lot of calculations and is hard to render them in real time.

Gary, I've read about your fake CSM and I have two questions.
First, how does env_global_light works, you said multiple projection instead of one, how does differ from env_projectedtexture , it's using the same texture projection like env_projectedtexture ?
The second one, your fake CSM take cares of ambient lighting (beside the places where sun light will appears and the shadows casted by it, CSM create an ambient light for indoors)? I mean for example, when using a env_projectedtexture, without using another lighting system behind the places where texture is projected it's completely dark so it's not effective when attempting to use it as a sun light.


EDIT: I've tried something, I put 4 env_projectedtextures without casting shadow in each side of map and one env_projectedtexture that represents sun light and have enabled shadows, but I have a problem with it. Shadows are starting far from the walls :

Image
amdphenom92
Dumpling
Dumpling
 
Joined: Fri Sep 07, 2012 3:55 pm

Return to Programming

Who is online

Users browsing this forum: No registered users