Skip to content

Commit 4968571

Browse files
committed
Initial surface nets implementation
1 parent 801fb64 commit 4968571

File tree

16 files changed

+1626
-39
lines changed

16 files changed

+1626
-39
lines changed

assets/shaders/BlockPBR.nzsl

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ option MaxLightCount: u32 = 3;
5151
const HasNormal = (VertexNormalLoc != InvalidLoc);
5252
const HasVertexColor = (VertexColorLoc != InvalidLoc);
5353
const HasColor = (HasVertexColor || Billboard);
54-
const HasTangent = (VertexTangentLoc != InvalidLoc);
54+
const HasTangent = (VertexTangentLoc != InvalidLoc && false);
5555
const HasUV = (VertexUvLoc != InvalidLoc);
5656
const HasNormalMapping = HasNormalTexture && HasNormal && HasTangent && !DepthPass;
5757
const HasSkinning = (VertexJointIndicesLoc != InvalidLoc && VertexJointWeightsLoc != InvalidLoc);
@@ -141,10 +141,30 @@ fn ComputeColor(input: VertOut) -> vec4[f32]
141141
color *= input.color;
142142

143143
const if (HasBaseColorTexture)
144-
color *= MaterialBaseColorMap.Sample(input.uv);
144+
{
145+
// Triplanar mapping
146+
let x = MaterialBaseColorMap.Sample(vec3[f32](input.worldPos.yz, input.uv.z));
147+
let y = MaterialBaseColorMap.Sample(vec3[f32](input.worldPos.zx, input.uv.z));
148+
let z = MaterialBaseColorMap.Sample(vec3[f32](input.worldPos.xy, input.uv.z));
149+
150+
let m = pow(abs(input.normal), (4.0).xxx);
151+
let textureColor = (x*m.x + y*m.y + z*m.z) / (m.x + m.y + m.z);
152+
153+
color *= textureColor;
154+
}
145155

146156
const if (HasAlphaTexture)
147-
color.w *= MaterialAlphaMap.Sample(input.uv).x;
157+
{
158+
// Triplanar mapping
159+
let x = MaterialAlphaMap.Sample(vec3[f32](input.worldPos.yz, input.uv.z));
160+
let y = MaterialAlphaMap.Sample(vec3[f32](input.worldPos.zx, input.uv.z));
161+
let z = MaterialAlphaMap.Sample(vec3[f32](input.worldPos.xy, input.uv.z));
162+
163+
let m = pow(abs(input.normal), (4.0).xxx);
164+
let textureColor = (x*m.x + y*m.y + z*m.z) / (m.x + m.y + m.z);
165+
166+
color.w *= textureColor.x;
167+
}
148168

149169
const if (AlphaTest)
150170
{
@@ -162,6 +182,8 @@ fn ComputeLighting(color: vec3[f32], input: VertOut) -> vec3[f32]
162182

163183
let eyeVec = normalize(viewerData.eyePosition - input.worldPos);
164184

185+
let uv = input.uv;
186+
165187
let normal: vec3[f32];
166188
const if (HasNormalMapping)
167189
{
@@ -170,7 +192,7 @@ fn ComputeLighting(color: vec3[f32], input: VertOut) -> vec3[f32]
170192
let B = cross(N, T);
171193
let tbnMatrix = mat3[f32](T, B, N);
172194

173-
normal = (MaterialNormalMap.Sample(input.uv).xyz * 2.0 - (1.0).rrr);
195+
normal = (MaterialNormalMap.Sample(uv).xyz * 2.0 - (1.0).rrr);
174196
normal = normalize(tbnMatrix * normal);
175197
}
176198
else
@@ -182,16 +204,16 @@ fn ComputeLighting(color: vec3[f32], input: VertOut) -> vec3[f32]
182204

183205
const if (HasDetailTexture)
184206
{
185-
let detail = MaterialDetailMap.Sample(input.uv).rgb;
207+
let detail = MaterialDetailMap.Sample(uv).rgb;
186208
roughness = 1.0 - detail.r;
187209
metallic = detail.y;
188210
}
189211

190212
const if (HasMetallicTexture)
191-
metallic = MaterialMetallicMap.Sample(input.uv).x;
213+
metallic = MaterialMetallicMap.Sample(uv).x;
192214

193215
const if (HasRoughnessTexture)
194-
roughness = MaterialRoughnessMap.Sample(input.uv).x;
216+
roughness = MaterialRoughnessMap.Sample(uv).x;
195217

196218
let F0 = vec3[f32](0.04, 0.04, 0.04);
197219
F0 = albedo * metallic + F0 * (1.0 - metallic);

include/CommonLib/BlockIndex.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,16 @@
88
#define TSOM_COMMONLIB_BLOCKINDEX_HPP
99

1010
#include <NazaraUtils/Prerequisites.hpp>
11-
#include <limits>
11+
#include <NazaraUtils/Constants.hpp>
1212

1313
namespace tsom
1414
{
1515
using BlockIndex = Nz::UInt16;
1616

1717
constexpr BlockIndex EmptyBlockIndex = 0;
18-
constexpr BlockIndex InvalidBlockIndex = std::numeric_limits<BlockIndex>::max();
18+
constexpr BlockIndex InvalidBlockIndex = Nz::MaxValue();
1919
}
2020

21+
#include <CommonLib/BlockIndex.inl>
22+
2123
#endif // TSOM_COMMONLIB_BLOCKINDEX_HPP

include/CommonLib/BlockIndex.inl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
2+
// This file is part of the "This Space Of Mine" project
3+
// For conditions of distribution and use, see copyright notice in LICENSE
4+
5+
namespace tsom
6+
{
7+
}

include/CommonLib/BlockLibrary.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@ namespace tsom
5353
std::string baseUpPath;
5454
bool hasCollisions = true;
5555
bool isDoubleSided = false;
56+
bool isSmooth = false;
5657
bool isTransparent = false;
58+
float density = 1.0f;
5759
float permeability = 0.f;
5860
};
5961

@@ -65,6 +67,8 @@ namespace tsom
6567
bool hasCollisions;
6668
bool isDoubleSided;
6769
bool isTransparent;
70+
bool isSmooth;
71+
float density;
6872
float permeability;
6973
};
7074

include/CommonLib/Chunk.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ namespace tsom
6969

7070
inline void ClearFlags(ChunkFlags flags);
7171

72-
virtual std::optional<HitBlock> ComputeHitCoordinates(const Nz::Vector3f& hitPos, const Nz::Vector3f& hitNormal, const Nz::Collider3D& collider, std::uint32_t hitSubshapeId) const = 0;
7372
virtual Nz::EnumArray<Nz::BoxCorner, Nz::Vector3f> ComputeBlockCorners(const Nz::Vector3ui& indices) const;
73+
virtual std::optional<HitBlock> ComputeHitCoordinates(const Nz::Vector3f& hitPos, const Nz::Vector3f& hitNormal, const Nz::Collider3D& collider, std::uint32_t hitSubshapeId) const = 0;
7474

7575
virtual void DeformNormals(Nz::SparsePtr<Nz::Vector3f> normals, const Nz::Vector3f& referenceNormal, Nz::SparsePtr<const Nz::Vector3f> positions, std::size_t vertexCount) const;
7676
virtual void DeformNormalsAndTangents(Nz::SparsePtr<Nz::Vector3f> normals, Nz::SparsePtr<Nz::Vector3f> tangents, const Nz::Vector3f& referenceNormal, Nz::SparsePtr<const Nz::Vector3f> positions, std::size_t vertexCount) const;
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
2+
// This file is part of the "This Space Of Mine" project
3+
// For conditions of distribution and use, see copyright notice in LICENSE
4+
5+
#pragma once
6+
7+
#ifndef TSOM_COMMONLIB_MARCHINGCHUNK_HPP
8+
#define TSOM_COMMONLIB_MARCHINGCHUNK_HPP
9+
10+
#include <CommonLib/Chunk.hpp>
11+
#include <Nazara/Math/Box.hpp>
12+
#include <NazaraUtils/FunctionRef.hpp>
13+
14+
namespace tsom
15+
{
16+
class TSOM_COMMONLIB_API MarchingCubeChunk : public Chunk
17+
{
18+
public:
19+
using Chunk::Chunk;
20+
MarchingCubeChunk(const MarchingCubeChunk&) = delete;
21+
MarchingCubeChunk(MarchingCubeChunk&&) = delete;
22+
~MarchingCubeChunk() = default;
23+
24+
std::pair<std::shared_ptr<Nz::Collider3D>, Nz::Vector3f> BuildBlockCollider(const Nz::Vector3ui& blockIndices, float scale = 1.f) const override;
25+
std::shared_ptr<Nz::Collider3D> BuildCollider(std::size_t layerIndex) const override;
26+
void BuildMesh(std::size_t layerIndex, std::vector<Nz::UInt32>& indices, const Nz::Vector3f& center, const Nz::FunctionRef<VertexAttributes(const Nz::Vector3ui& blockIndices, Direction direction)>& addFace) const override;
27+
28+
std::optional<Nz::Vector3ui> ComputeCoordinates(const Nz::Vector3f& position) const;
29+
std::optional<HitBlock> ComputeHitCoordinates(const Nz::Vector3f& hitPos, const Nz::Vector3f& hitNormal, const Nz::Collider3D& collider, std::uint32_t hitSubshapeId) const override;
30+
31+
MarchingCubeChunk& operator=(const MarchingCubeChunk&) = delete;
32+
MarchingCubeChunk& operator=(MarchingCubeChunk&&) = delete;
33+
34+
static void BuildCollider(const Nz::Vector3ui& dims, Nz::Bitset<Nz::UInt64> collisionCellMask, Nz::FunctionRef<void(const Nz::Boxf& box)> callback);
35+
};
36+
}
37+
38+
#include <CommonLib/MarchingCubeChunk.inl>
39+
40+
#endif // TSOM_COMMONLIB_FLATCHUNK_HPP
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
2+
// This file is part of the "This Space Of Mine" project
3+
// For conditions of distribution and use, see copyright notice in LICENSE
4+
5+
namespace tsom
6+
{
7+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
2+
// This file is part of the "This Space Of Mine" project
3+
// For conditions of distribution and use, see copyright notice in LICENSE
4+
5+
#pragma once
6+
7+
#ifndef TSOM_COMMONLIB_SURFACENETSCHUNK_HPP
8+
#define TSOM_COMMONLIB_SURFACENETSCHUNK_HPP
9+
10+
#include <CommonLib/Chunk.hpp>
11+
#include <Nazara/Math/Box.hpp>
12+
#include <NazaraUtils/FunctionRef.hpp>
13+
14+
namespace tsom
15+
{
16+
class TSOM_COMMONLIB_API SurfaceNetsChunk : public Chunk
17+
{
18+
public:
19+
using Chunk::Chunk;
20+
SurfaceNetsChunk(const SurfaceNetsChunk&) = delete;
21+
SurfaceNetsChunk(SurfaceNetsChunk&&) = delete;
22+
~SurfaceNetsChunk() = default;
23+
24+
std::pair<std::shared_ptr<Nz::Collider3D>, Nz::Vector3f> BuildBlockCollider(const Nz::Vector3ui& blockIndices, float scale = 1.f) const override;
25+
std::shared_ptr<Nz::Collider3D> BuildCollider(std::size_t layerIndex) const override;
26+
void BuildMesh(std::size_t layerIndex, std::vector<Nz::UInt32>& indices, const Nz::Vector3f& center, const Nz::FunctionRef<VertexAttributes(const Nz::Vector3ui& blockIndices, Direction direction)>& addFace) const override;
27+
28+
Nz::EnumArray<Nz::BoxCorner, Nz::Vector3f> ComputeBlockCorners(const Nz::Vector3ui& indices) const override;
29+
std::optional<Nz::Vector3ui> ComputeCoordinates(const Nz::Vector3f& position) const;
30+
std::optional<HitBlock> ComputeHitCoordinates(const Nz::Vector3f& hitPos, const Nz::Vector3f& hitNormal, const Nz::Collider3D& collider, std::uint32_t hitSubshapeId) const override;
31+
32+
SurfaceNetsChunk& operator=(const SurfaceNetsChunk&) = delete;
33+
SurfaceNetsChunk& operator=(SurfaceNetsChunk&&) = delete;
34+
35+
private:
36+
void BuildMesh(std::size_t layerIndex, std::vector<Nz::UInt32>& indices, const Nz::FunctionRef<VertexAttributes(const Nz::Vector3ui& blockIndices, Direction direction)>& addFace, bool generateVisualMesh) const;
37+
};
38+
}
39+
40+
#include <CommonLib/SurfaceNetsChunk.inl>
41+
42+
#endif // TSOM_COMMONLIB_SURFACENETSCHUNK_HPP
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Copyright (C) 2025 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
2+
// This file is part of the "This Space Of Mine" project
3+
// For conditions of distribution and use, see copyright notice in LICENSE
4+
5+
namespace tsom
6+
{
7+
}

src/ClientLib/ClientChunkEntities.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,8 @@ namespace tsom
175175

176176
std::shared_ptr<Nz::StaticMesh> staticMesh = std::make_shared<Nz::StaticMesh>(std::move(vertexBuffer), std::move(indexBuffer));
177177
staticMesh->GenerateAABB();
178-
staticMesh->GenerateTangents(); //< FIXME: Tangent generation should be fixed
178+
staticMesh->GenerateNormalsAndTangents(); //< FIXME: Tangent generation should be fixed
179+
//staticMesh->GenerateTangents(); //< FIXME: Tangent generation should be fixed
179180

180181
std::shared_ptr<Nz::Mesh> chunkMesh = std::make_shared<Nz::Mesh>();
181182
chunkMesh->CreateStatic();

0 commit comments

Comments
 (0)