diff --git a/interface/resources/shaders/metavoxel_voxel_splat.vert b/interface/resources/shaders/metavoxel_voxel_splat.vert index 31ddbef395..1cd1bfb6ba 100644 --- a/interface/resources/shaders/metavoxel_voxel_splat.vert +++ b/interface/resources/shaders/metavoxel_voxel_splat.vert @@ -11,6 +11,9 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +// the splat texture offset +uniform vec3 splatTextureOffset; + // the splat textures scales on the S axis uniform vec4 splatTextureScalesS; @@ -43,7 +46,7 @@ void main(void) { normal = gl_Normal; // pass along the scaled/offset texture coordinates - vec4 textureSpacePosition = gl_Vertex.xyyz; + vec4 textureSpacePosition = (gl_Vertex.xyz + splatTextureOffset).xyyz; gl_TexCoord[0] = textureSpacePosition * vec4(splatTextureScalesS[0], splatTextureScalesT[0], splatTextureScalesS[0], splatTextureScalesT[0]); gl_TexCoord[1] = textureSpacePosition * vec4(splatTextureScalesS[1], splatTextureScalesT[1], diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index 7e5714ef0f..10dbdcb17d 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -428,8 +428,9 @@ void MetavoxelSystem::render() { GL_UNSIGNED_BYTE, (qint64)&point->materials, SPLAT_COUNT, sizeof(VoxelPoint)); _splatVoxelProgram.setAttributeBuffer(_splatVoxelLocations.materialWeights, GL_UNSIGNED_BYTE, (qint64)&point->materialWeights, SPLAT_COUNT, sizeof(VoxelPoint)); - + const float QUARTER_STEP = 0.25f * EIGHT_BIT_MAXIMUM_RECIPROCAL; + _splatVoxelProgram.setUniform(_splatVoxelLocations.splatTextureOffset, batch.splatTextureOffset); _splatVoxelProgram.setUniform(_splatVoxelLocations.splatTextureScalesS, batch.splatTextureScalesS); _splatVoxelProgram.setUniform(_splatVoxelLocations.splatTextureScalesT, batch.splatTextureScalesT); _splatVoxelProgram.setUniformValue( @@ -1244,7 +1245,11 @@ void VoxelBuffer::render(const glm::vec3& translation, const glm::quat& rotation splatBatch.indexBuffer = &_indexBuffer; splatBatch.vertexCount = _vertexCount; splatBatch.indexCount = _indexCount; - + splatBatch.splatTextureOffset = glm::vec3( + glm::dot(translation, rotation * glm::vec3(1.0f, 0.0f, 0.0f)) / scale.x, + glm::dot(translation, rotation * glm::vec3(0.0f, 1.0f, 0.0f)) / scale.y, + glm::dot(translation, rotation * glm::vec3(0.0f, 0.0f, 1.0f)) / scale.z); + for (int i = 0; i < _materials.size(); i += SPLAT_COUNT) { for (int j = 0; j < SPLAT_COUNT; j++) { int index = i + j; @@ -1252,8 +1257,8 @@ void VoxelBuffer::render(const glm::vec3& translation, const glm::quat& rotation const NetworkTexturePointer& texture = _networkTextures.at(index); if (texture) { MaterialObject* material = static_cast(_materials.at(index).data()); - splatBatch.splatTextureScalesS[j] = 1.0f / material->getScaleS(); - splatBatch.splatTextureScalesT[j] = 1.0f / material->getScaleT(); + splatBatch.splatTextureScalesS[j] = scale.x / material->getScaleS(); + splatBatch.splatTextureScalesT[j] = scale.z / material->getScaleT(); splatBatch.splatTextureIDs[j] = texture->getID(); } else { @@ -2317,10 +2322,7 @@ void HeightfieldNodeRenderer::render(const HeightfieldNodePointer& node, const g int stackWidth = node->getStack()->getWidth(); int stackHeight = node->getStack()->getContents().size() / stackWidth; int innerStackWidth = stackWidth - HeightfieldData::SHARED_EDGE; - int innerStackHeight = stackHeight - HeightfieldData::SHARED_EDGE; const StackArray* src = node->getStack()->getContents().constData(); - glm::vec3 step(1.0f / innerStackWidth, scale.x / (innerStackWidth * scale.y), - 1.0f / innerStackHeight); const int EDGES_PER_CUBE = 12; EdgeCrossing crossings[EDGES_PER_CUBE]; @@ -2329,6 +2331,7 @@ void HeightfieldNodeRenderer::render(const HeightfieldNodePointer& node, const g IndexVector lastIndicesX; QVector indicesZ(stackWidth + 1); QVector lastIndicesZ(stackWidth + 1); + float scale = 1.0f / innerStackWidth; for (int z = 0; z <= stackHeight; z++) { bool middleZ = (z != 0 && z != stackHeight); @@ -2364,21 +2367,21 @@ void HeightfieldNodeRenderer::render(const HeightfieldNodePointer& node, const g glm::vec3 normal; float distance = entry.getHermiteX(normal); if (normal != glm::vec3()) { - glm::vec3 start = glm::vec3(clampedX + distance, y, clampedZ) * step; + glm::vec3 start = glm::vec3(clampedX + distance, y, clampedZ) * scale; hermiteSegments.append(start); - hermiteSegments.append(start + normal * step); + hermiteSegments.append(start + normal * scale); } distance = entry.getHermiteY(normal); if (normal != glm::vec3()) { - glm::vec3 start = glm::vec3(clampedX, y + distance, clampedZ) * step; + glm::vec3 start = glm::vec3(clampedX, y + distance, clampedZ) * scale; hermiteSegments.append(start); - hermiteSegments.append(start + normal * step); + hermiteSegments.append(start + normal * scale); } distance = entry.getHermiteZ(normal); if (normal != glm::vec3()) { - glm::vec3 start = glm::vec3(clampedX, y, clampedZ + distance) * step; + glm::vec3 start = glm::vec3(clampedX, y, clampedZ + distance) * scale; hermiteSegments.append(start); - hermiteSegments.append(start + normal * step); + hermiteSegments.append(start + normal * scale); } } int alpha0 = qAlpha(entry.color); @@ -2612,7 +2615,7 @@ void HeightfieldNodeRenderer::render(const HeightfieldNodePointer& node, const g if (totalWeight > 0.0f) { materialWeights *= (numeric_limits::max() / totalWeight); } - VoxelPoint point = { (glm::vec3(clampedX, y, clampedZ) + center) * step, + VoxelPoint point = { (glm::vec3(clampedX, y, clampedZ) + center) * scale, { (quint8)(red / crossingCount), (quint8)(green / crossingCount), (quint8)(blue / crossingCount) }, { (char)(normals[0].x * 127.0f), (char)(normals[0].y * 127.0f), (char)(normals[0].z * 127.0f) }, { materials[0], materials[1], materials[2], materials[3] }, @@ -2748,7 +2751,7 @@ void HeightfieldNodeRenderer::render(const HeightfieldNodePointer& node, const g } if (_voxels) { - _voxels->render(translation, rotation, scale, cursor); + _voxels->render(translation, rotation, glm::vec3(scale.x, scale.x, scale.x), cursor); } if (cursor) { diff --git a/interface/src/MetavoxelSystem.h b/interface/src/MetavoxelSystem.h index 51424be930..1a43c36464 100644 --- a/interface/src/MetavoxelSystem.h +++ b/interface/src/MetavoxelSystem.h @@ -203,6 +203,7 @@ public: /// A batch containing a voxel splat. class VoxelSplatBatch : public MetavoxelBatch { public: + glm::vec3 splatTextureOffset; int splatTextureIDs[4]; glm::vec4 splatTextureScalesS; glm::vec4 splatTextureScalesT; diff --git a/libraries/metavoxels/src/Spanner.cpp b/libraries/metavoxels/src/Spanner.cpp index 8b1983b90b..69e461f916 100644 --- a/libraries/metavoxels/src/Spanner.cpp +++ b/libraries/metavoxels/src/Spanner.cpp @@ -1178,6 +1178,10 @@ static inline float getHermite(QRgb value, glm::vec3& normal) { normal.x = (char)qRed(value) / (float)numeric_limits::max(); normal.y = (char)qGreen(value) / (float)numeric_limits::max(); normal.z = (char)qBlue(value) / (float)numeric_limits::max(); + float length = glm::length(normal); + if (length > 0.0f) { + normal /= length; + } return qAlpha(value) / (float)numeric_limits::max(); }