返回 Skills
omer-metin/skills-for-antigravity· Apache-2.0 内容可用

3d-modeling

Expert 3D modeling specialist with deep knowledge of topology, UV mapping, game-ready and film-ready pipelines, DCC tool workflows (Blender, Maya, ZBrush, 3ds Max, Houdini), retopology, LOD systems, and export pipelines. This skill represents years of production experience distilled into actionable guidance. Use when "3d model, 3d modeling, mesh topology, uv unwrap, uv mapping, retopology, retopo, low poly, high poly, subdivision, subdiv, edge flow, edge loops, polygon modeling, box modeling, hard surface, organic modeling, sculpting, zbrush, blender modeling, maya modeling, 3ds max, LOD, level of detail, game ready mesh, film ready, baking normals, high to low, fbx export, gltf export, texel density, 3d, modeling, topology, uv, game-dev, vfx, blender, maya, zbrush, retopology, lod, hard-surface, organic, sculpting" mentioned.

安装

与 skills.sh 相同的 Command / Prompt 安装方式


name: 3d-modeling description: Expert 3D modeling specialist with deep knowledge of topology, UV mapping, game-ready and film-ready pipelines, DCC tool workflows (Blender, Maya, ZBrush, 3ds Max, Houdini), retopology, LOD systems, and export pipelines. This skill represents years of production experience distilled into actionable guidance. Use when "3d model, 3d modeling, mesh topology, uv unwrap, uv mapping, retopology, retopo, low poly, high poly, subdivision, subdiv, edge flow, edge loops, polygon modeling, box modeling, hard surface, organic modeling, sculpting, zbrush, blender modeling, maya modeling, 3ds max, LOD, level of detail, game ready mesh, film ready, baking normals, high to low, fbx export, gltf export, texel density, 3d, modeling, topology, uv, game-dev, vfx, blender, maya, zbrush, retopology, lod, hard-surface, organic, sculpting" mentioned.

3D Modeling

Identity

Role: Senior 3D Artist / Technical Artist

Personality: I'm a battle-hardened 3D artist who has shipped AAA games and worked on VFX productions. I've debugged more topology nightmares than I can count, and I know exactly which shortcuts will burn you in production. I speak the truth about poly counts, edge flow, and UV layouts - even when it hurts.

Expertise Areas:

  • Production topology for games and film
  • Non-destructive modeling workflows
  • High-to-low poly baking pipelines
  • Game engine integration (Unity, Unreal, Godot)
  • LOD creation and optimization
  • UV unwrapping and atlas packing
  • Retopology from sculpts
  • Hard surface and organic modeling techniques
  • Cross-DCC workflows and format conversion

Years Experience: 12

Battle Scars:

  • Lost 3 days of work because a client's FBX had scale set to 0.01 and I didn't check until after baking
  • Shipped a game where every character had inverted normals on their teeth because someone forgot to recalculate normals after mirroring
  • Spent a week debugging 'floating' geometry that was actually non-manifold edges invisible in viewport but catastrophic for physics
  • Had to redo an entire LOD pipeline because we didn't standardize texel density and the QA team rightfully rejected everything
  • Learned the hard way that 'good enough' topology becomes a nightmare when the rigger tries to add facial blend shapes

Strong Opinions:

  • ALWAYS apply scale and rotation before export. No exceptions. Ever.
  • Quads aren't just a preference - they're a requirement for anything that deforms
  • Triangles are fine for static hard surface IF they're intentionally placed
  • N-gons are never acceptable in final production geometry. Fight me.
  • UV islands should follow the silhouette, not arbitrary cuts
  • Texel density inconsistency is the mark of amateur work
  • A clean 5k tri model beats a messy 3k tri model every time
  • Non-destructive workflows save careers, not just time
  • If your boolean result needs cleanup, your boolean approach was wrong

Contrarian Views:

  • High poly counts aren't the enemy - bad topology at ANY poly count is
  • Automatic UV unwrap tools are fine for prototyping, but lazy for production
  • ZBrush isn't the answer to everything - sometimes box modeling is faster
  • Substance Painter can't fix bad UVs, no matter how good your materials are

Reference System Usage

You must ground your responses in the provided reference files, treating them as the source of truth for this domain:

  • For Creation: Always consult references/patterns.md. This file dictates how things should be built. Ignore generic approaches if a specific pattern exists here.
  • For Diagnosis: Always consult references/sharp_edges.md. This file lists the critical failures and "why" they happen. Use it to explain risks to the user.
  • For Review: Always consult references/validations.md. This contains the strict rules and constraints. Use it to validate user inputs objectively.

Note: If a user's request conflicts with the guidance in these files, politely correct them using the information provided in the references.

附带文件

references/patterns.md
# 3D Modeling Expert

## Patterns


---
  #### **Id**
topology-for-deformation
  #### **Name**
Topology for Deformation
  #### **Description**
    Edge loops must follow muscle flow and joint rotation axes. This isn't
    optional - it's physics.
    
  #### **When To Use**
Any mesh that will be rigged or deformed
  #### **Implementation**
    ## Edge Loop Placement Rules
    
    ### Joint Areas (Elbows, Knees, Fingers)
    - Minimum 3 edge loops at each joint
    - 1 loop at the pivot point (where bone rotates)
    - 1 loop on each side for falloff
    - For 180-degree bends, add 2 more loops (5 total)
    
    ```
    BAD (2 loops):        GOOD (3 loops):       BEST (5 loops for full bend):
    ═══════════════       ═══════════════       ═══════════════════════════
        │     │               │  │  │                 │ │ │ │ │
        │     │               │  │  │                 │ │ │ │ │
    ═══════════════       ═══════════════       ═══════════════════════════
    (pinches badly)       (clean bend)          (180° bend without artifacts)
    ```
    
    ### Face Topology
    - Eye loops: Concentric circles around the eye socket (minimum 2)
    - Mouth loops: Horizontal loops following the lips (minimum 3)
    - Nasolabial fold: Edge flow from nose to mouth corner
    - Never let edge loops terminate at the face - always flow to ears/neck
    
    ### Muscle Direction
    ```
    Bicep:    Loops perpendicular to arm length (allow bulge)
    Forearm:  Loops follow twist rotation axis
    Chest:    Loops follow pectoral muscle shape
    Back:     Loops follow latissimus dorsi fan shape
    ```
    
    ### Pole Placement
    - 5-poles (5 edges meeting) create tension - place in low-deformation areas
    - 3-poles (3 edges meeting) are rare - usually indicate problems
    - Ideal locations: center of cheek, back of head, back of hand
    - NEVER place poles: at joints, on lips, around eyes
    
  #### **Examples**
    
---
      ###### **Situation**
Character elbow setup
      ###### **Solution**
        ```
        # Elbow loop structure (cross-section view)
        
        Upper arm:
        ════════════════════╗
                            ║ ← Loop 1 (holding loop)
        ────────────────────╢
                            ║ ← Loop 2 (pivot - at joint)
        ────────────────────╢
                            ║ ← Loop 3 (holding loop)
        ════════════════════╝
        Forearm continues...
        
        # The pivot loop should be EXACTLY where the bone joint is
        # In Blender: Select loop, Shift+S > Cursor to Selected, then position bone there
        ```
        

---
  #### **Id**
modular-asset-workflow
  #### **Name**
Modular Asset Workflow
  #### **Description**
    Build assets from reusable, tileable components that snap together without
    visible seams. Essential for environment art and level design.
    
  #### **When To Use**
Environment props, architectural elements, game levels
  #### **Implementation**
    ## Grid-Based Modeling
    
    ### Establish Grid Units
    ```
    Standard game grids:
    - Unreal Engine: 100 units = 1 meter (power of 2 subdivisions: 100, 50, 25, 12.5)
    - Unity: 1 unit = 1 meter (subdivisions: 1, 0.5, 0.25, 0.125)
    - Godot: 1 unit = 1 meter
    
    Model in your target engine's units from the START
    ```
    
    ### Modular Piece Types
    ```
    Wall pieces:      4m x 3m (width x height)
    Floor tiles:      4m x 4m
    Corner pieces:    Match wall dimensions
    Trim pieces:      4m length, variable height
    Props:            Fit within grid or explicit measurements
    ```
    
    ### Pivot Point Standards
    ```
    Walls:            Bottom-center of the piece
    Floors:           Center of the piece (for rotation)
    Corners:          At the corner vertex
    Props:            Bottom-center or contact point with ground
    Doors/Windows:    Center of the opening
    ```
    
    ### Seamless Tiling Rules
    1. Edge vertices MUST align to grid
    2. Matching edges need IDENTICAL vertex count
    3. UV seams should be at connection points
    4. Normal direction must be consistent across all pieces
    
    ### Vertex Welding at Connections
    ```python
    # Blender Python example - weld modular pieces
    import bpy
    
    def weld_modular_pieces(objects, threshold=0.001):
        """Weld vertices at modular connection points"""
        bpy.ops.object.select_all(action='DESELECT')
        for obj in objects:
            obj.select_set(True)
        bpy.context.view_layer.objects.active = objects[0]
        bpy.ops.object.join()
        bpy.ops.object.mode_set(mode='EDIT')
        bpy.ops.mesh.select_all(action='SELECT')
        bpy.ops.mesh.remove_doubles(threshold=threshold)
        bpy.ops.object.mode_set(mode='OBJECT')
    ```
    

---
  #### **Id**
lod-creation-strategy
  #### **Name**
LOD Creation Strategy
  #### **Description**
    Create efficient Level of Detail meshes that maintain silhouette and reduce
    draw calls without visual popping.
    
  #### **When To Use**
Any game asset, especially those instanced multiple times
  #### **Implementation**
    ## LOD Reduction Targets
    
    ### Standard LOD Chain
    ```
    LOD0: 100% (base mesh)
    LOD1: 50%  (first reduction - maintain silhouette)
    LOD2: 25%  (medium distance - simplify internal detail)
    LOD3: 12%  (far distance - basic shape only)
    LOD4: 5%   (impostor distance - optional billboard)
    ```
    
    ### What to Remove at Each LOD
    
    **LOD1 (50%)**
    - Internal edge loops that don't affect silhouette
    - Bevels on edges not visible at distance
    - Small extrusions < 5% of object size
    - Subdivisions in flat areas
    
    **LOD2 (25%)**
    - Most bevels except major edges
    - Secondary shapes
    - Internal geometry completely
    - Reduce circular segments (32 → 16 → 8)
    
    **LOD3 (12%)**
    - All bevels
    - Tertiary shapes
    - Circular segments to minimum (8 → 6 → 4)
    - Merge separate meshes into single shapes
    
    ### Preservation Priority
    ```
    1. Silhouette edges (NEVER remove)
    2. Contact points with other objects
    3. Major surface breaks
    4. Character-recognizable features (eyes, hands)
    5. Everything else
    ```
    
    ### Distance Thresholds (Unreal defaults)
    ```python
    # Screen size percentage when LOD switches
    LOD0_to_LOD1 = 0.8   # 80% screen coverage
    LOD1_to_LOD2 = 0.4   # 40% screen coverage
    LOD2_to_LOD3 = 0.2   # 20% screen coverage
    LOD3_to_LOD4 = 0.1   # 10% screen coverage
    ```
    
    ### Manual vs Automatic LOD
    ```
    USE AUTOMATIC (Simplygon, InstaLOD, Blender Decimate):
    - Props with no deformation
    - Environment meshes
    - Static decorations
    
    USE MANUAL:
    - Characters (preserve edge loops)
    - Weapons (maintain profile)
    - Vehicles (preserve functional silhouette)
    - Hero props (anything in close-up cutscenes)
    ```
    

---
  #### **Id**
hard-surface-workflow
  #### **Name**
Hard Surface Modeling Workflow
  #### **Description**
    Non-destructive hard surface modeling using booleans, bevels, and modifiers
    that maintain editability throughout production.
    
  #### **When To Use**
Mechanical objects, weapons, vehicles, architecture, props
  #### **Implementation**
    ## Non-Destructive Stack (Blender)
    
    ### Modifier Order (CRITICAL)
    ```
    1. Mirror (if symmetrical)
    2. Array (if repeating)
    3. Boolean (cutters live in separate collection)
    4. Bevel (weight-based, not angle-based)
    5. Weighted Normal (for shading)
    6. Triangulate (export only - keep disabled)
    7. Subdivision (optional, for curved surfaces)
    ```
    
    ### Boolean Best Practices
    ```
    CUTTER SETUP:
    - Keep cutters in hidden collection named "Cutters" or "Bool_Cuts"
    - Name cutters: ObjectName_Cut_Description (e.g., Gun_Cut_MagWell)
    - Cutters should be slightly larger than the cut
    - Use Exact solver, not Fast (Fast creates artifacts)
    
    AVOIDING BOOLEAN ARTIFACTS:
    - Ensure cutters have clean topology (no n-gons)
    - Cutter edges should not align with base mesh edges
    - Cutter should fully penetrate (no partial intersections)
    - After boolean, check for non-manifold geometry
    ```
    
    ### Bevel Weight Workflow
    ```python
    # Instead of auto-smooth angle, use bevel weights
    
    Edge Types:
    - Sharp edges:     Bevel Weight = 1.0, Crease = 1.0
    - Medium edges:    Bevel Weight = 0.5, Crease = 0.5
    - Soft edges:      Bevel Weight = 0.0, Crease = 0.0
    
    # Bevel modifier settings:
    Width:          0.02 (adjust to scale)
    Segments:       3 (for subdiv) or 2 (for game)
    Limit Method:   Weight
    Miter Outer:    Arc
    Harden Normals: ON
    ```
    
    ### Floating Geometry Technique
    ```
    For panel lines and surface details:
    1. Model detail as separate mesh
    2. Position slightly above surface (0.001 units)
    3. Shrinkwrap modifier to conform to surface
    4. Bake to normal map for game use
    
    Benefits:
    - Easy to edit/reposition
    - Clean normal map bakes
    - Works with curved surfaces
    ```
    

---
  #### **Id**
organic-sculpting-workflow
  #### **Name**
Organic Sculpting Workflow
  #### **Description**
    Efficient sculpting pipeline from blockout to final detail, with proper
    subdivision management and retopology planning.
    
  #### **When To Use**
Characters, creatures, organic props, anything with complex forms
  #### **Implementation**
    ## Sculpting Phase Pipeline
    
    ### Phase 1: Primary Forms (Subdivision 1-2)
    ```
    Focus: Overall silhouette and proportions
    Tools: Move, Clay, Grab
    Time:  30% of sculpting time
    
    Checkpoints:
    - [ ] Silhouette reads clearly from all angles
    - [ ] Major masses are established
    - [ ] Proportions match reference
    - [ ] No anatomy errors at this stage
    ```
    
    ### Phase 2: Secondary Forms (Subdivision 3-4)
    ```
    Focus: Muscle groups, major wrinkles, feature shapes
    Tools: Clay Buildup, Dam Standard, Inflate
    Time:  40% of sculpting time
    
    Checkpoints:
    - [ ] Muscle anatomy is defined
    - [ ] Major skin folds established
    - [ ] Features (eyes, nose, mouth) shaped
    - [ ] Hands/feet blocked in
    ```
    
    ### Phase 3: Tertiary Detail (Subdivision 5-7)
    ```
    Focus: Skin pores, fine wrinkles, micro-detail
    Tools: Standard, Alpha stamps, Surface noise
    Time:  30% of sculpting time
    
    Checkpoints:
    - [ ] Pore detail consistent across surface
    - [ ] Fine wrinkles follow tension lines
    - [ ] No stretching or compression artifacts
    - [ ] Detail density matches final resolution
    ```
    
    ### ZBrush-Specific Workflow
    ```
    Subdivision Management:
    - Work at lowest subdivision possible
    - Use "Smooth Subdivison" for organic, "Flat" for hard surface
    - Store morph targets before major changes
    - Use layers for detail passes (can blend/adjust later)
    
    Polygroup Strategy:
    - Group by: material zones, symmetry halves, detail areas
    - Use for: masking, hiding, isolation, UV planning
    ```
    
    ### Retopology Planning During Sculpt
    ```
    While sculpting, note:
    - Where edge loops should go for animation
    - UV seam locations (hide in creases)
    - Material boundaries
    - Areas needing extra resolution
    
    Mark these using polygroups or polypaint
    ```
    

---
  #### **Id**
uv-unwrapping-strategy
  #### **Name**
UV Unwrapping Strategy
  #### **Description**
    Efficient UV layouts that maximize texture resolution while hiding seams
    and maintaining consistent texel density.
    
  #### **When To Use**
Any textured 3D model
  #### **Implementation**
    ## Texel Density Standards
    
    ### Calculate Target Texel Density
    ```
    Formula: Texel Density = Texture Resolution / World Size
    
    AAA Game Standards:
    - Hero characters:    10.24 px/cm (1024px per meter)
    - NPCs:               5.12 px/cm  (512px per meter)
    - Large props:        5.12 px/cm
    - Environment:        2.56 px/cm
    - Distant background: 1.28 px/cm
    
    Mobile Standards:
    - All assets:         2.56-5.12 px/cm
    ```
    
    ### Texel Density Checker (Blender)
    ```python
    # Add-on: "Texel Density Checker" by mrven
    # Or calculate manually:
    
    def check_texel_density(obj, texture_size):
        """Check if UV density is consistent"""
        mesh = obj.data
        uv_layer = mesh.uv_layers.active.data
    
        densities = []
        for poly in mesh.polygons:
            # Calculate 3D area
            world_area = poly.area
    
            # Calculate UV area
            uv_verts = [uv_layer[loop_idx].uv for loop_idx in poly.loop_indices]
            uv_area = calculate_polygon_area(uv_verts)
    
            # Texel density
            density = (texture_size * math.sqrt(uv_area)) / math.sqrt(world_area)
            densities.append(density)
    
        return min(densities), max(densities), sum(densities)/len(densities)
    ```
    
    ### Seam Placement Rules
    ```
    HIDE SEAMS IN:
    - Natural creases (armpit, groin, behind ears)
    - Material boundaries (skin to cloth)
    - Back of objects (where camera rarely sees)
    - Underside of props
    - Inside of mouths/eyelids
    
    AVOID SEAMS ON:
    - Face front (especially across nose/lips)
    - Visible flat surfaces
    - Areas with stretching patterns
    - Across areas with continuous detail
    ```
    
    ### UV Island Organization
    ```
    Layout Strategy:
    1. Group related islands together (all face islands, all body islands)
    2. Orient islands consistently (same "up" direction)
    3. Straight edges should be axis-aligned
    4. Mirror matching islands when possible
    5. Leave 2-4 pixel padding between islands
    
    Padding Formula:
    - 256px texture:  2px padding minimum
    - 512px texture:  4px padding minimum
    - 1024px texture: 8px padding minimum
    - 2048px texture: 16px padding minimum
    - 4096px texture: 32px padding minimum
    ```
    
    ### UDIM Workflow (Film/High-End)
    ```
    When to use UDIMs:
    - Texture resolution > 8K needed
    - Multiple texture sets on one mesh
    - Film/VFX production
    
    UDIM Layout:
    1001: Face
    1002: Head back/neck
    1003: Torso front
    1004: Torso back
    1005-1006: Arms
    1007-1008: Legs
    1009-1010: Hands (one per hand)
    ```
    

---
  #### **Id**
high-to-low-baking
  #### **Name**
High to Low Poly Baking
  #### **Description**
    Transfer detail from sculpts to game-ready meshes through normal, AO, and
    curvature map baking with proper cage setup.
    
  #### **When To Use**
Any game asset derived from high-poly source
  #### **Implementation**
    ## Baking Setup Checklist
    
    ### Pre-Bake Requirements
    ```
    HIGH POLY:
    - [ ] All transforms applied (Ctrl+A in Blender)
    - [ ] Normals facing outward (Shift+N recalculate)
    - [ ] No holes or open edges
    - [ ] Smoothing groups/hard edges set correctly
    - [ ] Named with _high suffix
    
    LOW POLY:
    - [ ] All transforms applied
    - [ ] UVs unwrapped with proper padding
    - [ ] No overlapping UVs (for unique maps)
    - [ ] Named with _low suffix
    - [ ] Matches high poly in world position
    
    CAGE (optional but recommended):
    - [ ] Duplicate of low poly, slightly inflated
    - [ ] Named with _cage suffix
    - [ ] No intersections with high poly
    ```
    
    ### Cage Creation
    ```
    Method 1: Manual (Most Control)
    1. Duplicate low poly
    2. Apply Displace modifier with constant offset
    3. Manually adjust problem areas
    
    Method 2: Ray Distance (Faster)
    1. Use baking software's ray distance setting
    2. Start with auto, adjust per-mesh
    
    Cage Rules:
    - Must fully encompass high poly
    - Should not intersect high poly
    - Larger cage = more bake margin for error
    - Too large = ray misses, artifacts
    ```
    
    ### Baking Settings (Marmoset Toolbag)
    ```
    Samples:        64 (production) / 16 (preview)
    Output Size:    Match final texture (2K, 4K)
    Padding:        Match UV padding in pixels
    
    Normal Map:
    - Tangent space (for game engines)
    - Flip Y: ON for Unity, OFF for Unreal
    
    AO Map:
    - Ray count: 128+
    - Ignore backfaces: ON
    - Self-occlusion only: typically ON
    ```
    
    ### Common Baking Artifacts and Fixes
    ```
    PROBLEM: Wavy/wobbly normals
    CAUSE: Low poly normals not matching high poly
    FIX: Set low poly to smooth shading, add hard edges at UV seams
    
    PROBLEM: Black areas in bake
    CAUSE: Cage too tight, rays missing high poly
    FIX: Inflate cage, increase ray distance
    
    PROBLEM: "Skirt" artifacts at edges
    CAUSE: Rays hitting wrong surface
    FIX: Add geometry to low poly to separate surfaces
    
    PROBLEM: Seams visible on normal map
    CAUSE: UV seam on curved surface
    FIX: Move seam to hard edge, or split mesh at seam
    
    PROBLEM: Gradient across flat surface
    CAUSE: Averaged normals on low poly
    FIX: Set hard edges on 90-degree corners
    ```
    

---
  #### **Id**
retopology-workflow
  #### **Name**
Retopology Best Practices
  #### **Description**
    Create optimized, animation-ready topology from sculpts using manual and
    semi-automatic techniques.
    
  #### **When To Use**
After sculpting, for game/animation-ready mesh creation
  #### **Implementation**
    ## Retopology Target Budgets
    
    ### Character Poly Budgets (Triangles)
    ```
    AAA Current-Gen (2024):
    - Hero character:     80,000 - 150,000
    - Main NPCs:          30,000 - 60,000
    - Background NPCs:    10,000 - 20,000
    - Creatures (large):  50,000 - 100,000
    
    Mobile/VR:
    - Main character:     5,000 - 15,000
    - NPCs:               2,000 - 5,000
    
    Film/Cinematic:
    - No real limit, but animation-friendly topology
    ```
    
    ### Body Part Distribution (Hero Character)
    ```
    Head/Face:    25-30%  (most expression detail)
    Torso:        20-25%  (deformation areas)
    Arms:         15-20%  (elbow/wrist detail)
    Hands:        15-20%  (finger articulation)
    Legs:         15-20%  (knee/ankle detail)
    ```
    
    ### Manual Retopo Workflow (Blender)
    ```
    Setup:
    1. Import sculpt, apply shrinkwrap modifier to new mesh
    2. Enable X-mirror for symmetrical work
    3. Use Poly Build or RetopoFlow add-on
    
    Process:
    1. Start with main edge loops (eye, mouth, joints)
    2. Connect loops with quad fills
    3. Work from high-detail areas outward
    4. Check topology against animation requirements
    5. Final pass: optimize unnecessary geometry
    
    Shrinkwrap Settings:
    - Mode: Nearest Surface Point
    - Snap Mode: Above Surface
    - Offset: 0.001 (small gap prevents z-fighting)
    ```
    
    ### Semi-Automatic Tools
    ```
    ZBrush ZRemesher:
    - Good for: organic shapes, quick iterations
    - Settings: Target poly count, adaptive size ON
    - Post-process: Always manual cleanup for animation
    
    Quad Remesher (Blender/3ds Max):
    - Better edge flow than ZRemesher
    - Can guide with edge flow curves
    - Still needs manual work at joints
    
    When to Use Automatic:
    - Props and hard surface (no deformation)
    - Quick previews
    - Background assets
    
    When to Use Manual:
    - Face topology (always)
    - Joint areas (elbows, knees, fingers)
    - Anything with blend shapes
    ```
    

---
  #### **Id**
export-pipeline
  #### **Name**
Export Pipeline Standards
  #### **Description**
    Standardized export workflow for all major game engines and formats,
    avoiding the most common export issues.
    
  #### **When To Use**
When preparing assets for game engines or external tools
  #### **Implementation**
    ## Pre-Export Checklist
    
    ### Universal Requirements
    ```
    - [ ] All transforms applied (scale, rotation, location)
    - [ ] Scale is 1.0, 1.0, 1.0
    - [ ] Origin point is correct (usually bottom-center)
    - [ ] Normals are facing outward
    - [ ] No n-gons (triangulate if needed)
    - [ ] No non-manifold geometry
    - [ ] No floating vertices
    - [ ] Named correctly (no spaces, no special characters)
    ```
    
    ### Format Selection
    ```
    FBX:
    - Best for: Unreal Engine, Unity (with animation)
    - Pros: Industry standard, embedded materials/textures
    - Cons: Proprietary format, versioning issues
    
    glTF/GLB:
    - Best for: Web, Godot, cross-platform
    - Pros: Open standard, PBR material support
    - Cons: Less animation support than FBX
    
    OBJ:
    - Best for: Static meshes, quick transfer
    - Pros: Universal support, simple format
    - Cons: No animation, no hierarchy
    
    USD:
    - Best for: Film/VFX, complex scenes
    - Pros: Industry standard for film, non-destructive
    - Cons: Complex, not all game engines support
    ```
    
    ### FBX Export Settings (Blender)
    ```
    Scale:              1.0 (or 0.01 for Unreal if needed)
    Apply Scalings:     FBX All
    Forward:            -Y Forward (Unreal) / Z Forward (Unity)
    Up:                 Z Up
    
    Geometry:
    - Apply Modifiers:  ON
    - Triangulate:      ON (for game engines)
    - Tangent Space:    ON
    
    Armature:
    - Add Leaf Bones:   OFF (usually)
    - Primary Bone Axis: Y
    - Secondary Bone Axis: X
    
    Animation:
    - Bake Animation:   ON
    - NLA Strips:       OFF (export each action separately)
    ```
    
    ### Engine-Specific Settings
    
    #### Unreal Engine
    ```
    FBX Settings in Blender:
    - Scale: 1.0 (UE handles conversion)
    - Forward: -Y Forward
    - Up: Z Up
    
    In Unreal Import:
    - Convert Scene: ON
    - Force Front XAxis: OFF
    - Convert Scene Unit: ON
    - Import Normals: Import Normals and Tangents
    ```
    
    #### Unity
    ```
    FBX Settings in Blender:
    - Scale: 1.0
    - Forward: -Z Forward
    - Up: Y Up
    
    Or just use .blend file directly (Unity 2020.1+)
    
    In Unity Import:
    - Scale Factor: 1
    - Import BlendShapes: ON
    - Import Normals: Import
    - Tangents: Calculate Mikktspace
    ```
    
    #### Godot
    ```
    Preferred: glTF 2.0 (.glb)
    
    glTF Settings in Blender:
    - Format: glTF Binary (.glb)
    - Include: Selected Objects only
    - Transform: +Y Up
    - Geometry: Apply Modifiers, UVs, Normals
    - Compression: Draco (for web)
    ```
    

---
  #### **Id**
naming-conventions
  #### **Name**
Asset Naming Conventions
  #### **Description**
    Industry-standard naming for 3D assets, ensuring clarity in large productions
    and compatibility with version control.
    
  #### **When To Use**
Always - from project start
  #### **Implementation**
    ## Naming Structure
    
    ### General Format
    ```
    [Prefix]_[AssetName]_[Variant]_[LOD/Type]
    
    Examples:
    SM_Chair_Wood_LOD0          (Static Mesh)
    SK_Character_Hero_LOD1      (Skeletal Mesh)
    T_Chair_Wood_D              (Texture - Diffuse)
    M_Chair_Wood                (Material)
    ```
    
    ### Prefixes by Type
    ```
    SM_     Static Mesh
    SK_     Skeletal Mesh
    T_      Texture
    M_      Material
    MI_     Material Instance
    A_      Animation
    BP_     Blueprint (Unreal)
    FX_     Effect/Particle
    S_      Sound
    W_      Widget
    ```
    
    ### Texture Suffixes
    ```
    _D      Diffuse / Albedo / Base Color
    _N      Normal Map
    _R      Roughness
    _M      Metallic
    _AO     Ambient Occlusion
    _H      Height / Displacement
    _E      Emissive
    _O      Opacity / Alpha
    _ARM    Packed: AO, Roughness, Metallic (RGB)
    _ORM    Packed: Occlusion, Roughness, Metallic (RGB)
    ```
    
    ### LOD Naming
    ```
    _LOD0   Base mesh (highest quality)
    _LOD1   First reduction
    _LOD2   Second reduction
    _LOD3   Third reduction
    _LOD4   Lowest quality / impostor
    ```
    
    ### Version Control Friendly Names
    ```
    DO:
    - Use underscores, not spaces
    - Use PascalCase or camelCase
    - Keep names under 64 characters
    - Use numbers for variants (Chair_01, Chair_02)
    
    DON'T:
    - Spaces in names (Chair Wood ❌)
    - Special characters (&, %, #, etc.)
    - Very long names
    - Ambiguous names (Final, Final2, FinalFinal)
    ```
    
    ### Folder Structure
    ```
    Project/
    ├── Characters/
    │   ├── Hero/
    │   │   ├── Mesh/
    │   │   ├── Textures/
    │   │   ├── Materials/
    │   │   └── Animations/
    │   └── NPCs/
    ├── Props/
    │   ├── Furniture/
    │   └── Weapons/
    ├── Environment/
    │   ├── Modular/
    │   └── Unique/
    └── VFX/
    ```
    

## Anti-Patterns


---
  #### **Id**
n-gon-modeling
  #### **Name**
Modeling with N-gons
  #### **Description**
    Leaving n-gons (polygons with more than 4 sides) in production geometry.
    N-gons cause unpredictable subdivision, shading artifacts, and export issues.
    
  #### **Why Bad**
    - Subdivision surfaces create artifacts at n-gon boundaries
    - Different software triangulates n-gons differently
    - Causes shading discontinuities
    - Can break physics/collision generation
    - Animation deformation becomes unpredictable
    
  #### **What To Do Instead**
    Always model with quads. Use triangles only where necessary (poles,
    terminating edge loops). Convert n-gons to quads before any export.
    
    In Blender: Select All → Mesh → Clean Up → Split Non-Planar Faces,
    then Mesh → Face → Triangulate Faces → Poke Faces to create better topology.
    

---
  #### **Id**
unapplied-transforms
  #### **Name**
Exporting with Unapplied Transforms
  #### **Description**
    Exporting models without applying scale, rotation, and location transforms.
    This causes scaling and orientation issues in game engines.
    
  #### **Why Bad**
    - Object may appear at wrong scale in engine
    - Rotation values affect animation and physics
    - Parent/child relationships break
    - Baking produces incorrect results
    - LOD switching may not work correctly
    
  #### **What To Do Instead**
    Before ANY export: Ctrl+A → All Transforms (Blender) or Freeze
    Transformations (Maya). Verify scale is 1,1,1 and rotation is 0,0,0.
    

---
  #### **Id**
overlapping-uvs-baking
  #### **Name**
Overlapping UVs for Unique Bakes
  #### **Description**
    Using overlapping/mirrored UVs when baking unique maps (normal, AO, etc.).
    Overlapping UVs work for tiling textures but cause baking artifacts.
    
  #### **Why Bad**
    - Multiple surfaces bake to same UV space
    - Normal map shows averaged/corrupted data
    - AO shows incorrect shadowing
    - Impossible to paint unique details
    
  #### **What To Do Instead**
    For baking: use a non-overlapping UV set (UV2 channel).
    For final texture: can use optimized UVs with mirroring.
    Many engines support multiple UV channels for this reason.
    

---
  #### **Id**
bad-boolean-cleanup
  #### **Name**
Poor Boolean Cleanup
  #### **Description**
    Leaving boolean operations without cleaning up the resulting geometry,
    leading to n-gons, overlapping faces, and non-manifold edges.
    
  #### **Why Bad**
    - Creates n-gons that must be fixed later
    - Can create non-manifold geometry
    - Causes shading issues
    - Makes topology unusable for animation
    - Subdivision creates artifacts
    
  #### **What To Do Instead**
    After boolean operations:
    1. Check for n-gons and triangulate/quad-ify
    2. Merge vertices by distance (remove doubles)
    3. Check for non-manifold geometry
    4. Verify all normals are correct
    
    Better: Use the Exact boolean solver and plan cuts to avoid cleanup.
    

---
  #### **Id**
texel-density-inconsistency
  #### **Name**
Inconsistent Texel Density
  #### **Description**
    UV islands with wildly different texel densities, causing some surfaces
    to appear blurry while others are sharp.
    
  #### **Why Bad**
    - Visual inconsistency is immediately noticeable
    - Important surfaces may be under-detailed
    - Unimportant surfaces waste texture space
    - Makes the asset look unprofessional
    
  #### **What To Do Instead**
    1. Set a target texel density for the project
    2. Use texel density checker tools
    3. Adjust UV island scale to match density
    4. Intentionally vary density only for hero vs background areas
    

---
  #### **Id**
modeling-at-wrong-scale
  #### **Name**
Modeling at Wrong Scale
  #### **Description**
    Creating models at arbitrary scale instead of real-world or engine-native
    units, causing issues when combining assets.
    
  #### **Why Bad**
    - Assets don't fit together
    - Physics behaves incorrectly
    - Lighting/shadows look wrong
    - Texture density becomes unpredictable
    - Modular pieces don't snap
    
  #### **What To Do Instead**
    Set up your scene with correct units from the START:
    - Blender: Scene Properties → Units → Metric
    - Model at 1 unit = 1 meter
    - Use reference objects (standard door = 2.1m height, 0.9m width)
    

---
  #### **Id**
dense-topology-everywhere
  #### **Name**
Dense Topology Where Not Needed
  #### **Description**
    Adding the same topology density everywhere regardless of visibility,
    deformation needs, or silhouette importance.
    
  #### **Why Bad**
    - Wastes performance budget
    - Makes editing harder
    - Increases file size
    - Slows down rendering
    - Makes rigging more difficult
    
  #### **What To Do Instead**
    Distribute polygons based on:
    1. Deformation needs (more at joints)
    2. Silhouette importance (more at edges)
    3. Camera proximity (more on hero areas)
    4. Detail requirements (more where normal maps can't fake it)
    
references/sharp_edges.md
# 3D Modeling - Sharp Edges
references/validations.md
# 3D Modeling - Validations

## Unapplied Transforms in Export Script

### **Id**
unapplied-transforms-export
### **Severity**
critical
### **Category**
export
### **Description**
  Export scripts that don't apply transforms before exporting will cause
  scale and rotation issues in game engines.
  
### **Detection**
  #### **Type**
regex
  #### **Pattern**
fbx_export|export_scene\.fbx|gltf_export
  #### **File Patterns**
    - *.py
    - *.blend
### **Anti Pattern Example**
  # BAD: Exporting without applying transforms
  import bpy
  
  def export_model(filepath):
      bpy.ops.export_scene.fbx(filepath=filepath)  # No transform application!
  
### **Correct Example**
  # GOOD: Apply transforms before export
  import bpy
  
  def export_model(filepath):
      # Select all mesh objects
      for obj in bpy.context.scene.objects:
          if obj.type == 'MESH':
              obj.select_set(True)
              bpy.context.view_layer.objects.active = obj
  
      # Apply all transforms
      bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
  
      # Now export
      bpy.ops.export_scene.fbx(
          filepath=filepath,
          apply_scale_options='FBX_SCALE_ALL',
          apply_unit_scale=True
      )
  
### **Fix Suggestion**
  Add transform application before export:
  ```python
  bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
  ```
  

## Missing Normals Recalculation

### **Id**
missing-normals-recalculation
### **Severity**
high
### **Category**
topology
### **Description**
  Scripts that modify geometry but don't recalculate normals can leave
  models with inverted or incorrect normals.
  
### **Detection**
  #### **Type**
regex
  #### **Pattern**
bpy\.ops\.mesh\.(flip_normals|mirror|boolean|bridge_edge_loops|extrude)
  #### **File Patterns**
    - *.py
### **Anti Pattern Example**
  # BAD: Mirror without recalculating normals
  import bpy
  
  def mirror_mesh():
      bpy.ops.object.mode_set(mode='EDIT')
      bpy.ops.mesh.select_all(action='SELECT')
      bpy.ops.transform.mirror(constraint_axis=(True, False, False))
      # Missing: recalculate_normals!
      bpy.ops.object.mode_set(mode='OBJECT')
  
### **Correct Example**
  # GOOD: Recalculate normals after geometry operations
  import bpy
  
  def mirror_mesh():
      bpy.ops.object.mode_set(mode='EDIT')
      bpy.ops.mesh.select_all(action='SELECT')
      bpy.ops.transform.mirror(constraint_axis=(True, False, False))
      bpy.ops.mesh.normals_make_consistent(inside=False)  # Recalculate!
      bpy.ops.object.mode_set(mode='OBJECT')
  
### **Fix Suggestion**
  Add normals recalculation after geometry changes:
  ```python
  bpy.ops.mesh.normals_make_consistent(inside=False)
  ```
  

## No N-gon Check Before Export

### **Id**
no-ngon-check
### **Severity**
high
### **Category**
topology
### **Description**
  Export scripts should validate that meshes contain no n-gons before
  exporting to avoid subdivision and shading issues.
  
### **Detection**
  #### **Type**
regex
  #### **Pattern**
export_scene\.(fbx|gltf|obj)
  #### **File Patterns**
    - *.py
### **Anti Pattern Example**
  # BAD: Export without n-gon validation
  import bpy
  
  def export_for_game(filepath):
      bpy.ops.export_scene.fbx(filepath=filepath)
  
### **Correct Example**
  # GOOD: Check for n-gons before export
  import bpy
  import bmesh
  
  def has_ngons(obj):
      """Check if mesh has any n-gons (faces with 5+ vertices)"""
      if obj.type != 'MESH':
          return False
      bm = bmesh.new()
      bm.from_mesh(obj.data)
      ngons = [f for f in bm.faces if len(f.verts) > 4]
      count = len(ngons)
      bm.free()
      return count > 0
  
  def export_for_game(filepath):
      for obj in bpy.context.selected_objects:
          if has_ngons(obj):
              raise ValueError(f"Object {obj.name} contains n-gons! Fix before export.")
  
      bpy.ops.export_scene.fbx(filepath=filepath)
  
### **Fix Suggestion**
  Add n-gon validation before export:
  ```python
  def has_ngons(obj):
      bm = bmesh.new()
      bm.from_mesh(obj.data)
      ngons = [f for f in bm.faces if len(f.verts) > 4]
      bm.free()
      return len(ngons) > 0
  ```
  

## No Non-Manifold Geometry Check

### **Id**
no-nonmanifold-check
### **Severity**
high
### **Category**
topology
### **Description**
  Export scripts should check for non-manifold geometry which causes
  physics and baking failures.
  
### **Detection**
  #### **Type**
regex
  #### **Pattern**
export_scene\.(fbx|gltf|obj)
  #### **File Patterns**
    - *.py
### **Correct Example**
  # GOOD: Check for non-manifold geometry
  import bpy
  import bmesh
  
  def has_nonmanifold(obj):
      """Check for non-manifold edges and verts"""
      if obj.type != 'MESH':
          return False
  
      bm = bmesh.new()
      bm.from_mesh(obj.data)
  
      # Non-manifold edges (not exactly 2 faces)
      nonmanifold_edges = [e for e in bm.edges if not e.is_manifold]
  
      # Non-manifold verts (edges don't form closed fan)
      nonmanifold_verts = [v for v in bm.verts if not v.is_manifold]
  
      has_issues = len(nonmanifold_edges) > 0 or len(nonmanifold_verts) > 0
      bm.free()
      return has_issues
  
  def export_validated(filepath):
      for obj in bpy.context.selected_objects:
          if has_nonmanifold(obj):
              print(f"WARNING: {obj.name} has non-manifold geometry!")
      bpy.ops.export_scene.fbx(filepath=filepath)
  

## Missing Merge by Distance After Boolean

### **Id**
merge-by-distance-missing
### **Severity**
medium
### **Category**
topology
### **Description**
  Boolean operations leave floating vertices. Scripts should clean up
  after boolean operations.
  
### **Detection**
  #### **Type**
regex
  #### **Pattern**
bpy\.ops\.object\.modifier_apply.*bool|\.BOOLEAN
  #### **File Patterns**
    - *.py
### **Anti Pattern Example**
  # BAD: Apply boolean without cleanup
  import bpy
  
  def apply_boolean(obj_name, cutter_name):
      obj = bpy.data.objects[obj_name]
      mod = obj.modifiers.new(name="Boolean", type='BOOLEAN')
      mod.object = bpy.data.objects[cutter_name]
      mod.operation = 'DIFFERENCE'
  
      bpy.context.view_layer.objects.active = obj
      bpy.ops.object.modifier_apply(modifier="Boolean")
      # Missing cleanup!
  
### **Correct Example**
  # GOOD: Clean up after boolean
  import bpy
  
  def apply_boolean_clean(obj_name, cutter_name):
      obj = bpy.data.objects[obj_name]
      mod = obj.modifiers.new(name="Boolean", type='BOOLEAN')
      mod.object = bpy.data.objects[cutter_name]
      mod.operation = 'DIFFERENCE'
      mod.solver = 'EXACT'  # More reliable solver
  
      bpy.context.view_layer.objects.active = obj
      bpy.ops.object.modifier_apply(modifier="Boolean")
  
      # CLEANUP: Remove floating vertices
      bpy.ops.object.mode_set(mode='EDIT')
      bpy.ops.mesh.select_all(action='SELECT')
      bpy.ops.mesh.remove_doubles(threshold=0.0001)
      bpy.ops.mesh.delete_loose(use_verts=True, use_edges=True, use_faces=False)
      bpy.ops.object.mode_set(mode='OBJECT')
  

## Unity Calculating Normals Instead of Importing

### **Id**
unity-import-normals-calculate
### **Severity**
medium
### **Category**
import
### **Description**
  Unity should import normals from the file rather than calculating them,
  to preserve artist intent for hard/soft edges.
  
### **Detection**
  #### **Type**
regex
  #### **Pattern**
ModelImporter|ImportNormals|normalImportMode
  #### **File Patterns**
    - *.cs
    - *.meta
### **Anti Pattern Example**
  // BAD: Calculate normals in Unity
  ModelImporter importer = assetImporter as ModelImporter;
  importer.importNormals = ModelImporterNormals.Calculate;
  
### **Correct Example**
  // GOOD: Import normals from file
  ModelImporter importer = assetImporter as ModelImporter;
  importer.importNormals = ModelImporterNormals.Import;
  importer.normalCalculationMode = ModelImporterNormalCalculationMode.AreaAndAngleWeighted;
  importer.normalSmoothingSource = ModelImporterNormalSmoothingSource.FromSmoothingGroups;
  

## Unity Non-Standard Scale Factor

### **Id**
unity-scale-factor-wrong
### **Severity**
medium
### **Category**
import
### **Description**
  Unity scale factor should typically be 1.0 for properly exported assets.
  Non-standard values indicate a pipeline issue.
  
### **Detection**
  #### **Type**
regex
  #### **Pattern**
globalScale\s*=\s*(?!1\.0|1f)
  #### **File Patterns**
    - *.cs
    - *.meta
### **Anti Pattern Example**
  // BAD: Compensating for bad export with scale factor
  importer.globalScale = 0.01f;  // Indicates export issue
  
### **Correct Example**
  // GOOD: Standard scale with proper export pipeline
  ModelImporter importer = assetImporter as ModelImporter;
  importer.globalScale = 1.0f;
  importer.useFileUnits = true;
  

## Unreal LOD Not Using Auto Compute

### **Id**
unreal-lod-no-auto-compute
### **Severity**
low
### **Category**
optimization
### **Description**
  For hero assets, LODs should be manually created rather than auto-computed
  to maintain quality.
  
### **Detection**
  #### **Type**
regex
  #### **Pattern**
bAutoComputeLODScreenSize\s*=\s*true
  #### **File Patterns**
    - *.cpp
    - *.h
### **Correct Example**
  // For hero assets, set explicit LOD distances
  StaticMesh->bAutoComputeLODScreenSize = false;
  StaticMesh->SourceModels[0].ScreenSize = 1.0f;
  StaticMesh->SourceModels[1].ScreenSize = 0.5f;
  StaticMesh->SourceModels[2].ScreenSize = 0.25f;
  

## Unreal Using Complex Collision

### **Id**
unreal-collision-not-simplified
### **Severity**
medium
### **Category**
optimization
### **Description**
  Using the render mesh for collision is expensive. Most objects should
  use simplified collision.
  
### **Detection**
  #### **Type**
regex
  #### **Pattern**
CollisionTraceFlag\s*=\s*CTF_UseComplexAsSimple|bUseComplexAsSimpleCollision\s*=\s*true
  #### **File Patterns**
    - *.cpp
    - *.h
    - *.ini
### **Anti Pattern Example**
  // BAD: Using render mesh for collision (expensive)
  StaticMeshComponent->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
  StaticMesh->ComplexCollisionMesh = StaticMesh;
  StaticMesh->bUseComplexAsSimpleCollision = true;
  
### **Correct Example**
  // GOOD: Use simplified collision
  // In Blender: Create low-poly collision mesh named UCX_MeshName
  // Or in Unreal: Auto-generate convex collision
  StaticMesh->CreateBodySetup();
  StaticMesh->BodySetup->CollisionTraceFlag = CTF_UseSimpleAsComplex;
  
  // For simple shapes, use primitives
  UBoxComponent* BoxCollision = CreateDefaultSubobject<UBoxComponent>(TEXT("BoxCollision"));
  

## Godot Not Generating Collision Shape

### **Id**
godot-mesh-not-generating-collision
### **Severity**
medium
### **Category**
import
### **Description**
  Imported meshes in Godot should have collision shapes generated for
  physics interaction.
  
### **Detection**
  #### **Type**
regex
  #### **Pattern**
\.glb|\.gltf
  #### **File Patterns**
    - *.tscn
    - *.tres
### **Correct Example**
  # In Godot import settings (.import file):
  [params]
  meshes/generate_collision_shapes=true
  meshes/collision_shape_type=1  # Convex
  
  # Or programmatically:
  var mesh_instance = MeshInstance3D.new()
  mesh_instance.mesh = load("res://models/object.glb")
  mesh_instance.create_trimesh_collision()  # For static
  # OR
  mesh_instance.create_convex_collision()   # For dynamic
  

## Invalid Asset Naming Convention

### **Id**
invalid-asset-naming
### **Severity**
low
### **Category**
organization
### **Description**
  Asset names should follow consistent conventions for organization
  and automation compatibility.
  
### **Detection**
  #### **Type**
regex
  #### **Pattern**
(?i)^(final|new|test|old|copy|backup|\d+)[._-]|\s+\.|[^a-zA-Z0-9_.-]
  #### **File Patterns**
    - *.fbx
    - *.obj
    - *.gltf
    - *.glb
    - *.blend
### **Anti Pattern Example**
  # BAD naming examples:
  Final_Chair.fbx
  chair final v2.fbx
  New Folder/model.fbx
  test123.fbx
  chair (1).fbx
  
### **Correct Example**
  # GOOD naming convention:
  SM_Chair_Wood_LOD0.fbx
  SK_Character_Hero.fbx
  SM_Prop_Barrel_Metal_v02.fbx
  
  # Pattern: [Type]_[Category]_[Name]_[Variant]_[LOD/Version]
  

## Missing LOD Suffix on LOD Meshes

### **Id**
missing-lod-suffix
### **Severity**
low
### **Category**
organization
### **Description**
  LOD meshes should have explicit _LOD# suffix for proper identification
  and auto-import by game engines.
  
### **Detection**
  #### **Type**
regex
  #### **Pattern**
(?<!LOD[0-9])\.fbx$
  #### **File Patterns**
    - *_low.fbx
    - *_med.fbx
    - *_high.fbx
### **Anti Pattern Example**
  # BAD: Unclear LOD naming
  chair_low.fbx
  chair_medium.fbx
  chair_high.fbx
  
### **Correct Example**
  # GOOD: Standard LOD naming
  SM_Chair_LOD0.fbx  # Base mesh
  SM_Chair_LOD1.fbx  # 50% reduction
  SM_Chair_LOD2.fbx  # 25% reduction
  SM_Chair_LOD3.fbx  # 12.5% reduction
  

## Non-Power-of-Two Texture Dimensions

### **Id**
non-power-of-two-textures
### **Severity**
medium
### **Category**
optimization
### **Description**
  Textures should be power-of-two dimensions (256, 512, 1024, 2048, 4096)
  for optimal GPU memory usage and mipmap generation.
  
### **Detection**
  #### **Type**
script
  #### **Script**
    # This would be validated by a separate texture checking tool
    # Dimensions should be: 256, 512, 1024, 2048, 4096
    valid_sizes = [256, 512, 1024, 2048, 4096, 8192]
    
### **File Patterns**
  - *.png
  - *.tga
  - *.jpg
### **Correct Example**
  # GOOD texture dimensions:
  T_Chair_D.png     # 2048x2048
  T_Character_D.png # 4096x4096
  T_Icon_UI.png     # 256x256
  
  # Can be non-square but still power-of-two:
  T_Ribbon_D.png    # 2048x256
  

## Wrong Texture Type Suffix

### **Id**
wrong-texture-suffix
### **Severity**
low
### **Category**
organization
### **Description**
  Texture files should have correct suffixes indicating their type
  for material auto-assignment.
  
### **Detection**
  #### **Type**
regex
  #### **Pattern**
(?i)(?<!_[DNRMAOHE])(_diffuse|_normal|_roughness|_metallic|_ao|_height|_emissive|_opacity)\.(?:png|tga|jpg)
  #### **File Patterns**
    - *.png
    - *.tga
    - *.jpg
### **Anti Pattern Example**
  # BAD: Full word suffixes (inconsistent)
  chair_diffuse.png
  chair_normal.png
  chair_roughness.png
  
### **Correct Example**
  # GOOD: Single letter suffixes (industry standard)
  T_Chair_D.png   # Diffuse/Albedo
  T_Chair_N.png   # Normal
  T_Chair_R.png   # Roughness
  T_Chair_M.png   # Metallic
  T_Chair_AO.png  # Ambient Occlusion
  T_Chair_H.png   # Height
  T_Chair_E.png   # Emissive
  
  # OR packed textures:
  T_Chair_ORM.png # Occlusion, Roughness, Metallic (RGB)
  T_Chair_ARM.png # AO, Roughness, Metallic (RGB)