//----------------------------------------------------------------------------- // Program Name: SL_Lighting // Program Desc: Per pixel lighting functions. // Program Type: Vertex/Pixel shader // Language: GLSL //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void SL_TransformNormal(in mat4 m, in vec3 v, out vec3 vOut) { vOut = mat3(m) * v; } //----------------------------------------------------------------------------- void SL_TransformPosition(in mat4 mWorldView, in vec4 vPos, out vec3 vOut) { vOut = (mWorldView * vPos).xyz; } //----------------------------------------------------------------------------- void SL_Light_Directional_Diffuse( in vec3 vNormal, in vec3 vNegLightDirView, in vec3 vDiffuseColour, in vec3 vBaseColour, out vec3 vOut) { vec3 vNormalView = normalize(vNormal); float nDotL = dot(vNormalView, vNegLightDirView); vOut = vBaseColour + vDiffuseColour * clamp(nDotL, 0.0, 1.0); } //----------------------------------------------------------------------------- void SL_Light_Directional_DiffuseSpecular( in vec3 vNormal, in vec3 vViewPos, in vec3 vNegLightDirView, in vec3 vDiffuseColour, in vec3 vSpecularColour, in float fSpecularPower, in vec3 vBaseDiffuseColour, in vec3 vBaseSpecularColour, out vec3 vOutDiffuse, out vec3 vOutSpecular) { vOutDiffuse = vBaseDiffuseColour; vOutSpecular = vBaseSpecularColour; vec3 vNormalView = normalize(vNormal); float nDotL = dot(vNormalView, vNegLightDirView); vec3 vView = -normalize(vViewPos); vec3 vHalfWay = normalize(vView + vNegLightDirView); float nDotH = dot(vNormalView, vHalfWay); nDotL = max(nDotL, 0); vOutDiffuse += vDiffuseColour * nDotL; vOutSpecular += vSpecularColour * pow(clamp(nDotH, 0.0, 1.0), fSpecularPower); } //----------------------------------------------------------------------------- void SL_Light_Ambient_Diffuse_Inner( in vec3 vNormal, in vec3 vLightView, in float fLightDist, in vec3 vNegLightDirView, in vec3 vSpotParams, in vec3 vDiffuseColour, inout vec3 vColorOut) { float fLightDistInv = 1 / fLightDist; float nDotL = dot(vNormal, vLightView) * fLightDistInv; float fAtten = (1 - (fLightDist * vSpotParams.x)); fAtten = fAtten * fAtten; float rho = dot(vNegLightDirView, vLightView) * fLightDistInv; float fSpotT = clamp((rho - vSpotParams.y) * vSpotParams.z, 0.0, 1.0); nDotL = step(0,nDotL) * (0.7 + (0.3 * nDotL)); vColorOut += vDiffuseColour * 2* nDotL * fAtten * fSpotT; } //----------------------------------------------------------------------------- void SL_Light_Ambient_Diffuse( in vec3 vNormal, in vec3 vViewPos, in vec3 vLightPosView, in vec3 vNegLightDirView, in vec3 vSpotParams, in vec3 vDiffuseColour, inout vec3 vColorOut) { vec3 vLightView = vLightPosView - vViewPos; float fLightDist = length(vLightView); if (fLightDist * vSpotParams.x < 1) { SL_Light_Ambient_Diffuse_Inner(vNormal, vLightView, fLightDist, vNegLightDirView, vSpotParams, vDiffuseColour, vColorOut); } } //----------------------------------------------------------------------------- void SL_Light_Segment_Texture_Ambient_Diffuse( in vec3 vNormal, in vec3 vViewPos, in sampler2D dataTexture, in vec2 lightIndexLimit, in vec4 lightBounds, in float invWidth, in float invHeight, inout vec3 vColorOut) { float widthOffset = invWidth * 0.5; float heightOffset = invHeight * 0.5; vec2 indexes = (vViewPos.xz - lightBounds.xy) * lightBounds.zw; indexes = clamp(indexes,0,8); int index = int(indexes.x + (indexes.y * 9)); widthOffset += invWidth * 3 * index; vec4 indexBounds = textureLod(dataTexture, vec2(widthOffset,heightOffset), 0); int toIndex = int(min(lightIndexLimit.y, indexBounds.x)); for(int i = int(lightIndexLimit.x); i <= toIndex; ++i) { float heightCoord = heightOffset + invHeight * i; vec4 dat1 = textureLod(dataTexture, vec2(widthOffset,heightCoord), 0); vec3 vLightView = dat1.xyz - vViewPos; float fLightDist = length(vLightView); if (fLightDist * dat1.w < 1) { vec4 dat2 = textureLod(dataTexture, vec2(widthOffset + invWidth,heightCoord),0); vec4 dat3 = textureLod(dataTexture, vec2(widthOffset + invWidth * 2,heightCoord),0); SL_Light_Ambient_Diffuse_Inner(vNormal, vLightView, fLightDist, dat2.xyz, vec3(dat1.w, dat2.w, dat3.w), dat3.xyz, vColorOut); } } } //----------------------------------------------------------------------------- void SL_Light_Segment_Debug( in vec3 vNormal, in vec3 vViewPos, in sampler2D dataTexture, in vec2 lightIndexLimit, in vec4 lightBounds, in float invWidth, in float invHeight, inout vec3 vColorOut) { float widthOffset = invWidth * 0.5; float heightOffset = invHeight * 0.5; vec2 indexes = (vViewPos.xz - lightBounds.xy) * lightBounds.zw; indexes = clamp(indexes,0,8); int index = int(indexes.x + (indexes.y * 9)); vec4 indexBounds = textureLod(dataTexture, vec2(widthOffset,heightOffset),0); vec2 debugColors = vColorOut.xy * 0.5 + ((mod(floor(indexes.xy),2) == vec2(0)) ? 0.1 : 0.2); vColorOut.xy = debugColors; int toIndex = int(min(lightIndexLimit.y, indexBounds.x)); vColorOut.z = (toIndex - lightIndexLimit.x) / 32; }