<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>JMRUDENT</title>
	<atom:link href="https://jmrudent.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://jmrudent.com</link>
	<description></description>
	<lastBuildDate>Sat, 06 Dec 2025 15:13:47 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://jmrudent.com/wp-content/uploads/2025/02/unnamed-150x150.png</url>
	<title>JMRUDENT</title>
	<link>https://jmrudent.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Retour d’expérience : Together de Biird</title>
		<link>https://jmrudent.com/2025/06/25/retour-dexperience-together-de-biird/</link>
		
		<dc:creator><![CDATA[jmrudent]]></dc:creator>
		<pubDate>Wed, 25 Jun 2025 16:25:59 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">https://jmrudent.com/?p=895</guid>

					<description><![CDATA[Le projet TOGETHER de Biird a été une belle surprise. À la fois [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h3 class="wp-block-heading">Le projet TOGETHER de <em>Biird</em> a été une belle surprise. À la fois amusant et intime, ce jeu de cartes pour couples a pour but d&rsquo;aider à mieux se connaître à travers des questions réparties par catégories.</h3>



<p>Mais pour moi qui devait en faire une vidéo promotionnelle, ce projet m’a permis d&rsquo;essayer une nouvelle méthode de production 3D plus rigoureuse, d’optimiser mes workflows pour le motion design, et d&rsquo;utiliser des nouveaux outils aujourd’hui intégrés à mes prestations pour mes clients.</p>



<figure class="wp-block-video wp-block-embed is-type-video is-provider-videopress"><video height="1080" style="aspect-ratio: 1920 / 1080;" width="1920" src="https://www.duvo4124.odns.fr/wp-content/uploads/2025/06/biird.mp4"></video></figure>



<p>Voici ce que j’ai appris</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">Une organisation modulaire grâce aux fichiers .blend séparés</h3>



<p>En terme d&rsquo;organisation de travail, je suis de nature pragmatique, à créer des visuels de manière destructives, c&rsquo;est à dire rapide à faire mais difficile à éditer ensuite.</p>



<p>Je suis habitué aux petites productions. Des images ou de courtes vidéos. Mais pour ce projet, certes de petite envergure, mais qui compte plusieurs plans, j&rsquo;ai choisi dès le départ une approche modulaire sur blender pour structurer le projet. J’ai créé un dossier <em><code>Assets</code> </em>où chaque élément (la boîte du jeu, les cartes, le dé) possède son propre fichier <code><em>.blend</em></code>.</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="825" height="398" src="https://jmrudent8.wordpress.com/wp-content/uploads/2025/05/image-2.png?w=825" alt="" class="wp-image-900" srcset="https://jmrudent.com/wp-content/uploads/2025/05/image-2.png 825w, https://jmrudent.com/wp-content/uploads/2025/05/image-2-300x145.png 300w, https://jmrudent.com/wp-content/uploads/2025/05/image-2-768x371.png 768w" sizes="(max-width: 825px) 100vw, 825px" /><figcaption class="wp-element-caption"><em>Exemple de mon fichier cards.blend</em></figcaption></figure>



<p>Dans chacun de ces fichiers, les objets sont rangés dans des <strong>collections clairement nommées</strong>. Puis, dans les fichiers de production (plan 1, plan 2, plan 3…), j’ai utilisé la fonction <strong>Link</strong> de Blender pour importer ces assets sans les dupliquer.</p>



<p>Le client n&rsquo;avait pas encore terminé tous les visuels des cartes, alors que la production avait commencée. L’intérêt ?  Une édition plus tard dans le fichier source met à jour automatiquement les assets dans chaque plan utilisé.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1536" height="1024" src="https://jmrudent8.wordpress.com/wp-content/uploads/2025/05/image-5.png?w=1024" alt="" class="wp-image-904" srcset="https://jmrudent.com/wp-content/uploads/2025/05/image-5.png 1536w, https://jmrudent.com/wp-content/uploads/2025/05/image-5-300x200.png 300w, https://jmrudent.com/wp-content/uploads/2025/05/image-5-1024x683.png 1024w, https://jmrudent.com/wp-content/uploads/2025/05/image-5-768x512.png 768w" sizes="(max-width: 1536px) 100vw, 1536px" /></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">Overrides : la flexibilité sans casser le système</h3>



<p>Travailler avec des <em>Link</em>, c’est puissant, mais parfois on a besoin de faire des ajustements spécifiques à une scène. Par exemple, changer la texture d’une carte, animer l&rsquo;élément ou ajuster son shader.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="694" height="392" src="https://jmrudent8.wordpress.com/wp-content/uploads/2025/05/image-7.png?w=694" alt="" class="wp-image-907" srcset="https://jmrudent.com/wp-content/uploads/2025/05/image-7.png 694w, https://jmrudent.com/wp-content/uploads/2025/05/image-7-300x169.png 300w" sizes="(max-width: 694px) 100vw, 694px" /><figcaption class="wp-element-caption"><em>Ici je demande de faire un override sur mon armature afin de pouvoir faire l&rsquo;animation de la boîte</em></figcaption></figure>



<p>Grâce aux Library Overrides, j’ai pu ajuster certains paramètres localement sans rompre le lien avec l’asset d’origine. Cela offre une vraie souplesse dans le workflow, tout en permettant de revenir à tout moment à l’état initial si nécessaire</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">Un addon maison pour recharger tous les liens en un seul clic</h3>



<p>Une limite de Blender (ou bien j&rsquo;ai pas trouvé le bouton), c’est la gestion manuelle du rechargement des libraries linkées. </p>



<p>Quand je modifie à la volée un asset dans son fichier d&rsquo;origine, je veux le voir changé tout de suite dans mes plans ouverts en même temps.</p>



<p>Pour ce faire, par défaut, il faut soit réouvrir le fichier de mon plan, soit aller dans l’outliner et recharger chaque bibliothèque une par une.</p>



<p>Parce que j&rsquo;ai tout plein de links dans mes scènes et que j&rsquo;ai un peu la flemme de les recharger un à un, j’ai développé un petit <strong>addon custom</strong> qui ajoute un <strong>bouton « Reload Libraries »</strong> dans l’interface. Résultat : tous les assets se mettent à jour en un clic, ce qui accélère les allers-retours entre modifications et rendu.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="412" height="310" src="https://jmrudent8.wordpress.com/wp-content/uploads/2025/05/image-15.png?w=412" alt="" class="wp-image-918" srcset="https://jmrudent.com/wp-content/uploads/2025/05/image-15.png 412w, https://jmrudent.com/wp-content/uploads/2025/05/image-15-300x226.png 300w" sizes="auto, (max-width: 412px) 100vw, 412px" /></figure>



<p>Voilà le code de l&rsquo;addon que j&rsquo;ai fait faire par une ia, c&rsquo;est cadeau:</p>



<details class="wp-block-details is-layout-flow wp-block-details-is-layout-flow"><summary>Code python</summary>
<pre class="wp-block-code"><code>bl_info = {
    "name": "Reload Linked Libraries",
    "author": "Jean-Marie Rudent + ia",
    "version": (1, 0),
    "blender": (4, 4, 0),
    "location": "Outliner &gt; Header",
    "description": "Adds a button to the Outliner header to reload all linked libraries (bpy.data.libraries)",
    "category": "System",
}

import bpy

# Operator to reload linked libraries
class WM_OT_reload_linked_libraries(bpy.types.Operator):
    bl_idname = "wm.reload_linked_libraries"
    bl_label = "Reload Linked Libraries"
    bl_description = "Reloads all linked libraries (bpy.data.libraries)"
    
    def execute(self, context):
        count = 0
        for lib in bpy.data.libraries:
            try:
                lib.reload()
                count += 1
            except Exception as e:
                self.report({'WARNING'}, f"Failed to reload {lib.filepath}: {str(e)}")
        self.report({'INFO'}, f"{count} library/libraries reloaded")
        return {'FINISHED'}

# Draw function to add the button to the Outliner header
def draw_reload_button(self, context):
    layout = self.layout
    layout.operator("wm.reload_linked_libraries", text="Reload Libraries", icon='FILE_REFRESH')

# Register classes and add the button to the Outliner header
def register():
    bpy.utils.register_class(WM_OT_reload_linked_libraries)
    bpy.types.OUTLINER_HT_header.append(draw_reload_button)

def unregister():
    bpy.types.OUTLINER_HT_header.remove(draw_reload_button)
    bpy.utils.unregister_class(WM_OT_reload_linked_libraries)

if __name__ == "__main__":
    register()
</code></pre>



<p></p>
</details>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">Add-ons Blender et techniques visuelles qui ont fait la différence</h3>



<p>En complément de mon outil maison, j’ai utilisé plusieurs add-ons puissants et des petites techniques de filou pour obtenir un rendu à la hauteur des attentes du projet :</p>



<h4 class="wp-block-heading"><a href="https://smouse.gumroad.com/l/shaderplus" target="_blank" rel="noreferrer noopener">Smouse Shader Plus</a></h4>



<p>Utilisé pour simuler des caustiques poussés, ou bien pour avoir des effets de matériau iridescents, c&rsquo;est aujourd&rsquo;hui un incontournable dans la création de mes shaders.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1119" height="473" src="https://jmrudent8.wordpress.com/wp-content/uploads/2025/05/image-9.png?w=1024" alt="" class="wp-image-910" srcset="https://jmrudent.com/wp-content/uploads/2025/05/image-9.png 1119w, https://jmrudent.com/wp-content/uploads/2025/05/image-9-300x127.png 300w, https://jmrudent.com/wp-content/uploads/2025/05/image-9-1024x433.png 1024w, https://jmrudent.com/wp-content/uploads/2025/05/image-9-768x325.png 768w" sizes="auto, (max-width: 1119px) 100vw, 1119px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1161" height="501" src="https://jmrudent8.wordpress.com/wp-content/uploads/2025/05/image-10.png?w=1024" alt="" class="wp-image-911" srcset="https://jmrudent.com/wp-content/uploads/2025/05/image-10.png 1161w, https://jmrudent.com/wp-content/uploads/2025/05/image-10-300x129.png 300w, https://jmrudent.com/wp-content/uploads/2025/05/image-10-1024x442.png 1024w, https://jmrudent.com/wp-content/uploads/2025/05/image-10-768x331.png 768w" sizes="auto, (max-width: 1161px) 100vw, 1161px" /></figure>



<h4 class="wp-block-heading"><a href="https://smouse.gumroad.com/l/gobosplus?layout=profile" target="_blank" rel="noreferrer noopener">Gobos Plus</a></h4>



<p>Un addon qui créée des lampes qui projettent des <strong>ombres stylisées</strong> et texturées, qui ajoutent de la profondeur sans alourdir la scène.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1121" height="457" src="https://jmrudent8.wordpress.com/wp-content/uploads/2025/05/image-11.png?w=1024" alt="" class="wp-image-913" srcset="https://jmrudent.com/wp-content/uploads/2025/05/image-11.png 1121w, https://jmrudent.com/wp-content/uploads/2025/05/image-11-300x122.png 300w, https://jmrudent.com/wp-content/uploads/2025/05/image-11-1024x417.png 1024w, https://jmrudent.com/wp-content/uploads/2025/05/image-11-768x313.png 768w" sizes="auto, (max-width: 1121px) 100vw, 1121px" /></figure>



<h4 class="wp-block-heading"><a href="https://superhivemarket.com/products/light-wrangler" target="_blank" rel="noreferrer noopener">Light Wrangler (Leonid Altman)</a></h4>



<p>Un outil game changer. Très précieux pour organiser et ajuster rapidement toutes les lumières d’une scène. Idéal pour affiner l’éclairage en motion design 3D.</p>



<p>Il propose une gestion des reflets facile et intuitif qui améliore grandement l&rsquo;éclairage d&rsquo;un produit, notamment métallique.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="808" height="384" src="https://jmrudent8.wordpress.com/wp-content/uploads/2025/05/image-12.png?w=808" alt="" class="wp-image-915" srcset="https://jmrudent.com/wp-content/uploads/2025/05/image-12.png 808w, https://jmrudent.com/wp-content/uploads/2025/05/image-12-300x143.png 300w, https://jmrudent.com/wp-content/uploads/2025/05/image-12-768x365.png 768w" sizes="auto, (max-width: 808px) 100vw, 808px" /></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h4 class="wp-block-heading">Réflecteur invisible dans les réflexions</h4>



<p>C&rsquo;est pas un addon, mais une technique que j&rsquo;ai découvert pour mettre en valeur les reflets.</p>



<p>J’ai ajouté un plan multicolore visible uniquement dans les <strong>réflexions</strong>, pour d’améliorer les <strong>highlights</strong> sur les cartes. Ce simple ajout donne plus de couleurs dans les reflets et valorise les matériaux sans modifier la lumière principale.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="886" height="563" src="https://jmrudent8.wordpress.com/wp-content/uploads/2025/05/image-13.png?w=886" alt="" class="wp-image-916" srcset="https://jmrudent.com/wp-content/uploads/2025/05/image-13.png 886w, https://jmrudent.com/wp-content/uploads/2025/05/image-13-300x191.png 300w, https://jmrudent.com/wp-content/uploads/2025/05/image-13-768x488.png 768w" sizes="auto, (max-width: 886px) 100vw, 886px" /></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">Affiner l’animation en synchronisation avec le son</h3>



<p>Pour caler précisément les animations sur la musique, j’ai adopté une méthode simple mais redoutablement efficace :</p>



<ul class="wp-block-list">
<li>J’ai effectué des <strong>rendus rapides avec <em>burn-in</em></strong>, tu texte à l&rsquo;image incluant le numéro de frame.</li>



<li>Ça m’a permis de <strong>travailler le rythme et les cuts dans DaVinci Resolve</strong>, en passant d’un logiciel à l’autre.</li>



<li>Une fois le montage affiné, je revenais dans Blender pour <strong>ajuster les mouvements, les accélérations, ou les timings d’apparition</strong>, en fonction du rythme et des transitions sonores.</li>
</ul>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" width="815" height="458" src="https://jmrudent8.wordpress.com/wp-content/uploads/2025/05/image-14-edited.png" alt="" class="wp-image-921" style="width:556px;height:auto" srcset="https://jmrudent.com/wp-content/uploads/2025/05/image-14-edited.png 815w, https://jmrudent.com/wp-content/uploads/2025/05/image-14-edited-300x169.png 300w, https://jmrudent.com/wp-content/uploads/2025/05/image-14-edited-768x432.png 768w" sizes="auto, (max-width: 815px) 100vw, 815px" /></figure>



<p>Cette méthode itérative m’a permis d’assurer une bonne cohérence entre l&rsquo;animation et le son pour un rendu rythmé et professionnel.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1536" height="1024" src="https://jmrudent8.wordpress.com/wp-content/uploads/2025/05/image-16.png?w=1024" alt="" class="wp-image-920" srcset="https://jmrudent.com/wp-content/uploads/2025/05/image-16.png 1536w, https://jmrudent.com/wp-content/uploads/2025/05/image-16-300x200.png 300w, https://jmrudent.com/wp-content/uploads/2025/05/image-16-1024x683.png 1024w, https://jmrudent.com/wp-content/uploads/2025/05/image-16-768x512.png 768w" sizes="auto, (max-width: 1536px) 100vw, 1536px" /></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">Ce que j’en retiens et que j’applique aujourd’hui pour mes clients</h3>



<ul class="wp-block-list">
<li><strong>Travailler en fichiers modulaires .blend</strong> prend un peu de temps au départ, mais ça assure clarté, évolutivité et rapidité de modification selon les retours.</li>



<li><strong>Link + Overrides</strong> permet de gérer efficacement les scènes complexes sans perdre la souplesse nécessaire aux ajustements créatifs.</li>



<li><strong>Automatiser les tâches répétitives</strong> (comme le rechargement d’assets) améliore le workflow.</li>



<li><strong>Des add-ons ciblés et des astuces techniques</strong> contribuent directement à laqualité des rendus.</li>



<li><strong>L&rsquo;alternance et la flexibilité entre animation et montage sur l&rsquo;audio</strong> se joue dès les premières itérations pour un résultat rapidement évaluable.</li>
</ul>



<p>Ces méthodes m&rsquo;ont permises de proposer des visuels 3D optimisés et adaptabkles, que j&rsquo;utiliserai systématiquement pour la promotion de jeux, de produits ou d’univers de marque.</p>



<p>La solution de créer une bibliothèque d&rsquo;assets via le « asset library » aurait été une bonne solution aussi. Cet section de blender est particulièrement pratique pour ce genre de projet aussi, et qui utilise aussi ce système de « link » ou « append » mais qui viennent directement d&rsquo;un tiroir accessible depuis les scènes.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">En bref : en vrai, c&rsquo;est chouette d&rsquo;être organisé</h3>



<p>Together de <em>Biird </em>m’a appris qu’en production 3D, on a beau connaître sur le papier les théories, mais les appliquer donne un toute nouvelle vision des méthodes. Avec les bons outils et une organisation solide, on crée plus vite, plus proprement pour son propre plaisir de faire les choses bien mais aussi pour s&rsquo;adapter aux attentes client.</p>



<p>Et quand l’image compte, ce sont ces méthodes invisibles, ce le travail bien fait en coulisses qui fait la différence.</p>



<p></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>J&#8217;ai créé un Addon Blender pour Gérer des Palettes de Couleurs</title>
		<link>https://jmrudent.com/2025/03/05/creer-un-addon-blender-pour-gerer-des-palettes-de-couleurs/</link>
		
		<dc:creator><![CDATA[jmrudent]]></dc:creator>
		<pubDate>Wed, 05 Mar 2025 22:13:47 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">https://jmrudent.com/?p=796</guid>

					<description><![CDATA[Créer dans Blender, c’est cool. Gérer ses couleurs dans Blender, c’est une autre [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p></p>



<h2 class="wp-block-heading">Pourquoi un addon de palettes dans Blender ?</h2>



<p>Je suis <strong>Jean-Marie Rudent</strong>, motion designer 3D. Récemment, j&rsquo;ai eu besoin d&rsquo;avoir des couleurs spécifiques et réutilisables pour mes shaders.</p>



<figure class="wp-block-image alignfull size-large"><img loading="lazy" decoding="async" width="961" height="442" src="https://jmrudent8.wordpress.com/wp-content/uploads/2025/03/image-3.png?w=961" alt="" class="wp-image-831" srcset="https://jmrudent.com/wp-content/uploads/2025/03/image-3.png 961w, https://jmrudent.com/wp-content/uploads/2025/03/image-3-300x138.png 300w, https://jmrudent.com/wp-content/uploads/2025/03/image-3-768x353.png 768w" sizes="auto, (max-width: 961px) 100vw, 961px" /></figure>



<p>J’ai cherché des addons de palettes pour le shading editor, mais j&rsquo;ai pas trouvé facilement. Je me suis dit: « Bon allez, je vais me le faire moi même alors ».</p>



<div class="wp-block-group is-nowrap is-layout-flex wp-container-core-group-is-layout-ad2f72ca wp-block-group-is-layout-flex">
<h2 class="wp-block-heading">Il existe déjà des palettes </h2>
</div>



<p>Blender a bien un système de palettes, mais il est caché dans des outils comme le <strong>Grease Pencil</strong> ou la <strong>Texture Paint</strong>, donc <strong>inaccessible</strong> directement quand on bosse dans le Shading Editor.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="261" height="482" src="https://jmrudent8.wordpress.com/wp-content/uploads/2025/03/capture-decran-2025-03-05-220756.png?w=261" alt="" class="wp-image-798" srcset="https://jmrudent.com/wp-content/uploads/2025/03/capture-decran-2025-03-05-220756.png 261w, https://jmrudent.com/wp-content/uploads/2025/03/capture-decran-2025-03-05-220756-162x300.png 162w" sizes="auto, (max-width: 261px) 100vw, 261px" /><figcaption class="wp-element-caption">Ça c&rsquo;est dans l&rsquo;outil de peinture, moi je le veux dans l&rsquo;outil de shader</figcaption></figure>
</div>


<p>Pour un projets de <strong>motion design 3D</strong>, j’avais besoin d’un accès rapide à des palettes personnalisées, sans perdre du temps à chercher des couleurs, à utiliser le eye-dropper à chaque fois sur une image externe ou copier-coller des valeurs RGB à la main.</p>



<h2 class="wp-block-heading">Solution : un addon de palettes dans le shader editor de Blender</h2>



<h3 class="wp-block-heading">Fonctionnalités principales :</h3>



<ul class="wp-block-list">
<li>Créer une <strong>bibliothèque de palettes</strong></li>



<li>Pouvoir renommer les palettes</li>



<li>Chaque palette peut contenir <strong>jusqu’à 10 couleurs</strong></li>



<li>Pouvoir renommer les couleurs</li>



<li>Les couleurs sont directement accessibles via un <strong>color picker</strong> natif de Blender</li>



<li>Accessible depuis le <strong>N-Panel</strong> du Shading Editor</li>
</ul>



<h2 class="wp-block-heading">Mon process de flemmard :</h2>



<h3 class="wp-block-heading">1. Première tentative avec Mercury</h3>



<p>Pour faire un addon sur blender, il faut faire un peu de python. Mais je connais pas le python. Donc j’ai utilisé <strong><a href="https://www.inceptionlabs.ai/">Mercury </a></strong>de <strong>Inception Labs</strong>, une IA spécialisée dev, pour qu’elle me génère la structure de mon addon. Première déception: Mercury me sortait uniquement des <strong>valeurs RGBA</strong> classiques, c’est-à-dire des champs numériques pour chaque canal (R, G, B, A), mais <strong>sans le bouton color picker</strong> de Blender, celui avec la <strong>roue chromatique</strong>.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="248" height="277" src="https://jmrudent8.wordpress.com/wp-content/uploads/2025/03/capture-decran-2025-03-05-214519.png?w=248" alt="" class="wp-image-805" /><figcaption class="wp-element-caption">Nul, je veux les boîtes colorées</figcaption></figure>
</div>


<h3 class="wp-block-heading">2. Recherche de la bonne propriété</h3>



<p>Pour corriger ça, j’ai posé la question suivante à <strong>ChatGPT</strong> :</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>« Dans Blender, comment on appelle ce bouton de sélection de couleur pour un addon Python ? S&rsquo;il te plaît »</p>
</blockquote>



<p>Et là, jackpot : ChatGPT m’a guidé vers la bonne solution : utiliser une <code><strong>FloatVectorProperty</strong></code><strong> avec </strong><code><strong>subtype='COLOR'</strong></code>. Ça m’a permis d’avoir le vrai <strong>bouton color picker</strong> Blender, propre et standard.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img loading="lazy" decoding="async" width="552" height="118" src="https://jmrudent8.wordpress.com/wp-content/uploads/2025/03/capture-decran-2025-03-05-214359.png?w=552" alt="" class="wp-image-802" style="width:412px;height:auto" srcset="https://jmrudent.com/wp-content/uploads/2025/03/capture-decran-2025-03-05-214359.png 552w, https://jmrudent.com/wp-content/uploads/2025/03/capture-decran-2025-03-05-214359-300x64.png 300w" sizes="auto, (max-width: 552px) 100vw, 552px" /></figure>
</div>

<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img loading="lazy" decoding="async" width="352" height="496" src="https://jmrudent8.wordpress.com/wp-content/uploads/2025/03/capture-decran-2025-03-05-214624.png?w=352" alt="" class="wp-image-806" style="width:245px;height:auto" srcset="https://jmrudent.com/wp-content/uploads/2025/03/capture-decran-2025-03-05-214624.png 352w, https://jmrudent.com/wp-content/uploads/2025/03/capture-decran-2025-03-05-214624-213x300.png 213w" sizes="auto, (max-width: 352px) 100vw, 352px" /></figure>
</div>


<h3 class="wp-block-heading">3. C&rsquo;est bien mais je veux des palettes, pas simplement une liste de couleurs</h3>



<p>Ce qu’il me fallait vraiment, c’était une <strong>liste de palettes</strong>, chaque palette contenant <strong>jusqu’à 10 couleurs</strong> (nombre arbitraire). J’ai donc demandé à Mercury de repenser la structure de l’addon.</p>



<h3 class="wp-block-heading">4. Et voilà, l&rsquo;addon fait exactement ce que je veux</h3>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="271" height="495" src="https://jmrudent8.wordpress.com/wp-content/uploads/2025/03/capture-decran-2025-03-05-215308.png?w=271" alt="" class="wp-image-811" srcset="https://jmrudent.com/wp-content/uploads/2025/03/capture-decran-2025-03-05-215308.png 271w, https://jmrudent.com/wp-content/uploads/2025/03/capture-decran-2025-03-05-215308-164x300.png 164w" sizes="auto, (max-width: 271px) 100vw, 271px" /></figure>
</div>


<p>Une liste de palettes, dans le N-Panel du shading editor, avec les noms des couleurs et des palettes qu&rsquo;on peut éditer.</p>



<p>Ça marche, missa content.</p>



<h2 class="wp-block-heading">Limites actuelles de l’addon</h2>



<h3 class="wp-block-heading">Ce qui manque</h3>



<p>Actuellement, l’addon <strong>ne sauvegarde les palettes que dans le fichier .blend</strong> dans lequel elles ont été créées. On <strong>ne peut pas transférer facilement les palettes d’un projet Blender à un autre</strong>.</p>



<h3 class="wp-block-heading">Une meilleure solution à explorer</h3>



<p>La bonne approche serait probablement de s’appuyer sur les systèmes de palettes existants de Blender, notamment ceux intégrés au mode <strong>Texture Paint</strong>. Ça permettrait d’avoir une gestion cohérente avec le reste du logiciel et de rendre les palettes <strong>partageables</strong> entre projets.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="264" height="105" src="https://jmrudent8.wordpress.com/wp-content/uploads/2025/03/image.png?w=264" alt="" class="wp-image-809" /></figure>
</div>


<p>Je sais pas encore si je pourrais faire en sorte de pouvoir éditer les noms des couleurs, ce qui est pas mal pour se rappeler de leurs utilités.</p>



<p>Mon objectif initial était de faire un outil <strong>rapide, pratique et minimaliste</strong>. Cette solution simple répond à mon besoin immédiat, mais j’envisage une <strong>évolution future</strong> pour aller plus loin, ça peut aller tellement vite avec Mercury. <br><br><a href="https://www.inceptionlabs.ai/">Mercury Coder</a> est assez dingue en terme de rapidité. Il fonctionne différemment des autres LLM classiques, il repose sur un système de diffusion de réponse totale, comme les générateurs d&rsquo;images, contrairement aux autres qui font de la prédiction de manière plus linéaire, mot après mot.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1026" height="723" src="https://jmrudent8.wordpress.com/wp-content/uploads/2025/03/image-1.png?w=1024" alt="" class="wp-image-813" srcset="https://jmrudent.com/wp-content/uploads/2025/03/image-1.png 1026w, https://jmrudent.com/wp-content/uploads/2025/03/image-1-300x211.png 300w, https://jmrudent.com/wp-content/uploads/2025/03/image-1-1024x722.png 1024w, https://jmrudent.com/wp-content/uploads/2025/03/image-1-768x541.png 768w" sizes="auto, (max-width: 1026px) 100vw, 1026px" /></figure>



<h2 class="wp-block-heading">Pourquoi mon addon est utile pour les créateurs 3D et motion designers ?</h2>



<p>Prenons un exemple concret :</p>



<p>Tu crées un <strong>pack d’assets 3D</strong> pour un client. Il y a une charte graphique à respecter avec des couleurs bien définies. Avec cet addon, tu peux enregistrer cette palette une bonne fois pour toutes, et la <strong>rappeler instantanément</strong> depuis le shadng editor.</p>



<ul class="wp-block-list">
<li>Gain de temps</li>



<li>Cohérence chromatique assurée</li>



<li>Adapté aux workflows pros (motion design, packshot produit, charte de jeu vidéo, etc.)</li>



<li>Moult K€ à la clé</li>
</ul>



<h2 class="wp-block-heading">Mon addon est dispo sur Gumroad</h2>



<p>En <strong>prix libre</strong>. Si c&rsquo;est pour juste tester, c’est gratuit. Si tu veux soutenir mon travail d’explorateur python, tu peux donner ce que tu veux (beaucoup d&rsquo;argent je veux bien)</p>



<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f449.png" alt="👉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <a href="https://jmrudent.gumroad.com/l/colorpalettes">[Lien Gumroad ici]</a></p>



<h2 class="wp-block-heading">Le script complet</h2>



<p>Pour les amateurs de ctrl+c ctrl+v :</p>



<details class="wp-block-details is-layout-flow wp-block-details-is-layout-flow"><summary>Script :</summary>
<pre class="wp-block-syntaxhighlighter-code">bl_info = {
    "name": "Global Color Palettes",
    "version": (1, 4, 1),
    "description": "A global color library for Blender with multiple colors per palette, stored in a user-defined JSON file.",
    "author": "Jean-Marie Rudent (modified by Gemini)",
    "blender": (4, 2, 0),
    "location": "Shader Editor &gt; Color Library",
    "warning": "",
    "category": "Material"
}

import bpy
import json
import os

# -----------------------------
# Data Structures
# -----------------------------

def update_palette(self, context):
    context.scene.palettes_modified = True

def update_color_item(self, context):
    context.scene.palettes_modified = True

class ColorItem(bpy.types.PropertyGroup):
    name: bpy.props.StringProperty(name="Name", default="Color", update=update_color_item)
    color: bpy.props.FloatVectorProperty(
        name="Color",
        size=4,
        min=0.0,
        max=1.0,
        default=(1.0, 1.0, 1.0, 1.0),
        subtype='COLOR',
        update=update_color_item
    )

class ColorPalette(bpy.types.PropertyGroup):
    name: bpy.props.StringProperty(name="Name", update=update_palette)
    colors: bpy.props.CollectionProperty(type=ColorItem)

# -----------------------------
# Addon Preferences
# -----------------------------

class ColorPalettesAddonPreferences(bpy.types.AddonPreferences):
    bl_idname = __name__

    global_config_path: bpy.props.StringProperty(
        name="Global Color Palette File",
        subtype='FILE_PATH',
        default="",
        description="Path to the JSON file storing global color palettes"
    )

# -----------------------------
# UI Panel
# -----------------------------

class COLOR_LIBRARY_PT_panel(bpy.types.Panel):
    bl_idname = "COLOR_LIBRARY_PT_panel"
    bl_label = "Color Palettes"
    bl_space_type = 'NODE_EDITOR'
    bl_region_type = 'UI'
    bl_category = 'Color Palettes'

    def draw(self, context):
        layout = self.layout
        scene = context.scene
        prefs = context.preferences.addons[__name__].preferences

        layout.label(text="Configuration File:")
        row = layout.row()
        row.prop(prefs, "global_config_path", text="")
        row = layout.row()
        row.operator("color_library.load_global_config", text="Load Palettes")
        layout.separator()

        row = layout.row()
        row.template_list("COLOR_LIBRARY_UL_list", "", scene, "color_palettes", scene, "color_palette_index")

        row = layout.row()
        row.operator("color_library.add_palette", text="Add Palette")
        row.operator("color_library.delete_palette", text="Delete Palette")

        layout.separator()
        row = layout.row()
        save_text = "Save Palettes"
        if scene.palettes_modified:
            save_text += " *"
        row.operator("color_library.save_global_config", text=save_text)

        if scene.color_palette_index &gt;= 0 and len(scene.color_palettes) &gt; 0:
            palette = scene.color_palettes[scene.color_palette_index]
            layout.prop(palette, "name")
            box = layout.box()
            for color in palette.colors:
                row = box.row(align=True)
                row.prop(color, "name", text="")
                row.prop(color, "color", text="")

class COLOR_LIBRARY_UL_list(bpy.types.UIList):
    def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
        if self.layout_type in {'DEFAULT', 'COMPACT'}:
            layout.label(text=item.name)
        elif self.layout_type == 'GRID':
            layout.alignment = 'CENTER'
            layout.label(text="")

# -----------------------------
# Operators
# -----------------------------

class COLOR_LIBRARY_OT_add_palette(bpy.types.Operator):
    bl_idname = "color_library.add_palette"
    bl_label = "Add Palette"

    def execute(self, context):
        scene = context.scene
        new_palette = scene.color_palettes.add()
        new_palette.name = f"Palette {len(scene.color_palettes)}"
        for i in range(10):
            new_color = new_palette.colors.add()
            new_color.name = f"Color {i+1}"
            new_color.color = (1.0, 1.0, 1.0, 1.0)
        context.scene.palettes_modified = True
        return {'FINISHED'}

class COLOR_LIBRARY_OT_delete_palette(bpy.types.Operator):
    bl_idname = "color_library.delete_palette"
    bl_label = "Delete Palette"

    def execute(self, context):
        scene = context.scene
        if scene.color_palette_index &gt;= 0 and len(scene.color_palettes) &gt; 0:
            scene.color_palettes.remove(scene.color_palette_index)
            scene.color_palette_index = min(scene.color_palette_index, len(scene.color_palettes) - 1)
        context.scene.palettes_modified = True
        return {'FINISHED'}

class COLOR_LIBRARY_OT_add_color(bpy.types.Operator):
    bl_idname = "color_library.add_color"
    bl_label = "Add Color"
    index: bpy.props.IntProperty()

    def execute(self, context):
        scene = context.scene
        if scene.color_palette_index &gt;= 0 and len(scene.color_palettes) &gt; 0:
            palette = scene.color_palettes[scene.color_palette_index]
            new_color = palette.colors.add()
            new_color.name = f"Color {len(palette.colors)}"
            new_color.color = (1.0, 1.0, 1.0, 1.0)
        context.scene.palettes_modified = True
        return {'FINISHED'}

class COLOR_LIBRARY_OT_load_global_config(bpy.types.Operator):
    bl_idname = "color_library.load_global_config"
    bl_label = "Load Palettes"

    def execute(self, context):
        load_global_config_function(context)
        context.scene.palettes_modified = False
        return {'FINISHED'}

class COLOR_LIBRARY_OT_save_global_config(bpy.types.Operator):
    bl_idname = "color_library.save_global_config"
    bl_label = "Save Palettes"

    def execute(self, context):
        save_global_config_function(context)
        context.scene.palettes_modified = False
        return {'FINISHED'}

# -----------------------------
# Config Load/Save (global)
# -----------------------------

def load_global_config_function(context):
    prefs = context.preferences.addons[__name__].preferences
    config_file_path = prefs.global_config_path

    if not config_file_path:
        print("[ColorPalettes] Global config path not set.")
        return

    if hasattr(bpy.context, 'scene'):
        scene = bpy.context.scene
        if os.path.exists(config_file_path):
            with open(config_file_path, 'r') as file:
                try:
                    config = json.load(file)
                    scene.color_palettes.clear()
                    for palette_data in config.get('palettes', []):
                        new_palette = scene.color_palettes.add()
                        new_palette.name = palette_data.get('name', '')
                        for color_data in palette_data.get('colors', []):
                            new_color = new_palette.colors.add()
                            new_color.name = color_data.get('name', 'Color')
                            new_color.color = tuple(color_data.get('color', [1.0, 1.0, 1.0, 1.0]))
                    print(f"[ColorPalettes] Palettes loaded from: {config_file_path}")
                except json.JSONDecodeError as e:
                    print(f"[ColorPalettes] Failed to load config (invalid JSON): {e}")
                except Exception as e:
                    print(f"[ColorPalettes] Failed to load config: {e}")
        else:
            print(f"[ColorPalettes] Global config file not found: {config_file_path}")

def save_global_config_function(context):
    prefs = context.preferences.addons[__name__].preferences
    config_file_path = prefs.global_config_path

    if not config_file_path:
        print("[ColorPalettes] Global config path not set.")
        return

    if hasattr(bpy.context, 'scene'):
        scene = bpy.context.scene
        config = {'palettes': []}
        for palette in scene.color_palettes:
            palette_data = {
                'name': palette.name,
                'colors': []
            }
            for color in palette.colors:
                palette_data['colors'].append({
                    'name': color.name,
                    'color': list(color.color)
                })
            config['palettes'].append(palette_data)
        try:
            os.makedirs(os.path.dirname(config_file_path), exist_ok=True)
            with open(config_file_path, 'w') as file:
                json.dump(config, file, indent=4)
            print(f"[ColorPalettes] Palettes saved to: {config_file_path}")
        except Exception as e:
            print(f"[ColorPalettes] Failed to save config: {e}")

# -----------------------------
# Registration
# -----------------------------

classes = (
    ColorItem,
    ColorPalette,
    ColorPalettesAddonPreferences,
    COLOR_LIBRARY_PT_panel,
    COLOR_LIBRARY_UL_list,
    COLOR_LIBRARY_OT_add_palette,
    COLOR_LIBRARY_OT_delete_palette,
    COLOR_LIBRARY_OT_add_color,
    COLOR_LIBRARY_OT_load_global_config,
    COLOR_LIBRARY_OT_save_global_config,
)

def register():
    for cls in classes:
        bpy.utils.register_class(cls)

    bpy.types.Scene.color_palettes = bpy.props.CollectionProperty(type=ColorPalette)
    bpy.types.Scene.color_palette_index = bpy.props.IntProperty(name="Palette Index")
    bpy.types.Scene.palettes_modified = bpy.props.BoolProperty(default=False)

    # Load config on register (Blender startup if addon is enabled)
    if bpy.context:
        load_global_config_function(bpy.context)

def unregister():
    for cls in reversed(classes):
        bpy.utils.unregister_class(cls)

    if hasattr(bpy.types.Scene, "color_palettes"):
        del bpy.types.Scene.color_palettes
    if hasattr(bpy.types.Scene, "color_palette_index"):
        del bpy.types.Scene.color_palette_index
    if hasattr(bpy.types.Scene, "palettes_modified"):
        del bpy.types.Scene.palettes_modified

if __name__ == "__main__":
    register()
</pre>
</details>



<h2 class="wp-block-heading">Conclusion</h2>



<p>J’ai voulu montrer que même sans être développeur Python de formation, il est possible de se débrouiller en utilisant des <strong>outils modernes</strong> et un peu de jugeotte pour <strong>créer des solutions adaptées à ses besoins réels</strong>.</p>



<p>Cela dit, si demain j&rsquo;ai besoin d&rsquo;un addon beaucoup plus complexe, je pense que je passerai par un humain habile en python.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
