MaxScript to automate rgb color conversion to gamma 2.2?

hi, I was wondering if there is a plugin to do so, but couldn't find, so I started to script my own.

decided to do so because I have many old models wich I use to populate my scenes at work, and these models have materials made on a 1.0 gamma environment, and everytime I want to use one of them, I have to manually convert all colors to match a 2.2 gamma equivalent.

to convert their colors, I use this formula on each color channel: 255*((old/255)^2.2), it's based on a tutorial by mintviz, but having to manually correct all colors is a tedious and time consuming process, and I'm assuming it could be 100% automated.

what I'm thinking is a simple button that when you press, uses that formula on all RGB channels from all color map slots set on all existing materials on selected objects only.

I don't have much experience with maxscript, but I did a few control interfaces and such, and I can google my way around. I just need some help because this can start getting too specific to google everything, and it also shouldn't be hard for someone with experience on maxscript.

I've got it working with diffuse and reflection maps for vray materials, and diffuse map for standard materials, the problem starts when I have a multi/sub-object material, and also when colors are set in sub maps, as if I wanted to convert the 2 colors set on a falloff map inside the diffuse slot. those are the two situations I wasn't able to figure out.

code looks like this so far:

function StdDiffuseRGBtoLinear =
(
oldr = $.material.diffuseColor.r
oldg = $.material.diffuseColor.g
oldb = $.material.diffuseColor.b
$.material.diffuseColor.r = 255*((oldr/255)^2.2)
$.material.diffuseColor.g = 255*((oldg/255)^2.2)
$.material.diffuseColor.b = 255*((oldb/255)^2.2)
)
 
function VrayDiffuseRGBtoLinear =
(
oldr = $.material.diffuse.r
oldg = $.material.diffuse.g
oldb = $.material.diffuse.b
$.material.diffuse.r = 255*((oldr/255)^2.2)
$.material.diffuse.g = 255*((oldg/255)^2.2)
$.material.diffuse.b = 255*((oldb/255)^2.2)
)
 
function VrayReflectRGBtoLinear =
(
oldr = $.material.reflection.r
oldg = $.material.reflection.g
oldb = $.material.reflection.b
$.material.reflection.r = 255*((oldr/255)^2.2)
$.material.reflection.g = 255*((oldg/255)^2.2)
$.material.reflection.b = 255*((oldb/255)^2.2)
)
 
for obj in selection do 
(
if classof $.material == StandardMaterial do 
(
StdDiffuseRGBtoLinear ()
)
if classof $.material == VRayMtl do 
(
VrayDiffuseRGBtoLinear ()
VrayReflectRGBtoLinear ()
)
)

what can I do to make it work with multi material, and sub maps?

thanks in advance,
Rafael

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
fajar's picture

Combination of cgtalk and mine

clearListener()
 
fn getCorrectedGammaFlag node = 
(
	corrected_gamma_flag_channel = 1771
	(getAppData node corrected_gamma_flag_channel) == "1"
)
 
fn setCorrectedGammaFlag node val:"1" = 
(
	corrected_gamma_flag_channel = 1771
	setAppData node corrected_gamma_flag_channel val
)
 
fn collectAllMaterials mat mats:#() = 
(
	if iskindof mat Material and (appendifunique mats mat) do 
	(
		for k=1 to getNumSubMtls mat do collectAllMaterials (getSubMtl mat k) mats:mats
	)
	mats
)
 
fn collectAllMat selectedOnly:false includeParent:false = 
(
	local allMat=#()
	local nodeToCollect 
 
	case selectedOnly of 
	(
		true : (nodeToCollect = selection as array)
		false : (nodeToCollect = objects as array)
	)
 
     case includeParent of 
     (
     true :    (
                    for node in nodeToCollect where node.mat!=undefined do
                         (
                              for mat in (collectAllMaterials node.mat) where (appendifunique allMat mat) collect mat
                         )
                  )
 
     false :   (
                    for node in nodeToCollect where node.mat!=undefined do
                         (
                              for mat in (for j in collectAllMaterials node.mat where (getNumSubMtls j==0) collect j ) where (appendifunique allMat mat) collect mat
                         )
                )
     )
 
	makeUniqueArray allMat
)
 
 
fn correctColorPropGamma node arrProp:#() = 
(
	local changed = 0
	if arrProp.count==0 do (arrProp=getpropnames node)
 
	fn correctColorGamma c = 
	(
		255.0 * color ((c.r/255)^2.2) ((c.g/255)^2.2) ((c.b/255)^2.2)
	)
 
	if not (getCorrectedGammaFlag node) do
	(
		for p in arrProp where (iskindof (d = getproperty node p) Color) do
		(
			setproperty node p (correctColorGamma d)
			changed += 1
		)
	)
	setCorrectedGammaFlag node
	changed
)
 
fn correctColorProp node =
(
	if classof node == StandardMaterial then
	(
		if node.adLock == off then 
		(
			correctColorPropGamma node arrProp:#(#FilterColor, #Diffuse, #Specular, #selfillumcolor)
		)
		else
		(
			correctColorPropGamma node arrProp:#(#FilterColor, #ambient, #Diffuse, #Specular, #selfillumcolor)
		)
	)
	else
	(
		correctColorPropGamma node
	)
)
clearlistener()
start = timeStamp()
maToCorrect = collectAllMat selectedOnly:false includeParent:false
for i in maToCorrect do correctColorProp i
end = timeStamp()
format "Processing methods A took : % seconds\n" ((end - start) / 1000.0)
--Processing methods A took : 0.568 seconds

Try that .....
- I hope it wont apply corrected value twice....
- support :
1. VrayMtl
2. StandardMaterial
3. CoronaMtl
4. Architectural
5. Arch___Design__mi
6. Car_Paint_Material__mi
you can add it by yourself what you want to support tho. See : collectAllMat function

** edited :

Hope support all materials tho....maybe there's an error if you turn on "include parent=true" tho...

pixamoon's picture

`

hi, did you try this one:
http://www.scriptspot.com/3ds-max/scripts/massgammacolor

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.