summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bgfx/examples/18-ibl/fs_ibl_mesh.sc
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/bgfx/examples/18-ibl/fs_ibl_mesh.sc')
-rw-r--r--3rdparty/bgfx/examples/18-ibl/fs_ibl_mesh.sc143
1 files changed, 88 insertions, 55 deletions
diff --git a/3rdparty/bgfx/examples/18-ibl/fs_ibl_mesh.sc b/3rdparty/bgfx/examples/18-ibl/fs_ibl_mesh.sc
index 3ac5278f44f..28aa831331f 100644
--- a/3rdparty/bgfx/examples/18-ibl/fs_ibl_mesh.sc
+++ b/3rdparty/bgfx/examples/18-ibl/fs_ibl_mesh.sc
@@ -1,77 +1,110 @@
$input v_view, v_normal
/*
- * Copyright 2014 Dario Manesku. All rights reserved.
+ * Copyright 2014-2016 Dario Manesku. All rights reserved.
* License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
*/
#include "../common/common.sh"
-
-uniform vec4 u_params;
-uniform mat4 u_mtx;
-uniform vec4 u_flags;
-uniform vec4 u_rgbDiff;
-uniform vec4 u_rgbSpec;
+#include "uniforms.sh"
SAMPLERCUBE(s_texCube, 0);
SAMPLERCUBE(s_texCubeIrr, 1);
-#define u_glossiness u_params.x
-#define u_exposure u_params.y
-#define u_diffspec u_params.z
-
-#define u_doDiffuse u_flags.x
-#define u_doSpecular u_flags.y
-#define u_doDiffuseIbl u_flags.z
-#define u_doSpecularIbl u_flags.w
-
-vec3 fresnel(vec3 _cspec, float _dot)
+vec3 calcFresnel(vec3 _cspec, float _dot)
{
- return _cspec + (1.0 - _cspec) * pow(1.0 - _dot, 5);
+ return _cspec + (1.0 - _cspec)*pow(1.0 - _dot, 5.0);
}
-void main()
+vec3 calcLambert(vec3 _cdiff, float _ndotl)
{
- vec3 light = vec3(0.0, 0.0, -1.0);
- vec3 clight = vec3(1.0, 1.0, 1.0);
-
- vec3 v = v_view;
- vec3 n = normalize(v_normal);
- vec3 l = normalize(light);
- vec3 h = normalize(v + l);
-
- float ndotl = clamp(dot(n, l), 0.0, 1.0); //diff
- float ndoth = clamp(dot(n, h), 0.0, 1.0); //spec
- float vdoth = clamp(dot(v, h), 0.0, 1.0); //spec fresnel
- float ndotv = clamp(dot(n, v), 0.0, 1.0); //env spec fresnel
-
- vec3 r = 2.0*ndotv*n - v; // reflect(v, n);
-
- vec3 cubeR = normalize(mul(u_mtx, vec4(r, 0.0)).xyz);
- vec3 cubeN = normalize(mul(u_mtx, vec4(n, 0.0)).xyz);
-
- float mipLevel = min((1.0 - u_glossiness)*11.0 + 1.0, 8.0);
- vec3 cenv = textureCubeLod(s_texCube, cubeR, mipLevel).xyz;
-
- vec3 kd = u_rgbDiff.xyz;
- vec3 ks = u_rgbSpec.xyz;
-
- vec3 cs = ks * u_diffspec;
- vec3 cd = kd * (1.0 - cs);
-
- vec3 diff = cd;
- float pwr = exp2(u_glossiness * 11.0 + 1.0);
- vec3 spec = cs * pow(ndoth, pwr) * ( (pwr + 8.0)/8.0) * fresnel(cs, vdoth);
+ return _cdiff*_ndotl;
+}
- vec3 ambspec = fresnel(cs, ndotv) * cenv;
- vec3 ambdiff = cd * textureCube(s_texCubeIrr, cubeN).xyz;
+vec3 calcBlinn(vec3 _cspec, float _ndoth, float _ndotl, float _specPwr)
+{
+ float norm = (_specPwr+8.0)*0.125;
+ float brdf = pow(_ndoth, _specPwr)*_ndotl*norm;
+ return _cspec*brdf;
+}
- vec3 lc = ( diff * u_doDiffuse + spec * u_doSpecular ) * ndotl * clight;
- vec3 ec = (ambdiff * u_doDiffuseIbl + ambspec * u_doSpecularIbl);
+float specPwr(float _gloss)
+{
+ return exp2(10.0*_gloss+2.0);
+}
- vec3 color = lc + ec;
+void main()
+{
+ // Light.
+ vec3 ld = normalize(u_lightDir);
+ vec3 clight = u_lightCol;
+
+ // Input.
+ vec3 nn = normalize(v_normal);
+ vec3 vv = normalize(v_view);
+ vec3 hh = normalize(vv + ld);
+
+ float ndotv = clamp(dot(nn, vv), 0.0, 1.0);
+ float ndotl = clamp(dot(nn, ld), 0.0, 1.0);
+ float ndoth = clamp(dot(nn, hh), 0.0, 1.0);
+ float hdotv = clamp(dot(hh, vv), 0.0, 1.0);
+
+ // Material params.
+ vec3 albedo = u_rgbDiff.xyz;
+ float reflectivity = u_reflectivity;
+ float gloss = u_glossiness;
+
+ // Reflection.
+ vec3 refl;
+ if (0.0 == u_metalOrSpec) // Metalness workflow.
+ {
+ refl = mix(vec3_splat(0.04), albedo, reflectivity);
+ }
+ else // Specular workflow.
+ {
+ refl = u_rgbSpec.xyz * vec3_splat(reflectivity);
+ }
+ vec3 dirF0 = calcFresnel(refl, hdotv);
+ vec3 envF0 = calcFresnel(refl, ndotv);
+
+ // Direct lighting.
+ vec3 dirSpec = dirF0;
+ vec3 dirDiff = albedo * 1.0-dirF0;
+
+ vec3 lambert = u_doDiffuse * calcLambert(dirDiff, ndotl);
+ vec3 blinn = u_doSpecular * calcBlinn(dirSpec, ndoth, ndotl, specPwr(gloss));
+ vec3 direct = (lambert + blinn)*clight;
+
+ // Indirect lighting.
+ vec3 envSpec = envF0;
+ vec3 envDiff = albedo * 1.0-envF0;
+
+ // Note: Environment textures are filtered with cmft: https://github.com/dariomanesku/cmft
+ // Params used:
+ // --excludeBase true //!< First level mip is not filtered.
+ // --mipCount 7 //!< 7 mip levels are used in total, [256x256 .. 4x4]. Lower res mip maps should be avoided.
+ // --glossScale 10 //!< Spec power scale. See: specPwr().
+ // --glossBias 2 //!< Spec power bias. See: specPwr().
+ // --edgeFixup warp //!< This must be used on DirectX9. When fileted with 'warp', fixCubeLookup() should be used.
+ float mip = 1.0 + 5.0*(1.0 - gloss); // Use mip levels [1..6] for radiance.
+
+ mat4 mtx;
+ mtx[0] = u_mtx0;
+ mtx[1] = u_mtx1;
+ mtx[2] = u_mtx2;
+ mtx[3] = u_mtx3;
+ vec3 vr = 2.0*ndotv*nn - vv; // Same as: -reflect(vv, nn);
+ vec3 cubeR = normalize(instMul(mtx, vec4(vr, 0.0)).xyz);
+ vec3 cubeN = normalize(instMul(mtx, vec4(nn, 0.0)).xyz);
+ cubeR = fixCubeLookup(cubeR, mip, 256.0);
+
+ vec3 radiance = u_doDiffuseIbl * envSpec * toLinear(textureCubeLod(s_texCube, cubeR, mip).xyz);
+ vec3 irradiance = u_doSpecularIbl * envDiff * toLinear(textureCube(s_texCubeIrr, cubeN).xyz);
+ vec3 indirect = radiance + irradiance;
+
+ // Color.
+ vec3 color = direct + indirect;
color = color * exp2(u_exposure);
-
gl_FragColor.xyz = toFilmic(color);
gl_FragColor.w = 1.0;
}