diff --git a/Src/Graphics/New3D/New3D.cpp b/Src/Graphics/New3D/New3D.cpp
index 742b6e5..f69b1d0 100644
--- a/Src/Graphics/New3D/New3D.cpp
+++ b/Src/Graphics/New3D/New3D.cpp
@@ -207,7 +207,7 @@ void CNew3D::DrawScrollFog()
 					rgba[2] = vp.fogParams[2];
 					rgba[3] = vp.scrollFog;
 					glViewport(vp.x, vp.y, vp.width, vp.height);
-					m_r3dScrollFog.DrawScrollFog(rgba, 0, vp.fogParams[6]);
+					m_r3dScrollFog.DrawScrollFog(rgba, n.viewport.scrollAtt, n.viewport.fogParams[6], n.viewport.spotFogColor, n.viewport.spotEllipse);
 					break;
 				}
 			}
@@ -246,7 +246,7 @@ void CNew3D::DrawAmbientFog()
 		auto& vp = nodePtr->viewport;
 		float rgba[] = { 0.0f, 0.0f, 0.0f, 1.0f - fogAmbient };
 		glViewport(vp.x, vp.y, vp.width, vp.height);
-		m_r3dScrollFog.DrawScrollFog(rgba, 0.0f, 1.0f);
+		m_r3dScrollFog.DrawScrollFog(rgba, 0.0f, 1.0f, vp.spotFogColor, vp.spotEllipse); // we assume spot light is not used
 	}
 }
 
diff --git a/Src/Graphics/New3D/R3DScrollFog.cpp b/Src/Graphics/New3D/R3DScrollFog.cpp
index 4469ec5..2a75ca8 100644
--- a/Src/Graphics/New3D/R3DScrollFog.cpp
+++ b/Src/Graphics/New3D/R3DScrollFog.cpp
@@ -3,7 +3,7 @@
 
 namespace New3D {
 
-static const char *vertexShaderFog = R"glsl(
+	static const char* vertexShaderFog = R"glsl(
 
 #version 410 core
 
@@ -19,13 +19,25 @@ void main(void)
 
 )glsl";
 
-static const char *fragmentShaderFog = R"glsl(
+	static const char* fragmentShaderFog = R"glsl(
 
 #version 410 core
 
 uniform float	fogAttenuation;
 uniform float	fogAmbient;
 uniform vec4	fogColour;
+uniform vec3	spotFogColor;
+uniform vec4	spotEllipse;
+
+// Spotlight on fog
+float	ellipse;
+vec2	position, size;
+vec3	lSpotFogColor;
+
+// Scroll fog
+float	lfogAttenuation;
+vec3	lFogColor;
+vec4	scrollFog;
 
 // outputs
 layout(location = 0) out vec4 out0;		// opaque
@@ -44,10 +56,21 @@ void WriteOutputs(vec4 colour)
 void main()
 {
 	// Scroll fog base color
-	vec3 lFogColor = fogColour.rgb * fogAmbient;
+	lFogColor = fogColour.rgb * fogAmbient;
+
+	// Spotlight on fog (area) 
+	position = spotEllipse.xy;
+	size = spotEllipse.zw;
+	ellipse = length((gl_FragCoord.xy - position) / size);
+	ellipse = ellipse * ellipse;			// decay rate = square of distance from center
+	ellipse = 1.0 - ellipse;				// invert
+	ellipse = max(0.0, ellipse);			// clamp
+
+	// Spotlight on fog (color)
+	lSpotFogColor = mix(vec3(0.0), spotFogColor * ellipse * fogColour.rgb, fogAttenuation);
 
 	// Scroll fog density
-	vec4 scrollFog = vec4(lFogColor, fogColour.a * (1.0 - fogAttenuation));
+	scrollFog = vec4(lFogColor + lSpotFogColor, fogColour.a);
 
 	// Final Color
 	WriteOutputs(scrollFog);
@@ -56,71 +79,75 @@ void main()
 )glsl";
 
 
-R3DScrollFog::R3DScrollFog(const Util::Config::Node &config)
-  : m_config(config),
-	m_vao(0)
-{
-	m_shaderProgram		= 0;
-	m_vertexShader		= 0;
-	m_fragmentShader	= 0;
+	R3DScrollFog::R3DScrollFog(const Util::Config::Node& config)
+		: m_config(config),
+		m_vao(0)
+	{
+		m_shaderProgram		= 0;
+		m_vertexShader		= 0;
+		m_fragmentShader	= 0;
 
-	AllocResources();
+		AllocResources();
 
-	glGenVertexArrays(1, &m_vao);
-	glBindVertexArray(m_vao);
-	// no states needed since we do it in the shader
-	glBindVertexArray(0);
-}
-
-R3DScrollFog::~R3DScrollFog()
-{
-	DeallocResources();
-
-	if (m_vao) {
-		glDeleteVertexArrays(1, &m_vao);
-		m_vao = 0;
-	}
-}
-
-void R3DScrollFog::DrawScrollFog(float rgba[4], float attenuation, float ambient)
-{
-	// some ogl states
-	glDepthMask			(GL_FALSE);			// disable z writes
-	glDisable			(GL_DEPTH_TEST);	// disable depth testing
-
-	glBindVertexArray	(m_vao);
-	glUseProgram		(m_shaderProgram);
-	glUniform4fv		(m_locFogColour, 1, rgba);
-	glUniform1f			(m_locFogAttenuation, attenuation);
-	glUniform1f			(m_locFogAmbient, ambient);
-
-	glDrawArrays		(GL_TRIANGLE_STRIP, 0, 4);
-
-	glUseProgram		(0);
-	glBindVertexArray	(0);
-
-	glDisable			(GL_BLEND);
-	glDepthMask			(GL_TRUE);
-}
-
-void R3DScrollFog::AllocResources()
-{
-	bool success = LoadShaderProgram(&m_shaderProgram, &m_vertexShader, &m_fragmentShader, m_config["VertexShaderFog"].ValueAs<std::string>(), m_config["FragmentShaderFog"].ValueAs<std::string>(), vertexShaderFog, fragmentShaderFog);
-
-	m_locFogColour		= glGetUniformLocation(m_shaderProgram, "fogColour");
-	m_locFogAttenuation	= glGetUniformLocation(m_shaderProgram, "fogAttenuation");
-	m_locFogAmbient		= glGetUniformLocation(m_shaderProgram, "fogAmbient");
-}
-
-void R3DScrollFog::DeallocResources()
-{
-	if (m_shaderProgram) {
-		DestroyShaderProgram(m_shaderProgram, m_vertexShader, m_fragmentShader);
+		glGenVertexArrays(1, &m_vao);
+		glBindVertexArray(m_vao);
+		// no states needed since we do it in the shader
+		glBindVertexArray(0);
 	}
 
-	m_shaderProgram		= 0;
-	m_vertexShader		= 0;
-	m_fragmentShader	= 0;
-}
+	R3DScrollFog::~R3DScrollFog()
+	{
+		DeallocResources();
+
+		if (m_vao) {
+			glDeleteVertexArrays(1, &m_vao);
+			m_vao = 0;
+		}
+	}
+
+	void R3DScrollFog::DrawScrollFog(float rgba[4], float attenuation, float ambient, float spotRGB[3], float spotEllipse[4])
+	{
+		// some ogl states
+		glDepthMask			(GL_FALSE);			// disable z writes
+		glDisable			(GL_DEPTH_TEST);	// disable depth testing
+
+		glBindVertexArray	(m_vao);
+		glUseProgram		(m_shaderProgram);
+		glUniform4fv		(m_locFogColour, 1, rgba);
+		glUniform1f			(m_locFogAttenuation, attenuation);
+		glUniform1f			(m_locFogAmbient, ambient);
+		glUniform3fv		(m_locSpotFogColor, 1, spotRGB);
+		glUniform4fv		(m_locSpotEllipse, 1, spotEllipse);
+
+		glDrawArrays		(GL_TRIANGLE_STRIP, 0, 4);
+
+		glUseProgram		(0);
+		glBindVertexArray	(0);
+
+		glDisable			(GL_BLEND);
+		glDepthMask			(GL_TRUE);
+	}
+
+	void R3DScrollFog::AllocResources()
+	{
+		bool success = LoadShaderProgram(&m_shaderProgram, &m_vertexShader, &m_fragmentShader, m_config["VertexShaderFog"].ValueAs<std::string>(), m_config["FragmentShaderFog"].ValueAs<std::string>(), vertexShaderFog, fragmentShaderFog);
+
+		m_locFogColour		= glGetUniformLocation(m_shaderProgram, "fogColour");
+		m_locFogAttenuation	= glGetUniformLocation(m_shaderProgram, "fogAttenuation");
+		m_locFogAmbient		= glGetUniformLocation(m_shaderProgram, "fogAmbient");
+		m_locSpotFogColor	= glGetUniformLocation(m_shaderProgram, "spotFogColor");
+		m_locSpotEllipse	= glGetUniformLocation(m_shaderProgram, "spotEllipse");
+	}
+
+	void R3DScrollFog::DeallocResources()
+	{
+		if (m_shaderProgram) {
+			DestroyShaderProgram(m_shaderProgram, m_vertexShader, m_fragmentShader);
+		}
+
+		m_shaderProgram		= 0;
+		m_vertexShader		= 0;
+		m_fragmentShader	= 0;
+	}
 
 }
diff --git a/Src/Graphics/New3D/R3DScrollFog.h b/Src/Graphics/New3D/R3DScrollFog.h
index 8593a40..e38897a 100644
--- a/Src/Graphics/New3D/R3DScrollFog.h
+++ b/Src/Graphics/New3D/R3DScrollFog.h
@@ -6,32 +6,34 @@
 
 namespace New3D {
 
-class R3DScrollFog
-{
-public:
+	class R3DScrollFog
+	{
+	public:
 
-	R3DScrollFog(const Util::Config::Node &config);
-	~R3DScrollFog();
+		R3DScrollFog(const Util::Config::Node& config);
+		~R3DScrollFog();
 
-	void DrawScrollFog(float rbga[4], float attenuation, float ambient);
+		void DrawScrollFog(float rbga[4], float attenuation, float ambient, float spotRGB[3], float spotEllipse[4]);
 
-private:
+	private:
 
-	void AllocResources();
-	void DeallocResources();
+		void AllocResources();
+		void DeallocResources();
 
-  const Util::Config::Node &m_config;
+		const Util::Config::Node& m_config;
 
-	GLuint m_shaderProgram;
-	GLuint m_vertexShader;
-	GLuint m_fragmentShader;
+		GLuint m_shaderProgram;
+		GLuint m_vertexShader;
+		GLuint m_fragmentShader;
 
-	GLint m_locFogColour;
-	GLint m_locFogAttenuation;
-	GLint m_locFogAmbient;
+		GLint m_locFogColour;
+		GLint m_locFogAttenuation;
+		GLint m_locFogAmbient;
+		GLint m_locSpotFogColor;
+		GLint m_locSpotEllipse;
 
-	GLuint m_vao;
-};
+		GLuint m_vao;
+	};
 
 }