mirror of
https://github.com/minetest/minetest.git
synced 2024-11-27 01:53:45 +01:00
Add texture bumpmapping feature.
This commit is contained in:
parent
b850f0f038
commit
3f6f327cb9
1
client/shaders/bumpmaps_liquids/base.txt
Normal file
1
client/shaders/bumpmaps_liquids/base.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
trans_alphach
|
47
client/shaders/bumpmaps_liquids/opengl_fragment.glsl
Normal file
47
client/shaders/bumpmaps_liquids/opengl_fragment.glsl
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
|
||||||
|
uniform sampler2D myTexture;
|
||||||
|
uniform sampler2D normalTexture;
|
||||||
|
|
||||||
|
uniform vec4 skyBgColor;
|
||||||
|
uniform float fogDistance;
|
||||||
|
|
||||||
|
varying vec3 vPosition;
|
||||||
|
|
||||||
|
varying vec3 viewVec;
|
||||||
|
|
||||||
|
void main (void)
|
||||||
|
{
|
||||||
|
vec4 col = texture2D(myTexture, vec2(gl_TexCoord[0]));
|
||||||
|
float alpha = col.a;
|
||||||
|
vec2 uv = gl_TexCoord[0].st;
|
||||||
|
vec4 base = texture2D(myTexture, uv);
|
||||||
|
vec4 final_color = vec4(0.2, 0.2, 0.2, 1.0) * base;
|
||||||
|
vec3 vVec = normalize(viewVec);
|
||||||
|
vec3 bump = normalize(texture2D(normalTexture, uv).xyz * 2.0 - 1.0);
|
||||||
|
vec3 R = reflect(-vVec, bump);
|
||||||
|
vec3 lVec = normalize(vec3(0.0, -0.4, 0.5));
|
||||||
|
float diffuse = max(dot(lVec, bump), 0.0);
|
||||||
|
|
||||||
|
vec3 color = diffuse * texture2D(myTexture, gl_TexCoord[0].st).rgb;
|
||||||
|
|
||||||
|
|
||||||
|
float specular = pow(clamp(dot(R, lVec), 0.0, 1.0),1.0);
|
||||||
|
vec4 vSpecular = 0.2*specular * diffuse;
|
||||||
|
color += vSpecular;
|
||||||
|
|
||||||
|
|
||||||
|
col = vec4(color.r, color.g, color.b, alpha);
|
||||||
|
col *= gl_Color;
|
||||||
|
col = col * col; // SRGB -> Linear
|
||||||
|
col *= 1.8;
|
||||||
|
col.r = 1.0 - exp(1.0 - col.r) / exp(1.0);
|
||||||
|
col.g = 1.0 - exp(1.0 - col.g) / exp(1.0);
|
||||||
|
col.b = 1.0 - exp(1.0 - col.b) / exp(1.0);
|
||||||
|
col = sqrt(col); // Linear -> SRGB
|
||||||
|
if(fogDistance != 0.0){
|
||||||
|
float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0));
|
||||||
|
alpha = mix(alpha, 0.0, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
gl_FragColor = vec4(col.r, col.g, col.b, alpha);
|
||||||
|
}
|
98
client/shaders/bumpmaps_liquids/opengl_vertex.glsl
Normal file
98
client/shaders/bumpmaps_liquids/opengl_vertex.glsl
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
|
||||||
|
uniform mat4 mWorldViewProj;
|
||||||
|
uniform mat4 mInvWorld;
|
||||||
|
uniform mat4 mTransWorld;
|
||||||
|
uniform float dayNightRatio;
|
||||||
|
|
||||||
|
varying vec3 vPosition;
|
||||||
|
varying vec3 viewVec;
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
gl_Position = mWorldViewProj * gl_Vertex;
|
||||||
|
|
||||||
|
vPosition = (mWorldViewProj * gl_Vertex).xyz;
|
||||||
|
|
||||||
|
vec3 tangent;
|
||||||
|
vec3 binormal;
|
||||||
|
|
||||||
|
vec3 c1 = cross( gl_Normal, vec3(0.0, 0.0, 1.0) );
|
||||||
|
vec3 c2 = cross( gl_Normal, vec3(0.0, 1.0, 0.0) );
|
||||||
|
|
||||||
|
if( length(c1)>length(c2) )
|
||||||
|
{
|
||||||
|
tangent = c1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tangent = c2;
|
||||||
|
}
|
||||||
|
|
||||||
|
tangent = normalize(tangent);
|
||||||
|
|
||||||
|
//binormal = cross(gl_Normal, tangent);
|
||||||
|
//binormal = normalize(binormal);
|
||||||
|
|
||||||
|
vec4 color;
|
||||||
|
//color = vec4(1.0, 1.0, 1.0, 1.0);
|
||||||
|
|
||||||
|
float day = gl_Color.r;
|
||||||
|
float night = gl_Color.g;
|
||||||
|
float light_source = gl_Color.b;
|
||||||
|
|
||||||
|
/*color.r = mix(night, day, dayNightRatio);
|
||||||
|
color.g = color.r;
|
||||||
|
color.b = color.r;*/
|
||||||
|
|
||||||
|
float rg = mix(night, day, dayNightRatio);
|
||||||
|
rg += light_source * 1.5; // Make light sources brighter
|
||||||
|
float b = rg;
|
||||||
|
|
||||||
|
// Moonlight is blue
|
||||||
|
b += (day - night) / 13.0;
|
||||||
|
rg -= (day - night) / 13.0;
|
||||||
|
|
||||||
|
// Emphase blue a bit in darker places
|
||||||
|
// See C++ implementation in mapblock_mesh.cpp finalColorBlend()
|
||||||
|
b += max(0.0, (1.0 - abs(b - 0.13)/0.17) * 0.025);
|
||||||
|
|
||||||
|
// Artificial light is yellow-ish
|
||||||
|
// See C++ implementation in mapblock_mesh.cpp finalColorBlend()
|
||||||
|
rg += max(0.0, (1.0 - abs(rg - 0.85)/0.15) * 0.065);
|
||||||
|
|
||||||
|
color.r = rg;
|
||||||
|
color.g = rg;
|
||||||
|
color.b = b;
|
||||||
|
|
||||||
|
// Make sides and bottom darker than the top
|
||||||
|
color = color * color; // SRGB -> Linear
|
||||||
|
if(gl_Normal.y <= 0.5)
|
||||||
|
color *= 0.6;
|
||||||
|
//color *= 0.7;
|
||||||
|
color = sqrt(color); // Linear -> SRGB
|
||||||
|
|
||||||
|
color.a = gl_Color.a;
|
||||||
|
|
||||||
|
gl_FrontColor = gl_BackColor = color;
|
||||||
|
|
||||||
|
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||||
|
|
||||||
|
vec3 n1 = normalize(gl_NormalMatrix * gl_Normal);
|
||||||
|
vec4 tangent1 = vec4(tangent.x, tangent.y, tangent.z, 0);
|
||||||
|
//vec3 t1 = normalize(gl_NormalMatrix * tangent1);
|
||||||
|
//vec3 b1 = cross(n1, t1);
|
||||||
|
|
||||||
|
vec3 v;
|
||||||
|
vec3 vVertex = vec3(gl_ModelViewMatrix * gl_Vertex);
|
||||||
|
vec3 vVec = -vVertex;
|
||||||
|
//v.x = dot(vVec, t1);
|
||||||
|
//v.y = dot(vVec, b1);
|
||||||
|
//v.z = dot(vVec, n1);
|
||||||
|
//viewVec = vVec;
|
||||||
|
viewVec = normalize(vec3(0.0, -0.4, 0.5));
|
||||||
|
//Vector representing the 0th texture coordinate passed to fragment shader
|
||||||
|
//gl_TexCoord[0] = vec2(gl_MultiTexCoord0);
|
||||||
|
|
||||||
|
// Transform the current vertex
|
||||||
|
//gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||||
|
}
|
1
client/shaders/bumpmaps_solids/base.txt
Normal file
1
client/shaders/bumpmaps_solids/base.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
trans_alphach_ref
|
46
client/shaders/bumpmaps_solids/opengl_fragment.glsl
Normal file
46
client/shaders/bumpmaps_solids/opengl_fragment.glsl
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
|
||||||
|
uniform sampler2D myTexture;
|
||||||
|
uniform sampler2D normalTexture;
|
||||||
|
|
||||||
|
uniform vec4 skyBgColor;
|
||||||
|
uniform float fogDistance;
|
||||||
|
|
||||||
|
varying vec3 vPosition;
|
||||||
|
|
||||||
|
varying vec3 viewVec;
|
||||||
|
|
||||||
|
void main (void)
|
||||||
|
{
|
||||||
|
vec4 col = texture2D(myTexture, vec2(gl_TexCoord[0]));
|
||||||
|
float alpha = col.a;
|
||||||
|
vec2 uv = gl_TexCoord[0].st;
|
||||||
|
vec4 base = texture2D(myTexture, uv);
|
||||||
|
vec4 final_color = vec4(0.2, 0.2, 0.2, 1.0) * base;
|
||||||
|
vec3 vVec = normalize(viewVec);
|
||||||
|
vec3 bump = normalize(texture2D(normalTexture, uv).xyz * 2.0 - 1.0);
|
||||||
|
vec3 R = reflect(-vVec, bump);
|
||||||
|
vec3 lVec = normalize(vec3(0.0, -0.4, 0.5));
|
||||||
|
float diffuse = max(dot(lVec, bump), 0.0);
|
||||||
|
|
||||||
|
vec3 color = diffuse * texture2D(myTexture, gl_TexCoord[0].st).rgb;
|
||||||
|
|
||||||
|
|
||||||
|
float specular = pow(clamp(dot(R, lVec), 0.0, 1.0),1.0);
|
||||||
|
vec4 vSpecular = 0.2*specular * diffuse;
|
||||||
|
color += vSpecular;
|
||||||
|
|
||||||
|
|
||||||
|
col = vec4(color.r, color.g, color.b, alpha);
|
||||||
|
col *= gl_Color;
|
||||||
|
col = col * col; // SRGB -> Linear
|
||||||
|
col *= 1.8;
|
||||||
|
col.r = 1.0 - exp(1.0 - col.r) / exp(1.0);
|
||||||
|
col.g = 1.0 - exp(1.0 - col.g) / exp(1.0);
|
||||||
|
col.b = 1.0 - exp(1.0 - col.b) / exp(1.0);
|
||||||
|
col = sqrt(col); // Linear -> SRGB
|
||||||
|
if(fogDistance != 0.0){
|
||||||
|
float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0));
|
||||||
|
col = mix(col, skyBgColor, d);
|
||||||
|
}
|
||||||
|
gl_FragColor = vec4(col.r, col.g, col.b, alpha);
|
||||||
|
}
|
98
client/shaders/bumpmaps_solids/opengl_vertex.glsl
Normal file
98
client/shaders/bumpmaps_solids/opengl_vertex.glsl
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
|
||||||
|
uniform mat4 mWorldViewProj;
|
||||||
|
uniform mat4 mInvWorld;
|
||||||
|
uniform mat4 mTransWorld;
|
||||||
|
uniform float dayNightRatio;
|
||||||
|
|
||||||
|
varying vec3 vPosition;
|
||||||
|
varying vec3 viewVec;
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
gl_Position = mWorldViewProj * gl_Vertex;
|
||||||
|
|
||||||
|
vPosition = (mWorldViewProj * gl_Vertex).xyz;
|
||||||
|
|
||||||
|
vec3 tangent;
|
||||||
|
vec3 binormal;
|
||||||
|
|
||||||
|
vec3 c1 = cross( gl_Normal, vec3(0.0, 0.0, 1.0) );
|
||||||
|
vec3 c2 = cross( gl_Normal, vec3(0.0, 1.0, 0.0) );
|
||||||
|
|
||||||
|
if( length(c1)>length(c2) )
|
||||||
|
{
|
||||||
|
tangent = c1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tangent = c2;
|
||||||
|
}
|
||||||
|
|
||||||
|
tangent = normalize(tangent);
|
||||||
|
|
||||||
|
//binormal = cross(gl_Normal, tangent);
|
||||||
|
//binormal = normalize(binormal);
|
||||||
|
|
||||||
|
vec4 color;
|
||||||
|
//color = vec4(1.0, 1.0, 1.0, 1.0);
|
||||||
|
|
||||||
|
float day = gl_Color.r;
|
||||||
|
float night = gl_Color.g;
|
||||||
|
float light_source = gl_Color.b;
|
||||||
|
|
||||||
|
/*color.r = mix(night, day, dayNightRatio);
|
||||||
|
color.g = color.r;
|
||||||
|
color.b = color.r;*/
|
||||||
|
|
||||||
|
float rg = mix(night, day, dayNightRatio);
|
||||||
|
rg += light_source * 1.5; // Make light sources brighter
|
||||||
|
float b = rg;
|
||||||
|
|
||||||
|
// Moonlight is blue
|
||||||
|
b += (day - night) / 13.0;
|
||||||
|
rg -= (day - night) / 13.0;
|
||||||
|
|
||||||
|
// Emphase blue a bit in darker places
|
||||||
|
// See C++ implementation in mapblock_mesh.cpp finalColorBlend()
|
||||||
|
b += max(0.0, (1.0 - abs(b - 0.13)/0.17) * 0.025);
|
||||||
|
|
||||||
|
// Artificial light is yellow-ish
|
||||||
|
// See C++ implementation in mapblock_mesh.cpp finalColorBlend()
|
||||||
|
rg += max(0.0, (1.0 - abs(rg - 0.85)/0.15) * 0.065);
|
||||||
|
|
||||||
|
color.r = rg;
|
||||||
|
color.g = rg;
|
||||||
|
color.b = b;
|
||||||
|
|
||||||
|
// Make sides and bottom darker than the top
|
||||||
|
color = color * color; // SRGB -> Linear
|
||||||
|
if(gl_Normal.y <= 0.5)
|
||||||
|
color *= 0.6;
|
||||||
|
//color *= 0.7;
|
||||||
|
color = sqrt(color); // Linear -> SRGB
|
||||||
|
|
||||||
|
color.a = gl_Color.a;
|
||||||
|
|
||||||
|
gl_FrontColor = gl_BackColor = color;
|
||||||
|
|
||||||
|
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||||
|
|
||||||
|
vec3 n1 = normalize(gl_NormalMatrix * gl_Normal);
|
||||||
|
vec4 tangent1 = vec4(tangent.x, tangent.y, tangent.z, 0);
|
||||||
|
//vec3 t1 = normalize(gl_NormalMatrix * tangent1);
|
||||||
|
//vec3 b1 = cross(n1, t1);
|
||||||
|
|
||||||
|
vec3 v;
|
||||||
|
vec3 vVertex = vec3(gl_ModelViewMatrix * gl_Vertex);
|
||||||
|
vec3 vVec = -vVertex;
|
||||||
|
//v.x = dot(vVec, t1);
|
||||||
|
//v.y = dot(vVec, b1);
|
||||||
|
//v.z = dot(vVec, n1);
|
||||||
|
//viewVec = vVec;
|
||||||
|
viewVec = normalize(vec3(0.0, -0.4, 0.5));
|
||||||
|
//Vector representing the 0th texture coordinate passed to fragment shader
|
||||||
|
//gl_TexCoord[0] = vec2(gl_MultiTexCoord0);
|
||||||
|
|
||||||
|
// Transform the current vertex
|
||||||
|
//gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||||
|
}
|
@ -172,6 +172,8 @@
|
|||||||
# (1: low level shaders; not implemented)
|
# (1: low level shaders; not implemented)
|
||||||
# 2: enable high level shaders
|
# 2: enable high level shaders
|
||||||
#enable_shaders = 2
|
#enable_shaders = 2
|
||||||
|
# Set to true to enable textures bumpmapping. Requires shaders enabled.
|
||||||
|
#enable_bumpmapping = false
|
||||||
# The time in seconds it takes between repeated
|
# The time in seconds it takes between repeated
|
||||||
# right clicks when holding the right mouse button
|
# right clicks when holding the right mouse button
|
||||||
#repeat_rightclick_time = 0.25
|
#repeat_rightclick_time = 0.25
|
||||||
|
@ -127,6 +127,7 @@ void set_default_settings(Settings *settings)
|
|||||||
settings->setDefault("trilinear_filter", "false");
|
settings->setDefault("trilinear_filter", "false");
|
||||||
settings->setDefault("preload_item_visuals", "true");
|
settings->setDefault("preload_item_visuals", "true");
|
||||||
settings->setDefault("enable_shaders", "2");
|
settings->setDefault("enable_shaders", "2");
|
||||||
|
settings->setDefault("enable_bumpmapping", "false");
|
||||||
settings->setDefault("repeat_rightclick_time", "0.25");
|
settings->setDefault("repeat_rightclick_time", "0.25");
|
||||||
settings->setDefault("enable_particles", "true");
|
settings->setDefault("enable_particles", "true");
|
||||||
|
|
||||||
|
@ -804,6 +804,10 @@ public:
|
|||||||
u32 daynight_ratio = m_client->getEnv().getDayNightRatio();
|
u32 daynight_ratio = m_client->getEnv().getDayNightRatio();
|
||||||
float daynight_ratio_f = (float)daynight_ratio / 1000.0;
|
float daynight_ratio_f = (float)daynight_ratio / 1000.0;
|
||||||
services->setPixelShaderConstant("dayNightRatio", &daynight_ratio_f, 1);
|
services->setPixelShaderConstant("dayNightRatio", &daynight_ratio_f, 1);
|
||||||
|
|
||||||
|
// Normal map texture layer
|
||||||
|
int layer = 1;
|
||||||
|
services->setPixelShaderConstant("normalTexture" , (irr::f32*)&layer, 1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1072,12 +1072,18 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data):
|
|||||||
Also store animation info
|
Also store animation info
|
||||||
*/
|
*/
|
||||||
bool enable_shaders = (g_settings->getS32("enable_shaders") > 0);
|
bool enable_shaders = (g_settings->getS32("enable_shaders") > 0);
|
||||||
|
bool enable_bumpmapping = g_settings->getBool("enable_bumpmapping");
|
||||||
video::E_MATERIAL_TYPE shadermat1 = m_gamedef->getShaderSource()->
|
video::E_MATERIAL_TYPE shadermat1 = m_gamedef->getShaderSource()->
|
||||||
getShader("test_shader_1").material;
|
getShader("test_shader_1").material;
|
||||||
video::E_MATERIAL_TYPE shadermat2 = m_gamedef->getShaderSource()->
|
video::E_MATERIAL_TYPE shadermat2 = m_gamedef->getShaderSource()->
|
||||||
getShader("test_shader_2").material;
|
getShader("test_shader_2").material;
|
||||||
video::E_MATERIAL_TYPE shadermat3 = m_gamedef->getShaderSource()->
|
video::E_MATERIAL_TYPE shadermat3 = m_gamedef->getShaderSource()->
|
||||||
getShader("test_shader_3").material;
|
getShader("test_shader_3").material;
|
||||||
|
video::E_MATERIAL_TYPE bumpmaps1 = m_gamedef->getShaderSource()->
|
||||||
|
getShader("bumpmaps_solids").material;
|
||||||
|
video::E_MATERIAL_TYPE bumpmaps2 = m_gamedef->getShaderSource()->
|
||||||
|
getShader("bumpmaps_liquids").material;
|
||||||
|
|
||||||
for(u32 i = 0; i < collector.prebuffers.size(); i++)
|
for(u32 i = 0; i < collector.prebuffers.size(); i++)
|
||||||
{
|
{
|
||||||
PreMeshBuffer &p = collector.prebuffers[i];
|
PreMeshBuffer &p = collector.prebuffers[i];
|
||||||
@ -1154,8 +1160,33 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data):
|
|||||||
material.MaterialType
|
material.MaterialType
|
||||||
= video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
= video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
||||||
material.setTexture(0, p.tile.texture);
|
material.setTexture(0, p.tile.texture);
|
||||||
if(enable_shaders)
|
if (enable_shaders)
|
||||||
p.tile.applyMaterialOptionsWithShaders(material, shadermat1, shadermat2, shadermat3);
|
{
|
||||||
|
if (enable_bumpmapping)
|
||||||
|
{
|
||||||
|
ITextureSource *tsrc = data->m_gamedef->tsrc();
|
||||||
|
std::string basename,normal,replace;
|
||||||
|
replace = "_normal.png";
|
||||||
|
basename = tsrc->getTextureName(p.tile.texture_id);
|
||||||
|
unsigned pos = basename.find(".");
|
||||||
|
normal = basename.substr (0, pos) + replace;
|
||||||
|
if (tsrc->isKnownSourceImage(normal))
|
||||||
|
{
|
||||||
|
// look for image extension and replace it
|
||||||
|
for(std::string::size_type i = 0; (i = basename.find(".", i)) != std::string::npos;)
|
||||||
|
{
|
||||||
|
basename.replace(i, 4, replace);
|
||||||
|
i += replace.length();
|
||||||
|
}
|
||||||
|
material.setTexture(1, tsrc->getTexture(basename));
|
||||||
|
p.tile.applyMaterialOptionsWithShaders(material, bumpmaps1,bumpmaps2, shadermat3);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
p.tile.applyMaterialOptionsWithShaders(material, shadermat1, shadermat2, shadermat3);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
p.tile.applyMaterialOptionsWithShaders(material, shadermat1, shadermat2, shadermat3);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
p.tile.applyMaterialOptions(material);
|
p.tile.applyMaterialOptions(material);
|
||||||
|
|
||||||
@ -1217,6 +1248,9 @@ MapBlockMesh::~MapBlockMesh()
|
|||||||
|
|
||||||
bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_ratio)
|
bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_ratio)
|
||||||
{
|
{
|
||||||
|
bool enable_shaders = (g_settings->getS32("enable_shaders") > 0);
|
||||||
|
bool enable_bumpmapping = g_settings->getBool("enable_bumpmapping");
|
||||||
|
|
||||||
if(!m_has_animation)
|
if(!m_has_animation)
|
||||||
{
|
{
|
||||||
m_animation_force_timer = 100000;
|
m_animation_force_timer = 100000;
|
||||||
@ -1271,6 +1305,19 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_rat
|
|||||||
os<<"^[verticalframe:"<<(int)tile.animation_frame_count<<":"<<frame;
|
os<<"^[verticalframe:"<<(int)tile.animation_frame_count<<":"<<frame;
|
||||||
// Set the texture
|
// Set the texture
|
||||||
buf->getMaterial().setTexture(0, tsrc->getTexture(os.str()));
|
buf->getMaterial().setTexture(0, tsrc->getTexture(os.str()));
|
||||||
|
if (enable_shaders && enable_bumpmapping)
|
||||||
|
{
|
||||||
|
std::string basename,normal;
|
||||||
|
basename = tsrc->getTextureName(tile.texture_id);
|
||||||
|
unsigned pos;
|
||||||
|
pos = basename.find(".");
|
||||||
|
normal = basename.substr (0, pos);
|
||||||
|
normal += "_normal.png";
|
||||||
|
os.str("");
|
||||||
|
os<<normal<<"^[verticalframe:"<<(int)tile.animation_frame_count<<":"<<frame;
|
||||||
|
if (tsrc->isKnownSourceImage(normal))
|
||||||
|
buf->getMaterial().setTexture(1, tsrc->getTexture(os.str()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Day-night transition
|
// Day-night transition
|
||||||
|
255
util/generate-texture-normals.sh
Executable file
255
util/generate-texture-normals.sh
Executable file
@ -0,0 +1,255 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# This script generates normalmaps using The GIMP to do the heavy lifting.
|
||||||
|
# give any unrecognized switch (say, -h) for usage info.
|
||||||
|
|
||||||
|
rm /tmp/normals_filelist.txt
|
||||||
|
|
||||||
|
numprocs=6
|
||||||
|
|
||||||
|
skiptools=false
|
||||||
|
skipinventory=false
|
||||||
|
invresolution=64
|
||||||
|
dryrun=false
|
||||||
|
pattern="*.png *.jpg"
|
||||||
|
|
||||||
|
filter=0
|
||||||
|
scale=8
|
||||||
|
wrap=0
|
||||||
|
heightsource=0
|
||||||
|
conversion=0
|
||||||
|
invertx=0
|
||||||
|
inverty=0
|
||||||
|
|
||||||
|
while test -n "$1"; do
|
||||||
|
case "$1" in
|
||||||
|
--scale|-s)
|
||||||
|
if [ -z "$2" ] ; then echo "Missing scale parameter"; exit 1; fi
|
||||||
|
scale=$2
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--pattern|-p)
|
||||||
|
if [ -z "$2" ] ; then echo "Missing pattern parameter"; exit 1; fi
|
||||||
|
pattern=$2
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--skiptools|-t)
|
||||||
|
skiptools=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--skipinventory|-i)
|
||||||
|
if [[ $2 =~ ^[0-9]+$ ]]; then
|
||||||
|
invresolution=$2
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
skipinventory=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--filter|-f)
|
||||||
|
if [ -z "$2" ] ; then echo "Missing filter parameter"; exit 1; fi
|
||||||
|
|
||||||
|
case "$2" in
|
||||||
|
sobel3|1)
|
||||||
|
filter=1
|
||||||
|
;;
|
||||||
|
sobel5|2)
|
||||||
|
filter=2
|
||||||
|
;;
|
||||||
|
prewitt3|3)
|
||||||
|
filter=3
|
||||||
|
;;
|
||||||
|
prewitt5|4)
|
||||||
|
filter=4
|
||||||
|
;;
|
||||||
|
3x3|5)
|
||||||
|
filter=5
|
||||||
|
;;
|
||||||
|
5x5|6)
|
||||||
|
filter=6
|
||||||
|
;;
|
||||||
|
7x7|7)
|
||||||
|
filter=7
|
||||||
|
;;
|
||||||
|
9x9|8)
|
||||||
|
filter=8
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
filter=0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--heightalpha|-a)
|
||||||
|
heightsource=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--conversion|-c)
|
||||||
|
if [ -z "$2" ] ; then echo "Missing conversion parameter"; exit 1; fi
|
||||||
|
|
||||||
|
case "$2" in
|
||||||
|
biased|1)
|
||||||
|
conversion=1
|
||||||
|
;;
|
||||||
|
red|2)
|
||||||
|
conversion=2
|
||||||
|
;;
|
||||||
|
green|3)
|
||||||
|
conversion=3
|
||||||
|
;;
|
||||||
|
blue|4)
|
||||||
|
conversion=4
|
||||||
|
;;
|
||||||
|
maxrgb|5)
|
||||||
|
conversion=5
|
||||||
|
;;
|
||||||
|
minrgb|6)
|
||||||
|
conversion=6
|
||||||
|
;;
|
||||||
|
colorspace|7)
|
||||||
|
conversion=7
|
||||||
|
;;
|
||||||
|
normalize-only|8)
|
||||||
|
conversion=8
|
||||||
|
;;
|
||||||
|
heightmap|9)
|
||||||
|
conversion=9
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
conversion=0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--wrap|-w)
|
||||||
|
wrap=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--invertx|-x)
|
||||||
|
invertx=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--inverty|-y)
|
||||||
|
inverty=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--dryrun|-d)
|
||||||
|
dryrun=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo -e "\nUsage:\n"
|
||||||
|
echo "`basename $0` [--scale|-s <value>] [--filter|-f <string>]"
|
||||||
|
echo " [--wrap|-w] [--heightalpha|-a] [--invertx|-x] [--inverty|-y]"
|
||||||
|
echo " [--conversion|-c <string>] [--skiptools|-t] [--skipinventory|-i [<value>]]"
|
||||||
|
echo " [--dryrun|-d] [--pattern|-p <pattern>]"
|
||||||
|
echo -e "\nDefaults to a scale of 8, checking all files in the current directory, and not"
|
||||||
|
echo "skipping apparent tools or inventory images. Filter, if specified, may be one"
|
||||||
|
echo "of: sobel3, sobel5, prewitt3, prewitt5, 3x3, 5x5, 7x7, or 9x9, or a value 1"
|
||||||
|
echo "through 8 (1=sobel3, 2=sobel5, etc.). Defaults to 0 (four-sample). The height"
|
||||||
|
echo "source is taken from the image's alpha channel if heightalpha is specified.\n"
|
||||||
|
echo ""
|
||||||
|
echo "If inventory skip is specified, an optional resolution may also be included"
|
||||||
|
echo "(default is 64). Conversion can be one of: biased, red, green, blue, maxrgb,"
|
||||||
|
echo "minrgb, colorspace, normalize-only, heightmap or a value from 1 to 9"
|
||||||
|
echo "corresponding respectively to those keywords. Defaults to 0 (simple"
|
||||||
|
echo "normalize) if not specified. Wrap, if specified, enables wrapping of the"
|
||||||
|
echo "normalmap around the edges of the texture (defaults to no). Invert X/Y"
|
||||||
|
echo "reverses the calculated gradients for the X and/or Y dimensions represented"
|
||||||
|
echo "by the normalmap (both default to non-inverted)."
|
||||||
|
echo ""
|
||||||
|
echo "The pattern, can be an escaped pattern string such as \*apple\* or"
|
||||||
|
echo "default_\*.png or similar (defaults to all PNG and JPG images in the current"
|
||||||
|
echo "directory that do not contain \"_normal\" or \"_specular\" in their filenames)."
|
||||||
|
echo ""
|
||||||
|
echo "If set for dry-run, the actions this script will take will be printed, but no"
|
||||||
|
echo "images will be generated. Passing an invalid value to a switch will generally"
|
||||||
|
echo "cause that switch to revert to its default value."
|
||||||
|
echo ""
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
echo -e "\nProcessing files based on pattern \"$pattern\" ..."
|
||||||
|
|
||||||
|
normalMap()
|
||||||
|
{
|
||||||
|
out=`echo "$1" | sed 's/.png/_normal.png/' | sed 's/.jpg/_normal.png/'`
|
||||||
|
|
||||||
|
echo "Launched process to generate normalmap: \"$1\" --> \"$out\"" >&2
|
||||||
|
|
||||||
|
gimp -i -b "
|
||||||
|
(define
|
||||||
|
(normalMap-fbx-conversion fileName newFileName filter nscale wrap heightsource conversion invertx inverty)
|
||||||
|
(let*
|
||||||
|
(
|
||||||
|
(image (car (gimp-file-load RUN-NONINTERACTIVE fileName fileName)))
|
||||||
|
(drawable (car (gimp-image-get-active-layer image)))
|
||||||
|
(drawable (car (gimp-image-flatten image)))
|
||||||
|
)
|
||||||
|
(if (> (car (gimp-drawable-type drawable)) 1)
|
||||||
|
(gimp-convert-rgb image) ()
|
||||||
|
)
|
||||||
|
|
||||||
|
(plug-in-normalmap
|
||||||
|
RUN-NONINTERACTIVE
|
||||||
|
image
|
||||||
|
drawable
|
||||||
|
filter
|
||||||
|
0.0
|
||||||
|
nscale
|
||||||
|
wrap
|
||||||
|
heightsource
|
||||||
|
0
|
||||||
|
conversion
|
||||||
|
0
|
||||||
|
invertx
|
||||||
|
inverty
|
||||||
|
0
|
||||||
|
0.0
|
||||||
|
drawable)
|
||||||
|
(gimp-file-save RUN-NONINTERACTIVE image drawable newFileName newFileName)
|
||||||
|
(gimp-image-delete image)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(normalMap-fbx-conversion \"$1\" \"$out\" $2 $3 $4 $5 $6 $7 $8)" -b '(gimp-quit 0)'
|
||||||
|
}
|
||||||
|
|
||||||
|
export -f normalMap
|
||||||
|
|
||||||
|
for file in `ls $pattern |grep -v "_normal.png"|grep -v "_specular"` ; do
|
||||||
|
|
||||||
|
invtest=`file "$file" |grep "$invresolution x $invresolution"`
|
||||||
|
if $skipinventory && [ -n "$invtest" ] ; then
|
||||||
|
echo "Skipped presumed "$invresolution"px inventory image: $file" >&2
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
tooltest=`echo "$file" \
|
||||||
|
| grep -v "_tool" \
|
||||||
|
| grep -v "_shovel" \
|
||||||
|
| grep -v "_pick" \
|
||||||
|
| grep -v "_axe" \
|
||||||
|
| grep -v "_sword" \
|
||||||
|
| grep -v "_hoe" \
|
||||||
|
| grep -v "bucket_"`
|
||||||
|
|
||||||
|
if $skiptools && [ -z "$tooltest" ] ; then
|
||||||
|
echo "Skipped presumed tool image: $file" >&2
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
if $dryrun ; then
|
||||||
|
echo "Would have generated a normalmap for $file" >&2
|
||||||
|
continue
|
||||||
|
else
|
||||||
|
echo \"$file\" $filter $scale $wrap $heightsource $conversion $invertx $inverty
|
||||||
|
fi
|
||||||
|
done | xargs -P $numprocs -n 8 -I{} bash -c normalMap\ \{\}\ \{\}\ \{\}\ \{\}\ \{\}\ \{\}\ \{\}\ \{\}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user