Commit 3aa922c4 authored by Alexander Wiebel's avatar Alexander Wiebel
Browse files

[ADD #390] Style checking for glsl shaders

[STYLE #390] adapted all shaders to style
parent 599948cd
......@@ -285,6 +285,7 @@ ENDIF()
# noncolored if it is set to OFF
FILE( GLOB_RECURSE STYLE_CPP ${PROJECT_SOURCE_DIR}/*.cpp )
FILE( GLOB_RECURSE STYLE_H ${PROJECT_SOURCE_DIR}/*.h )
FILE( GLOB_RECURSE STYLE_GLSL ${PROJECT_SOURCE_DIR}/*.glsl )
# Set dirs to exclude from stylecheck
SET( EXCLUDE_DIRS "/ext/nifti/;/dataHandler/io/biosig/;/dataHandler/io/biosigWin/;/dataHandler/io/biosig/XMLParser/;/dataHandler/io/biosigWin/XMLParser/;/ext/libeep/avr/;/ext/libeep/cnt/;/ext/libeep/eep/;/common/platformDependent/visualStudio/;/modules/lic/fibernavigator/;/modules/lic/fantom/" )
FOREACH( dirname ${EXCLUDE_DIRS} )
......@@ -316,7 +317,7 @@ ELSE()
ENDIF()
FILE( WRITE ${PROJECT_BINARY_DIR}/brainlintlist "" )
FOREACH( fname ${STYLE_CPP} ${STYLE_H} )
FOREACH( fname ${STYLE_CPP} ${STYLE_H} ${STYLE_GLSL} )
FILE( APPEND ${PROJECT_BINARY_DIR}/brainlintlist "${fname}\n" )
ENDFOREACH()
......
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV-Leipzig and CNCF-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
uniform int useColorMap;
vec3 blueGreenPurpleColorMap( in float value )
......@@ -22,42 +46,42 @@ vec3 blueGreenPurpleColorMap( in float value )
}
vec3 rainbowColorMap ( in float value )
vec3 rainbowColorMap( in float value )
{
float i = floor(6.*value);
float f = 6.*value - i;
float q = 1.0-f;
float i = floor( 6. * value );
float f = 6. * value - i;
float q = 1.0 - f;
int iq = int(mod(i, 6.));
int iq = int( mod( i, 6. ) );
if ((iq == 0) || (iq == 6))
return vec3(1., f, 0.);
if ( ( iq == 0 ) || ( iq == 6 ) )
return vec3( 1., f, 0. );
else if (iq == 1)
return vec3(q, 1., 0.);
return vec3( q, 1., 0. );
else if (iq == 2)
return vec3(0., 1., f);
return vec3( 0., 1., f );
else if (iq == 3)
return vec3(0., q, 1.);
return vec3( 0., q, 1. );
else if (iq == 4)
return vec3(f, 0., 1.);
return vec3( f, 0., 1. );
else // iq == 5
return vec3(1., 0., q);
return vec3( 1., 0., q );
}
vec3 hotIronColorMap( in float value )
{
vec4 color8 = vec4(255./255., 255./255., 204./255., 1.);
vec4 color7 = vec4(255./255., 237./255., 160./255., 1.);
vec4 color6 = vec4(254./255., 217./255., 118./255., 1.);
vec4 color5 = vec4(254./255., 178./255., 76./255., 1.);
vec4 color4 = vec4(253./255., 141./255., 60./255., 1.);
vec4 color3 = vec4(252./255., 78./255., 42./255., 1.);
vec4 color2 = vec4(227./255., 26./255., 28./255., 1.);
vec4 color1 = vec4(189./255., 0./255., 38./255., 1.);
vec4 color0 = vec4(128./255., 0./255., 38./255., 1.);
vec4 color8 = vec4( 255. / 255., 255. / 255., 204. / 255., 1. );
vec4 color7 = vec4( 255. / 255., 237. / 255., 160. / 255., 1. );
vec4 color6 = vec4( 254. / 255., 217. / 255., 118. / 255., 1. );
vec4 color5 = vec4( 254. / 255., 178. / 255., 76. / 255., 1. );
vec4 color4 = vec4( 253. / 255., 141. / 255., 60. / 255., 1. );
vec4 color3 = vec4( 252. / 255., 78. / 255., 42. / 255., 1. );
vec4 color2 = vec4( 227. / 255., 26. / 255., 28. / 255., 1. );
vec4 color1 = vec4( 189. / 255., 0. / 255., 38. / 255., 1. );
vec4 color0 = vec4( 128. / 255., 0. / 255., 38. / 255., 1. );
float colorValue = value * 8.;
int sel = int(floor(colorValue));
int sel = int( floor( colorValue ) );
if ( sel >= 8 )
return color0.rgb;
......@@ -65,40 +89,41 @@ vec3 hotIronColorMap( in float value )
return color0.rgb;
else
{
colorValue -= float(sel);
colorValue -= float( sel );
if (sel < 1)
return ( color1*colorValue + color0*(1.-colorValue)).rgb;
else if (sel < 2)
return ( color2*colorValue + color1*(1.-colorValue)).rgb;
else if (sel < 3)
return ( color3*colorValue + color2*(1.-colorValue)).rgb;
else if (sel < 4)
return ( color4*colorValue + color3*(1.-colorValue)).rgb;
else if (sel < 5)
return ( color5*colorValue + color4*(1.-colorValue)).rgb;
else if (sel < 6)
return ( color6*colorValue + color5*(1.-colorValue)).rgb;
else if (sel < 7)
return ( color7*colorValue + color6*(1.-colorValue)).rgb;
else if (sel < 8)
return ( color8*colorValue + color7*(1.-colorValue)).rgb;
else return color0.rgb;
if ( sel < 1 )
return ( color1 * colorValue + color0 * ( 1. - colorValue ) ).rgb;
else if ( sel < 2 )
return ( color2 * colorValue + color1 * ( 1. - colorValue ) ).rgb;
else if ( sel < 3 )
return ( color3 * colorValue + color2 * ( 1. - colorValue ) ).rgb;
else if ( sel < 4 )
return ( color4 * colorValue + color3 * ( 1. - colorValue ) ).rgb;
else if ( sel < 5 )
return ( color5 * colorValue + color4 * ( 1. - colorValue ) ).rgb;
else if ( sel < 6 )
return ( color6 * colorValue + color5 * ( 1. - colorValue ) ).rgb;
else if ( sel < 7 )
return ( color7 * colorValue + color6 * ( 1. - colorValue ) ).rgb;
else if ( sel < 8 )
return ( color8 * colorValue + color7 * ( 1. - colorValue ) ).rgb;
else
return color0.rgb;
}
}
vec3 redYellowColorMap( in float value )
{
vec4 color0 = vec4(1., 0., 0., 1.);
vec4 color1 = vec4(1., 1., 0., 1.);
return ( color1*value + color0*(1.-value)).rgb;
vec4 color0 = vec4( 1., 0., 0., 1. );
vec4 color1 = vec4( 1., 1., 0., 1. );
return ( color1 * value + color0 * ( 1. - value ) ).rgb;
}
vec3 blueLightBlueColorMap( in float value )
{
vec4 color0 = vec4(0., 0., 1., 1.);
vec4 color1 = vec4(0.78, 1., 1., 1.);
return ( color1*value + color0*(1.-value)).rgb;
vec4 color0 = vec4( 0., 0., 1., 1. );
vec4 color1 = vec4( 0.78, 1., 1., 1. );
return ( color1 * value + color0 * ( 1. - value ) ).rgb;
}
vec3 negative2positive( in float value )
......@@ -116,10 +141,11 @@ vec3 negative2positive( in float value )
{
return ( zeroColor - posColor * val );
}
else return vec3( 0.0, 0.0, 0.0 );
else
return vec3( 0.0, 0.0, 0.0 );
}
// TODO(math): Remove this function and replace its calls with bitwise operations as soon as there
// TODO(math): Remove this function and replace its calls with bitwise operations as soon as there
// on all platforms available. Currently Mac OS 10.6.4. doesn't support GLSL 1.30 which introduces
// those operations.
// e.g. replace: isBitSet( val, 5 ) with ( val & 32 ) == 1
......@@ -128,14 +154,14 @@ bool isBitSet( in float value, in float bitpos )
return ( abs( mod( floor( value / pow( 2.0, bitpos ) ), 2.0 ) - 1.0 ) ) < 0.001;
}
vec3 atlasColorMap ( in float value )
vec3 atlasColorMap( in float value )
{
float val = floor( value * 255.0 );
float r = 0.0;
float g = 0.0;
float b = 0.0;
float mult = 1.0;
if ( val == 0.0 )
{
return vec3( 0.0 );
......@@ -164,7 +190,6 @@ vec3 atlasColorMap ( in float value )
b = 1.0;
g = 1.0;
}
}
if ( isBitSet( val, 5.0 ) )
{
......@@ -174,7 +199,6 @@ vec3 atlasColorMap ( in float value )
r = 1.0;
b = 1.0;
}
}
if ( isBitSet( val, 6.0 ) )
{
......@@ -183,7 +207,6 @@ vec3 atlasColorMap ( in float value )
{
g = 1.0;
}
}
if ( isBitSet( val, 7.0 ) )
{
......@@ -192,16 +215,15 @@ vec3 atlasColorMap ( in float value )
{
r = 1.0;
}
}
r *= mult;
g *= mult;
b *= mult;
clamp( r, 0., 1.);
clamp( g, 0., 1.);
clamp( b, 0., 1.);
clamp( r, 0., 1. );
clamp( g, 0., 1. );
clamp( b, 0., 1. );
return vec3( r, g, b );
}
......@@ -210,18 +232,18 @@ vec3 atlasColorMap ( in float value )
vec3 colorMap5( in float value )
{
vec4 color0 = vec4(255./255., 255./255., 217./255., 1.);
vec4 color1 = vec4(237./255., 248./255., 177./255., 1.);
vec4 color2 = vec4(199./255., 233./255., 180./255., 1.);
vec4 color3 = vec4(127./255., 205./255., 187./255., 1.);
vec4 color4 = vec4( 65./255., 182./255., 196./255., 1.);
vec4 color5 = vec4( 29./255., 145./255., 192./255., 1.);
vec4 color6 = vec4( 34./255., 94./255., 168./255., 1.);
vec4 color7 = vec4( 37./255., 52./255., 148./255., 1.);
vec4 color8 = vec4( 8./255., 29./255., 88./255., 1.);
vec4 color0 = vec4( 255. / 255., 255. / 255., 217. / 255., 1. );
vec4 color1 = vec4( 237. / 255., 248. / 255., 177. / 255., 1. );
vec4 color2 = vec4( 199. / 255., 233. / 255., 180. / 255., 1. );
vec4 color3 = vec4( 127. / 255., 205. / 255., 187. / 255., 1. );
vec4 color4 = vec4( 65. / 255., 182. / 255., 196. / 255., 1. );
vec4 color5 = vec4( 29. / 255., 145. / 255., 192. / 255., 1. );
vec4 color6 = vec4( 34. / 255., 94. / 255., 168. / 255., 1. );
vec4 color7 = vec4( 37. / 255., 52. / 255., 148. / 255., 1. );
vec4 color8 = vec4( 8. / 255., 29. / 255., 88. / 255., 1. );
float colorValue = value * 8.;
int sel = int(floor(colorValue));
int sel = int( floor( colorValue ) );
if ( sel >= 8 )
return color0.rgb;
......@@ -229,25 +251,26 @@ vec3 colorMap5( in float value )
return color0.rgb;
else
{
colorValue -= float(sel);
colorValue -= float( sel );
if (sel < 1)
return ( color1*colorValue + color0*(1.-colorValue)).rgb;
if( sel < 1 )
return ( color1 * colorValue + color0 * ( 1. - colorValue ) ).rgb;
else if (sel < 2)
return ( color2*colorValue + color1*(1.-colorValue)).rgb;
return ( color2 * colorValue + color1 * ( 1. - colorValue ) ).rgb;
else if (sel < 3)
return ( color3*colorValue + color2*(1.-colorValue)).rgb;
return ( color3 * colorValue + color2 * ( 1. - colorValue ) ).rgb;
else if (sel < 4)
return ( color4*colorValue + color3*(1.-colorValue)).rgb;
return ( color4 * colorValue + color3 * ( 1. - colorValue ) ).rgb;
else if (sel < 5)
return ( color5*colorValue + color4*(1.-colorValue)).rgb;
return ( color5 * colorValue + color4 * ( 1. - colorValue ) ).rgb;
else if (sel < 6)
return ( color6*colorValue + color5*(1.-colorValue)).rgb;
return ( color6 * colorValue + color5 * ( 1. - colorValue ) ).rgb;
else if (sel < 7)
return ( color7*colorValue + color6*(1.-colorValue)).rgb;
return ( color7 * colorValue + color6 * ( 1. - colorValue ) ).rgb;
else if (sel < 8)
return ( color8*colorValue + color7*(1.-colorValue)).rgb;
else return color0.rgb;
return ( color8 * colorValue + color7 * ( 1. - colorValue ) ).rgb;
else
return color0.rgb;
}
}
......@@ -255,27 +278,26 @@ vec3 colorMap6( in float value )
{
float basecolor = 0.0;
float frequency = 5.0;
float sqrt3 = sqrt(3.);
float sqrt3 = sqrt( 3. );
float onedtwodsqrt3 = 1. / 2. / sqrt3;
float onepsqrt3 = 1. + sqrt3;
float onemsqrt3 = 1. - sqrt3;
float wvalue = sqrt(3./2.) * value * (1.-value); // = omega(value)
float wvalue = sqrt( 3. / 2. ) * value * ( 1. - value ); // = omega(value)
float twotz = 2. * sqrt3 * value; // = 2. * z(value)
float sinTerm = sin(frequency*value+basecolor);
float cosTerm = cos(frequency*value+basecolor);
float sinTerm = sin( frequency * value + basecolor );
float cosTerm = cos( frequency * value + basecolor );
float wtsinTerm = wvalue * sinTerm;
float wtcosTerm = wvalue * cosTerm;
float colorRed = (onedtwodsqrt3*(onepsqrt3*wtsinTerm + onemsqrt3*wtcosTerm + twotz));
float colorGreen = (onedtwodsqrt3*(onemsqrt3*wtsinTerm + onepsqrt3*wtcosTerm + twotz));
float colorBlue = (onedtwodsqrt3*(-2.*(wtsinTerm + wtcosTerm) + twotz));
float colorRed = ( onedtwodsqrt3 * ( onepsqrt3 * wtsinTerm + onemsqrt3 * wtcosTerm + twotz ) );
float colorGreen = ( onedtwodsqrt3 * ( onemsqrt3 * wtsinTerm + onepsqrt3 * wtcosTerm + twotz ) );
float colorBlue = ( onedtwodsqrt3 * ( -2. * ( wtsinTerm + wtcosTerm ) + twotz ) );
return vec3(colorRed, colorGreen, colorBlue);
return vec3( colorRed, colorGreen, colorBlue );
}
void colorMap( inout vec3 col, in float value, int cmap )
{
if ( cmap == 1 )
col = rainbowColorMap( value );
else if ( cmap == 2 )
......
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV-Leipzig and CNCF-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
varying vec3 normal;
varying vec4 vertex;
varying vec3 halfvec;
const vec4 AMBIENT_BLACK = vec4(0.0, 0.0, 0.0, 1.0);
const vec4 DEFAULT_BLACK = vec4(0.0, 0.0, 0.0, 0.0);
const vec4 AMBIENT_BLACK = vec4( 0.0, 0.0, 0.0, 1.0 );
const vec4 DEFAULT_BLACK = vec4( 0.0, 0.0, 0.0, 0.0 );
void directionalLight( in int i, in vec3 normal, in float shininess,
inout vec4 ambient, inout vec4 diffuse, inout vec4 specular)
inout vec4 ambient, inout vec4 diffuse, inout vec4 specular )
{
float nDotVP;
float nDotHV;
float pf;
vec3 L = normalize (gl_LightSource[i].position.xyz - vertex.xyz);
vec3 H = normalize (L + halfvec.xyz);
vec3 L = normalize( gl_LightSource[i].position.xyz - vertex.xyz );
vec3 H = normalize( L + halfvec.xyz );
nDotVP = max(0.0, dot(normal, normalize((gl_LightSource[i].position.xyz))));
nDotHV = max(0.0, dot(normal, H));
nDotVP = max( 0.0, dot( normal, normalize( ( gl_LightSource[i].position.xyz ) ) ) );
nDotHV = max( 0.0, dot( normal, H ) );
if (nDotVP == 0.0)
if ( nDotVP == 0.0 )
pf = 0.0;
else
pf = pow(nDotHV, gl_FrontMaterial.shininess);
pf = pow( nDotHV, gl_FrontMaterial.shininess );
ambient += gl_LightSource[i].ambient;
diffuse += gl_LightSource[i].diffuse * nDotVP;
specular += gl_LightSource[i].specular * pf;
}
void calculateLighting(in vec3 N, in float shininess, inout vec4 ambient, inout vec4 diffuse, inout vec4 specular)
void calculateLighting( in vec3 N, in float shininess, inout vec4 ambient, inout vec4 diffuse, inout vec4 specular )
{
directionalLight(0, N, shininess, ambient, diffuse, specular);
directionalLight( 0, N, shininess, ambient, diffuse, specular );
}
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV-Leipzig and CNCF-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
varying vec3 normal;
varying vec4 vertex;
varying vec3 halfvec;
const vec4 AMBIENT_BLACK = vec4(0.0, 0.0, 0.0, 1.0);
const vec4 DEFAULT_BLACK = vec4(0.0, 0.0, 0.0, 0.0);
const vec4 AMBIENT_BLACK = vec4( 0.0, 0.0, 0.0, 1.0 );
const vec4 DEFAULT_BLACK = vec4( 0.0, 0.0, 0.0, 0.0 );
/**
* Computes normal and makes transformation to eye space.
......@@ -11,12 +35,12 @@ const vec4 DEFAULT_BLACK = vec4(0.0, 0.0, 0.0, 0.0);
void prepareLight()
{
// Calculate the normal
normal = normalize(gl_NormalMatrix * gl_Normal).xyz;
normal = normalize( gl_NormalMatrix * gl_Normal ).xyz;
// Transform the vertex position to eye space
vertex = vec4(gl_ModelViewMatrix * gl_Vertex);
vertex = vec4( gl_ModelViewMatrix * gl_Vertex );
vec3 L = normalize(gl_LightSource[0].position.xyz - vertex.xyz);
vec3 L = normalize( gl_LightSource[0].position.xyz - vertex.xyz );
halfvec = vec3(L + vec3(0.0, 0.0, 1.0));
halfvec = vec3( L + vec3( 0.0, 0.0, 1.0 ) );
}
/**
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV-Leipzig and CNCF-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
/**
* Function to calculate lighting based on "Real-Time Volume Graphics, p 119, chapter 5.4, Listing 5.1".
*
* @param ambient materials ambient color
......@@ -10,33 +34,33 @@
* @param normalDir the normal
* @param viewDir viewing direction
* @param lightDir light direction
*
*
* @return the color.
*/
vec4 blinnPhongIllumination( vec3 ambient, vec3 diffuse, vec3 specular, float shininess,
vec3 lightColor, vec3 ambientLight,
vec3 normalDir, vec3 viewDir, vec3 lightDir )
vec4 blinnPhongIllumination( vec3 ambient, vec3 diffuse, vec3 specular, float shininess,
vec3 lightColor, vec3 ambientLight,
vec3 normalDir, vec3 viewDir, vec3 lightDir )
{
vec3 H = normalize( lightDir + viewDir );
// compute ambient term
vec3 ambientV = ambient * ambientLight;
// compute diffuse term
float diffuseLight = max(dot(lightDir, normalDir), 0.);
float diffuseLight = max( dot( lightDir, normalDir ), 0. );
vec3 diffuseV = diffuse * diffuseLight;
// compute specular term
float specularLight = pow(max(dot(H, normalDir), 0.), shininess);
float specularLight = pow( max( dot( H, normalDir ), 0. ), shininess );
if( diffuseLight <= 0.) specularLight = 0.;
vec3 specularV = specular * specularLight;
return vec4(ambientV + (diffuseV + specularV)*lightColor, 1.);
return vec4( ambientV + ( diffuseV + specularV ) * lightColor, 1. );
}
/**
/**
* @brief Function to calculate lighting intensitybased on "Real-Time Volume Graphics, p 119, chapter 5.4, Listing 5.1".
* It is basically the same as blinnPhongIllumination function above. But it is faster if you just need
* It is basically the same as blinnPhongIllumination function above. But it is faster if you just need
* the intensity.
*
* @param ambient materials ambient intensity
......@@ -48,27 +72,28 @@ vec4 blinnPhongIllumination( vec3 ambient, vec3 diffuse, vec3 specular, float sh
* @param normalDir the normal
* @param viewDir viewing direction
* @param lightDir light direction
*
*
* @return the light intensity.
*/
float blinnPhongIlluminationIntensity(float ambient, float diffuse, float specular, float shininess,
float lightIntensity, float ambientIntensity,
vec3 normalDir, vec3 viewDir, vec3 lightDir )
float blinnPhongIlluminationIntensity( float ambient, float diffuse, float specular,
float shininess,
float lightIntensity, float ambientIntensity,
vec3 normalDir, vec3 viewDir, vec3 lightDir )
{
vec3 H = normalize( lightDir + viewDir );
<