mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-24 06:58:46 +02:00
fix(track): seasonal and specgloss track materials blended at the joints
This commit is contained in:
@@ -756,6 +756,25 @@ material_manager::create_tinted( material_handle const Material, glm::vec3 const
|
||||
return tintedhandle;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
// the shaders a material is lit by which the blending shaders can light the same way, by the names they're fetched by, in the
|
||||
// order of the lighting they stand for (1 normalmap, 2 sunless, 3 shadowless)
|
||||
char const *const blend_normal_shaders[] = { "normalmap", "sunlessnormalmap", "shadowlessnormalmap" };
|
||||
char const *const blend_specgloss_shaders[] = { "normalmap_specgloss", "sunlessnormalmap_specgloss", "shadowlessnormalmap_specgloss" };
|
||||
int constexpr blend_specgloss { 4 }; // added to the lighting for a material with a specgloss map
|
||||
|
||||
std::string
|
||||
blend_shader( int const Lighting, bool const Grain ) {
|
||||
|
||||
std::string name { "trackblend" };
|
||||
if( Lighting & blend_specgloss ) { name += "_specgloss"; }
|
||||
else if( Lighting > 0 ) { name += "_normalmap"; }
|
||||
return ( Grain ? name + "_grain" : name );
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int
|
||||
material_manager::blend_lighting( material_handle const Material ) {
|
||||
|
||||
@@ -774,28 +793,29 @@ material_manager::blend_lighting( material_handle const Material ) {
|
||||
if( material.is_good
|
||||
&& material.shader
|
||||
&& material.texture_variants.empty()
|
||||
&& false == material.update_on_weather_change
|
||||
&& false == material.update_on_season_change
|
||||
// a tint takes the parameters the blending shader keeps its lighting in
|
||||
&& false == ( material.params[ 2 ].w < 0.f )
|
||||
&& has( "diffuse" ) ) {
|
||||
try {
|
||||
auto lighting { -1 };
|
||||
auto const lit_as = [&]( char const *const ( &Shaders )[ 3 ], int const Extra ) {
|
||||
for( int index = 0; index < 3; ++index ) {
|
||||
if( material.shader == GfxRenderer->Fetch_Shader( Shaders[ index ] ) ) {
|
||||
lighting = index + 1 + Extra;
|
||||
}
|
||||
} };
|
||||
if( conf.size() == 1 ) {
|
||||
lighting = 0;
|
||||
}
|
||||
else if( conf.size() == 2 && has( "normalmap" ) ) {
|
||||
// the shaders lit as the blending one can be, by the names they're fetched by
|
||||
char const *const shaders[] = { "normalmap", "sunlessnormalmap", "shadowlessnormalmap" };
|
||||
for( int index = 0; index < 3; ++index ) {
|
||||
if( material.shader == GfxRenderer->Fetch_Shader( shaders[ index ] ) ) {
|
||||
lighting = index + 1;
|
||||
}
|
||||
}
|
||||
lit_as( blend_normal_shaders, 0 );
|
||||
}
|
||||
else if( conf.size() == 3 && has( "normalmap" ) && has( "specgloss" ) ) {
|
||||
lit_as( blend_specgloss_shaders, blend_specgloss );
|
||||
}
|
||||
if( lighting >= 0 ) {
|
||||
// the parameters of the material go to the blending one as they are, so they have to be in the same places in both
|
||||
auto const blend { GfxRenderer->Fetch_Shader( lighting > 0 ? "trackblend_normalmap" : "trackblend" ) };
|
||||
auto const blend { GfxRenderer->Fetch_Shader( blend_shader( lighting, false ) ) };
|
||||
auto const fits { std::all_of(
|
||||
std::begin( material.shader->param_conf ), std::end( material.shader->param_conf ),
|
||||
[&]( auto const &Entry ) {
|
||||
@@ -822,7 +842,6 @@ material_manager::blend_lighting( material_handle const Material ) {
|
||||
+ ( material.is_good ? "" : " not good;" )
|
||||
+ ( material.shader ? " a shader with the textures " + textures + ";" : " no shader;" )
|
||||
+ ( material.texture_variants.empty() ? "" : " texture variants;" )
|
||||
+ ( material.update_on_weather_change || material.update_on_season_change ? " changes with the weather or seasons;" : "" )
|
||||
+ ( material.params[ 2 ].w < 0.f ? " tinted;" : "" ) );
|
||||
}
|
||||
m_blendables.emplace( Material, result );
|
||||
@@ -835,16 +854,15 @@ material_manager::blendable( material_handle const Material ) {
|
||||
return blend_lighting( Material ) >= 0;
|
||||
}
|
||||
|
||||
material_handle
|
||||
material_manager::create_blend( material_handle const Material, std::array<material_handle, 3> const &Others, bool const Grain ) {
|
||||
bool
|
||||
material_manager::build_blend( blend_key const &Key, opengl_material &Blend ) {
|
||||
|
||||
auto const lighting { blend_lighting( Material ) };
|
||||
auto const material { std::get<0>( Key ) };
|
||||
std::array<material_handle, 3> const others { std::get<1>( Key ), std::get<2>( Key ), std::get<3>( Key ) };
|
||||
auto const grain { std::get<4>( Key ) };
|
||||
auto const lighting { blend_lighting( material ) };
|
||||
if( lighting < 0 ) {
|
||||
return Material;
|
||||
}
|
||||
auto const key { std::make_tuple( Material, Others[ 0 ], Others[ 1 ], Others[ 2 ], Grain ) };
|
||||
if( auto const lookup { m_blends.find( key ) }; lookup != m_blends.end() ) {
|
||||
return lookup->second;
|
||||
return false;
|
||||
}
|
||||
auto const texture_of = [&]( material_handle const Source, char const *Name ) -> texture_handle {
|
||||
if( false == blendable( Source ) ) {
|
||||
@@ -854,52 +872,98 @@ material_manager::create_blend( material_handle const Material, std::array<mater
|
||||
auto const found { source.shader->texture_conf.find( Name ) };
|
||||
return ( found != source.shader->texture_conf.end() ? source.textures[ found->second.id ] : null_handle );
|
||||
};
|
||||
// the slots of the textures in the blending shaders (mat_trackblend*.frag): with a specgloss map there's room for the textures
|
||||
// of two ends alone, p1 and p2, which is all the rails of a plain track have
|
||||
auto const normals { lighting > 0 };
|
||||
auto blend { variant_of( m_materials[ Material ], Grain ? ":blendgrain" : ":blend" ) };
|
||||
auto result { Material };
|
||||
auto const specgloss { ( lighting & blend_specgloss ) != 0 };
|
||||
int const diffuseslots[] = { 0, 1, 2, 3 };
|
||||
int const normalslots[] = { ( specgloss ? 3 : 4 ), ( specgloss ? 4 : 5 ), ( specgloss ? 5 : 6 ), 7 };
|
||||
auto const ends { specgloss ? 2 : 3 };
|
||||
try {
|
||||
blend.shader = GfxRenderer->Fetch_Shader( std::string { "trackblend" } + ( normals ? "_normalmap" : "" ) + ( Grain ? "_grain" : "" ) );
|
||||
blend.texture_variants.clear();
|
||||
blend.textures.fill( null_handle );
|
||||
auto const owndiffuse { texture_of( Material, "diffuse" ) };
|
||||
auto const ownnormal { texture_of( Material, "normalmap" ) };
|
||||
blend.textures[ 0 ] = owndiffuse;
|
||||
Blend = variant_of( m_materials[ material ], grain ? ":blendgrain" : ":blend" );
|
||||
Blend.shader = GfxRenderer->Fetch_Shader( blend_shader( lighting, grain ) );
|
||||
Blend.texture_variants.clear();
|
||||
Blend.textures.fill( null_handle );
|
||||
auto const owndiffuse { texture_of( material, "diffuse" ) };
|
||||
auto const ownnormal { texture_of( material, "normalmap" ) };
|
||||
Blend.textures[ diffuseslots[ 0 ] ] = owndiffuse;
|
||||
if( normals ) {
|
||||
blend.textures[ 4 ] = ownnormal;
|
||||
Blend.textures[ normalslots[ 0 ] ] = ownnormal;
|
||||
}
|
||||
for( std::size_t other = 0; other < Others.size(); ++other ) {
|
||||
if( specgloss ) {
|
||||
Blend.textures[ 6 ] = texture_of( material, "specgloss" );
|
||||
}
|
||||
for( int end = 0; end < ends; ++end ) {
|
||||
// the slots of the ends nothing is blended at take the own textures, the shader samples them only with a weight; a
|
||||
// material without a normal map blended into one with it takes its normal map
|
||||
auto const diffuse { texture_of( Others[ other ], "diffuse" ) };
|
||||
blend.textures[ 1 + other ] = ( diffuse != null_handle ? diffuse : owndiffuse );
|
||||
auto const diffuse { texture_of( others[ end ], "diffuse" ) };
|
||||
Blend.textures[ diffuseslots[ 1 + end ] ] = ( diffuse != null_handle ? diffuse : owndiffuse );
|
||||
if( normals ) {
|
||||
auto const normal { texture_of( Others[ other ], "normalmap" ) };
|
||||
blend.textures[ 5 + other ] = ( normal != null_handle ? normal : ownnormal );
|
||||
auto const normal { texture_of( others[ end ], "normalmap" ) };
|
||||
Blend.textures[ normalslots[ 1 + end ] ] = ( normal != null_handle ? normal : ownnormal );
|
||||
}
|
||||
}
|
||||
// lit as the shader of the material: normalmap, sunlessnormalmap or shadowlessnormalmap
|
||||
blend.params[ 2 ].x = static_cast<float>( lighting );
|
||||
// lit as the shader of the material: 0 mat_default, 1 normalmap, 2 sunless, 3 shadowless
|
||||
Blend.params[ 2 ].x = static_cast<float>( lighting & 3 );
|
||||
// the parameters taken from the bindings again, by the shader
|
||||
blend.params_state.clear();
|
||||
blend.finalize( true );
|
||||
if( blend.is_good ) {
|
||||
result = static_cast<material_handle>( m_materials.size() );
|
||||
m_materials.emplace_back( std::move( blend ) );
|
||||
}
|
||||
Blend.params_state.clear();
|
||||
Blend.finalize( true );
|
||||
return Blend.is_good;
|
||||
}
|
||||
catch( gl::shader_exception const &e ) {
|
||||
ErrorLog( "invalid shader: " + std::string( e.what() ) );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
material_handle
|
||||
material_manager::create_blend( material_handle const Material, std::array<material_handle, 3> const &Others, bool const Grain ) {
|
||||
|
||||
if( false == blendable( Material ) ) {
|
||||
return Material;
|
||||
}
|
||||
blend_key const key { Material, Others[ 0 ], Others[ 1 ], Others[ 2 ], Grain };
|
||||
if( auto const lookup { m_blends.find( key ) }; lookup != m_blends.end() ) {
|
||||
return lookup->second;
|
||||
}
|
||||
auto result { Material };
|
||||
opengl_material blend;
|
||||
if( build_blend( key, blend ) ) {
|
||||
result = static_cast<material_handle>( m_materials.size() );
|
||||
m_materials.emplace_back( std::move( blend ) );
|
||||
m_blendsources.emplace_back( result, key );
|
||||
}
|
||||
m_blends.emplace( key, result );
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
material_manager::rebuild_blends() {
|
||||
|
||||
if( m_blendsources.empty() ) {
|
||||
return;
|
||||
}
|
||||
// the materials blended took the textures of another season or weather, the blending ones take them anew in their places
|
||||
m_blendables.clear();
|
||||
for( auto const &[ handle, key ] : m_blendsources ) {
|
||||
opengl_material blend;
|
||||
if( build_blend( key, blend ) ) {
|
||||
m_materials[ handle ] = std::move( blend );
|
||||
}
|
||||
else {
|
||||
// can't be blended any more: drawn as the material of the track itself, the weights of its vertices unused
|
||||
m_materials[ handle ] = variant_of( m_materials[ std::get<0>( key ) ], ":blend" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
material_manager::on_weather_change() {
|
||||
|
||||
for( auto &material : m_materials ) {
|
||||
if( material.update_on_weather_change ) { material.update(); }
|
||||
}
|
||||
rebuild_blends();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -908,6 +972,7 @@ material_manager::on_season_change() {
|
||||
for( auto &material : m_materials ) {
|
||||
if( material.update_on_season_change ) { material.update(); }
|
||||
}
|
||||
rebuild_blends();
|
||||
}
|
||||
|
||||
// checks whether specified material is in the material bank. returns handle to the material, or a null handle
|
||||
|
||||
@@ -152,8 +152,9 @@ public:
|
||||
// itself where it can't be blended
|
||||
material_handle
|
||||
create_blend( material_handle const Material, std::array<material_handle, 3> const &Others, bool const Grain );
|
||||
// whether the material can be blended so: a diffuse texture lit as mat_default, or with a normal map lit as normalmap,
|
||||
// sunlessnormalmap or shadowlessnormalmap; not changing with the weather and seasons, not tinted
|
||||
// whether the material can be blended so: a diffuse texture lit as mat_default, or with a normal map (and a specgloss map)
|
||||
// lit as normalmap, sunlessnormalmap or shadowlessnormalmap (and their _specgloss); not tinted. the blending materials take the
|
||||
// textures of another season or weather with the materials they blend
|
||||
bool
|
||||
blendable( material_handle const Material );
|
||||
opengl_material const &
|
||||
@@ -171,14 +172,22 @@ private:
|
||||
// types
|
||||
typedef std::vector<opengl_material> material_sequence;
|
||||
typedef std::unordered_map<std::string, std::size_t> index_map;
|
||||
// a blending material: the material of the track, those it blends into at the ends, whether in grains
|
||||
using blend_key = std::tuple<material_handle, material_handle, material_handle, material_handle, bool>;
|
||||
// methods:
|
||||
// checks whether specified texture is in the texture bank. returns texture id, or npos.
|
||||
material_handle
|
||||
find_in_databank( std::string const &Materialname ) const;
|
||||
// how the material is lit, of the materials a track blends: 0 as mat_default, 1 normalmap, 2 sunlessnormalmap,
|
||||
// 3 shadowlessnormalmap; -1 where it can't be blended
|
||||
// 3 shadowlessnormalmap, 4 more for their _specgloss; -1 where it can't be blended
|
||||
int
|
||||
blend_lighting( material_handle const Material );
|
||||
// the blending material made of the current textures of the materials. returns: false when they can't be blended
|
||||
bool
|
||||
build_blend( blend_key const &Key, opengl_material &Blend );
|
||||
// the blending materials made again in their places, after the materials changed their textures
|
||||
void
|
||||
rebuild_blends();
|
||||
public:
|
||||
// checks whether specified file exists. returns name of the located file, or empty string.
|
||||
static std::pair<std::string, std::string>
|
||||
@@ -190,7 +199,8 @@ private:
|
||||
index_map m_materialmappings;
|
||||
std::unordered_map<material_handle, material_handle> m_mattes;
|
||||
std::map<std::tuple<material_handle, float, float, float>, material_handle> m_tints;
|
||||
std::map<std::tuple<material_handle, material_handle, material_handle, material_handle, bool>, material_handle> m_blends;
|
||||
std::map<blend_key, material_handle> m_blends;
|
||||
std::vector<std::pair<material_handle, blend_key>> m_blendsources;
|
||||
std::unordered_map<material_handle, int> m_blendables;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,2 +1,10 @@
|
||||
// the rails of a track faded into those of the tracks joined at its ends, see trackblend.glsl
|
||||
#texture (diffuse, 0, sRGB_A)
|
||||
uniform sampler2D diffuse;
|
||||
#texture (diffuse1, 1, sRGB_A)
|
||||
uniform sampler2D diffuse1;
|
||||
#texture (diffuse2, 2, sRGB_A)
|
||||
uniform sampler2D diffuse2;
|
||||
#texture (diffuse3, 3, sRGB_A)
|
||||
uniform sampler2D diffuse3;
|
||||
#include <trackblend.glsl>
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
// the ballast of a track mixed in grains into that of the tracks joined at its ends, see trackblend.glsl
|
||||
#define TRACKBLEND_GRAIN 1
|
||||
#texture (diffuse, 0, sRGB_A)
|
||||
uniform sampler2D diffuse;
|
||||
#texture (diffuse1, 1, sRGB_A)
|
||||
uniform sampler2D diffuse1;
|
||||
#texture (diffuse2, 2, sRGB_A)
|
||||
uniform sampler2D diffuse2;
|
||||
#texture (diffuse3, 3, sRGB_A)
|
||||
uniform sampler2D diffuse3;
|
||||
#include <trackblend.glsl>
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
// the rails of a track of a normal mapped material faded into those of the tracks joined at its ends, see trackblend.glsl
|
||||
#define TRACKBLEND_NORMALMAP 1
|
||||
#texture (diffuse, 0, sRGB_A)
|
||||
uniform sampler2D diffuse;
|
||||
#texture (diffuse1, 1, sRGB_A)
|
||||
uniform sampler2D diffuse1;
|
||||
#texture (diffuse2, 2, sRGB_A)
|
||||
uniform sampler2D diffuse2;
|
||||
#texture (diffuse3, 3, sRGB_A)
|
||||
uniform sampler2D diffuse3;
|
||||
#texture (normalmap, 4, RGBA)
|
||||
uniform sampler2D normalmap;
|
||||
#texture (normalmap1, 5, RGBA)
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
// the ballast of a track of a normal mapped material mixed in grains into that of the tracks joined at its ends, see trackblend.glsl
|
||||
#define TRACKBLEND_GRAIN 1
|
||||
#define TRACKBLEND_NORMALMAP 1
|
||||
#texture (diffuse, 0, sRGB_A)
|
||||
uniform sampler2D diffuse;
|
||||
#texture (diffuse1, 1, sRGB_A)
|
||||
uniform sampler2D diffuse1;
|
||||
#texture (diffuse2, 2, sRGB_A)
|
||||
uniform sampler2D diffuse2;
|
||||
#texture (diffuse3, 3, sRGB_A)
|
||||
uniform sampler2D diffuse3;
|
||||
#texture (normalmap, 4, RGBA)
|
||||
uniform sampler2D normalmap;
|
||||
#texture (normalmap1, 5, RGBA)
|
||||
|
||||
18
shaders/mat_trackblend_specgloss.frag
Normal file
18
shaders/mat_trackblend_specgloss.frag
Normal file
@@ -0,0 +1,18 @@
|
||||
// the rails of a track of a material with normal and specgloss maps faded into those of the tracks joined at its ends, see trackblend.glsl
|
||||
#define TRACKBLEND_NORMALMAP 1
|
||||
#define TRACKBLEND_SPECGLOSS 1
|
||||
#texture (diffuse, 0, sRGB_A)
|
||||
uniform sampler2D diffuse;
|
||||
#texture (diffuse1, 1, sRGB_A)
|
||||
uniform sampler2D diffuse1;
|
||||
#texture (diffuse2, 2, sRGB_A)
|
||||
uniform sampler2D diffuse2;
|
||||
#texture (normalmap, 3, RGBA)
|
||||
uniform sampler2D normalmap;
|
||||
#texture (normalmap1, 4, RGBA)
|
||||
uniform sampler2D normalmap1;
|
||||
#texture (normalmap2, 5, RGBA)
|
||||
uniform sampler2D normalmap2;
|
||||
#texture (specgloss, 6, RGBA)
|
||||
uniform sampler2D specgloss;
|
||||
#include <trackblend.glsl>
|
||||
19
shaders/mat_trackblend_specgloss_grain.frag
Normal file
19
shaders/mat_trackblend_specgloss_grain.frag
Normal file
@@ -0,0 +1,19 @@
|
||||
// the ballast of a track of a material with normal and specgloss maps mixed in grains into that of the tracks joined at its ends, see trackblend.glsl
|
||||
#define TRACKBLEND_GRAIN 1
|
||||
#define TRACKBLEND_NORMALMAP 1
|
||||
#define TRACKBLEND_SPECGLOSS 1
|
||||
#texture (diffuse, 0, sRGB_A)
|
||||
uniform sampler2D diffuse;
|
||||
#texture (diffuse1, 1, sRGB_A)
|
||||
uniform sampler2D diffuse1;
|
||||
#texture (diffuse2, 2, sRGB_A)
|
||||
uniform sampler2D diffuse2;
|
||||
#texture (normalmap, 3, RGBA)
|
||||
uniform sampler2D normalmap;
|
||||
#texture (normalmap1, 4, RGBA)
|
||||
uniform sampler2D normalmap1;
|
||||
#texture (normalmap2, 5, RGBA)
|
||||
uniform sampler2D normalmap2;
|
||||
#texture (specgloss, 6, RGBA)
|
||||
uniform sampler2D specgloss;
|
||||
#include <trackblend.glsl>
|
||||
@@ -1,12 +1,15 @@
|
||||
// a track drawn with the textures of the tracks joined at its ends blended in near them (world/TrackBlend.h): the weights of the
|
||||
// tracks joined at the ends p1, p2 and p4 of a switch in UserData.yzw, their textures in diffuse1..3, lit as mat_default.
|
||||
// TRACKBLEND_GRAIN: the others come in as grains, as the stones of two ballasts would mix, rather than faded in.
|
||||
// TRACKBLEND_NORMALMAP: with the normal maps of the four in normalmap..normalmap3 (declared by the including shader), lit as
|
||||
// the shader of the material of the track: param[2].x 1 normalmap, 2 sunlessnormalmap, 3 shadowlessnormalmap
|
||||
// tracks joined at the ends p1, p2 and p4 of a switch in UserData.yzw, their textures in diffuse1..3, normalmap1..3. the
|
||||
// including shader declares the textures and sets:
|
||||
// TRACKBLEND_GRAIN the others come in as grains, as the stones of two ballasts would mix, rather than faded in
|
||||
// TRACKBLEND_NORMALMAP with the normal maps of the four, lit as the shader of the material of the track: param[2].x 0 as
|
||||
// mat_default, 1 normalmap, 2 sunlessnormalmap, 3 shadowlessnormalmap
|
||||
// TRACKBLEND_SPECGLOSS the specgloss map of the track itself as well, the textures of the ends p1 and p2 alone (no room
|
||||
// for a third set of them)
|
||||
in vec3 f_normal;
|
||||
in vec2 f_coord;
|
||||
in vec4 f_pos;
|
||||
#if TRACKBLEND_NORMALMAP
|
||||
#ifdef TRACKBLEND_NORMALMAP
|
||||
in mat3 f_tbn;
|
||||
#endif
|
||||
|
||||
@@ -22,15 +25,6 @@ in vec4 f_clip_future_pos;
|
||||
#param (glossiness, 1, 3, 1, glossiness)
|
||||
#param (blendlighting, 2, 0, 1, zero)
|
||||
|
||||
#texture (diffuse, 0, sRGB_A)
|
||||
uniform sampler2D diffuse;
|
||||
#texture (diffuse1, 1, sRGB_A)
|
||||
uniform sampler2D diffuse1;
|
||||
#texture (diffuse2, 2, sRGB_A)
|
||||
uniform sampler2D diffuse2;
|
||||
#texture (diffuse3, 3, sRGB_A)
|
||||
uniform sampler2D diffuse3;
|
||||
|
||||
layout(location = 0) out vec4 out_color;
|
||||
#if MOTIONBLUR_ENABLED
|
||||
layout(location = 1) out vec4 out_motion;
|
||||
@@ -40,7 +34,7 @@ layout(location = 1) out vec4 out_motion;
|
||||
#include <apply_fog.glsl>
|
||||
#include <tonemapping.glsl>
|
||||
|
||||
#if TRACKBLEND_GRAIN
|
||||
#ifdef TRACKBLEND_GRAIN
|
||||
// grains per repeat of the texture: a ballast texture repeats every few metres, a grain is a handful of its stones
|
||||
const float GRAIN_CELLS = 28.0;
|
||||
|
||||
@@ -85,7 +79,11 @@ float grain_value(vec2 p)
|
||||
|
||||
void main()
|
||||
{
|
||||
#ifdef TRACKBLEND_SPECGLOSS
|
||||
vec3 weights = clamp(vec3(UserData.yz, 0.0), 0.0, 1.0);
|
||||
#else
|
||||
vec3 weights = clamp(UserData.yzw, 0.0, 1.0);
|
||||
#endif
|
||||
float total = weights.x + weights.y + weights.z;
|
||||
if (total > 1.0)
|
||||
{
|
||||
@@ -95,19 +93,19 @@ void main()
|
||||
// the gradients are taken outside the branches the textures are sampled in
|
||||
vec2 dx = dFdx(f_coord);
|
||||
vec2 dy = dFdy(f_coord);
|
||||
#if TRACKBLEND_GRAIN
|
||||
#ifdef TRACKBLEND_GRAIN
|
||||
vec2 grainpos = f_coord * GRAIN_CELLS;
|
||||
// grains smaller than a pixel would shimmer, there the textures fade into each other instead
|
||||
float footprint = max(length(dx), length(dy)) * GRAIN_CELLS;
|
||||
float grained = 1.0 - smoothstep(0.35, 0.9, footprint);
|
||||
#endif
|
||||
vec4 tex_color = textureGrad(diffuse, f_coord, dx, dy);
|
||||
#if TRACKBLEND_NORMALMAP
|
||||
#ifdef TRACKBLEND_NORMALMAP
|
||||
vec4 tex_normal = textureGrad(normalmap, f_coord, dx, dy);
|
||||
#endif
|
||||
if (total > 0.0)
|
||||
{
|
||||
#if TRACKBLEND_GRAIN
|
||||
#ifdef TRACKBLEND_GRAIN
|
||||
// the grain is of the track joined at the end whose share its value falls in, of the track itself past them
|
||||
float pick = grain_value(grainpos);
|
||||
float first = weights.x;
|
||||
@@ -117,32 +115,34 @@ void main()
|
||||
total = weights.x + weights.y + weights.z;
|
||||
#endif
|
||||
vec4 blended = tex_color * (1.0 - total);
|
||||
#if TRACKBLEND_NORMALMAP
|
||||
#ifdef TRACKBLEND_NORMALMAP
|
||||
vec4 blendednormal = tex_normal * (1.0 - total);
|
||||
#endif
|
||||
if (weights.x > 0.0)
|
||||
{
|
||||
blended += textureGrad(diffuse1, f_coord, dx, dy) * weights.x;
|
||||
#if TRACKBLEND_NORMALMAP
|
||||
#ifdef TRACKBLEND_NORMALMAP
|
||||
blendednormal += textureGrad(normalmap1, f_coord, dx, dy) * weights.x;
|
||||
#endif
|
||||
}
|
||||
if (weights.y > 0.0)
|
||||
{
|
||||
blended += textureGrad(diffuse2, f_coord, dx, dy) * weights.y;
|
||||
#if TRACKBLEND_NORMALMAP
|
||||
#ifdef TRACKBLEND_NORMALMAP
|
||||
blendednormal += textureGrad(normalmap2, f_coord, dx, dy) * weights.y;
|
||||
#endif
|
||||
}
|
||||
#ifndef TRACKBLEND_SPECGLOSS
|
||||
if (weights.z > 0.0)
|
||||
{
|
||||
blended += textureGrad(diffuse3, f_coord, dx, dy) * weights.z;
|
||||
#if TRACKBLEND_NORMALMAP
|
||||
#ifdef TRACKBLEND_NORMALMAP
|
||||
blendednormal += textureGrad(normalmap3, f_coord, dx, dy) * weights.z;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
tex_color = blended;
|
||||
#if TRACKBLEND_NORMALMAP
|
||||
#ifdef TRACKBLEND_NORMALMAP
|
||||
tex_normal = blendednormal;
|
||||
#endif
|
||||
}
|
||||
@@ -152,14 +152,21 @@ void main()
|
||||
discard;
|
||||
|
||||
vec3 fragcolor = ambient;
|
||||
#if TRACKBLEND_NORMALMAP
|
||||
#ifdef TRACKBLEND_NORMALMAP
|
||||
vec3 normal;
|
||||
normal.xy = (tex_normal.rg * 2.0 - 1.0);
|
||||
normal.z = sqrt(1.0 - clamp((dot(normal.xy, normal.xy)), 0.0, 1.0));
|
||||
vec3 fragnormal = normalize(f_tbn * normalize(normal.xyz));
|
||||
float reflectivity = param[1].z * tex_normal.a;
|
||||
#ifdef TRACKBLEND_SPECGLOSS
|
||||
vec4 tex_specgloss = textureGrad(specgloss, f_coord, dx, dy);
|
||||
float specularity = tex_specgloss.r;
|
||||
glossiness = tex_specgloss.g * abs(param[1].w);
|
||||
metalic = tex_specgloss.b;
|
||||
#else
|
||||
float specularity = (tex_color.r + tex_color.g + tex_color.b) * 0.5;
|
||||
legacy_gloss();
|
||||
#endif
|
||||
int lighting = int(param[2].x + 0.5);
|
||||
if (lighting == 2)
|
||||
fragcolor = apply_lights_sunless(fragcolor, fragnormal, tex_color.rgb, reflectivity, specularity, shadow_tone);
|
||||
|
||||
Reference in New Issue
Block a user