GLTF Model Generation Guide
This guide explains how to generate GLTF/GLB model data for Three.js rendering in your fishing log application.
Overview
Your system supports three ways to store 3D model data:
- External URL (preferred): Store GLTF/GLB files on S3/CDN, reference via URL
- Embedded JSON: Store GLTF JSON directly in database
- Base64 Encoded: Store small models as base64 strings
Option 1: Create Models in 3D Software (Recommended for Complex Models)
Using Blender (Free & Open Source)
-
Install Blender: Download from blender.org
-
Create Your Model:
- Create basic shapes (cylinders for rods/reels, boxes for equipment)
- Use proper scale (1 unit = 1 meter in Blender, convert to feet for your system)
- Apply materials using Principled BSDF shader
-
Export to GLTF:
File > Export > glTF 2.0 (.glb/.gltf)- Choose
.glb(binary) for single file - Choose
.gltf(JSON + separate files) if you have textures - Export settings:
- Format: GLB (recommended) or GLTF
- Include: Selected Objects, Materials, Textures
- Transform: +Y Up (Three.js default)
- Choose
-
Upload to S3/CDN:
aws s3 cp model.glb s3://your-bucket/models/fishing/rod-spinning-7ft.glb -
Update Database:
var model = await context.ThreeJsModels.FirstOrDefaultAsync(m => m.Name == "Spinning Rod 7ft");
model.ModelUrl = "https://cdn.example.com/models/rod-spinning-7ft.glb";
model.Format = ModelFormat.Glb;
await context.SaveChangesAsync();
Using Other 3D Software
- Maya/3ds Max: Use glTF exporter plugins
- SketchUp: Use glTF exporter extensions
- Online Tools:
Option 2: Generate Simple Models Programmatically
For basic geometric shapes (rods, reels, cannon balls), you can generate GLTF JSON programmatically.
Simple GLTF Generator Service
See GltfModelGenerator.cs for a helper service that generates basic shapes.
Example: Generate a Cylinder (Rod)
var rodGltf = GltfModelGenerator.CreateCylinder(
lengthFt: 7.0f,
diameterInches: 0.5f,
segments: 32,
materialColor: "#4A4A4A" // Gray
);
// Store as JSON
model.ModelJson = JsonSerializer.Serialize(rodGltf);
model.Format = ModelFormat.Gltf;
Example: Generate a Sphere (Cannon Ball)
var cannonBallGltf = GltfModelGenerator.CreateSphere(
diameterInches: 5.0f,
segments: 32,
materialColor: "#2A2A2A" // Dark gray/black
);
Example: Generate a Box (Battery)
var batteryGltf = GltfModelGenerator.CreateBox(
lengthFt: 1.01f, // Group 27 battery
widthFt: 0.57f,
heightFt: 0.74f,
materialColor: "#000000" // Black
);
Option 3: Use Procedural Generation in Seeder
Update ThreeJsModelSeeder.cs to generate simple models:
private static ThreeJsModel CreateRodModelWithGltf(string name, string description,
float length, float diameter, int? modelTypeId, int? formatId)
{
// Generate simple cylinder GLTF
var gltfJson = GltfModelGenerator.CreateCylinder(length, diameter);
return new ThreeJsModel
{
Name = name,
Description = description,
ModelType = ModelType.Rod,
ModelTypeLookupId = modelTypeId,
Format = ModelFormat.Gltf,
FormatLookupId = formatId,
ModelJson = JsonSerializer.Serialize(gltfJson), // Store GLTF JSON
ReferenceLengthFt = length,
ReferenceDiameterInches = diameter,
AnchorPoint = AnchorPoint.BottomFront,
IsDefault = true,
IsPublic = true,
IsActive = true
};
}
GLTF Structure Overview
A basic GLTF file contains:
{
"asset": { "version": "2.0", "generator": "FishingLog" },
"scene": 0,
"scenes": [{ "nodes": [0] }],
"nodes": [{ "mesh": 0 }],
"meshes": [{
"primitives": [{
"attributes": {
"POSITION": 0,
"NORMAL": 1
},
"indices": 2,
"material": 0
}]
}],
"materials": [{
"pbrMetallicRoughness": {
"baseColorFactor": [0.5, 0.5, 0.5, 1.0],
"metallicFactor": 0.0,
"roughnessFactor": 0.8
}
}],
"accessors": [...],
"bufferViews": [...],
"buffers": [...]
}
Storage Strategy Recommendations
For Production:
-
Boats (large, complex): External URL (S3/CDN)
- File size: 1-10MB
- Example:
https://cdn.fishinglog.com/models/boats/center-console-base.glb
-
Rods/Reels (medium): External URL or Embedded JSON
- File size: 50-500KB
- Simple shapes can be JSON, detailed models should be GLB
-
Equipment (small): Embedded JSON or Base64
- File size: <50KB
- Cannon balls, rod holders, etc. can be simple shapes
Storage Workflow:
// 1. Generate or create model
var gltfData = GenerateOrLoadGltfModel();
// 2. Determine storage method
if (gltfData.FileSizeBytes > 500_000) // >500KB
{
// Upload to S3
var s3Url = await UploadToS3(gltfData, $"models/{category}/{name}.glb");
model.ModelUrl = s3Url;
model.Format = ModelFormat.Glb;
}
else
{
// Store as JSON in database
model.ModelJson = JsonSerializer.Serialize(gltfData);
model.Format = ModelFormat.Gltf;
}
Three.js Loading
Frontend (React Native/Web):
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js'; // For compressed models
// Load from URL
const loader = new GLTFLoader();
loader.load(modelUrl, (gltf) => {
const model = gltf.scene;
// Apply scaling based on reference dimensions
const scaleX = userLength / referenceLength;
const scaleY = userWidth / referenceWidth;
const scaleZ = userHeight / referenceHeight;
model.scale.set(scaleX, scaleY, scaleZ);
// Position based on anchor point
// ... anchor point logic ...
scene.add(model);
});
// Load from JSON (if embedded)
if (modelJson) {
const gltf = JSON.parse(modelJson);
const model = parseGltf(gltf); // Use GLTFLoader.parse() or similar
scene.add(model);
}
Model Optimization Tips
- Reduce Polygon Count: Use fewer segments for simple shapes
- Compress Textures: Use JPEG/WebP, reduce resolution
- Use DRACO Compression: Compress geometry data
- LOD (Level of Detail): Multiple detail levels for different distances
- Remove Unused Data: Clean up materials, animations, etc.
Testing Models
- GLTF Validator: github.com/KhronosGroup/glTF-Validator
- Three.js Editor: Load and preview models
- Babylon.js Sandbox: Test loading and rendering
- glTF Viewer: gltf.report
Next Steps
- Create
GltfModelGenerator.cshelper class for programmatic generation - Set up S3 bucket for model storage
- Create API endpoint for model upload
- Update seeder to generate simple models
- Create frontend model loader service