Make grass shader colorizable
This commit is contained in:
parent
31b6a0a4b1
commit
7d5f786da8
@ -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;
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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.);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
|
@ -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>
|
||||
{};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user