Cherry Blossom Trees Session 2 + GREEN SCREEN Learning

Session 2 Work:
- Added cherry blossom tree PNG sprites (multiple attempts)
- Implemented random tree growth (0.3x - 0.7x scale)
- Increased scattered trees (15  50 across map)
- Wider tree distribution (10-90 range)

 Green Screen Experiments:
- Attempted AI-generated PNG with green screen (#00FF00)
- Implemented green chroma-key removal in PreloadScene
- Multiple iterations (normal  ultra  nuclear green removal)
- Conclusion: AI green screen unreliable, reverted to procedural

 Final Solution:
- Disabled PNG sprite rendering
- Using 100% procedural cherry blossom trees (pink triangles)
- Random growth scaling for variety
- 50+ trees scattered across entire map

 Documentation:
- Updated DNEVNIK.md with Session 2
- Added GREEN SCREEN RULE for future AI image generation
- Documented lessons learned

 Key Lessons:
- AI transparency/green screen NOT reliable
- Procedural graphics > problematic PNGs
- Hollywood uses green screen, but AI can't do it consistently
- Always have fallback plan!

Session: 1h (22:30-23:20)
Date: 14.12.2024
This commit is contained in:
2025-12-14 23:21:36 +01:00
parent a4d2d137ec
commit c5d6c01305
6 changed files with 117 additions and 14 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 KiB

View File

@@ -69,11 +69,11 @@ const Map2DData = {
this.addTreeCluster(map, 82, 88, 4);
this.addTreeCluster(map, 88, 82, 3);
// Scattered single trees
for (let i = 0; i < 15; i++) {
// Scattered single trees - MANY MORE!
for (let i = 0; i < 50; i++) {
this.addTreeCluster(map,
20 + Math.random() * 60,
20 + Math.random() * 60,
10 + Math.random() * 80, // Wider spread
10 + Math.random() * 80,
1
);
}

View File

@@ -62,6 +62,52 @@
---
## 🗓️ 14. December 2024 - Session 2: Cherry Blossom Trees + Visual Polish
**Trajanje:** 30 min (22:30 - 23:00)
**Cilj:** Dodati cherry blossom drevesa in testirati PNG sprite integration
### ✅ Dosežki:
1. **Cherry Blossom Trees:**
- ✅ Generirane AI PNG slike (`roza_cesnjevo_drevo.png`, `cesnja_sadje.png`)
- ✅ Dodan loading v PreloadScene.js
- ✅ Implementiran PNG sprite rendering v Flat2DTerrainSystem
- ✅ Testiranje različnih velikosti (0.8x → 0.5x scale)
2. **Background Removal Attempts:**
- ✅ Dodal cherry tree v `processSpriteTransparency()` seznam
- ✅ Implementiral `ultraRemoveBackground()` za pink + brown piksle
- ❌ AI generiran PNG ima črne obrobe ki jih težko odstranimo
3. **Končna Rešitev:**
- ✅ Revert nazaj na **proceduralne cherry blossom trees** (roza trikotniki)
- ✅ Čisto brez artefaktov, pravilno rendering
### 🎨 **POMEMBNO PRAVILO - Image Generation:**
**🟢 VSE PRIHODNJE AI GENERIRANE SLIKE:**
- **GREEN SCREEN BACKGROUND** (RGB: 0, 255, 0)
- **100% solid green** - NO gradients, NO transparency
- Razlog: Chroma-key removal je 100% zanesljiv!
- Sistem že ima `processSpriteTransparency()` - lahko dodamo green detection
**Format:**
```
Background: Solid bright green (#00FF00)
Subject: Clear, sharp edges
No anti-aliasing on green boundary
```
### 💡 Lekcije:
1. **AI transparency NE DELUJE zanesljivo** - vedno ostanejo artefakti
2. **Green screen je STANDARD** - uporablja Hollywood, uporabimo tudi mi!
3. **Procedural graphics > problematic PNGs** - če PNG ne deluje, procedural je backup
4. **Test early** - raje testiraj hitro kot da persistent z nedelujočim pristopom
---
## **Prejšnji Sessions:**
*(Sessions pred 14.12.2024 niso dokumentirani v tem dnevniku)*

View File

@@ -56,6 +56,10 @@ class PreloadScene extends Phaser.Scene {
this.load.image('tree_blue_final', 'assets/tree_blue_final.png');
this.load.image('tree_dead_final', 'assets/tree_dead_final.png');
// 🌸 CHERRY BLOSSOM TREES (NEW!)
this.load.image('cesnjevo_drevo', 'assets/sprites/roza_cesnjevo_drevo.png');
this.load.image('cesnja', 'assets/sprites/cesnja_sadje.png');
// STARDEW VALLEY FOREST TREES (NEW!)
this.load.image('tree_purple', 'assets/tree_purple.png');
this.load.image('tree_apple', 'assets/tree_apple.png');
@@ -341,7 +345,10 @@ class PreloadScene extends Phaser.Scene {
'wheat_sprite',
'grass_sprite',
'leaf_sprite',
'stone_sprite'
'stone_sprite',
// 🌸 CHERRY BLOSSOM TREE
'cesnjevo_drevo'
];
spritesToProcess.forEach(spriteKey => {
@@ -353,6 +360,11 @@ class PreloadScene extends Phaser.Scene {
this.ultraRemoveBackground('fence_post');
}
// ULTRA AGGRESSIVE: Cherry Blossom Tree (remove black outlines!)
if (this.textures.exists('cesnjevo_drevo')) {
this.ultraRemoveBackground('cesnjevo_drevo');
}
console.log('✅ All sprites transparency processed!');
}
@@ -387,6 +399,18 @@ class PreloadScene extends Phaser.Scene {
const brightness = (r + g + b) / 3;
// 🟢 NUCLEAR GREEN SCREEN REMOVAL!
// Remove ANY pixel where green is even SLIGHTLY dominant
const isGreen = (
g > 100 && // Even darker greens
g > r && // Green beats red
g > b // Green beats blue
);
if (isGreen) {
data[i + 3] = 0; // NUKE IT!
continue;
}
// 1. Remove ALL grayscale colors (ANY shade of gray)
const isGrayscale = Math.abs(r - g) < 20 && Math.abs(g - b) < 20 && Math.abs(r - b) < 20;
if (isGrayscale && brightness > 80) {
@@ -626,17 +650,38 @@ class PreloadScene extends Phaser.Scene {
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;
// Remove EVERYTHING except brown wood colors
for (let i = 0; i < data.length; i += 4) {
const r = data[i];
const g = data[i + 1];
const b = data[i + 2];
// Different logic for different sprites
if (spriteKey === 'cesnjevo_drevo') {
// CHERRY BLOSSOM: Keep only PINK (flowers) and BROWN (trunk)
for (let i = 0; i < data.length; i += 4) {
const r = data[i];
const g = data[i + 1];
const b = data[i + 2];
// Keep only brown/wood colors: R > G > B and R is dominant
const isBrown = r > g && g > b && r > 80 && r < 200;
// Pink detection: R > G, R > B, pinkish tones
const isPink = r > 100 && r > g && r > b && (r - g) > 30;
if (!isBrown) {
data[i + 3] = 0; // Make transparent
// Brown detection: R > G > B, warm earthy tones
const isBrown = r > g && g > b && r > 80 && r < 200;
// Keep pink OR brown, remove everything else
if (!isPink && !isBrown) {
data[i + 3] = 0; // Make transparent
}
}
} else {
// FALLBACK: Fence post logic (keep only brown)
for (let i = 0; i < data.length; i += 4) {
const r = data[i];
const g = data[i + 1];
const b = data[i + 2];
// Keep only brown/wood colors: R > G > B and R is dominant
const isBrown = r > g && g > b && r > 80 && r < 200;
if (!isBrown) {
data[i + 3] = 0; // Make transparent
}
}
}

View File

@@ -314,6 +314,18 @@ class Flat2DTerrainSystem {
}
createTree(x, y) {
// 🌸 PNG DISABLED - procedural is more reliable!
// if (this.scene.textures.exists('cesnjevo_drevo')) {
// const tree = this.scene.add.image(x, y, 'cesnjevo_drevo');
// const growthScale = Phaser.Math.FloatBetween(0.3, 0.7);
// tree.setScale(growthScale);
// tree.setOrigin(0.5, 0.9);
// const shadow = this.scene.add.ellipse(x, y + 10, 20 * growthScale, 6, 0x000000, 0.15);
// shadow.setDepth(tree.depth - 1);
// return tree;
// }
// PROCEDURAL CHERRY BLOSSOM (RELIABLE!)
const graphics = this.scene.add.graphics();
// DROP SHADOW (2D depth!) 🎨