Translucency Simulation Script

Hi
The script from this topic
https://blenderartists.org/forum/viewtopic.php?t=32467

here

###############################
## Translucency Script V 1.0 ## 
## 30/10/2004				 ##
## by Caio Stein D'Agostini  ##
###############################

from Blender import *
import math


objeto = Object.GetSelected()
malha = objeto[0].getData()
faces = malha.faces
lista_de_vertices = malha.verts
vInf = range(len(lista_de_vertices))
coorObj = [objeto[0].LocX, objeto[0].LocY, objeto[0].LocZ]
faces_ilum = []
tuplas = [] # [ angulo, [modulo, modulo, modulo, ...], [vetorX, vetorY, vetorZ]]
vetor_ref = [10, 0, 0] 

extra_vermelho = 0 #if you want more redishy
extra_verde = 0	#if you want more greenishy
extra_azul = 10	#inf you want more bluishy

distancia = 3 #affects the light atenuation (not the scattered light)
intensidade = 5 #intensity of the light
atenuacaoSSS = 3 #how fast the light being scattered decreases intensity with distance
atenuacaoLuz = 2 #how fast the light coming from the light source decreases power with distance
dif_sombra = 1 #adjust the 'shadow detection' in function 'sombra'


coordLuz = [-1.0, 0.0, 1.0] # the light location

############################################################################################################
############################################################################################################

def normal(face): ##not using that

	Ai = faces[i_face].v[0].co[0] - faces[i_face].v[1].co[0]
	Aj = faces[i_face].v[0].co[1] - faces[i_face].v[1].co[1]
	Ak = faces[i_face].v[0].co[2] - faces[i_face].v[1].co[2]
	vetor1 = [Ai,Aj,Ak]

	Bi = faces[i_face].v[2].co[0] - faces[i_face].v[1].co[0]
	Bj = faces[i_face].v[2].co[1] - faces[i_face].v[1].co[1]
	Bk = faces[i_face].v[2].co[2] - faces[i_face].v[1].co[2]
	vetor2 = [Bi,Bj,Bk]

	vetorNormal = [-(Aj*Bk - Ak*Bj), -(Ak*Bi - Ai*Bk), -(Ai*Bj - Aj*Bi)]
	return vetorNormal

################################################

def modulo(vetor):
	
	mod = math.sqrt(math.pow(vetor[0],2) + math.pow(vetor[1],2) + math.pow(vetor[2],2))
	return mod

###############################################

def escalar(vetor1, vetor2):

	escalar = vetor1[0]*vetor2[0] + vetor1[1]*vetor2[1] + vetor1[2]*vetor2[2]
	return escalar

###############################################

def unitario(vetor1):

	mod = modulo(vetor1)
	vetor = vetor1

	vetor[0] = vetor1[0]/mod
	vetor[1] = vetor1[1]/mod
	vetor[2] = vetor1[2]/mod
	
	return vetor

###############################################

def loc_face(objeto, face):
	tamanho = 0
	locx = 0
	locy = 0
	locz = 0
	for indice in range(len(face.v)):
		locx = locx + face.v[indice].co[0]
		locy = locy + face.v[indice].co[1]
		locz = locz + face.v[indice].co[2]
		tamanho = tamanho + 1
	return [locx/tamanho + objeto.LocX, locy/tamanho + objeto.LocY, locz/tamanho + objeto.LocZ]
###############################################


def angulo(vetor1, vetor2):

	modulo1 = modulo(vetor1)
	modulo2 = modulo(vetor2)
	esc = escalar(vetor1, vetor2) 
	cosTeta = esc/(modulo2*modulo1)
	an = math.acos(cosTeta) *180/math.pi
	return an
	
#############################################

def sombra(vetor1):  #to know if a face is under another face's shadow... works fine

	mod = modulo(vetor1)
	resposta = mod	

	angul = angulo(vetor1, vetor_ref)	

	indice = 0
	
	while indice<len(tuplas):
		if tuplas[indice][0] == int(angul):
			array_dist = tuplas[indice][1]
			array_vet = tuplas[indice][2]
			for indice_tupla in range(len(array_dist)):
				dist = array_dist[indice_tupla]
				angul2 = angulo(array_vet[indice_tupla], vetor_ref)
				diferenca = math.fabs(angul2 - angul)	
				if dist<mod and diferenca<dif_sombra:
					mod = dist
					indice = len(tuplas)+1
			resposta = mod
			
		indice = indice+1
	
	return resposta

###############################################
hora_i = sys.time()

for i_face in range(len(faces)):  #stores data to use on the function 'sombra'

	coordFace = loc_face(objeto[0], faces[i_face])
	vetorFonteLuz = [coordLuz[0] - coordFace[0], coordLuz[1] - coordFace[1], coordLuz[2] - coordFace[2]]
	mod = modulo(vetorFonteLuz)

	angul = int(angulo(vetorFonteLuz, vetor_ref))
	achou = False

	if len(tuplas)==0:
		tuplas.append([angul, [mod], [vetorFonteLuz]])
	else:
		indice=0
		while indice<len(tuplas):
			if tuplas[indice][0] == angul:
				tuplas[indice][1].append(mod)
				tuplas[indice][2].append(vetorFonteLuz)
				achou = True
				indice = len(tuplas)+1
			indice = indice + 1

	if achou == False:
		tuplas.append([angul, [mod], [vetorFonteLuz]])
 
###############################################

#################################################

for i_face in range( len(faces)):

	coordFace = loc_face(objeto[0], faces[i_face])
	vetorFonteLuz = [coordFace[0] - coordLuz[0], coordFace[1] - coordLuz[1], coordFace[2] - coordLuz[2]]

	vetorNormal = faces[i_face].no
	moduloNormal = modulo(vetorNormal)
	moduloLuz = modulo(vetorFonteLuz)

	anguloFaceLuz = angulo(vetorNormal, vetorFonteLuz)
	energia = (intensidade*anguloFaceLuz/90)
	if anguloFaceLuz > 0: #some other time I'll explain
		
		r=0 #red value
		rm=0 #red average value
		g=0
		gm=0
		b=0
		bm=0
		if anguloFaceLuz < 1:
			anguloFaceLuz = 1
	
		distancia_sombra = sombra(vetorFonteLuz)

		if distancia_sombra<moduloLuz:	
			for i_vert_face in range (len(malha.faces[i_face].col)):
				r = malha.faces[i_face].col[i_vert_face].r *energia/math.pow(distancia,atenuacaoLuz) + extra_vermelho
				if r > 32767:
					r = 32767
				g = malha.faces[i_face].col[i_vert_face].g *energia/math.pow(distancia,atenuacaoLuz) + extra_verde
				if g > 32767:
					g = 32767
				b = malha.faces[i_face].col[i_vert_face].b *energia/math.pow(distancia,atenuacaoLuz) + extra_azul
				if b > 32767:
					b = 32767

				malha.faces[i_face].col[i_vert_face].r = int(r)
				malha.faces[i_face].col[i_vert_face].g = int(g)
				malha.faces[i_face].col[i_vert_face].b = int(b)
		
				rm = rm + r
				gm = gm + g
				bm = bm + b

			#malha.update()
			#Redraw()
		if anguloFaceLuz > 90:	#store the faces that get direct lightning
			faces_ilum.append([i_face, energia, [rm/3, gm/3, bm/3]])

############################################################################################################
############################################################################################################

tamanho = len(faces_ilum)
#i = 0
for i_face_ilum in range( tamanho):
	#print "Ainda faltam ", tamanho-i, " face(s)"
	#i = i+1
	tupla = faces_ilum[i_face_ilum] 
	face = faces[tupla[0]]
	energia = tupla[1]
	coord = face.no
	rgb_medio = tupla[2] 

	for i_faces in range( len(faces)):
				
		f = faces[i_faces]
		v = f.col
		c = f.no
		vetor = [f.no[0] - coord[0], f.no[1] - coord[1], f.no[2] - coord[2]]
		distancia_faces = modulo(vetor)
			
		distancia_faces = distancia_faces * 10

		if distancia_faces<1:
			distancia_faces = 1
				

		if distancia_faces<10*distancia:
			
			i_vert_face = 0
			for i_vert_face in range( len(v)):
			
				if energia>1:
					r = v[i_vert_face].r +  rgb_medio[0]*energia/math.pow(distancia_faces,atenuacaoSSS)
					if r > 32767:
						r = 32767
					g = v[i_vert_face].g +  rgb_medio[1]*energia/math.pow(distancia_faces,atenuacaoSSS)
					if g > 32767:
						g = 32767
					b = v[i_vert_face].b +  rgb_medio[2]*energia/math.pow(distancia_faces,atenuacaoSSS)
					if b > 32767:
						b = 32767
	

				v[i_vert_face].r = int(r)
				v[i_vert_face].g = int(g)
				v[i_vert_face].b = int(b)
				
	#malha.update()
	#Redraw()
	
############################################################################################################
############################################################################################################
print "Tempo total = ", ((sys.time()) - hora_i)
malha.update()
Redraw()

###############################
## Translucency Script V 1.0 ## 
## 30/10/2004				 ##
## by Caio Stein D'Agostini  ##
###############################

It could be a lot faster using the right structures to store data, (like the faces that get direct lighting, my “shadow detection” data, etc)

I didn’t study blender python API for more than a few times, a few minutes each time, so there might be a lot of things that can be done better and faster

http://www.inf.ufsc.br/~csd/passaroTranslucido1.jpg

Vs

http://www.inf.ufsc.br/~csd/passaroNaoTranslucido1.jpg

How does that compare with the built-in transluency feature?

Martin

If I make a solid, and make a hole in side that gets direct light, and I look from the other side, with the built-in feature, I can see a lighter area on the side I’m looking at. It’s like if there was nothing inside.
It doesn’t have any kind of light dispersion, scattering or something like that

EDIT

and using this one I made, if you paint the vertex before using the script, with dark colors, the script has less effect, on the other side, the lighter the color you paint the vertex before, biggest is the effect from the script. So I can choose with areas will be translucent and with will not be.

orrrrrr…

I don’t know how to use the the built-in feature :stuck_out_tongue:

how do you use this script ???

Select a mesh with vcol light enabled (and it’s vertices painted) and hit alt+p

Hopefully if the parameters are OK, it will work.

extra_vermelho = 0 #if you want more redishy
extra_verde = 0   #if you want more greenishy
extra_azul = 10   #inf you want more bluishy

distancia = 3 #affects the light atenuation (not the scattered light)
intensidade = 5 #intensity of the light
atenuacaoSSS = 3 #how fast the light being scattered decreases intensity with distance
atenuacaoLuz = 2 #how fast the light coming from the light source decreases power with distance



coordLuz = [-1.0, 0.0, 1.0] # the light location 

depending on where your mesh is and were the value of the parameters are, nothing happens.
I’ll try to upload a blend file that you just need to “alt+p” to get a nice result, so people can play with