Per pixel lighting

For code related discussions and questions

Per pixel lighting

Postby Vincent » 02 Oct 2016, 00:56

Hi,

since I removed all legacy fixed function in my branch I'm playing with WZ lighting. I'm currently implementing per pixel lighting : currently at map loading time an illumination value is computed and stored for every tile (note: it's direct illumination ie dot product between sun position and tile normal) and when game runs the lightmap is updated every 80 ms with some maths relying on the tile's stored illumination and fog of war value. Local light (for instance explosion) also shades tiles locally. Since lighting is sourced from a texture it looks rather static and flat and can't be view dependant (but performance wise it's very efficient)
Per pixel lighting is moving the lighting computation inside shader which means lighting is pixel accurate and independant of tile. It's obviously more costly but it's a technic used in Doom3 which is more than 10 years old now.

Is there any objection to using this technic in wz2100 since it will slightly change the look of the game ?
Vincent
Trained
Trained
 
Posts: 101
Joined: 06 Aug 2016, 17:24

Re: Per pixel lighting

Postby Berg » 02 Oct 2016, 01:08

Vincent wrote:Is there any objection to using this technic in wz2100 since it will slightly change the look of the game ?


You first have to make it work I’m sure if you need new textures etc there are plenty of folks about to help bring the look back to acceptable.

Go for it and have a working test bed for others who don’t code but do models and texture to assess

Do note the shadows in game are in direct opposite position to the sun and the way real shadows would fall

Keep up the good work

PS: I think the skybox positioning was wrong.
User avatar
Berg
Regular
Regular
 
Posts: 1876
Joined: 02 Sep 2007, 23:25
Location: Australia

Re: Per pixel lighting

Postby Per » 02 Oct 2016, 12:06

It is obviously the right thing to do. We already have per pixel lighting for the 3D models.
Per
Warzone 2100 Team Member
Warzone 2100 Team Member
 
Posts: 3629
Joined: 03 Aug 2006, 19:39

Re: Per pixel lighting

Postby Jorzi » 03 Oct 2016, 07:26

I have been waiting for this. I even considered diving into the warzone codebase and doing it myself but I haven't really had the time. Also compiling on Windows seems complicated.
Anyway do you have a plan for the explosions and fog of war or will they remain per vertex for now?
ImageImage
-insert deep philosophical statement here-
Jorzi
Regular
Regular
 
Posts: 1944
Joined: 11 Apr 2010, 00:14

Re: Per pixel lighting

Postby Vincent » 06 Oct 2016, 22:52

Explosions will be per pixel, sorry I wasn't clear. Fog of war will remain texture based, it's rather a gameplay feature than a visual one.
I've mostly finished working on it, it's not ready for usage (I didn't add safety check in shader for buffer bounds so gpu often crashes) but I can détails the implementation :

At first this will concern terrains and terrain decals only. The light positions are passed via uniforms and at the moment uniforms are rebound for every non terrain object ; while it's fine to pass a couple of matrixes for every object light positions do represent 128 vec2+ up to 64 vec3 (color and position) + up to 32 float(range) which is unpractical if there is a lot of units (and unit are composed of 4 objects) on screen. It's possible to bind them only once but I need to tune the API. On the other hand uniforms terrain binding happens only ~10 times per frame.

About the implementation : I'm using a "clustered" renderer : the view frustrum is splitted in 16x8 clusters. Then for every light, light bounding box is transformed according to the view transform and tested against cluster coverage. For every cluster covered, light position color and range is added to a per cluster array. All of this happens on cpu.
The cluster arrays and their size is send as uniform to shader. In shader fragments check in which cluster they belong and iterate on the corresponding vector.
This approach is close to the one used in Doom (2016) and detailed in their publication for Siggraph 2016 : http://advances.realtimerendering.com/s2016/
Since lights computation happens per cluster instead of whole frame this reduce the per light cost. There's only a single z slice since wz2100 is an rts and mostly use a top down view.

The light équations are taken from "Frostbite going PBR" paper http://www.frostbite.com/2014/11/moving ... te-to-pbr/
There are 2 components in light reflection, diffuse and specular. The specular component uses the GGX equation (units currently uses blinn phong) while diffuse uses Burley's equation (a small tweak over the classic lambert equation that acount for energy conservation).
The GGX equation has a roughness input that doesn't exist in wz2100 atm, I'm using 1.0 as a default value. Future development could make possible to pass a texture (as well a normal map) which may greatly improve terrains visual.
PBR model is not completly implementing though, it lacks a tonemap step, a metalness input (which can be again passed as a texture) and cubemap probes for environment reflection. This will likely happen later.
Since PBR is now mainstream (it's the one implemented in Frostbite, Unreal Engine 4, Source 2, and internal Overwatch engine), using it as a base makes sense in my opinion.
Vincent
Trained
Trained
 
Posts: 101
Joined: 06 Aug 2016, 17:24

Re: Per pixel lighting

Postby Jorzi » 09 Oct 2016, 14:20

Cool stuff :)
So since you use a clustered renderer, does that also mean you will be doing deferred rendering? Maybe that is what you meant with per pixel lighting?

As for roughness, shouldn't the default be 0, like in the Oren Nayar model or is it defined in some other way? Usually one can get away with roughess 0 (purely lambertian) for everything, but it could be used for giving some more realism for dusty arizona rocks & cliffs, stucco/plaster walls and maybe snow.
MaNGusT has mentioned that it wouldn't be hard for him to generate normal maps for ground textures.
As for metalness, I usually make the distinction that metallic objects have coloured specular reflections while dielectrics have purely white speculars. In my own shader (prior to the introduction of a separate specular map slot) I used the normalmap's alpha channel for specularity and multiplied it with the (normalized) diffuse colour, which gives something comparable to metalness 1 shading. This isn't really a perfect solution but it gives complex shading with fairly low memory usage.
ImageImage
-insert deep philosophical statement here-
Jorzi
Regular
Regular
 
Posts: 1944
Joined: 11 Apr 2010, 00:14

Re: Per pixel lighting

Postby Vincent » 11 Oct 2016, 16:37

Actually clustered renderer is a forward rendering technic. Deferred rendering trades shader flexibility for the ability to render lots of small point light and has an heavy bandwidth requirement (due to gbuffer storage and access) ; it also makes MSAA impractical.
Clustered rendering technic on the other hand is based on the classical forward rendering model which means that any shader can be used to draw object and that MSAA is cheap ; on the other hand there is some overdraw as some object can be rendered and then partly hidden behind another one which means the computations on these discarded pixel are wasted (and since shaders are responsible for light calculation these computations are not that cheap). Since warzone 2100 is likely to be rendered with a top down view there is not a lot of geometry hidden behind another one though. Also the light grid is more coarse but again, since wz2100 is an RTS there is likely less light effect than there is in an fps game.

I used a non 0 roughness to make the specular highlight less apparent ; with a roughness of 0 everything would look mirror smooth even the ground : http://oliverm-h.blogspot.fr/2013/05/ud ... rials.html

For metalness/roughness storage I think it's better to have separate maps and let the tools or the engine combine them if necessary. Currently there is no dedicated texture tool since wz loads png and OpenGL compress them and compute the mipmap on the fly but I think it would be better to switch to raw data file contained like .dds (likely Embedded in a zip files). Providing the texture in already compressed and mipmapped form means faster loading time (compression can takes a lot of time, especially when using the more advanced BC6 and BC7 scheme) and a lot less variance accross drivers ; additionnaly Vulkan doesn't compress textures and doesn't generate mipmap and writing compression and mipmaping compute shaders is difficult.
Vincent
Trained
Trained
 
Posts: 101
Joined: 06 Aug 2016, 17:24

Re: Per pixel lighting

Postby Per » 12 Oct 2016, 00:28

Clustered forward rendering is really awesome. Maybe overkill for Warzone, but hey, why not... :-)

Texture compression and texture storage file formats used to be really difficult for open source projects, but fortunately the situation is quickly becoming a lot better. While the tools may not quite be there yet, and desktop hardware may still need to catch up, I think the future is with the KTX file format and the ASTC texture compression format, as these are standards-based and cross-platform rather than proprietary and platform-specific. Going with DDS now is probably not a forward-looking choice.
Per
Warzone 2100 Team Member
Warzone 2100 Team Member
 
Posts: 3629
Joined: 03 Aug 2006, 19:39

Re: Per pixel lighting

Postby Berg » 12 Oct 2016, 10:07

Just like to pointy out maybe some players dont have the drivers to use all this you beaut shaders etc would be good to keep in mind we already left a lot behind with the 3.2 version not running for them.
User avatar
Berg
Regular
Regular
 
Posts: 1876
Joined: 02 Sep 2007, 23:25
Location: Australia

Re: Per pixel lighting

Postby Vincent » 13 Oct 2016, 17:09

I'd like to keep GL2.1 compatibility as long as possible. Using GL 3.3 would make dev easier with uniform buffer objects but I think it can be possible to simplify thing by using some compile time reflection.
On the other hand a vulkan backend could be used to implement some advanced technics.
Vincent
Trained
Trained
 
Posts: 101
Joined: 06 Aug 2016, 17:24


Return to Coding