Building a 3D Texture Extractor with Gemini Flash

Image bc1

Benchmarks are mostly a lie. They tell us how a model handles a standardized test, but they don't tell us how it feels to actually build something with it. I spent the last week using Gemini 1.5 Flash inside the canvas environment to build a specialized photographic texture extractor for 3D workflows, and the results were surprisingly different from what the charts suggested.

The goal was simple. I wanted a tool that could isolate specific surface details from a photo and prep them for a 3D pipeline without the usual manual scrubbing in Photoshop. Most models struggle with the spatial logic required for this, but Flash handled the iterative prompting in the canvas layout with a level of precision that felt intuitive. It isn't perfect, and there are definitely moments where it hallucinates the geometry, but the utility is there.

The real question is whether this workflow actually saves time or just moves the friction from the brush tool to the prompt box. I've broken down exactly how the extractor works and where the model hits a wall.

The Flash Model Hierarchy

The Flash hierarchy is designed to trade intelligence for speed and cost, but the naming is a bit of a mess. Gemini 3.6 Flash is the heavy lifter here. It's the most capable of the three and is meant for complex reasoning tasks that still need to feel instant. Then you have 3.5 Flash, which is the balanced middle ground, and 3.5 Flash-Lite, which is essentially a stripped-down version for high-volume, low-complexity tasks like simple classification or basic data extraction.

Choosing between them usually comes down to your token budget and how much "reasoning" the model actually needs to do. If you're just cleaning up a CSV or tagging support tickets, using 3.6 Flash is a waste of money. 3.5 Flash-Lite is the right tool for that. I've found that the jump from Lite to 3.6 is noticeable in coding tasks, but for basic text manipulation, the difference is negligible.

import google.generativeai as genai

model = genai.GenerativeModel('gemini-3.5-flash-lite')

response = model.generate_content("Categorize this email as 'Urgent' or 'Normal': I can't log in.")
print(response.text)

The "Cyber" variant of 3.5 Flash is a different beast entirely. It's tuned specifically for security workloads and codebase analysis. This is where the hierarchy gets confusing because it isn't just about size or speed anymore; it's about specialization. It's better at spotting a buffer overflow than 3.6 Flash is, even though 3.6 is technically the "smarter" general model.

The pricing and performance specs follow a strict tier:

  • 3.6 Flash: Highest intelligence, highest cost per token.
  • 3.5 Flash: Balanced performance for general apps.
  • 3.5 Flash-Lite: Lowest cost, lowest latency, limited reasoning.

Case Study: The Photographic Texture Extractor

Extracting textures from photographs for 3D workflows is usually a nightmare of manual masking and tedious cleanup. 3.6 Flash handles this by treating the image as a spatial map rather than just a collection of pixels. It identifies the material boundaries and separates the diffuse color from the specular highlights. This part is genuinely confusing because the model isn't "seeing" the texture in a traditional CV sense; it's predicting the most likely UV-mapped representation based on the lighting it perceives in the photo.

The execution is straightforward. You send the image to the model with a prompt specifying the desired map—like a roughness map or a normal map—and it returns a coordinates-based mask or a transformed image. I've found that it struggles with highly reflective surfaces like chrome, which often results in "burnt" pixels in the output.

import google.generativeai as genai
from PIL import Image

model = genai.GenerativeModel('gemini-3.6-flash')

image = Image.open('brick_wall.jpg')
response = model.generate_content([
    "Extract a grayscale roughness map from this image. "
    "White is smooth, black is rough.", 
    image
])

response.text.save('brick_roughness.png')

The performance is decent, but there's a weird tension here. Some benchmarks suggest it's less intelligent and more expensive than GLM-5.2, and the fact that it's closed-weight makes it a black box. You're trading transparency and cost for a workflow that actually works without needing a degree in shader programming.

Performance in Practice

Spec sheets are usually a lie, or at least a curated version of the truth. When you move from a benchmark to 3D asset generation, the bottleneck isn't just raw tokens per second; it's how the model handles spatial reasoning and high-resolution image processing. For a lot of these models, the "intelligence" drops off a cliff the moment you ask them to coordinate a complex set of XYZ coordinates for a mesh.

This part is genuinely confusing because the marketing materials claim these models are multimodal, but they're often just treating images as a series of tokens. It's a lossy process. If you're trying to generate a precise JSON manifest for a 3D scene, the model might hallucinate the vertex positions or fail to close a loop in the geometry. I've seen this happen repeatedly where a model is "smart" at poetry but useless at calculating the distance between two vectors in a 3D space.

If you're actually implementing this, you'll likely need a wrapper to validate the output before it hits your renderer. You can't just trust the model to output valid geometry.

import json

def validate_mesh_data(model_output):
    try:
        data = json.loads(model_output)
        # Check if 'vertices' exists and has exactly 3 coordinates per point
        return all(len(v) == 3 for v in data.get("vertices", []))
    except json.JSONDecodeError:
        return False

raw_response = '{"vertices": [[0,0,0], [1,0,0], [1,1,0], [0,1,0]]}'
print(f"Is valid: {validate_mesh_data(raw_response)}")

The cost-to-performance ratio is also a mess. Some users have noted that certain closed-weight models are both less intelligent and more expensive than open alternatives like GLM-5.2. When you're processing thousands of image frames for a 3D reconstruction, those extra cents per million tokens add up quickly. You're paying a premium for a "brand" of intelligence that doesn't actually translate to better spatial accuracy.

From Prompt to Tool: The Canvas Workflow

The shift here isn't about the model's raw intelligence—which, based on the benchmarks, is debatable—but about the interface. Moving from a chat window to a canvas changes the role of the LLM from a chatbot to a temporary IDE. For a specific task like building a texture extractor for 3D workflows, the ability to iterate on a piece of code without re-generating the entire response is a legitimate quality-of-life win. It reduces the cognitive load of copy-pasting and tracking version changes manually.

I see the community pushing back on the benchmarks and the cost-to-performance ratio compared to GLM-5.2, and I think they're right. If the underlying model is mediocre or overpriced, a better UI is just a prettier wrapper for flawed output. I've seen this cycle before: a company ships a lackluster model but tries to win on "experience." That works for casual users, but for people actually building tools, the token quality is the only thing that matters in the long run.

This matters for rapid prototyping, but it doesn't replace a real development environment. I think there's a risk of overestimating how much "canvas" workflows actually speed up production when the debugging still happens in a separate terminal.

The real question is whether Google is pivoting toward making the LLM a "manager" of tools rather than a source of truth. If the model continues to lag in benchmarks, will they double down on the interface to hide the gap?

Conclusion

Gemini 3.6 Flash is fast, and using it within Canvas to build a texture extractor proves that the "Flash" tier is actually usable for specific, utility-driven tools rather than just being a cheaper version of a larger model. It turns a tedious 3D workflow task into something that happens in a few prompts.

I'm still not convinced that these "AI agents" are ready to operate at scale without a human babysitting every single output, regardless of what the product management slides claim. But for a niche tool like a texture extractor, the latency is low enough that it's actually helpful.

Will this replace a dedicated Substance Designer workflow? Probably not. But it's worth asking: how many other boring, manual 3D tasks can be offloaded to a model that costs this little to run?