Skip to content

Commit e77bbb6

Browse files
authored
Merge pull request #542 from BabylonJS/MaxCoating
Max support for coating
2 parents 4ee4631 + 54e2368 commit e77bbb6

File tree

6 files changed

+204
-10
lines changed

6 files changed

+204
-10
lines changed

3ds Max/Max2Babylon/Exporter/BabylonExporter.Material.cs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
using System.Collections.Generic;
44
using Autodesk.Max;
55
using BabylonExport.Entities;
6-
6+
using System.Diagnostics;
7+
78
namespace BabylonExport.Entities
89
{
910
partial class BabylonMaterial
@@ -487,6 +488,49 @@ private void ExportMaterial(IIGameMaterial materialNode, BabylonScene babylonSce
487488
babylonMaterial.emissive = emissionColor.Multiply(emissionWeight);
488489
}
489490

491+
// --- Clear Coat ---
492+
float coatWeight = propertyContainer.GetFloatProperty(75);
493+
if (coatWeight > 0.0f)
494+
{
495+
babylonMaterial.clearCoat.isEnabled = true;
496+
babylonMaterial.clearCoat.indexOfRefraction = propertyContainer.GetFloatProperty(84);
497+
498+
ITexmap intensityTexmap = _getTexMap(materialNode, 23);
499+
ITexmap roughnessTexmap = _getTexMap(materialNode, 25);
500+
var coatRoughness = propertyContainer.GetFloatProperty(81);
501+
var coatTexture = ExportClearCoatTexture(intensityTexmap, roughnessTexmap, coatWeight, coatRoughness, babylonScene, name, invertRoughness);
502+
if (coatTexture != null)
503+
{
504+
babylonMaterial.clearCoat.texture = coatTexture;
505+
babylonMaterial.clearCoat.roughness = 1.0f;
506+
babylonMaterial.clearCoat.intensity = 1.0f;
507+
}
508+
else
509+
{
510+
babylonMaterial.clearCoat.intensity = coatWeight;
511+
babylonMaterial.clearCoat.roughness = coatRoughness;
512+
}
513+
514+
float[] coatColor = propertyContainer.GetPoint3Property(78).ToArray();
515+
if (coatColor[0] != 1.0f || coatColor[1] != 1.0f || coatColor[2] != 1.0f)
516+
{
517+
babylonMaterial.clearCoat.isTintEnabled = true;
518+
babylonMaterial.clearCoat.tintColor = coatColor;
519+
}
520+
521+
babylonMaterial.clearCoat.tintTexture = ExportPBRTexture(materialNode, 24, babylonScene);
522+
if (babylonMaterial.clearCoat.tintTexture != null)
523+
{
524+
babylonMaterial.clearCoat.tintColor = new[] { 1.0f, 1.0f, 1.0f };
525+
babylonMaterial.clearCoat.isTintEnabled = true;
526+
}
527+
528+
// EyeBall deduction...
529+
babylonMaterial.clearCoat.tintThickness = 0.65f;
530+
531+
babylonMaterial.clearCoat.bumpTexture = ExportPBRTexture(materialNode, 27, babylonScene);
532+
}
533+
490534
// --- Textures ---
491535
// 1 - base_color ; 5 - specular_roughness ; 9 - metalness ; 10 - transparent
492536
ITexmap colorTexmap = _getTexMap(materialNode, 1);

3ds Max/Max2Babylon/Exporter/BabylonExporter.Texture.cs

Lines changed: 110 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -171,15 +171,116 @@ private BabylonTexture ExportPBRTexture(IIGameMaterial materialNode, int index,
171171
return null;
172172
}
173173

174-
/// <summary>
175-
///
176-
/// </summary>
177-
/// <param name="baseColorTexMap"></param>
178-
/// <param name="alphaTexMap">Transparency weight map</param>
179-
/// <param name="baseColor"></param>
180-
/// <param name="alpha"></param>
181-
/// <param name="babylonScene"></param>
182-
/// <param name="materialName"></param>
174+
private BabylonTexture ExportClearCoatTexture(ITexmap intensityTexMap, ITexmap roughnessTexMap, float coatWeight, float coatRoughness, BabylonScene babylonScene, string materialName, bool invertRoughness)
175+
{
176+
// --- Babylon texture ---
177+
var intensityTexture = _getBitmapTex(intensityTexMap);
178+
var roughnessTexture = _getBitmapTex(roughnessTexMap);
179+
180+
var texture = intensityTexture != null ? intensityTexture : roughnessTexture;
181+
if (texture == null)
182+
{
183+
return null;
184+
}
185+
186+
// Use one as a reference for UVs parameters
187+
188+
RaiseMessage("Export Clear Coat weight+roughness texture", 2);
189+
190+
string nameText = Path.GetFileNameWithoutExtension(texture.Map.FullFilePath);
191+
192+
var textureID = texture.GetGuid().ToString();
193+
if (textureMap.ContainsKey(textureID))
194+
{
195+
return textureMap[textureID];
196+
}
197+
else
198+
{
199+
var babylonTexture = new BabylonTexture(textureID)
200+
{
201+
name = nameText // TODO - unsafe name, may conflict with another texture name
202+
};
203+
204+
// Level
205+
babylonTexture.level = 1.0f;
206+
207+
// UVs
208+
var uvGen = _exportUV(texture.UVGen, babylonTexture);
209+
210+
// Is cube
211+
_exportIsCube(texture.Map.FullFilePath, babylonTexture, false);
212+
213+
// --- Merge maps ---
214+
var hasIntensity = isTextureOk(intensityTexture);
215+
var hasRoughness = isTextureOk(roughnessTexture);
216+
if (!hasIntensity && !hasRoughness)
217+
{
218+
return null;
219+
}
220+
221+
// Set image format
222+
ImageFormat imageFormat = ImageFormat.Jpeg;
223+
babylonTexture.name += ".jpg";
224+
225+
if (exportParameters.writeTextures)
226+
{
227+
// Load bitmaps
228+
var intensityBitmap = _loadTexture(intensityTexture);
229+
var roughnessBitmap = _loadTexture(roughnessTexture);
230+
231+
// Retreive dimensions
232+
int width = 0;
233+
int height = 0;
234+
var haveSameDimensions = _getMinimalBitmapDimensions(out width, out height, intensityBitmap, roughnessBitmap);
235+
if (!haveSameDimensions)
236+
{
237+
RaiseError("Base color and transparency color maps should have same dimensions", 3);
238+
}
239+
240+
// Create map
241+
var _intensity = (int)(coatWeight * 255);
242+
var _roughness = (int)(coatRoughness * 255);
243+
Bitmap intensityRoughnessBitmap = new Bitmap(width, height);
244+
for (int x = 0; x < width; x++)
245+
{
246+
for (int y = 0; y < height; y++)
247+
{
248+
var intensityAtPixel = (intensityBitmap == null) ? _intensity : intensityBitmap.GetPixel(x, y).R;
249+
250+
Color intensityRoughness;
251+
if (roughnessBitmap == null)
252+
{
253+
intensityRoughness = Color.FromArgb(intensityAtPixel, _roughness, 0);
254+
}
255+
else
256+
{
257+
var roughnessAtPixel = (roughnessBitmap == null) ?
258+
_roughness :
259+
invertRoughness ? 255 - roughnessBitmap.GetPixel(x, y).G : roughnessBitmap.GetPixel(x, y).G;
260+
261+
intensityRoughness = Color.FromArgb(intensityAtPixel, roughnessAtPixel, 0);
262+
}
263+
intensityRoughnessBitmap.SetPixel(x, y, intensityRoughness);
264+
}
265+
}
266+
267+
// Write bitmap
268+
if (isBabylonExported)
269+
{
270+
RaiseMessage($"Texture | write image '{babylonTexture.name}'", 3);
271+
SaveBitmap(intensityRoughnessBitmap, babylonScene.OutputPath, babylonTexture.name, imageFormat);
272+
}
273+
else
274+
{
275+
// Store created bitmap for further use in gltf export
276+
babylonTexture.bitmap = intensityRoughnessBitmap;
277+
}
278+
}
279+
280+
return babylonTexture;
281+
}
282+
}
283+
183284
/// <returns></returns>
184285
private BabylonTexture ExportBaseColorAlphaTexture(ITexmap baseColorTexMap, ITexmap alphaTexMap, float[] baseColor, float alpha, BabylonScene babylonScene, string materialName)
185286
{

SharedProjects/BabylonExport.Entities/BabylonExport.Entities.projitems

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
<Compile Include="$(MSBuildThisFileDirectory)BabylonMultiMaterial.cs" />
3434
<Compile Include="$(MSBuildThisFileDirectory)BabylonNode.cs" />
3535
<Compile Include="$(MSBuildThisFileDirectory)BabylonParticleSystem.cs" />
36+
<Compile Include="$(MSBuildThisFileDirectory)BabylonPBRClearCoat.cs" />
3637
<Compile Include="$(MSBuildThisFileDirectory)BabylonPBRMaterial.cs" />
3738
<Compile Include="$(MSBuildThisFileDirectory)BabylonPBRMetallicRoughnessMaterial.cs" />
3839
<Compile Include="$(MSBuildThisFileDirectory)BabylonProducer.cs" />
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using System.Runtime.Serialization;
2+
namespace BabylonExport.Entities
3+
{
4+
[DataContract]
5+
public class BabylonPBRClearCoat
6+
{
7+
[DataMember]
8+
public bool isEnabled { get; set; } = false;
9+
10+
[DataMember]
11+
public float intensity { get; set; } = 1.0f;
12+
13+
[DataMember]
14+
public float roughness { get; set; } = 0.0f;
15+
16+
[DataMember]
17+
public float indexOfRefraction { get; set; } = 1.5f;
18+
19+
[DataMember]
20+
public BabylonTexture texture { get; set; }
21+
22+
[DataMember]
23+
public BabylonTexture bumpTexture { get; set; }
24+
25+
[DataMember]
26+
public bool isTintEnabled { get; set; } = false;
27+
28+
[DataMember]
29+
public float[] tintColor { get; set; } = { 1.0f, 1.0f, 1.0f };
30+
31+
[DataMember]
32+
public float tintThickness { get; set; } = 1.0f;
33+
34+
[DataMember]
35+
public BabylonTexture tintTexture { get; set; }
36+
}
37+
}

SharedProjects/BabylonExport.Entities/BabylonPBRMaterial.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,9 @@ public class BabylonPBRMaterial : BabylonMaterial
133133
[DataMember]
134134
public int maxSimultaneousLights { get; set; }
135135

136+
[DataMember]
137+
public BabylonPBRClearCoat clearCoat { get; set; }
138+
136139
public BabylonPBRMaterial(string id) : base(id)
137140
{
138141
SetCustomType("BABYLON.PBRMaterial");
@@ -164,6 +167,8 @@ public BabylonPBRMaterial(string id) : base(id)
164167
reflectivity = new[] { 1f, 1f, 1f };
165168
reflection = new[] { 0.5f, 0.5f, 0.5f };
166169
emissive = new[] { 0f, 0f, 0f };
170+
171+
clearCoat = new BabylonPBRClearCoat();
167172
}
168173

169174
public void SetCustomType(string type)

SharedProjects/BabylonExport.Entities/BabylonPBRMetallicRoughnessMaterial.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ public enum TransparencyMode
6767
[DataMember]
6868
public bool doubleSided { get; set; }
6969

70+
[DataMember]
71+
public BabylonPBRClearCoat clearCoat { get; set; }
72+
7073
public BabylonPBRMetallicRoughnessMaterial(string id) : base(id)
7174
{
7275
customType = "BABYLON.PBRMetallicRoughnessMaterial";
@@ -76,6 +79,8 @@ public BabylonPBRMetallicRoughnessMaterial(string id) : base(id)
7679
occlusionStrength = 1.0f;
7780
alphaCutOff = 0.4f;
7881
transparencyMode = (int)TransparencyMode.OPAQUE;
82+
83+
clearCoat = new BabylonPBRClearCoat();
7984
}
8085

8186
public BabylonPBRMetallicRoughnessMaterial(BabylonPBRMetallicRoughnessMaterial original) : base(original)
@@ -98,6 +103,7 @@ public BabylonPBRMetallicRoughnessMaterial(BabylonPBRMetallicRoughnessMaterial o
98103
alphaCutOff = original.alphaCutOff;
99104
transparencyMode = original.transparencyMode;
100105
doubleSided = original.doubleSided;
106+
clearCoat = original.clearCoat;
101107
}
102108
}
103109
}

0 commit comments

Comments
 (0)