playcanvas/engine — pull request #82 by guycalledfrank (2014-11-19 21:44:25+00:00)
Title: Graphics features

Graphics changes.

HDR:
Textures now can be marked HDR by setting .hdr flag on them. This works as a hint to shader constructor. Technically, HDR textures are assumed to be 8-bit RGBM encoded.
If you don't know what RGBM is, read this: http://graphicrants.blogspot.ru/2009/04/rgbm-color-encoding.html (there are some custom precision tweaks in my version though, like using 8 instead of 6 and doing pow(0.5) at encode time)
In short, it allows us to pack HDR image into an ordinary RGBA texture with reasonable precision.
HDR textures aimed to be primarily used for reflections (cube and sphere maps supported) and lightmaps (not supported yet).
Ideally we need Designer to be able to convert HDR images (.hdr, .exr, .dds) to RGBM when importing assets (Unity does it, btw).
In future, engine will be also able to render and correctly filter in-scene cubemaps automatically, with RGBM encoding as well. But still, we need HDR asset importing for things like sky textures.

Tonemapping:
Is an operation of compressing HDR colors into our 0-1 screen. Can simulate human vision or film or whatever. Extremely important for realistic rendering.
It's NOT a post-effect in my version, but instead it is injected into material shaders. Valve did it the same way in Lost Coast, if I remember right. The advantage is that we save a lot of memory and bandwidth by doing it right in shaders, instead of outputting a fat HDR texture (which is not supported on all platforms), then reading it back and writing back tonemapped RGBA8.
The disadvantage is that we can't use true HDR post-effects like Bloom, it needs to be faked LDR-style. I don't think it's a big loss though. When we start going deferred, such effects will be possible, but we need some nice fast forward rendering for all possible platforms in the first place.
Tonemapping is currently a global scene value, like gamma correction. Currently it can be either 0 (no tonemapping) or 1 (Filmic tonemapping http://filmicgames.com/archives/75). More tonamapping operators (2, 3...) can be added later.
No eye adaptation effect yet.

Exposure:
Also a global scene value (should it be per-camera value maybe?) that affects tonemapping.

Prefiltered cubemaps:
Cubemaps with a specific mip chain generated by evaluating BRDF. Allows for environment reflection with variable glossiness in sync with mathematical specular. Due to WebGL limitations, each mip map has to be separate cubemap (we don't have textureCubeLod in PS).
Currently mips must be generated in an offline tool. Later I'll add in-engine generation.
Used for both reflections and ambient diffuse lighting.
Highest mip resolution is locked to 128x128 to simplify things (same in UE4, btw). Rarely higher res is needed, because higher number of in-scene cubemaps and fast filter time is more important.
Can be set to a material using new parameters:
prefilteredCube128
prefilteredCube64
prefilteredCube32
prefilteredCube16
prefilteredCube8
prefilteredCube4
Number means face resolution. If any of the cubemaps are not set, prefiltered stuff won't work, all are required.
4x4 is the lowest, because WebGL doesn't perform bilinear interpolation between cubemap faces, and lower res looks glitchy.
Due to this limitation, prefiltered cubemaps must be also processed with this technique to hide any seams: http://the-witness.net/news/2012/02/seamless-cube-map-filtering/
Shaders then read them assuming it is applied.

Skybox:
- Can be now created with cubemap as parameter instead of 6 asset ids;
- Can be HDR (if HDR cubemap is used);
- Shader code moved to shaderChunks.

Ambient occlusion map (baked):
Can be specified per-material. Currently uses lightmap UVs (should be later be able to choose). Changes ambient color by multiplying it.

Glossiness:
- now not just a "specular power" from 0 to 100, but defines a range from full hemisphere to mirror reflection (that is more meaningful). Blinn-Phong and prefiltered cubemaps are tweaked this way. Old Phong works as before.

Specular anti-aliasing:
Based on Toksvig: http://www.nvidia.com/object/mipmapping_normal_maps.html
Can be enabled with new specularAA material flag. Only works for Blinn-Phong.

Blending maps with colors:
Colors (diffuse, specular, emissive) and single float parameters (gloss, opacity) now can be multiplied by corresponding maps. This allows users to do easy tweaks, like darken albedo, reduce gloss a bit etc.
The behaviour is activated per-material by blendMapsWithColors flag, which is now true by default.
It probably requires a migration to set all colors/floats to white/one in packs where texture overrides where used, so they won't break after change.

Optimizations:
- Color/float multipliers are omitted from shader if set to white/one, degenerating to simple texture-only mode (saving uniforms/ALU);
- "Bumpiness" parameter code is removed from shader if set to 1 (avoiding normalize in PS/reducing uniforms).

Fixes:
- fixed reflection not being visible in some cases when there are no lights.