From 816d03eef307542f80b4e94b4699de009fbb36a3 Mon Sep 17 00:00:00 2001 From: duv Date: Wed, 12 Feb 2014 14:42:27 +0400 Subject: [PATCH] 0024323: TKOpenGl - spot light sources are not handled in Phong GLSL program Limit number of lights (breaks compatibility with old hardware). --- src/Shaders/PhongShading.fs | 55 +++++++++++++++++++- src/ViewerTest/ViewerTest_ViewerCommands.cxx | 25 ++++++--- 2 files changed, 72 insertions(+), 8 deletions(-) diff --git a/src/Shaders/PhongShading.fs b/src/Shaders/PhongShading.fs index af79124de6..0cb63e2270 100755 --- a/src/Shaders/PhongShading.fs +++ b/src/Shaders/PhongShading.fs @@ -56,6 +56,57 @@ void pointLight (in int theId, Specular += occLight_Specular (theId).rgb * aSpecl * anAtten; } +//! Computes contribution of spotlight source +void spotLight (in int theId, + in vec3 theNormal, + in vec3 theView, + in vec3 thePoint) +{ + vec3 aLight = occLight_Position (theId).xyz; + vec3 aSpotDir = occLight_SpotDirection (theId).xyz; + if (occLight_IsHeadlight (theId) == 0) + { + aLight = vec3 (occWorldViewMatrix * occModelWorldMatrix * vec4 (aLight, 1.0)); + aSpotDir = vec3 (occWorldViewMatrix * occModelWorldMatrix * vec4 (aSpotDir, 0.0)); + } + aLight -= thePoint; + + float aDist = length (aLight); + aLight = aLight * (1.0 / aDist); + + aSpotDir = normalize (aSpotDir); + + // light cone + float aCosA = dot (aSpotDir, -aLight); + if (aCosA >= 1.0 || aCosA < cos (occLight_SpotCutOff (theId))) + { + return; + } + + float anExponent = occLight_SpotExponent (theId); + float anAtten = 1.0 / (occLight_ConstAttenuation (theId) + + occLight_LinearAttenuation (theId) * aDist); + if (anExponent > 0.0) + { + anAtten *= pow (aCosA, anExponent * 128.0); + } + + vec3 aHalf = normalize (aLight + theView); + + vec3 aFaceSideNormal = gl_FrontFacing ? theNormal : -theNormal; + float aNdotL = max (0.0, dot (aFaceSideNormal, aLight)); + float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf )); + + float aSpecl = 0.0; + if (aNdotL > 0.0) + { + aSpecl = pow (aNdotH, gl_FrontFacing ? occFrontMaterial_Shininess() : occBackMaterial_Shininess()); + } + + Diffuse += occLight_Diffuse (theId).rgb * aNdotL * anAtten; + Specular += occLight_Specular (theId).rgb * aSpecl * anAtten; +} + //! Computes contribution of directional light source void directionalLight (in int theId, in vec3 theNormal, @@ -93,7 +144,7 @@ vec4 computeLighting (in vec3 theNormal, Diffuse = vec3 (0.0); Specular = vec3 (0.0); vec3 aPoint = thePoint.xyz / thePoint.w; - for (int anIndex = 0; anIndex < THE_MAX_LIGHTS; ++anIndex) + for (int anIndex = 0; anIndex < occLightSourcesCount; ++anIndex) { int aType = occLight_Type (anIndex); if (aType == OccLightType_Direct) @@ -106,7 +157,7 @@ vec4 computeLighting (in vec3 theNormal, } else if (aType == OccLightType_Spot) { - // Not implemented + spotLight (anIndex, theNormal, theView, aPoint); } } diff --git a/src/ViewerTest/ViewerTest_ViewerCommands.cxx b/src/ViewerTest/ViewerTest_ViewerCommands.cxx index 405e23c434..d4ced534d3 100644 --- a/src/ViewerTest/ViewerTest_ViewerCommands.cxx +++ b/src/ViewerTest/ViewerTest_ViewerCommands.cxx @@ -6539,12 +6539,25 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands) "vdefaults [absDefl=value] [devCoeff=value] [angDefl=value]", __FILE__, VDefaults, group); theCommands.Add("vlight", - "vlight [add|new {amb}ient|directional|{spot}light|positional]" - "\n\t\t: [{def}aults] [clear]" - "\n\t\t: [{del}ete|change lightId] [local|global]" - "\n\t\t: [{pos}ition X Y Z] [color colorName] [{head}light 0|1]" - "\n\t\t: [{constAtten}uation value] [{linearAtten}uation value]" - "\n\t\t: [angle angleDeg] [{spotexp}onent value]", + "tool to manage light sources, without arguments shows list of lights." + "\n Main commands: " + "\n 'clear' to clear lights" + "\n '{def}aults' to load deafault lights" + "\n 'add' (or 'new') to add any light source" + "\n where is one of {amb}ient|directional|{spot}light|positional" + "\n 'change' to edit light source with specified lightId" + "\n\n In addition to 'add' and 'change' commands you can use light parameters:" + "\n {pos}ition X Y Z" + "\n {dir}ection X Y Z (for directional light or for spotlight)" + "\n color colorName" + "\n {head}light 0|1" + "\n {constAtten}uation value" + "\n {linearAtten}uation value" + "\n angle angleDeg" + "\n {spotexp}onent value" + "\n local|global" + "\n\n example: vlight add positional head 1 pos 0 1 1 color red" + "\n example: vlight change 0 direction 0 -1 0 linearAttenuation 0.2", __FILE__, VLight, group); theCommands.Add("vraytrace", "vraytrace 0|1", -- 2.20.1