Add the final touch for the dirt shader

This commit is contained in:
samuncle 2018-09-09 23:18:32 +02:00
parent 7478ed6ad4
commit 0d56de5957
6 changed files with 69 additions and 10 deletions

View File

@ -13,14 +13,15 @@ layout(location = 1) out vec4 o_normal_color;
#stk_include "utils/rgb_conversion.frag"
#stk_include "utils/sp_texture_sampling.frag"
uniform sampler2D g_kart_dirt;
uniform sampler2D g_dirt_albedo;
uniform sampler2D g_dirt_normal;
uniform float dirt_factor;
void main()
{
// Triplanar detail map
vec2 xyuv = vec2(world_position.x, world_position.y);
vec3 dirt = texture(g_kart_dirt, uv * 32).rgb;
vec3 dirt = texture(g_dirt_albedo, uv * 4).rgb;
vec4 col = sampleTextureLayer0(uv);
if (hue_change > 0.0)
@ -41,19 +42,28 @@ void main()
}
float dirtMask = sampleTextureLayer4(uv).r;
dirtMask *= dirtMask;
float nitroMask = sampleTextureLayer4(uv).g;
//dirtMask *= dirtMask;
// Dirt factor
dirtMask = 1.0 - dirtMask;
dirtMask *= dirt_factor;
dirtMask *= clamp(dirt_factor, 0.0, 1.0);
nitroMask *= clamp(dirt_factor, 0.0, 1.0);
vec3 final_color = col.xyz * color.xyz;
final_color = mix(final_color, dirt, dirtMask);
final_color = mix(final_color, vec3(0, 0.415, 0.639), nitroMask);
#if defined(Advanced_Lighting_Enabled)
vec4 layer_2 = sampleTextureLayer2(uv);
vec4 layer_3 = sampleTextureLayer3(uv);
// Part emitting light
layer_2.z = mix(layer_2.z, 1.0, nitroMask);
o_diffuse_color = vec4(final_color, layer_2.z);
// Dirt part should not be glossy
layer_2.r = mix(layer_2.r, 0.0, dirtMask);
// Mix the normal map for the dirt
vec4 dirt_nor = texture(g_dirt_normal, uv * 4);
layer_3 = mix(layer_3, dirt_nor, dirtMask);
vec3 tangent_space_normal = 2.0 * layer_3.xyz - 1.0;
vec3 frag_tangent = normalize(tangent);

View File

@ -4,8 +4,10 @@
fragment-shader="sp_kart_dirt.frag"
skinned-mesh-shader="sp_skinning.vert">
<prefilled-textures>
<prefilled-texture name="g_kart_dirt" file="dirt.jpg"
<prefilled-texture name="g_dirt_albedo" file="gfx_kartDirt_a_Albedo.png"
srgb="Y" sampler="trilinear"/>
<prefilled-texture name="g_dirt_normal" file="gfx_kartDirt_a_Normal.png"
sampler="trilinear"/>
</prefilled-textures>
</first-pass>
<shadow-pass vertex-shader="sp_shadow.vert"

View File

@ -65,14 +65,16 @@ SPShaderManager::SPShaderManager()
{ "dirtFactorUniformAssigner", [](SPUniformAssigner* ua)
{
AbstractKart* k = NULL;
if (Camera::getNumCameras() > 1)
if (Camera::getNumCameras() > 0)
{
Camera* camera = Camera::getCamera(0);
k = camera->getKart();
if (Camera::getActiveCamera() != NULL)
{
k = Camera::getActiveCamera()->getKart();
}
}
if (k && k->isOnGround())
if (k)
{
ua->setValue(2.0f);
ua->setValue(k->getDirtFactor());
}
else
{

View File

@ -356,6 +356,9 @@ public:
/** True if the wheels are touching the ground. */
virtual bool isOnGround() const = 0;
// ------------------------------------------------------------------------
/** Returns the dirt factor (how dirty the kart is). */
virtual float getDirtFactor() const = 0;
// ------------------------------------------------------------------------
/** Returns the slipstream object of this kart. */
virtual const SlipStream* getSlipstream() const = 0;
// ------------------------------------------------------------------------

View File

@ -377,6 +377,8 @@ void Kart::reset()
m_view_blocked_by_plunger = 0;
m_has_caught_nolok_bubblegum = false;
m_is_jumping = false;
m_dirt_factor = 0.0f;
m_dirt_reset_counter = 0.0f;
for (int i=0;i<m_xyz_history_size;i++)
{
@ -1164,6 +1166,14 @@ bool Kart::isOnGround() const
&& !getKartAnimation());
} // isOnGround
//-----------------------------------------------------------------------------
/** The kart as a dirt factor (if the player skids and go in dirty places)
*/
float Kart::getDirtFactor() const
{
return m_dirt_factor;
} // getDirtFactor
//-----------------------------------------------------------------------------
/** The kart is near the ground, but not necessarily on it (small jumps). This
* is used to determine when to stop flying.
@ -1890,6 +1900,29 @@ void Kart::handleMaterialGFX(float dt)
{
const Material *material = getMaterial();
if (m_skidding->isSkidding())
{
m_dirt_factor += 0.001f;
if (m_dirt_factor > 1.0f)
{
m_dirt_factor = 1.0f;
}
m_dirt_reset_counter = 2.0f;
}
else
{
m_dirt_reset_counter -= 0.01f;
if (m_dirt_reset_counter < 0.0f)
{
m_dirt_reset_counter = 0.0f;
m_dirt_factor -= 0.002f;
if (m_dirt_factor < 0.0f)
{
m_dirt_factor = 0.0f;
}
}
}
// First test: give the terrain effect, if the kart is
// on top of a surface (i.e. not falling), actually touching
// something with the wheels, and the material has not the

View File

@ -166,6 +166,12 @@ protected:
* the kart is squashed. */
float m_squash_time;
/** How dirty the kart is, 0 = clean */
float m_dirt_factor;
/** Counter to reset the dirt */
float m_dirt_reset_counter;
/** Current leaning of the kart. */
float m_current_lean;
@ -453,6 +459,9 @@ public:
/** True if the wheels are touching the ground. */
virtual bool isOnGround() const OVERRIDE;
// ------------------------------------------------------------------------
/** Returns the dirt factor (how dirty the kart is). */
virtual float getDirtFactor() const OVERRIDE;
// ------------------------------------------------------------------------
/** Returns true if the kart is close to the ground, used to dis/enable
* the upright constraint to allow for more realistic explosions. */
bool isNearGround() const;