With the introduction of Operation Wildfire and the update of de_nuke, come a number of visual upgrades and features that we think mapmakers and community content creators alike will find useful and exciting. The following is an overview of these features and how they can be enabled in your own maps and content.
One of the areas that we upgraded extensively during the development of Nuke was the in-game lighting. With Nuke’s new look, we strived for a clean, colorful aesthetic with bold, realistic lighting and global illumination.
We started by improving the quality of our static prop model lighting by increasing the amount of global illumination light rays that get fired by VRAD (our pre-computed lighting engine) in addition, we also improved the accumulation of the ray results which leads to a smoother, higher quality result; basically, the more rays fired when calculating lighting, the more accurate the results.
BEFORE Note the splotchy, uneven lighting on the cube models.
AFTER With more rays fired and better accumulation, the cube models look smoother and free of splotches.
To enable these improvements, open up the compile options in Hammer (F9) and click on the Advanced button.
Then in light_exe (VRAD) make sure you have the parameter
This improvement does increase compile time, but to help with iteration we also included the ability to tweak the quality of the new lighting by adding the –StaticPropSampleScale x parameter (16=slow, high quality, 4=default and 0.25=fast, low quality) which is useful if you want to speed up compile times. Note that adding
-final is the equivalent of having -StaticPropLightingScale 16. We recommend you try some different values and see which one works best for you.
We then improved the quality of lighting on displacement surfaces (e.g terrain surfaces) by enabling a feature called super sampling which allows for smooth, accurate shadows. We also transferred over our static prop model lighting enhancements to the displacements for much improved bounced light between surfaces.
BEFORE The shadows from the fence on the displacement look pixelated and low quality in comparison to the brush surface.
AFTER The shadow quality on the displacement is now identical to the brush.
Next we set about upgrading the lighting of our normal mapped static props by implementing full, per-vertex lighting that uses the same radiosity calculations as our lightmaps do. The result is that normal mapped static prop models now light much more accurately and with results very similar to our lightmapped geometry (brushes, displacements, etc.). This should make using normal maps on static props much simpler and more awesome in the future:
BEFORE Note that the model’s lighting looks darker than that of the brush and doesn’t pick up as much color.
AFTER Now, both the model and the brush light identically.
As mentioned previously, to enable these features you will need to add –staticproplighting to the ($light_exe) advanced compile parameter, otherwise it will revert to the old lighting model.
One last thing we wanted to upgrade was how our cascade shadow maps interact with pre-computed lighting in our levels; Cascade shadow maps (CSMs) are our dynamic, high quality real-time shadows which can be seen in outdoor areas of Nuke and other maps.
To tackle this problem we separated all direct and indirect precomputed lighting data and use these two data sets to accurately blend our cascade shadow maps into the scene. This allows indirect and ambient lighting to alter the shadow color and strength in a much more natural way:
BEFORE Note the grey area between the CSM and the precomputed shadows. The CSMs don’t know what color the ambient indirect light is and cannot blend accurately.
AFTER With indirect lighting data available, the grey is gone and the CSMs now blend perfectly with the blue ambient lighting.
As before, to enable this upgrade you will need to add –staticproplighting to ($light_exe) in the advanced compile parameters dialog when compiling your maps.
Along the way we also added some cool new shader features to help enhance the look of de_nuke, some of which you might find pretty useful.
A nice feature that has been added recently is the ability to have phong specular reflections on lightmapped materials (brushes and displacements etc.). This works in conjunction with direct lighting (from the light_environment entity) so it is best used on outdoor areas where it will have the maximum impact.
To enable this feature, add the following lines to your material (.vmt file):
"$phong" "1" //Enables phong highlights
"$phongexponent" "60.0" //how sharp the highlight is 1=soft 100=sharp
"$phongMaskContrastBrightness" "[2 .7]" //increases the contrast of the phong mask
"$phongAmount" "[10 10 10 1]" //RGBA values that can boost, tint or lower highlight strength
Note that this should be used with the LightmappedGeneric and WorldVertexBlend shaders.
One powerful feature we wanted for Nuke was the ability to have support for a second UV set on our models. This would allow us to have multiple layouts for textures on one prop which is super useful for adding decals and other effects to models. With the introduction of FBX support for our model compiler a few updates ago, we were finally able to fully implement this feature. This feature is pretty powerful for content authors and can be also used for ambient occlusion maps, dirt maps, details, etc.
Here, each label on the crates is laid out on a separate UV channel to that of the main texture – this allows us to easily and efficiently reuse the same labels/decals on many different props without losing texture resolution.
To enable this feature, firstly make sure your model is compiled from an fbx file and has a second UV set, then add the following to your model’s material (vmt):
"$decaltexture" "yourdecaltexture" //path to you decal texture
"$decalblendmode" "0" // controls blending of decal: 0=alpha masked 1=multiplied
Note that this should be used with the VertexLitGeneric shader.
We now have the option to blend together multiple normal maps which is useful if you want to have a large macro normal map for surface variation mixed with a high frequency detail normal map. Additionally, we added the ability to tweak how strong each normal map is; this is useful when you only want very subtle surface variations or detail.
Here there is a small normal map for the fine details and a larger, subtle normal map for wider surface variation.
Here’s what it looks like when the bump strength parameter is turned up on the larger scale normal map.
To use this feature add the following lines in your material (vmt):
"$addbumpmaps" "1" //enables bumpmap blending
"$bumpmap" "texture" //bumpmap texture 1
"$bumptransform" "center 0 0 scale 1 1 rotate 0 translate 0 0" //scale & rotation of bumpmap 1
"$bumpdetailscale1" "1" //Controls how strong bumpmap 1 is (0-1, 0=off 1=full)
"$bumpmap2" "texture” //bumpmap texture 2
"$bumptransform2" "center 0 0 scale 1 1 rotate 0 translate 0 0" // scale & rotation of bumpmap 2
"$bumpdetailscale2" ".5" //Controls how strong bumpmap 2 is (0-1, 0=off 1=full)
Note that this works on the lightmappedgeneric shader. When a $detail texture is also used with $detailscale, it will override the "$bumptransform2" parameter.
A cool feature that’s been added for our cubemaps is emulation of anisotropic reflections. Anisotropic reflections usually occur on wet or shiny surfaces that have a high roughness and appear long and stretched, like in this example.
This can be enabled by adding the following parameters to your material (vmt):
"$envmap" "env_cubemap" // A cubemap is needed for this to work
"$envmapanisotropy" "1" // Enables cubemap anisotropic filtering
"$envmapanisotropyscale" "1" // Amount of ‘stretching’ that should be applied (0-1)
Note that this works with the LightmappedGeneric and WorldVertexTransition shaders
This is with $envmapanisotropyscale set to 1
Another useful feature we added to cubemap reflections is the ability to have their color and brightness influenced by the lighting in the environment. This works with auto-generated cubemaps but can also be useful if artists want to author a custom cubemap to simulate a certain look (faking chromatic reflections for example). Another benefit is that it diminishes the need for level designers to carefully tweak cube maps between light and dark areas.
Custom cubemap without lighting influence – notice how the reflections look overly bright and grey, not matching the lighting or environment.
Custom cubemap with lighting influence – reflection colors and brightness now adapt nicely to the lighting and environment
To enable this in your material, add the following parameters:
"$envmap" "cubemaptex" // Name of cubemap texture (envcubemap for auto)
"$envmaplightscale" "1" // (0-1) How much lighting influences the cubemap
"$envmaplightscaleminmax" "[0.0 0.3]" // [min max] How strong the reflections should be
"$envmapsaturation" "0.2" // (0-1) How saturated the reflections should be
This works on a variety of shaders, including LightmappedGeneric, WorldVertexTransition and VertexLitGeneric.
We added a feature to displacement blend materials (WorldVertexTransition shader) that lets you add simple drop shadows and highlights for blends based on the angle of the directional light (light_environment). This can really help bring depth to your blend transitions and is particularly useful for depicting surfaces like plaster peeling from brickwork.
Without drop shadows and highlights.
With drop shadows and highlights .
To enable this in your material, add the following lines to your vmt:
"$dropshadowopacity" "1" //How strong the highlights and shadows should be
"$dropshadowscale" "0.0125" //The size in UV coordinates of the drop shadow
"$dropshadowhighlightscale" "0.0125" //The size in UV coordinates of the drop highlight
"$dropshadowdepthexaggeration" "1" //Use the depth in the blend modulation texture to vary the size of the
drop shadow. Creates a more organic look. May require increasing
the drop shadow scale.
Note that this only works when your blend material has normal maps, a blend modulation texture and your shader settings on high. It is visible in direct lighting from the light_environment entity, so is best used on outdoor areas.
We added this material parameter for situations where you have a model made up of multiple materials, some which you might want tint-able and some not. Now, when applying tinting to a model in Hammer, it now ignores tinting on any material which has the $notint “1” parameter.
Here you can see a single forklift model with two materials and an orange tint - Material A has tinting and material B has the $notint parameter and tinting is ignored.
With the increasing complexity of our maps moving into the future, we upped the memory available to Hammer to allow for more stability.
When developing Nuke, we took a look at how our assets could be built to be more flexible, re-useable and efficient for level designers and artists, both internally and externally moving forward. We started by building a series of extensive modular systems for all of our most commonly used assets such as pipes, wires, HVACs, fences, I beams, joists, trims, etc. These systems are built to be as customizable as possible with options for tinting, multiple surface types (skins) and sizes that are also able to fully interconnect with each another. The idea being that we only need to build one prop set that can be re-used in an almost infinite number of scenarios.
As an added bonus you can find a new map in the latest CS:GO SDK that contains all of the modular systems and assets created for Nuke so that you can easily see examples of how they can be combined and customized and get started using them in your own maps today. Simply navigate to Steam\steamapps\common\Counter-Strike Global Offensive\sdk_content\maps\ and load the de_nuke_zoo VMF in Hammer.
You can get pretty creative with these modular pieces. Here are the examples of these assets as used in Nuke.
Thank you for reading. We hope that you find these updates useful, and we are really looking forward to seeing what you lot build in the future!