Make shaders run as efficient as possible

This commit is contained in:
Benau 2016-06-27 13:49:27 +08:00
parent 5424d49ce7
commit 892bc490f7
6 changed files with 59 additions and 70 deletions

View File

@ -8,14 +8,14 @@ flat in sampler2D handle;
flat in sampler2D secondhandle;
#endif
uniform vec2 color_change;
uniform float color_change;
in vec2 uv;
in vec4 color;
out vec4 FragColor;
vec3 getLightFactor(vec3 diffuseMatColor, vec3 specularMatColor, float specMapValue, float emitMapValue);
float rgbToValue(vec3 c);
vec3 rgbToHsv(vec3 c);
vec3 hsvToRgb(vec3 c);
void main(void)
@ -33,10 +33,12 @@ void main(void)
float emitmap = texture(SpecMap, uv).b;
#endif
if (color_change.x > 0.0)
if (color_change > 0.0)
{
vec3 new_color = hsvToRgb(vec3(color_change.x, color_change.y, rgbToValue(col.rgb)));
col = vec4(new_color.b, new_color.g, new_color.r, col.a);
vec3 old_hsv = rgbToHsv(col.rgb);
old_hsv.y = max(old_hsv.y, 0.93);
vec3 new_color = hsvToRgb(vec3(color_change, old_hsv.y, old_hsv.z));
col = vec4(new_color.r, new_color.g, new_color.b, col.a);
}
col.xyz *= pow(color.xyz, vec3(2.2));

View File

@ -6,14 +6,14 @@ uniform sampler2D Albedo;
uniform sampler2D SpecMap;
#endif
uniform vec2 color_change;
uniform float color_change;
in vec2 uv;
in vec4 color;
out vec4 FragColor;
vec3 getLightFactor(vec3 diffuseMatColor, vec3 specularMatColor, float specMapValue, float emitMapValue);
float rgbToValue(vec3 c);
vec3 rgbToHsv(vec3 c);
vec3 hsvToRgb(vec3 c);
void main(void)
@ -27,10 +27,12 @@ void main(void)
vec4 col = texture(Albedo, uv);
#endif
if (color_change.x > 0.0)
if (color_change > 0.0)
{
vec3 new_color = hsvToRgb(vec3(color_change.x, color_change.y, rgbToValue(col.rgb)));
col = vec4(new_color.b, new_color.g, new_color.r, col.a);
vec3 old_hsv = rgbToHsv(col.rgb);
old_hsv.y = max(old_hsv.y, 0.93);
vec3 new_color = hsvToRgb(vec3(color_change, old_hsv.y, old_hsv.z));
col = vec4(new_color.r, new_color.g, new_color.b, col.a);
}
col.xyz *= pow(color.xyz, vec3(2.2));

View File

@ -9,15 +9,6 @@ vec3 rgbToHsv(vec3 c)
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}
float rgbToValue(vec3 c)
{
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
return q.x;
}
vec3 hsvToRgb(vec3 c)
{
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);

View File

@ -153,10 +153,11 @@ public:
4, "SpecMap", ST_TRILINEAR_ANISOTROPIC_FILTERED);
} // InstancedObjectPass2Shader
void setHueSaturation(float hue, float saturation) const
virtual bool changeHue(float hue = 0.0f) const OVERRIDE
{
glUniform2f(m_color_change_location, hue, saturation);
} // setHueSaturation
glUniform1f(m_color_change_location, hue);
return true;
} // changeHue
}; // InstancedObjectPass2Shader
// ============================================================================
@ -997,23 +998,17 @@ void draw(const T *Shader, const GLMesh *mesh, uniforms... Args)
GLenum itype = mesh->IndexType;
size_t count = mesh->IndexCount;
const Shaders::ObjectPass2Shader* op2s = dynamic_cast<const Shaders::ObjectPass2Shader*>
(Shader);
if (op2s)
const video::E_RENDER_TYPE rt = mesh->mb->getRenderType();
const bool need_change_hue = (rt != video::ERT_DEFAULT);
if (need_change_hue)
{
const video::E_RENDER_TYPE rt = mesh->mb->getRenderType();
if (rt == video::ERT_RED)
{
op2s->setHueSaturation(0.69f, 0.97f);
Shader->changeHue(1.0f);
}
else if (rt == video::ERT_BLUE)
{
op2s->setHueSaturation(0.01f, 0.97f);
}
else
{
// Reset if not using custom render type
op2s->setHueSaturation(0.0f, 0.0f);
Shader->changeHue(0.66f);
}
}
@ -1021,6 +1016,13 @@ void draw(const T *Shader, const GLMesh *mesh, uniforms... Args)
glDrawElementsBaseVertex(ptype, (int)count, itype,
(GLvoid *)mesh->vaoOffset,
(int)mesh->vaoBaseVertex);
if (need_change_hue)
{
// Reset after changing
Shader->changeHue();
}
} // draw
// ----------------------------------------------------------------------------
@ -1302,47 +1304,31 @@ void renderInstancedMeshes2ndPass(const std::vector<GLuint> &Prefilled_tex, Args
TexExpander<typename T::InstancedSecondPassShader>::template
ExpandTex(*mesh, T::SecondPassTextures, Prefilled_tex[0],
Prefilled_tex[1], Prefilled_tex[2]);
T::InstancedSecondPassShader::getInstance()->setUniforms(args...);
glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT,
(const void*)((SolidPassCmd::getInstance()->Offset[T::MaterialType] + i)
* sizeof(DrawElementsIndirectCommand)));
}
} // renderInstancedMeshes2ndPass
// ----------------------------------------------------------------------------
template<>
void renderInstancedMeshes2ndPass<DefaultMaterial>(const std::vector<GLuint> &Prefilled_tex)
{
std::vector<GLMesh *> &meshes = DefaultMaterial::InstancedList::getInstance()->SolidPass;
DefaultMaterial::InstancedSecondPassShader::getInstance()->use();
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(DefaultMaterial::VertexType,
DefaultMaterial::Instance));
for (unsigned i = 0; i < meshes.size(); i++)
{
GLMesh *mesh = meshes[i];
TexExpander<DefaultMaterial::InstancedSecondPassShader>::template
ExpandTex(*mesh, DefaultMaterial::SecondPassTextures, Prefilled_tex[0],
Prefilled_tex[1], Prefilled_tex[2]);
const video::E_RENDER_TYPE rt = mesh->mb->getRenderType();
if (rt == video::ERT_RED)
const bool need_change_hue = (rt != video::ERT_DEFAULT);
if (need_change_hue)
{
DefaultMaterial::InstancedSecondPassShader::getInstance()->setHueSaturation(0.69f, 0.97f);
}
else if (rt == video::ERT_BLUE)
{
DefaultMaterial::InstancedSecondPassShader::getInstance()->setHueSaturation(0.01f, 0.97f);
}
else
{
// Reset if not using custom render type
DefaultMaterial::InstancedSecondPassShader::getInstance()->setHueSaturation(0.0f, 0.0f);
if (rt == video::ERT_RED)
{
T::InstancedSecondPassShader::getInstance()->changeHue(1.0f);
}
else if (rt == video::ERT_BLUE)
{
T::InstancedSecondPassShader::getInstance()->changeHue(0.66f);
}
}
DefaultMaterial::InstancedSecondPassShader::getInstance()->setUniforms();
T::InstancedSecondPassShader::getInstance()->setUniforms(args...);
glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT,
(const void*)((SolidPassCmd::getInstance()->Offset[DefaultMaterial::MaterialType] + i)
(const void*)((SolidPassCmd::getInstance()->Offset[T::MaterialType] + i)
* sizeof(DrawElementsIndirectCommand)));
if (need_change_hue)
{
// Reset after changing
T::InstancedSecondPassShader::getInstance()->changeHue();
}
}
} // renderInstancedMeshes2ndPass

View File

@ -150,10 +150,11 @@ public:
GLint m_color_change_location;
public:
ObjectPass2Shader();
void setHueSaturation(float hue, float saturation) const
virtual bool changeHue(float hue = 0.0f) const OVERRIDE
{
glUniform2f(m_color_change_location, hue, saturation);
} // setHueSaturation
glUniform1f(m_color_change_location, hue);
return true;
} // changeHue
}; // ObjectPass2Shader
// ========================================================================

View File

@ -21,6 +21,7 @@
#include "graphics/central_settings.hpp"
#include "graphics/gl_headers.hpp"
#include "graphics/shader.hpp"
#include "utils/cpp2011.hpp"
#include <assert.h>
#include <functional>
@ -241,6 +242,12 @@ public:
glDeleteSamplers(1, &m_sampler_ids[i]);
} // ~TextureShader
/** Override this class and return true if a shader can set different hue.
*/
virtual bool changeHue(float hue = 0.0f) const
{
return false;
} // changeHue
}; // class TextureShader