Skip to main content

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:

  1. External URL (preferred): Store GLTF/GLB files on S3/CDN, reference via URL
  2. Embedded JSON: Store GLTF JSON directly in database
  3. Base64 Encoded: Store small models as base64 strings

Using Blender (Free & Open Source)

  1. Install Blender: Download from blender.org

  2. 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
  3. 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)
  4. Upload to S3/CDN:

    aws s3 cp model.glb s3://your-bucket/models/fishing/rod-spinning-7ft.glb
  5. 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

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:

  1. Boats (large, complex): External URL (S3/CDN)

    • File size: 1-10MB
    • Example: https://cdn.fishinglog.com/models/boats/center-console-base.glb
  2. Rods/Reels (medium): External URL or Embedded JSON

    • File size: 50-500KB
    • Simple shapes can be JSON, detailed models should be GLB
  3. 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

  1. Reduce Polygon Count: Use fewer segments for simple shapes
  2. Compress Textures: Use JPEG/WebP, reduce resolution
  3. Use DRACO Compression: Compress geometry data
  4. LOD (Level of Detail): Multiple detail levels for different distances
  5. Remove Unused Data: Clean up materials, animations, etc.

Testing Models

  1. GLTF Validator: github.com/KhronosGroup/glTF-Validator
  2. Three.js Editor: Load and preview models
  3. Babylon.js Sandbox: Test loading and rendering
  4. glTF Viewer: gltf.report

Next Steps

  1. Create GltfModelGenerator.cs helper class for programmatic generation
  2. Set up S3 bucket for model storage
  3. Create API endpoint for model upload
  4. Update seeder to generate simple models
  5. Create frontend model loader service