mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-22 22:05:38 +00:00
Correct scroll fog attenuation logic (gm_matthew)
The attenuation value effects the spot light on fog for the scroll fog layer. The old implemention was nearly correct but the paramaters for the mix function were swapped.
This commit is contained in:
parent
aecf61762e
commit
a065df24b8
|
@ -207,7 +207,7 @@ void CNew3D::DrawScrollFog()
|
||||||
rgba[2] = vp.fogParams[2];
|
rgba[2] = vp.fogParams[2];
|
||||||
rgba[3] = vp.scrollFog;
|
rgba[3] = vp.scrollFog;
|
||||||
glViewport(vp.x, vp.y, vp.width, vp.height);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -246,7 +246,7 @@ void CNew3D::DrawAmbientFog()
|
||||||
auto& vp = nodePtr->viewport;
|
auto& vp = nodePtr->viewport;
|
||||||
float rgba[] = { 0.0f, 0.0f, 0.0f, 1.0f - fogAmbient };
|
float rgba[] = { 0.0f, 0.0f, 0.0f, 1.0f - fogAmbient };
|
||||||
glViewport(vp.x, vp.y, vp.width, vp.height);
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
namespace New3D {
|
namespace New3D {
|
||||||
|
|
||||||
static const char *vertexShaderFog = R"glsl(
|
static const char* vertexShaderFog = R"glsl(
|
||||||
|
|
||||||
#version 410 core
|
#version 410 core
|
||||||
|
|
||||||
|
@ -19,13 +19,25 @@ void main(void)
|
||||||
|
|
||||||
)glsl";
|
)glsl";
|
||||||
|
|
||||||
static const char *fragmentShaderFog = R"glsl(
|
static const char* fragmentShaderFog = R"glsl(
|
||||||
|
|
||||||
#version 410 core
|
#version 410 core
|
||||||
|
|
||||||
uniform float fogAttenuation;
|
uniform float fogAttenuation;
|
||||||
uniform float fogAmbient;
|
uniform float fogAmbient;
|
||||||
uniform vec4 fogColour;
|
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
|
// outputs
|
||||||
layout(location = 0) out vec4 out0; // opaque
|
layout(location = 0) out vec4 out0; // opaque
|
||||||
|
@ -44,10 +56,21 @@ void WriteOutputs(vec4 colour)
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Scroll fog base color
|
// 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
|
// Scroll fog density
|
||||||
vec4 scrollFog = vec4(lFogColor, fogColour.a * (1.0 - fogAttenuation));
|
scrollFog = vec4(lFogColor + lSpotFogColor, fogColour.a);
|
||||||
|
|
||||||
// Final Color
|
// Final Color
|
||||||
WriteOutputs(scrollFog);
|
WriteOutputs(scrollFog);
|
||||||
|
@ -56,71 +79,75 @@ void main()
|
||||||
)glsl";
|
)glsl";
|
||||||
|
|
||||||
|
|
||||||
R3DScrollFog::R3DScrollFog(const Util::Config::Node &config)
|
R3DScrollFog::R3DScrollFog(const Util::Config::Node& config)
|
||||||
: m_config(config),
|
: m_config(config),
|
||||||
m_vao(0)
|
m_vao(0)
|
||||||
{
|
{
|
||||||
m_shaderProgram = 0;
|
m_shaderProgram = 0;
|
||||||
m_vertexShader = 0;
|
m_vertexShader = 0;
|
||||||
m_fragmentShader = 0;
|
m_fragmentShader = 0;
|
||||||
|
|
||||||
AllocResources();
|
AllocResources();
|
||||||
|
|
||||||
glGenVertexArrays(1, &m_vao);
|
glGenVertexArrays(1, &m_vao);
|
||||||
glBindVertexArray(m_vao);
|
glBindVertexArray(m_vao);
|
||||||
// no states needed since we do it in the shader
|
// no states needed since we do it in the shader
|
||||||
glBindVertexArray(0);
|
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_shaderProgram = 0;
|
R3DScrollFog::~R3DScrollFog()
|
||||||
m_vertexShader = 0;
|
{
|
||||||
m_fragmentShader = 0;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,32 +6,34 @@
|
||||||
|
|
||||||
namespace New3D {
|
namespace New3D {
|
||||||
|
|
||||||
class R3DScrollFog
|
class R3DScrollFog
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
R3DScrollFog(const Util::Config::Node &config);
|
R3DScrollFog(const Util::Config::Node& config);
|
||||||
~R3DScrollFog();
|
~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 AllocResources();
|
||||||
void DeallocResources();
|
void DeallocResources();
|
||||||
|
|
||||||
const Util::Config::Node &m_config;
|
const Util::Config::Node& m_config;
|
||||||
|
|
||||||
GLuint m_shaderProgram;
|
GLuint m_shaderProgram;
|
||||||
GLuint m_vertexShader;
|
GLuint m_vertexShader;
|
||||||
GLuint m_fragmentShader;
|
GLuint m_fragmentShader;
|
||||||
|
|
||||||
GLint m_locFogColour;
|
GLint m_locFogColour;
|
||||||
GLint m_locFogAttenuation;
|
GLint m_locFogAttenuation;
|
||||||
GLint m_locFogAmbient;
|
GLint m_locFogAmbient;
|
||||||
|
GLint m_locSpotFogColor;
|
||||||
|
GLint m_locSpotEllipse;
|
||||||
|
|
||||||
GLuint m_vao;
|
GLuint m_vao;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue