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,
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)
}
else if (aType == OccLightType_Spot)
{
- // Not implemented
+ spotLight (anIndex, theNormal, theView, aPoint);
}
}
"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') <type> to add any light source"
+ "\n where <type> is one of {amb}ient|directional|{spot}light|positional"
+ "\n 'change' <lightId> 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",