Make grass shader colorizable

This commit is contained in:
Benau 2016-12-04 00:59:09 +08:00
parent 31b6a0a4b1
commit 7d5f786da8
12 changed files with 66 additions and 87 deletions

View File

@ -2,17 +2,21 @@
layout(bindless_sampler) uniform sampler2D Albedo;
layout(bindless_sampler) uniform sampler2D dtex;
layout(bindless_sampler) uniform sampler2D SpecMap;
layout(bindless_sampler) uniform sampler2D colorization_mask;
#else
uniform sampler2D Albedo;
uniform sampler2D dtex;
uniform sampler2D SpecMap;
uniform sampler2D colorization_mask;
#endif
in vec3 nor;
in vec2 uv;
uniform vec2 color_change;
out vec4 FragColor;
#stk_include "utils/getLightFactor.frag"
#stk_include "utils/rgb_conversion.frag"
void main(void)
{
@ -24,6 +28,15 @@ void main(void)
#endif
if (color.a < 0.5) discard;
float mask = texture(colorization_mask, uv).a;
if (color_change.x > 0.0)
{
vec3 old_hsv = rgbToHsv(color.rgb);
float mask_step = step(mask, 0.5);
vec2 new_xy = mix(vec2(old_hsv.x, old_hsv.y), vec2(color_change.x, max(old_hsv.y, color_change.y)), vec2(mask_step, mask_step));
color.xyz = hsvToRgb(vec3(new_xy.x, new_xy.y, old_hsv.z));
}
vec2 texc = gl_FragCoord.xy / screen;
float z = texture(dtex, texc).x;

View File

@ -9,9 +9,11 @@ layout(location = 3) in vec2 Texcoord;
layout(location = 7) in vec3 Origin;
layout(location = 8) in vec3 Orientation;
layout(location = 9) in vec3 Scale;
layout(location = 10) in vec4 misc_data;
#ifdef Use_Bindless_Texture
layout(location = 11) in sampler2D Handle;
layout(location = 12) in sampler2D SecondHandle;
layout(location = 13) in sampler2D ThirdHandle;
#endif
#else
@ -23,13 +25,16 @@ in vec2 Texcoord;
in vec3 Origin;
in vec3 Orientation;
in vec3 Scale;
in vec4 misc_data;
#endif
out vec3 nor;
out vec2 uv;
out vec2 color_change;
#ifdef Use_Bindless_Texture
flat out sampler2D handle;
flat out sampler2D secondhandle;
flat out sampler2D thirdhandle;
#endif
#stk_include "utils/getworldmatrix.vert"
@ -41,8 +46,10 @@ void main()
gl_Position = ProjectionViewMatrix * ModelMatrix * vec4(Position, 1.);
nor = (TransposeInverseModelView * vec4(Normal, 0.)).xyz;
uv = Texcoord;
color_change = misc_data.zw;
#ifdef Use_Bindless_Texture
handle = Handle;
secondhandle = SecondHandle;
thirdhandle = ThirdHandle;
#endif
}

View File

@ -4,32 +4,46 @@ layout(bindless_sampler) uniform sampler2D dtex;
uniform sampler2D Albedo;
uniform sampler2D SpecMap;
uniform sampler2D dtex;
uniform sampler2D colorization_mask;
#endif
#ifdef Use_Bindless_Texture
flat in sampler2D handle;
flat in sampler2D secondhandle;
flat in sampler2D thirdhandle;
#endif
in vec3 nor;
in vec2 uv;
in vec2 color_change;
out vec4 FragColor;
#stk_include "utils/getLightFactor.frag"
#stk_include "utils/rgb_conversion.frag"
void main(void)
{
#ifdef Use_Bindless_Texture
vec4 color = texture(handle, uv);
float specmap = texture(secondhandle, uv).g;
float mask = texture(thirdhandle, uv).a;
#ifdef SRGBBindlessFix
color.xyz = pow(color.xyz, vec3(2.2));
#endif
#else
vec4 color = texture(Albedo, uv);
float specmap = texture(SpecMap, uv).g;
float mask = texture(colorization_mask, uv).a;
#endif
if (color.a < 0.5) discard;
if (color_change.x > 0.0)
{
vec3 old_hsv = rgbToHsv(color.rgb);
float mask_step = step(mask, 0.5);
vec2 new_xy = mix(vec2(old_hsv.x, old_hsv.y), vec2(color_change.x, max(old_hsv.y, color_change.y)), vec2(mask_step, mask_step));
color.xyz = hsvToRgb(vec3(new_xy.x, new_xy.y, old_hsv.z));
}
vec2 texc = gl_FragCoord.xy / screen;
float z = texture(dtex, texc).x;
@ -46,7 +60,6 @@ void main(void)
float fLdotNBack = max(0., - dot(nor, L) * 0.6 + 0.4);
float scattering = mix(fPowEdotL, fLdotNBack, .5);
vec3 LightFactor = color.xyz * (scattering * 0.1) + getLightFactor(color.xyz, vec3(1.), specmap, 0.);
FragColor = vec4(LightFactor, 1.);
}

View File

@ -29,17 +29,6 @@ void InstanceFiller<InstanceDataSingleTex>::add(GLMesh* mesh,
instance.Texture = mesh->TextureHandles[0];
}
// ----------------------------------------------------------------------------
template<>
void InstanceFiller<InstanceDataDualTex>::add(GLMesh* mesh,
const InstanceSettings& is,
InstanceDataDualTex& instance)
{
fillOriginOrientationScale<InstanceDataDualTex>(STK::tuple_get<0>(is), instance);
instance.Texture = mesh->TextureHandles[0];
instance.SecondTexture = mesh->TextureHandles[1];
}
// ----------------------------------------------------------------------------
template<>
void InstanceFiller<InstanceDataThreeTex>::add(GLMesh* mesh,
@ -170,18 +159,13 @@ void SolidCommandBuffer::fill(SolidPassMeshMap *mesh_map)
if(!CVS->supportsAsyncInstanceUpload())
mapIndirectBuffer();
std::vector<int> dual_tex_material_list =
createVector<int>(Material::SHADERTYPE_VEGETATION);
fillInstanceData<InstanceDataDualTex, SolidPassMeshMap>
(mesh_map, dual_tex_material_list, InstanceTypeDualTex);
std::vector<int> three_tex_material_list =
createVector<int>(Material::SHADERTYPE_SOLID,
Material::SHADERTYPE_ALPHA_TEST,
Material::SHADERTYPE_SOLID_UNLIT,
Material::SHADERTYPE_SPHERE_MAP);
Material::SHADERTYPE_SPHERE_MAP,
Material::SHADERTYPE_VEGETATION);
fillInstanceData<InstanceDataThreeTex, SolidPassMeshMap>
(mesh_map, three_tex_material_list, InstanceTypeThreeTex);

View File

@ -315,7 +315,10 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
ListMatSplatting::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix);
break;
case Material::SHADERTYPE_VEGETATION:
ListMatGrass::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, m_wind_dir);
ListMatGrass::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, m_wind_dir,
(mesh->m_render_info && mesh->m_material ?
core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) :
core::vector2df(0.0f, 0.0f)));
break;
case Material::SHADERTYPE_ALPHA_BLEND:
break;
@ -378,7 +381,10 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
ListMatSplatting::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix);
break;
case Material::SHADERTYPE_VEGETATION:
ListMatGrass::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, m_wind_dir);
ListMatGrass::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, m_wind_dir,
(mesh->m_render_info && mesh->m_material ?
core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) :
core::vector2df(0.0f, 0.0f)));
case Material::SHADERTYPE_ALPHA_BLEND:
break;
case Material::SHADERTYPE_ADDITIVE:
@ -448,7 +454,10 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
ListMatSplatting::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix);
break;
case Material::SHADERTYPE_VEGETATION:
ListMatGrass::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, m_wind_dir);
ListMatGrass::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, m_wind_dir,
(mesh->m_render_info && mesh->m_material ?
core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) :
core::vector2df(0.0f, 0.0f)));
break;
case Material::SHADERTYPE_ALPHA_BLEND:
break;

View File

@ -88,7 +88,7 @@ void renderMeshes2ndPass( const std::vector<uint64_t> &Prefilled_Handle,
// ----------------------------------------------------------------------------
template<>
void renderMeshes2ndPass<GrassMat, 3, 1>
void renderMeshes2ndPass<GrassMat, 4, 3, 1>
(const std::vector<uint64_t> &Prefilled_Handle,
const std::vector<GLuint> &Prefilled_Tex)
{
@ -125,7 +125,7 @@ void renderMeshes2ndPass<GrassMat, 3, 1>
expandTex(mesh, GrassMat::SecondPassTextures, Prefilled_Tex[0],
Prefilled_Tex[1], Prefilled_Tex[2], Prefilled_Tex[3]);
}
CustomUnrollArgs<3, 1>::drawMesh<GrassMat::SecondPassShader>(meshes.at(i));
CustomUnrollArgs<4, 3, 1>::drawMesh<GrassMat::SecondPassShader>(meshes.at(i));
}
} // renderMeshes2ndPass
@ -196,7 +196,7 @@ void GL3DrawPolicy::drawSolidSecondPass (const DrawCalls& draw_calls,
renderMeshes2ndPass<SplattingMat, 1 > (handles, prefilled_tex);
renderMeshes2ndPass<SphereMap, 2, 1 > (handles, prefilled_tex);
renderMeshes2ndPass<DetailMat, 1 > (handles, prefilled_tex);
renderMeshes2ndPass<GrassMat, 3, 1 > (handles, prefilled_tex);
renderMeshes2ndPass<GrassMat, 4, 3, 1> (handles, prefilled_tex);
renderMeshes2ndPass<NormalMat, 4, 3, 1> (handles, prefilled_tex);
}

View File

@ -48,8 +48,8 @@ const STK::Tuple<size_t> UnlitMat::RSMTextures = STK::Tuple<size_t>(0);
// ----------------------------------------------------------------------------
const STK::Tuple<size_t, size_t> GrassMat::FirstPassTextures
= STK::Tuple<size_t, size_t>(0, 1);
const STK::Tuple<size_t, size_t> GrassMat::SecondPassTextures
= STK::Tuple<size_t, size_t>(0, 1);
const STK::Tuple<size_t, size_t, size_t> GrassMat::SecondPassTextures
= STK::Tuple<size_t, size_t, size_t>(0, 1, 2);
const STK::Tuple<size_t> GrassMat::ShadowTextures = STK::Tuple<size_t>(0);
const STK::Tuple<size_t> GrassMat::RSMTextures = STK::Tuple<size_t>(0);

View File

@ -536,26 +536,27 @@ public:
// ============================================================================
class GrassPass2Shader : public TextureShader<GrassPass2Shader, 6, core::matrix4,
core::vector3df>
class GrassPass2Shader : public TextureShader<GrassPass2Shader, 7, core::matrix4,
core::vector3df, core::vector2df>
{
public:
GrassPass2Shader()
{
loadProgram(OBJECT, GL_VERTEX_SHADER, "grass_pass.vert",
GL_FRAGMENT_SHADER, "grass_pass2.frag");
assignUniforms("ModelMatrix", "windDir");
assignUniforms("ModelMatrix", "windDir", "color_change");
assignSamplerNames(0, "DiffuseMap", ST_NEAREST_FILTERED,
1, "SpecularMap", ST_NEAREST_FILTERED,
2, "SSAO", ST_BILINEAR_FILTERED,
3, "dtex", ST_NEAREST_FILTERED,
3, "Albedo", ST_TRILINEAR_ANISOTROPIC_FILTERED,
4, "SpecMap", ST_TRILINEAR_ANISOTROPIC_FILTERED);
4, "Albedo", ST_TRILINEAR_ANISOTROPIC_FILTERED,
5, "SpecMap", ST_TRILINEAR_ANISOTROPIC_FILTERED,
6, "colorization_mask", ST_TRILINEAR_ANISOTROPIC_FILTERED);
} // GrassPass2Shader
}; // GrassPass2Shader
// ============================================================================
class InstancedGrassPass2Shader : public TextureShader<InstancedGrassPass2Shader, 6,
class InstancedGrassPass2Shader : public TextureShader<InstancedGrassPass2Shader, 7,
core::vector3df>
{
public:
@ -569,7 +570,8 @@ public:
2, "SSAO", ST_BILINEAR_FILTERED,
3, "dtex", ST_NEAREST_FILTERED,
4, "Albedo", ST_TRILINEAR_ANISOTROPIC_FILTERED,
5, "SpecMap", ST_TRILINEAR_ANISOTROPIC_FILTERED);
5, "SpecMap", ST_TRILINEAR_ANISOTROPIC_FILTERED,
6, "colorization_mask", ST_TRILINEAR_ANISOTROPIC_FILTERED);
} // InstancedGrassPass2Shader
}; // InstancedGrassPass2Shader
@ -714,9 +716,9 @@ struct GrassMat
static const enum video::E_VERTEX_TYPE VertexType = video::EVT_STANDARD;
static const enum Material::ShaderType MaterialType
= Material::SHADERTYPE_VEGETATION;
static const enum InstanceType Instance = InstanceTypeDualTex;
static const enum InstanceType Instance = InstanceTypeThreeTex;
static const STK::Tuple<size_t, size_t> FirstPassTextures;
static const STK::Tuple<size_t, size_t> SecondPassTextures;
static const STK::Tuple<size_t, size_t, size_t> SecondPassTextures;
static const STK::Tuple<size_t> ShadowTextures;
static const STK::Tuple<size_t> RSMTextures;
}; // GrassMat

View File

@ -402,14 +402,11 @@ void initTextures(GLMesh &mesh, Material::ShaderType mat)
switch (mat)
{
default:
case Material::SHADERTYPE_VEGETATION:
setTexture(mesh, 0, true, getShaderTypeName(mat));
setTexture(mesh, 1, false, getShaderTypeName(mat));
break;
case Material::SHADERTYPE_SOLID:
case Material::SHADERTYPE_ALPHA_TEST:
case Material::SHADERTYPE_SPHERE_MAP:
case Material::SHADERTYPE_SOLID_UNLIT:
case Material::SHADERTYPE_VEGETATION:
setTexture(mesh, 0, true, getShaderTypeName(mat));
setTexture(mesh, 1, false, getShaderTypeName(mat));
setTexture(mesh, 2, false, getShaderTypeName(mat));

View File

@ -129,7 +129,7 @@ class ListMatNormalMap : public MeshList<ListMatNormalMap, GLMesh *, core::matri
// ----------------------------------------------------------------------------
class ListMatGrass : public MeshList<ListMatGrass, GLMesh *, core::matrix4,
core::matrix4, core::vector3df>
core::matrix4, core::vector3df, core::vector2df>
{};
// ----------------------------------------------------------------------------

View File

@ -163,18 +163,6 @@ void VAOInstanceUtil<InstanceDataSingleTex>::SetVertexAttrib()
glVertexAttribDivisorARB(11, 1);
}
template<>
void VAOInstanceUtil<InstanceDataDualTex>::SetVertexAttrib()
{
SetVertexAttrib_impl();
glEnableVertexAttribArray(11);
glVertexAttribIPointer(11, 2, GL_UNSIGNED_INT, sizeof(InstanceDataDualTex), (GLvoid*)(9 * sizeof(float)));
glVertexAttribDivisorARB(11, 1);
glEnableVertexAttribArray(12);
glVertexAttribIPointer(12, 2, GL_UNSIGNED_INT, sizeof(InstanceDataDualTex), (GLvoid*)(9 * sizeof(float) + 2 * sizeof(unsigned)));
glVertexAttribDivisorARB(12, 1);
}
template<>
void VAOInstanceUtil<InstanceDataThreeTex>::SetVertexAttrib()
{
@ -235,11 +223,6 @@ void VAOManager::regenerateInstancedVAO()
if (!vbo[tp] || !ibo[tp])
continue;
GLuint vao = createVAO(vbo[tp], ibo[tp], tp);
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeDualTex]);
VAOInstanceUtil<InstanceDataDualTex>::SetVertexAttrib();
InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(tp, InstanceTypeDualTex)] = vao;
vao = createVAO(vbo[tp], ibo[tp], tp);
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeThreeTex]);
VAOInstanceUtil<InstanceDataThreeTex>::SetVertexAttrib();
InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(tp, InstanceTypeThreeTex)] = vao;

View File

@ -30,7 +30,6 @@ class RenderInfo;
enum InstanceType
{
InstanceTypeDualTex,
InstanceTypeThreeTex,
InstanceTypeFourTex,
InstanceTypeShadow,
@ -69,34 +68,6 @@ struct InstanceDataSingleTex
} __attribute__((packed));
#endif
struct InstanceDataDualTex
{
struct
{
float X;
float Y;
float Z;
} Origin;
struct
{
float X;
float Y;
float Z;
} Orientation;
struct
{
float X;
float Y;
float Z;
} Scale;
uint64_t Texture;
uint64_t SecondTexture;
#ifdef WIN32
};
#else
} __attribute__((packed));
#endif
struct InstanceDataThreeTex
{
struct