Implement blend masking, fix block_foliage model hack.

master
Nicole Collings 2020-02-12 16:16:10 -08:00
parent 32f4a9414c
commit dad2f216fa
18 changed files with 111 additions and 89 deletions

View File

@ -5,6 +5,7 @@ layout (location = 1) out vec4 gNormal;
layout (location = 2) out vec4 gSpecular;
in vec2 texCoords;
in vec2 blendMaskCoords;
in vec3 blend;
in vec3 fragPos;
in vec3 normal;
@ -14,10 +15,20 @@ uniform float time;
uniform sampler2D tex;
void main() {
vec4 spec = texture(tex, texCoords) * vec4(blend, 1);
if (spec.a < 0.1) discard;
gSpecular = spec;
float blendMaskMult = -1;
if (blendMaskCoords.x >= 0 && blendMaskCoords.y >= 0) blendMaskMult = texture(tex, blendMaskCoords).r;
vec4 spec = texture(tex, texCoords);
vec3 blendCol = blend;
if (blendMaskMult >= 0) {
blendCol = (vec3(1, 1, 1) * (1 - blendMaskMult)) + (blendCol * blendMaskMult);
}
spec = vec4(spec.xyz * blendCol, spec.w);
if (spec.a < 0.1) discard;
gSpecular = spec;
gPosition = vec4(fragPos, 1);
gNormal = vec4(normal, 1);
}

View File

@ -5,9 +5,10 @@
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoords;
layout (location = 2) in vec3 aBlend;
layout (location = 3) in float aNormal;
layout (location = 4) in float aShaderMod;
layout (location = 5) in vec3 aModValues;
layout (location = 3) in vec2 aBlendMaskCoords;
layout (location = 4) in float aNormal;
layout (location = 5) in float aShaderMod;
layout (location = 6) in vec3 aModValues;
uniform mat4 model;
uniform mat4 projection;
@ -18,6 +19,7 @@ uniform sampler2D swayTex;
uniform float time;
out vec2 texCoords;
out vec2 blendMaskCoords;
out vec3 blend;
out vec3 fragPos;
out vec3 normal;
@ -90,6 +92,7 @@ void main() {
fragPos = (view * worldPos).xyz;
texCoords = aTexCoords;
blendMaskCoords = aBlendMaskCoords;
blend = aBlend;
normal = nml.xyz;

View File

@ -41,7 +41,7 @@ struct BlockModel {
{glm::vec3{0, 1, 0}, glm::vec3{}, glm::vec2{0, 0}, glm::vec2{}}};
indices = {0, 1, 2, 2, 3, 0};
accessInd = std::max(0, std::min(static_cast<int>(textureRefs.size() - 1), 2));
MeshPart leftMeshPart(vertices, indices, textureRefs[accessInd], biomeTints[accessInd]);
MeshPart leftMeshPart(vertices, indices, textureRefs[accessInd], biomeTints[accessInd], nullptr);
blockModel.parts[static_cast<int>(Dir::LEFT)].push_back(leftMeshPart);
//Right Face
@ -52,7 +52,7 @@ struct BlockModel {
{glm::vec3{1, 1, 0}, glm::vec3{}, glm::vec2{0, 0}, glm::vec2{}}};
indices = {0, 1, 2, 2, 3, 0};
accessInd = std::max(0, std::min(static_cast<int>(textureRefs.size() - 1), 3));
MeshPart rightMeshPart(vertices, indices, textureRefs[accessInd], biomeTints[accessInd]);
MeshPart rightMeshPart(vertices, indices, textureRefs[accessInd], biomeTints[accessInd], nullptr);
blockModel.parts[static_cast<int>(Dir::RIGHT)].push_back(rightMeshPart);
//Top Face
@ -63,7 +63,7 @@ struct BlockModel {
{glm::vec3{1, 1, 0}, glm::vec3{}, glm::vec2{1, 0}, glm::vec2{}}};
indices = {0, 1, 2, 2, 3, 0};
accessInd = std::max(0, std::min(static_cast<int>(textureRefs.size() - 1), 0));
MeshPart topMeshPart(vertices, indices, textureRefs[accessInd], biomeTints[accessInd]);
MeshPart topMeshPart(vertices, indices, textureRefs[accessInd], biomeTints[accessInd], nullptr);
blockModel.parts[static_cast<int>(Dir::TOP)].push_back(topMeshPart);
//Bottom Face
@ -74,7 +74,7 @@ struct BlockModel {
{glm::vec3{0, 0, 1}, glm::vec3{}, glm::vec2{0, 1}, glm::vec2{}}};
indices = {0, 1, 2, 2, 3, 0};
accessInd = std::max(0, std::min(static_cast<int>(textureRefs.size() - 1), 1));
MeshPart bottomMeshPart(vertices, indices, textureRefs[accessInd], biomeTints[accessInd]);
MeshPart bottomMeshPart(vertices, indices, textureRefs[accessInd], biomeTints[accessInd], nullptr);
blockModel.parts[static_cast<int>(Dir::BOTTOM)].push_back(bottomMeshPart);
//Front Face
@ -85,7 +85,7 @@ struct BlockModel {
{glm::vec3{0, 1, 1}, glm::vec3{}, glm::vec2{0, 0}, glm::vec2{}}};
indices = {0, 1, 2, 2, 3, 0};
accessInd = std::max(0, std::min(static_cast<int>(textureRefs.size() - 1), 4));
MeshPart frontMeshPart(vertices, indices, textureRefs[accessInd], biomeTints[accessInd]);
MeshPart frontMeshPart(vertices, indices, textureRefs[accessInd], biomeTints[accessInd], nullptr);
blockModel.parts[static_cast<int>(Dir::FRONT)].push_back(frontMeshPart);
//Back Face
@ -96,7 +96,7 @@ struct BlockModel {
{glm::vec3{1, 0, 0}, glm::vec3{}, glm::vec2{1, 1}, glm::vec2{}}};
indices = {0, 1, 2, 2, 3, 0};
accessInd = std::max(0, std::min(static_cast<int>(textureRefs.size() - 1), 5));
MeshPart backMeshPart(vertices, indices, textureRefs[accessInd], biomeTints[accessInd]);
MeshPart backMeshPart(vertices, indices, textureRefs[accessInd], biomeTints[accessInd], nullptr);
blockModel.parts[static_cast<int>(Dir::BACK)].push_back(backMeshPart);
return blockModel;

View File

@ -11,5 +11,7 @@ struct BlockModelVertex {
glm::vec3 pos;
glm::vec3 nml;
glm::vec2 tex;
glm::vec2 blendMask;
glm::vec2 texUVs;
glm::vec2 blendMaskUVs;
};

View File

@ -3,12 +3,15 @@
//
#include "MeshPart.h"
#include "../../util/Util.h"
MeshPart::MeshPart(const std::vector<BlockModelVertex>& vertices, const std::vector<unsigned int>& indices, std::shared_ptr<AtlasRef> texture, bool biomeTint) :
MeshPart::MeshPart(const std::vector<BlockModelVertex>& vertices, const std::vector<unsigned int>& indices,
std::shared_ptr<AtlasRef> texture, unsigned int blendInd, std::shared_ptr<AtlasRef> blendMask) :
vertices(vertices),
indices(indices),
texture(texture),
biomeTint(biomeTint) {
blendInd(blendInd),
blendMask(blendMask) {
//We assume these vertex structs do not have normals, and generate them here from the triangle information.
//To do this, we have to assume that each group of 3 indices is a triangle (which it would be hard for it to not be)
@ -43,6 +46,23 @@ MeshPart::MeshPart(const std::vector<BlockModelVertex>& vertices, const std::vec
//Generate solid coordinates for the defs positions
vertex.tex.x = uv.x + ((uv.z - uv.x) * vertex.tex.x);
vertex.tex.y = uv.y + ((uv.w - uv.y) * vertex.tex.y);
if (blendMask) {
std::cout << Util::floatVecToString({vertex.blendMask.x, vertex.blendMask.y, 0}) << std::endl;
auto bUV = blendMask->uv;
//Store the old positions in blendMaskUVs
vertex.blendMaskUVs.x = vertex.blendMask.x;
vertex.blendMaskUVs.y = vertex.blendMask.y;
//Generate solid coordinates for the defs positions
vertex.blendMask.x = bUV.x + ((bUV.z - bUV.x) * vertex.blendMask.x);
vertex.blendMask.y = bUV.y + ((bUV.w - bUV.y) * vertex.blendMask.y);
}
else {
// Negative One denotes full blend on fragment shader.
vertex.blendMask.x = -1;
vertex.blendMask.y = -1;
}
}
}
}

View File

@ -18,17 +18,18 @@
#include "BlockModelVertex.h"
struct MeshPart {
MeshPart(const std::vector<BlockModelVertex>& vertices, const std::vector<unsigned int>& indices, std::shared_ptr<AtlasRef> texture, bool biomeTint);
MeshPart(const std::vector<BlockModelVertex>& vertices, const std::vector<unsigned int>& indices,
std::shared_ptr<AtlasRef> texture, unsigned int blendInd, std::shared_ptr<AtlasRef> blendMask);
std::vector<BlockModelVertex> vertices;
std::vector<unsigned int> indices;
std::shared_ptr<AtlasRef> texture;
unsigned int blendInd = 0;
std::shared_ptr<AtlasRef> blendMask;
ShaderMod shaderMod = ShaderMod::NONE;
float modValue = 0;
bool biomeTint = false;
};

View File

@ -19,6 +19,7 @@ void ChunkMesh::create(const std::vector<ChunkVertex>& vertices, const std::vect
createVertexAttrib(idx++, 3, GL_FLOAT, STRIDE_OFFSET_CHUNK(position));
createVertexAttrib(idx++, 2, GL_FLOAT, STRIDE_OFFSET_CHUNK(texCoords));
createVertexAttrib(idx++, 3, GL_FLOAT, STRIDE_OFFSET_CHUNK(blendColor));
createVertexAttrib(idx++, 2, GL_FLOAT, STRIDE_OFFSET_CHUNK(blendMaskCoords));
createVertexAttrib(idx++, 1, GL_FLOAT, STRIDE_OFFSET_CHUNK(normal));
createVertexAttrib(idx++, 1, GL_FLOAT, STRIDE_OFFSET_CHUNK(shaderMod));
createVertexAttrib(idx , 3, GL_FLOAT, STRIDE_OFFSET_CHUNK(modValues));

View File

@ -11,6 +11,7 @@ struct ChunkVertex {
glm::vec3 position;
glm::vec2 texCoords;
glm::vec3 blendColor;
glm::vec2 blendMaskCoords;
float normal;
float shaderMod;
glm::vec3 modValues;

View File

@ -33,7 +33,7 @@ MeshGenerator::MeshGenerator(MeshDetails* meshDetails, LocalDefs& defs, std::sha
glm::vec3 check;
for (unsigned short i = 0; i < 4096; i++) {
BlockModel& model = atlas.blockFromId(chunk->getBlock(i)).farModel;
BlockModel& model = atlas.blockFromId(chunk->getBlock(i)).model;
glm::vec3 biomeTint = defs.biomes.biomeFromId(chunk->getBiome(i)).biomeTint;
if (model.visible) {
@ -120,7 +120,8 @@ void MeshGenerator::addFaces(const glm::vec3 &offset, const std::vector<MeshPart
meshDetails->vertices.push_back({
vertex.pos + offset,
vertex.tex,
((mp.biomeTint) ? tint : glm::vec3{1, 1, 1}),
(mp.blendInd ? tint : glm::vec3 {1, 1, 1}),
(mp.blendInd ? vertex.blendMask : glm::vec2 {-1, -1}),
Util::packFloat(vertex.nml),
static_cast<float>(mp.shaderMod),
modData

View File

@ -103,7 +103,7 @@ namespace RegisterBlocks {
glm::vec3 pos(points[offset], points[offset + 1], points[offset + 2]);
glm::vec2 tex(points[offset + 3], points[offset + 4]);
vertices.push_back({pos, {0, 0, 0}, tex, {0, 0}});
vertices.push_back(BlockModelVertex {pos, {}, tex, tex, {}, {}});
}
int ind = 0;
@ -121,22 +121,47 @@ namespace RegisterBlocks {
int tex = std::max(static_cast<int>(meshPartTable.get_or<float>("tex", 1)), 1);
auto texture = textures[std::min(tex - 1, (int) textures.size() - 1)];
//TODO: Make this a proper texture modifier, dont do jank bullshit
bool biometint = false;
if (strncmp(texture.data(), "biometint(", 10) == 0) {
biometint = true;
texture = texture.substr(10, texture.length() - 11);
bool blendInd = false;
std::string blendMask = "";
if (strncmp(texture.data(), "tint(", 5) == 0 && texture.find_last_of(')') != std::string::npos) {
// Biome tinting time
texture.erase(std::remove(texture.begin(), texture.end(), ' '), texture.end());
std::string::size_type paramsBegin = texture.find_first_of('(');
std::string::size_type paramsEnd = texture.find_last_of(')');
std::string paramsString = texture.substr(paramsBegin + 1, paramsEnd - paramsBegin - 1);
std::vector<std::string> params;
std::string::size_type pos = 0;
while ((pos = paramsString.find(',')) != std::string::npos) {
params.push_back(paramsString.substr(0, pos));
paramsString.erase(0, pos + 1);
}
params.push_back(paramsString);
if (params.size() < 2) throw "Invalid biome tint values. Must have at least 2 params.";
texture = params[1];
blendInd = atoi(params[0].data()) + 1; //TODO: support multiple blend colors
blendMask = (params.size() >= 3 ? params[2] : "");
}
// Add texture refs to blockModel if the textures table is provided
std::shared_ptr<AtlasRef> textureRef = nullptr;
std::shared_ptr<AtlasRef> textureRef = nullptr, blendMaskRef = nullptr;
if (atlas) {
textureRef = (*atlas)[texture];
model.textureRefs.insert(textureRef);
if (blendInd && !blendMask.empty()) {
blendMaskRef = (*atlas)[blendMask];
model.textureRefs.insert(blendMaskRef);
}
}
// Create the meshpart object
MeshPart meshPart(std::move(vertices), std::move(indices), textureRef, biometint);
MeshPart meshPart(std::move(vertices), std::move(indices), textureRef, blendInd, blendMaskRef);
// Add the shader mod, if it exists
sol::optional<sol::table> shaderModTable = meshPartTable.get<sol::optional<sol::table>>("shader_mod");
@ -191,8 +216,8 @@ namespace RegisterBlocks {
std::vector<bool> biomeTints;
for (auto i = 0; i < lowdef_textures.size(); i++) {
std::string texture = lowdef_textures[i];
if (strncmp(texture.data(), "biometint(", 10) == 0) {
texture = texture.substr(10, texture.length() - 11);
if (strncmp(texture.data(), "tint(", 5) == 0) {
texture = texture.substr(8, texture.length() - 8);
biomeTints.emplace_back(true);
}
else {

View File

@ -62,47 +62,10 @@ zepha.register_blockmodel("base:block_foliage", {
1, 1, 0, 0, 0,
1, 0, 0, 0, 1
}
}, {
-- Hovered faces for biome tinting begin here
face = "left",
tex = 4,
points = {
-0.003, 0, 0, 0, 1,
-0.003, 0, 1, 1, 1,
-0.003, 1, 1, 1, 0,
-0.003, 1, 0, 0, 0
}
}, {
face = "right",
tex = 4,
points = {
1.003, 1, 1, 0, 0,
1.003, 0, 1, 0, 1,
1.003, 0, 0, 1, 1,
1.003, 1, 0, 1, 0
}
}, {
face = "front",
tex = 4,
points = {
0, 0, 1.003, 0, 1,
1, 0, 1.003, 1, 1,
1, 1, 1.003, 1, 0,
0, 1, 1.003, 0, 0
}
}, {
face = "back",
tex = 4,
points = {
0, 0, -0.003, 1, 1,
0, 1, -0.003, 1, 0,
1, 1, -0.003, 0, 0,
1, 0, -0.003, 0, 1
}
}, {
--Floats begin here
face = "front",
tex = 5,
tex = 4,
points = {
0, 1, 1, 0, 0,
0.005, 0.2, 1.2, 0, 1,
@ -115,7 +78,7 @@ zepha.register_blockmodel("base:block_foliage", {
}
}, {
face = "back",
tex = 5,
tex = 4,
points = {
1.005, 0.2, -0.2, 0, 1,
0.005, 0.2, -0.2, 1, 1,
@ -128,7 +91,7 @@ zepha.register_blockmodel("base:block_foliage", {
}
}, {
face = "right",
tex = 5,
tex = 4,
points = {
1.2, 0.2, 1.005, 0, 1,
1.2, 0.2, 0.005, 1, 1,
@ -141,7 +104,7 @@ zepha.register_blockmodel("base:block_foliage", {
}
}, {
face = "left",
tex = 5,
tex = 4,
points = {
0, 1, 0, 0, 0,
-0.2, 0.2, 0.005, 0, 1,

View File

@ -2,16 +2,15 @@ zepha.register_block("zeus:default:grass", {
name = "Grass",
model = "base:block_foliage",
textures = {
"biometint(zeus:default:grass_top)",
"tint(0, zeus:default:grass_top)",
"zeus:default:dirt",
"zeus:default:grass_side_under",
"biometint(zeus:default:grass_side)",
"biometint(zeus:default:grass_floating)",
"tint(0, zeus:default:grass_side_under, zeus:default:grass_side_under_mask)",
"tint(0, zeus:default:grass_floating)",
},
lowdef_textures = {
"zeus:default:grass_top",
"tint(0, zeus:default:grass_top)",
"zeus:default:dirt",
"zeus:default:grass_side_ld"
"tint(0, zeus:default:grass_side_ld, zeus:default:grass_side_ld_mask)"
},
toughness = {
hand = 3,
@ -29,20 +28,15 @@ zepha.register_block("zeus:default:grass_slab", {
name = "Grass Slab",
model = "base:block_slab_foliage",
textures = {
"biometint(zeus:default:grass_top)",
"tint(0, zeus:default:grass_top)",
"zeus:default:dirt",
"biometint(zeus:default:grass_top)",
"biometint(zeus:default:grass_top)",
"biometint(zeus:default:grass_top)",
"biometint(zeus:default:grass_top)",
"biometint(zeus:default:grass_floating)",
"tint(0, zeus:default:grass_top)",
"tint(0, zeus:default:grass_top)",
"tint(0, zeus:default:grass_top)",
"tint(0, zeus:default:grass_top)",
"tint(0, zeus:default:grass_floating)",
},
culls = false,
## lowdef_textures = {
## "zeus:default:grass_top",
## "zeus:default:dirt",
## "zeus:default:grass_side_ld"
## },
toughness = {
hand = 3,
shovel = 1,

View File

@ -5,7 +5,7 @@ for i = 1, 5, 1 {
name = "Tall Grass",
model = "base:cross_plant",
textures = {
"biometint(zeus:default:tallgrass_"..i..")"
"tint(0, zeus:default:tallgrass_"..i..")"
},
lowdef_render = false,
selection_box = {

View File

@ -8,7 +8,7 @@ zepha.register_entity("zeus:default:test", {
## walk = {0, 300}
## })
## self.object.anims:set_anim("walk"):play()
self.object.scale = 1/4
## self.object.scale = 1/4
},
on_update = fn(self, delta) {
self.object.pos = vector.add(vector.multiply(v(0.6 * math.sin(math.rad(self.object.yaw)), 0,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 761 B

After

Width:  |  Height:  |  Size: 824 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 823 B

After

Width:  |  Height:  |  Size: 876 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 B