PDA

Voir la version complète : Contrôler intensité lumière depuis texture



Fredaubailly
15/12/2016, 13h45
Hello les gars,

j'ai un petit problème à vous soumettre.
Je veux simuler la diffusion de lumière projetée par une télé.
Dans un matériau, j'utilise une vidéo dans le canal couleur. J'aimerais que "l'intensité" de cette vidéo commande l'intensité d'une lumière.
Grosso modo quand la moyenne des pixels de la vidéo est proche du noir, çà envoi 0% à l'intensité de ma lumière et quand la moyenne est proche du blanc, ça envoie 100% à l'intensité de ma lumière.
Le but du jeu étant de simuler la lumière qu'enverrait la vidéo projetée.

Des pistes ?

Bien sûr hors de question d'utiliser l'IG. :whistling:

dotcom
15/12/2016, 15h58
Mograph ?

texture vidéo (image seq) effecteur matière sur cloneur de lights : pour les couleurs
texture image seq noir et blanc sur effecteur intensité peut être grâce à Xpresso.
comme ça tu peux modifier l'intensité lumineuse sans toucher aux couleurs
++

Fredaubailly
15/12/2016, 16h29
J'ai un peu honte mais je ne comprends rien à ta technique.
Y'aurait moyen d'avoir un petit exemple ?
Merki :icon_redface:

dotcom
15/12/2016, 19h27
Une télé c'est quoi ?
c'est un ensemble de points lumineux côte à côte de couleur différente.
Donc je commencerais par cloner des lights en mode grille avec selon ta def 1280/720 ou full HD lights correspondant aux pixels, mais commence en 320/240 sur une grille fulle HD sinon tu vas planter.

Ensuite ces lights vont devoir récupérer un signal > texture
pas d'autre choix.

Applique une texture au cloneur essaie mode plan et tout ce qui traine.

Si ça ne fonctionne pas essaie avec le shader effector.

Sans GI tu es obligé de passer par des lights parce que ya que de slights pour vraiment éclairer,
un canal luminescence sur un matériau en dehors de calcul GI ça ne donne pas des trucs réaliste.

Je ne peux pas trop faire plus je suis en plein taff.

Bon courage ;)


++

Fredaubailly
15/12/2016, 19h34
Merci je vais essayer çà. ;)

olivierrob
15/12/2016, 20h02
Tu peux essayer de placer ta texture directement dans une lumière, il faut activer uniquement le canal transparence de ton matériau et d'importer ta vidéo dans ce canal, comme ça ta lumière sert de projecteur et tu peux également activer les ombres.

xs_yann
20/12/2016, 15h17
Salut,

J'arrive un peu tard mais j'ai écrit un script (noeud XPresso) qui fait ce que tu décris dans ton premier message Fredaubauilly.

Le noeud retourne la couleur rgb moyenne d'une séquence d'image (ainsi que l'intensité qui est la moyenne RGB).

Example vidéo avec la couleur (http://xsyann.com/fc4d/tv_script_color1.mp4)
Example vidéo avec l'intensité (http://xsyann.com/fc4d/tv_script_intensity.mp4)

Le noeud prend en entrée un nom de fichier, si le nom est suffixé par un numéro de frame, le script détecte le bon fichier pour la frame courante.
J'ai ajouté un paramètre "Step" pour éviter d'avoir à parcourir tout les pixels de l'image pour obtenir la moyenne.
Par exemple avec un step à 10 et une image de 640x480 la moyenne est faite sur 3072 pixels au lieu de 307200 pixels.

http://xsyann.com/fc4d/tv_script.png



import re
import os
import c4d

def get_frame_image(path, frame, ext):
current_frame = doc.GetTime().GetFrame(doc.GetFps())
padded = str(current_frame).zfill(len(frame))
return path + padded + ext

def split_seq_filename(filename):
match = re.match(r'^(.*?)(\d{2,9})(\.\w{2,4})$', filename)
path, frame, ext = ('', '', '')
if match:
path, frame, ext = match.groups()
else:
path, ext = os.path.splitext(filename)
return path, frame, ext

def load_bitmap(filename):
bmp = c4d.bitmaps.BaseBitmap()
res, _ = bmp.InitWith(filename)
if res != c4d.IMAGERESULT_OK:
return None
return bmp

def get_average_color(filename, step=10):
average = c4d.Vector(0)
bmp = load_bitmap(filename)
if not bmp:
return average
w, h = bmp.GetSize()
i = 0
for x in range(0, w, step):
for y in range(0, h, step):
color = bmp.GetPixel(x, y)
r, g, b = color[0], color[1], color[2]
average += (c4d.Vector(r, g, b) / 255.0)
i += 1
return average / i

def get_intensity(color):
return (color.x + color.y + color.z) / 3.0

def main():
step = max(Step, 0) # Input
filename = File # Input
path, frame, ext = split_seq_filename(filename)
frame_path = get_frame_image(path, frame, ext) if frame else filename
color = get_average_color(frame_path, step)

global Intensity
global Color
Intensity = get_intensity(color) # Output
Color = color # Output




Le fichier .c4d (http://xsyann.com/fc4d/tv_script.c4d)

Math1712
20/12/2016, 15h42
Arf :blink: excellent !!! :icon_prie:

Fredaubailly
20/12/2016, 17h33
Merci à tous. Je m'en suis sorti avec la solution d'olivierrob.
Yann, je vais quand même tester ta technique. Ne serait-ce que pour "amortir" le temps que tu as passé dessus. Merci beaucoup. :icon_prie: