hi there,
after having published this topic to the shader lab thread and getting nice feedback so far i think it is time to officially release Lux – an open source physically based shading framework.
Why physically based Shading?
First of all physically based shading will give you much more convincing results than traditional lambert or blinnphong shading: No more fights with washed out specular highlights or boring dark areas: everything is shiny!
Second: psb will help you to get much more constant and predictable results under varying lighting conditions: Author once, use everywhere!
Why open source?
There are already some commercial solutions out there available at the asset store, but none of those is free, some even break other shaders. So it might be rather difficult for the community to develop and improve unity’s rendering capabilities. But that is the whole idea behind this framework.
And i hope that there will be a tons of shaders out there supporting Lux soon.
So any feedback, tips and tricks are highly appriciated.
And in case you find any bug just let me know.
Lars
Latest version: 0.07 (3/10/2014)
Test the webplayer (version 0.04)
http://bit.ly/1dAiHxN
Download the latest package (version 0.07)
http://bit.ly/1gmApq1
How does it work?
The framework is mainly based on the work of Sebastién Lagarde and Dimitar Lazarov:
http://blog.selfshadow.com/publicati…_slides_v2.pdf
It supports forward and deferred lighting, lightmaps and lightprobes and handles gamma and linear lighting – although linear lighting is more than a key to physically based shading.
The ingredients
Direct lighting
- Specular: Blinn-Phong or Cook-Torrance (GGX Trowbridge Reitz)
- Visibility: Schlick-Smith or Smith
- Fresnel: Schlick-Fresnel approximation (deferred lighting only supports faked fresnel for direct specular lighting).
Ambient lighting
- Diffuse Cubemap IBL
- Specular Cubemap IBL (gloss values stored in mip chain) with fresnel term based on roughness and specular color
Both cubemaps can be sampled in gamma and linear space. Support for RGB or RGBM (HDR) cubemaps. - Spherical Harmonics in case you disabled “Diffuse Cubemap IBL”
- Ambient Occlusion controlled by texture input
The implementation
Deferred rendering
To make the shader work in deferred rendering i had to hack the "Internal-PrePassLighting“ shader, as i could not find another way yet to get the dotNL and especially the dot(h, lightDir) product. That is not as elegant as i would like to have it.
And as i had to „compress“ the spec value in the "Internal-PrePassLighting“ shader (log2) and decompress it in the lighting prepass function (exp2) in order to avoid wrong shaded spots in the center of the highlights, built in shaders will be broken (too less specular) when using deferred lighting. So i highly recommend to rebuilt all needed shaders using the Lux lighting functions – which is not that big deal i hope.
Ambient IBL
I did not spent much time on this part of the framework and it is pretty much straight forward using common rbgm decoding and a roughness based fresnel term on the specular distribution.
In case you disable ambient diffuse IBL the shaders will fall back to unity’s built in spherical harmonics.
Inputs
I have chosen an approach suggested by sebastién lagarde and only have a few parameters to feed the shader right now:
http://seblagarde.wordpress.com/2011…lighting-mode/
- Diffuse color as texture rgb
- Specular color as texture rgb
- Roughness (alpha in specular color)
- Normal map
- Diffuse and specular ambient cube (most of the time passed as global textures by script)
And in case you miss parameters like metalness: Lux supports a metalness workflow since version 0.07.
There is only one singe shader right now supporting this workflow but it is really easy to change all existing shaders. I guess more shaders natively supporting metalness will follow.
Changelog
version 0.07
Terrain detail shaders
All errors fixed for dx9 and dx11.
Terrain shaders
Possible division by zero fixed.
Lux Internal-PrePassLighting shader
doubled “max(0, dotNL)” removed.
LuxLightingAmbient.cginc
“o.Emission = 0.0;” added to make SH lighting work with the Lux diffuse shaders (Lux diffuse shader or the terrain detial shaders e.g.)
Metalness Shader
added
Dualforward lightmaps
docu entry added – so easily find out how to enable dualforward lightmaps in forward lighting
Deferred lighting
Disabling specular ambient lighting won’t let the faked fresnel go crazy in deferred lighting mode anymore
Treecreatorleaves shader
fixed
version 0.061
Lighting
blinn phong: visibility term now is more robust (by adding saturate)
cook torrance: sign corrected, no more magical numer needed to make deferred match forward
Terrain shader
normal blending enhanced
Detail shader
normal bending corrected
version 0.06
version 0.06 is a major update because it introduces a Cook Torrence based approach as second lighting model next to Blinn Phong.
In order to make it possible to switch between these models I had to rewrite some parts of the framework. i took this chance to make the naming a bit more flexible and descriptive:
“LuxLightingPhong.cginc” changed to “LuxLightingDirect.cginc”
“LuxIBL.cginc” changed to “LuxLightingAmbient.cginc”
Surface Shaders the name of the Lux lighting function changed to “LuxDirect”:
#pragma surface surf LuxDirect noambient
the name of the direct lighting functions include changed:
#include “LuxCore/LuxLightingDirect.cginc”
A new pragma makes it possible to switch between the lighting models:
#pragma multi_compile LUX_LIGHTING_BP LUX_LIGHTING_CT
Writing to o.Specular has changed to a function call:
o.Specular = LuxAdjustSpecular(spec_albedo.a);
Minor changes and fixes
- VertexBlend shaders added
- Lux ambient lighting: if “diffuse cube IBL” is disabled the shader won’t add ambient lighting based spherical harmonics in case the object is lightmapped.
- tree creator redertex shaders fixed but this will be an ongoing process…
- terrain shader first pass: fixed for cook torrence using complex blending for detail normal
version 0.05
Example shaders !!! important !!!
writing to o.DeferredFresnel changed to:
o.DeferredFresnel = exp2(-OneOnLN2_x6 * max(0, dot(o.Normal, normalize(IN.viewDir) ))); as it could cause some lighting artifacts on dx9 / dx11. now it is even a bit faster, You should do so in all your individual shaders too.
Ambient Lighting (LuxIBL.cginc)
spec ambient IBL changed from spec_albeo.rgb and spec_albedo.a to o.SpecularColor and o.Specular – just to make it more flexible
Lighting (LuxLightingPhong.cginc)
optimized “Final Composition” (forward lighting)
Tree creator shaders added
version 0.046
Ambient Lighting (LuxIBL.cginc)
- Fixed errors from version 0.045.
Shaders may declare “#define NORMAL_IS_WORLDNORMAL” to skip the calculation of the worldnormal and speed up rendering.
Used e.g. by the terrain grass shaders as here normal equals worldnormal.
Lux terrain shaders - Improved normal blending between different shader passes.
Added a the possibility to use a second normal map on detail texture number 3 to hide tiling artifacts on high frequent and bumpy textures such as rock.
Lux grass and vertex lit shaders added
version 0.045
Ambient Lighting(LuxIBL.cginc)
- Due to a bug in unity terrain materials i had to make the “#ifdef DIFFCUBE_ON” a bit more complex.
Now diffuse ambient IBL can be activated per material using the material inspector or globally for shaders in which the keyword “USE_GLOBAL_DIFFIBL_SETTINGS” is enabled.
Sorry for that mess.
Lighting (LuxLightingPhong.cginc) - color output.alpha is reduced to: c.a = s.Alpha;
as long as anybody can tell me what the rest sould be good for i will keep it this simple.
Lux terrain shaders added
Documentation added
DontnodGraphicChartForBlinnMicrofacet look up chart added
version 0.044
shader folder structure refactored
-“Resources” is now subfloder of “LuxCore”
ambient lighting (LuxIBL.cginc) - specular ambient lighting: added alternativ fresnel calculation which would give you only colorized specular reflections to match skyshop (deactivated by default, you will have to edit the cginc)
example shaders - advanced detail shader added
- parallax mapping shader added
- material test shader: small fix
version 0.043
ambient lighting (LuxIBL.cginc)
- specular ambient lighting fixed
example shaders - material test shader added which lets you adjust roughness and specularColor within unity
version 0.042
ambient lighting (LuxIBL.cginc)- Spherical Harmonics added: In case you deactivate “diffuse Cube IBL” in the material inspector the shader falls back to unity’s SH lighting. Use this function if you want to make the shader react to lightprobes or speed up rendering.
This makes the old Lux Lightprobes Shader obsolet (so i have removed it from the package)
- Ambient Occlusion added: now you may add an Ambient Occlusion texture which controls diffuse and specular ambient lighting
forward lighting - late dotNL to get rid of most artifacts on backsides and speed up rendering
surface shaders - o.DeferredFresnel is only written #if defined(UNITY_PASS_PREPASSFINAL) to speed up forward rendering.
see e.g.: “Lux Bumped Specular.shader” - sampler for ambient occlusion added
- sampler for diff Cube IBL and spec Cube IBL won’t be declared unless you activate diffuse and specular IBL lighting
- “#pragma multi_compile LUX_AO_OFF LUX_AO_ON” added to let you control the use o ambient occlusion via the material inspector
version 0.041
Forward lighting
- fixed for dx11
version 0.04
deferred lighting
- internal prepass lighting shader fixed for dx11
version 0.03
deferred lighting
- faked fresnel added based on n_dot_v (direct specular lighting)
version 0.02
deferred lighting
- refactored
- visibility term added
- fresnel fixed (direct lighting): fresnel according only to ONE directional light, light position has to be passed by script. see: “Lux Bumped Specular” shader
forward lighting - refactored
- visibility term fixed
lightmaps - lighting fixed when using lightmaps or lightprobes
version 0.01
initial release