Skip to content

Commit

Permalink
#149 Implement spotlight shader
Browse files Browse the repository at this point in the history
  • Loading branch information
ducphamhong committed Jun 1, 2022
1 parent 58e8ea9 commit 4e30d7e
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ uniform sampler2D uTexData;

uniform vec4 uCameraPosition;
uniform vec4 uLightPosition;
uniform vec4 uLightDirection;
uniform vec4 uLightAttenuation;
uniform vec4 uLightColor;

Expand All @@ -33,6 +34,18 @@ void main(void)
float attenuation = max(0.0, 1.0 - (distance * uLightAttenuation.z)) * uLightColor.a;

vec3 lightDir = normalize(direction);

float spotDot = dot(lightDir, uLightDirection.xyz);
if (spotDot < uLightAttenuation.x)
{
attenuation = 0.f;
}
else
{
float spotValue = smoothstep(uLightAttenuation.x, uLightAttenuation.y, spotDot);
attenuation = pow(spotValue, uLightAttenuation.w);
}

float NdotL = max(0.0, dot(lightDir, normal));

// Specular
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ cbuffer cbPerFrame
{
float4 uCameraPosition;
float4 uLightPosition;
float4 uLightDirection;
float4 uLightAttenuation;
float4 uLightColor;
};
Expand All @@ -37,8 +38,20 @@ float4 main(PS_INPUT input) : SV_TARGET
float3 direction = uLightPosition.xyz - position;
float distance = length(direction);
float attenuation = max(0.0, 1.0 - (distance * uLightAttenuation.z)) * uLightColor.a;

float3 lightDir = normalize(direction);

float spotDot = dot(lightDir, uLightDirection.xyz);
if (spotDot < uLightAttenuation.x)
{
attenuation = 0.f;
}
else
{
float spotValue = smoothstep(uLightAttenuation.x, uLightAttenuation.y, spotDot);
attenuation = pow(spotValue, uLightAttenuation.w);
}

float NdotL = max(0.0, dot(lightDir, normal));

// Specular
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

<uniform name="uCameraPosition" type="WORLD_CAMERA_POSITION" value="0" float="4"/>
<uniform name="uLightPosition" type="SPOT_LIGHT_POSITION" value="0" float="4"/>
<uniform name="uLightDirection" type="SPOT_LIGHT_DIRECTION" value="0" float="4"/>
<uniform name="uLightAttenuation" type="SPOT_LIGHT_ATTENUATION" value="0" float="4"/>
<uniform name="uLightColor" type="SPOT_LIGHT_COLOR" value="1.0,1.0,1.0,1.0" float="4"/>
</fs>
Expand Down
3 changes: 2 additions & 1 deletion Projects/Editor/Source/Selection/CSelection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ namespace Skylicht
m_selected.clear();

CSceneHistory* history = CSceneController::getInstance()->getHistory();
history->endSaveHistory();
if (history)
history->endSaveHistory();
}

std::vector<CSelectObject*> CSelection::getSelectedByType(CSelectObject::ESelectType type)
Expand Down
1 change: 1 addition & 0 deletions Projects/Skylicht/Engine/Source/Lighting/CLight.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ namespace Skylicht
m_color(1.0f, 1.0f, 1.0f, 1.0f),
m_spotCutoff(180.0f / 4.0f),
m_spotInnerCutoff(180.0f / 5.0f),
m_spotExponent(10.0f),
m_intensity(1.0f),
m_bakeBounce(1)
{
Expand Down
11 changes: 11 additions & 0 deletions Projects/Skylicht/Engine/Source/Lighting/CLight.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ namespace Skylicht
//! The angle of the spot's outer cone. Ignored for other lights.
float m_spotCutoff;
float m_spotInnerCutoff;
float m_spotExponent;

//! Direction of the light.
/** If Type is ELT_POINT, it is ignored. Changed via light scene node's rotation. */
Expand Down Expand Up @@ -125,6 +126,16 @@ namespace Skylicht
return m_spotInnerCutoff;
}

inline void setSpotExponent(float e)
{
m_spotExponent = e;
}

inline float getSpotExponent()
{
return m_spotExponent;
}

inline core::vector3df& getDirection()
{
return m_direction;
Expand Down
4 changes: 2 additions & 2 deletions Projects/Skylicht/Engine/Source/Lighting/CSpotLight.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ namespace Skylicht
object->autoRelease(new CFloatProperty(object, "radius", m_radius, 0.0f));
object->autoRelease(new CFloatProperty(object, "outer cutoff", m_spotCutoff, 0.0f, 180.0f));
object->autoRelease(new CFloatProperty(object, "inner cutoff", m_spotInnerCutoff, 0.0f, 180.0f));
object->autoRelease(new CFloatProperty(object, "spot exponent", m_spotExponent, 0.0f, 128.0f));

return object;
}
Expand All @@ -95,10 +96,9 @@ namespace Skylicht
float radius = object->get<float>("radius", 3.0f);
m_spotCutoff = object->get<float>("outer cutoff", 180.0f / 4.0f);
m_spotInnerCutoff = object->get<float>("inner cutoff", 180.0f / 5.0f);
m_spotExponent = object->get<float>("spot exponent", 10.0f);

setRadius(radius);
setSpotAngle(m_spotCutoff);
setSpotInnerAngle(m_spotInnerCutoff);
}

core::vector3df CSpotLight::getPosition()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,10 @@ namespace Skylicht
float attenuation[4] = { 0 };

// set attenuation
attenuation[0] = s_spotLight->getSplotCutoff();
attenuation[1] = s_spotLight->getSpotInnerCutof();
attenuation[0] = cosf(s_spotLight->getSplotCutoff() * core::DEGTORAD * 0.5f);
attenuation[1] = cosf(s_spotLight->getSpotInnerCutof() * core::DEGTORAD * 0.5f);
attenuation[2] = s_spotLight->getAttenuation();
attenuation[3] = s_spotLight->getSpotExponent();

// shader variable
if (vertexShader == true)
Expand Down

0 comments on commit 4e30d7e

Please sign in to comment.