瀏覽代碼

Merge pull request #1201 from Areloch/Particle_Material_InitPersistField_Reorg

Updates the initPersistFields for ParticleData and Material
Brian Roberts 1 年之前
父節點
當前提交
ddd2522fa6
共有 2 個文件被更改,包括 335 次插入320 次删除
  1. 94 83
      Engine/source/T3D/fx/particle.cpp
  2. 241 237
      Engine/source/materials/materialDefinition.cpp

+ 94 - 83
Engine/source/T3D/fx/particle.cpp

@@ -148,94 +148,105 @@ FRangeValidator spinRandFValidator(-1000.f, 1000.f);
 void ParticleData::initPersistFields()
 void ParticleData::initPersistFields()
 {
 {
    docsURL;
    docsURL;
-   addFieldV( "dragCoefficient", TYPEID< F32 >(), Offset(dragCoefficient, ParticleData), &dragCoefFValidator,
-      "Particle physics drag amount." );
-   addField( "windCoefficient", TYPEID< F32 >(), Offset(windCoefficient, ParticleData),
-      "Strength of wind on the particles." );
-   addFieldV( "gravityCoefficient", TYPEID< F32 >(), Offset(gravityCoefficient, ParticleData), &gravCoefFValidator,
-      "Strength of gravity on the particles." );
-   addFieldV( "inheritedVelFactor", TYPEID< F32 >(), Offset(inheritedVelFactor, ParticleData), &CommonValidators::NormalizedFloat,
-      "Amount of emitter velocity to add to particle initial velocity." );
-   addField( "constantAcceleration", TYPEID< F32 >(), Offset(constantAcceleration, ParticleData),
-      "Constant acceleration to apply to this particle." );
-   addField( "lifetimeMS", TYPEID< S32 >(), Offset(lifetimeMS, ParticleData),
-      "Time in milliseconds before this particle is destroyed." );
-   addField( "lifetimeVarianceMS", TYPEID< S32 >(), Offset(lifetimeVarianceMS, ParticleData),
-      "Variance in lifetime of particle, from 0 - lifetimeMS." );
-   addField( "spinSpeed", TYPEID< F32 >(), Offset(spinSpeed, ParticleData),
-      "Speed at which to spin the particle." );
-   addFieldV( "spinRandomMin", TYPEID< F32 >(), Offset(spinRandomMin, ParticleData), &spinRandFValidator,
-      "Minimum allowed spin speed of this particle, between -1000 and spinRandomMax." );
-   addFieldV( "spinRandomMax", TYPEID< F32 >(), Offset(spinRandomMax, ParticleData), &spinRandFValidator,
-      "Maximum allowed spin speed of this particle, between spinRandomMin and 1000." );
-   addField( "useInvAlpha", TYPEID< bool >(), Offset(useInvAlpha, ParticleData),
-      "@brief Controls how particles blend with the scene.\n\n"
-      "If true, particles blend like ParticleBlendStyle NORMAL, if false, "
-      "blend like ParticleBlendStyle ADDITIVE.\n"
-      "@note If ParticleEmitterData::blendStyle is set, it will override this value." );
-   addField( "animateTexture", TYPEID< bool >(), Offset(animateTexture, ParticleData),
-      "If true, allow the particle texture to be an animated sprite." );
-   addField( "framesPerSec", TYPEID< S32 >(), Offset(framesPerSec, ParticleData),
-      "If animateTexture is true, this defines the frames per second of the "
-      "sprite animation." );
-
-   addField( "textureCoords", TYPEID< Point2F >(), Offset(texCoords, ParticleData),  4,
-      "@brief 4 element array defining the UV coords into textureName to use "
-      "for this particle.\n\n"
-      "Coords should be set for the first tile only when using animTexTiling; "
-      "coordinates for other tiles will be calculated automatically. \"0 0\" is "
-      "top left and \"1 1\" is bottom right." );
-   addField( "animTexTiling", TYPEID< Point2I >(), Offset(animTexTiling, ParticleData),
-      "@brief The number of frames, in rows and columns stored in textureName "
-      "(when animateTexture is true).\n\n"
-      "A maximum of 256 frames can be stored in a single texture when using "
-      "animTexTiling. Value should be \"NumColumns NumRows\", for example \"4 4\"." );
-   addField( "animTexFrames", TYPEID< StringTableEntry >(), Offset(animTexFramesString,ParticleData),
-      "@brief A list of frames and/or frame ranges to use for particle "
-      "animation if animateTexture is true.\n\n"
-      "Each frame token must be separated by whitespace. A frame token must be "
-      "a positive integer frame number or a range of frame numbers separated "
-      "with a '-'. The range separator, '-', cannot have any whitspace around "
-      "it.\n\n"
-      "Ranges can be specified to move through the frames in reverse as well "
-      "as forward (eg. 19-14). Frame numbers exceeding the number of tiles will "
-      "wrap.\n"
-      "@tsexample\n"
-      "animTexFrames = \"0-16 20 19 18 17 31-21\";\n"
-      "@endtsexample\n" );
-
-   addProtectedField( "textureName", TYPEID< StringTableEntry >(), Offset(mTextureName, ParticleData), _setTextureData, defaultProtectedGetFn,
-      "Texture file to use for this particle.", AbstractClassRep::FIELD_HideInInspectors );
-   addField( "animTexName", TYPEID< StringTableEntry >(), Offset(mTextureName, ParticleData),
-      "@brief Texture file to use for this particle if animateTexture is true.\n\n"
-      "Deprecated. Use textureName instead.", AbstractClassRep::FIELD_HideInInspectors);
-   INITPERSISTFIELD_IMAGEASSET(Texture, ParticleData, "Texture to use for this particle.");
+   addGroup("Basic");
+      addProtectedField("textureName", TYPEID< StringTableEntry >(), Offset(mTextureName, ParticleData), _setTextureData, defaultProtectedGetFn,
+         "Texture file to use for this particle.", AbstractClassRep::FIELD_HideInInspectors);
+      addField("animTexName", TYPEID< StringTableEntry >(), Offset(mTextureName, ParticleData),
+         "@brief Texture file to use for this particle if animateTexture is true.\n\n"
+         "Deprecated. Use textureName instead.", AbstractClassRep::FIELD_HideInInspectors);
+      INITPERSISTFIELD_IMAGEASSET(Texture, ParticleData, "Texture to use for this particle.");
+      addField("useInvAlpha", TYPEID< bool >(), Offset(useInvAlpha, ParticleData),
+         "@brief Controls how particles blend with the scene.\n\n"
+         "If true, particles blend like ParticleBlendStyle NORMAL, if false, "
+         "blend like ParticleBlendStyle ADDITIVE.\n"
+         "@note If ParticleEmitterData::blendStyle is set, it will override this value.");
+      addField("lifetimeMS", TYPEID< S32 >(), Offset(lifetimeMS, ParticleData),
+         "Time in milliseconds before this particle is destroyed.");
+      addField("lifetimeVarianceMS", TYPEID< S32 >(), Offset(lifetimeVarianceMS, ParticleData),
+         "Variance in lifetime of particle, from 0 - lifetimeMS.");
+   endGroup("Basic");
+
+   addGroup("Motion");
+      addFieldV("dragCoefficient", TYPEID< F32 >(), Offset(dragCoefficient, ParticleData), &dragCoefFValidator,
+         "Particle physics drag amount.");
+      addField("windCoefficient", TYPEID< F32 >(), Offset(windCoefficient, ParticleData),
+         "Strength of wind on the particles.");
+      addFieldV("gravityCoefficient", TYPEID< F32 >(), Offset(gravityCoefficient, ParticleData), &gravCoefFValidator,
+         "Strength of gravity on the particles.");
+      addFieldV("inheritedVelFactor", TYPEID< F32 >(), Offset(inheritedVelFactor, ParticleData), &CommonValidators::NormalizedFloat,
+         "Amount of emitter velocity to add to particle initial velocity.");
+      addField("constantAcceleration", TYPEID< F32 >(), Offset(constantAcceleration, ParticleData),
+         "Constant acceleration to apply to this particle.");
+   endGroup("Motion");
    
    
+   addGroup("Spin");
+      addField("spinSpeed", TYPEID< F32 >(), Offset(spinSpeed, ParticleData),
+         "Speed at which to spin the particle.");
+      addFieldV("spinRandomMin", TYPEID< F32 >(), Offset(spinRandomMin, ParticleData), &spinRandFValidator,
+         "Minimum allowed spin speed of this particle, between -1000 and spinRandomMax.");
+      addFieldV("spinRandomMax", TYPEID< F32 >(), Offset(spinRandomMax, ParticleData), &spinRandFValidator,
+         "Maximum allowed spin speed of this particle, between spinRandomMin and 1000.");
+   endGroup("Spin");
+  
+   addGroup("Animation");
+      addField( "animateTexture", TYPEID< bool >(), Offset(animateTexture, ParticleData),
+         "If true, allow the particle texture to be an animated sprite." );
+      addField( "framesPerSec", TYPEID< S32 >(), Offset(framesPerSec, ParticleData),
+         "If animateTexture is true, this defines the frames per second of the "
+         "sprite animation." );
+
+      addField( "textureCoords", TYPEID< Point2F >(), Offset(texCoords, ParticleData),  4,
+         "@brief 4 element array defining the UV coords into textureName to use "
+         "for this particle.\n\n"
+         "Coords should be set for the first tile only when using animTexTiling; "
+         "coordinates for other tiles will be calculated automatically. \"0 0\" is "
+         "top left and \"1 1\" is bottom right." );
+      addField( "animTexTiling", TYPEID< Point2I >(), Offset(animTexTiling, ParticleData),
+         "@brief The number of frames, in rows and columns stored in textureName "
+         "(when animateTexture is true).\n\n"
+         "A maximum of 256 frames can be stored in a single texture when using "
+         "animTexTiling. Value should be \"NumColumns NumRows\", for example \"4 4\"." );
+      addField( "animTexFrames", TYPEID< StringTableEntry >(), Offset(animTexFramesString,ParticleData),
+         "@brief A list of frames and/or frame ranges to use for particle "
+         "animation if animateTexture is true.\n\n"
+         "Each frame token must be separated by whitespace. A frame token must be "
+         "a positive integer frame number or a range of frame numbers separated "
+         "with a '-'. The range separator, '-', cannot have any whitspace around "
+         "it.\n\n"
+         "Ranges can be specified to move through the frames in reverse as well "
+         "as forward (eg. 19-14). Frame numbers exceeding the number of tiles will "
+         "wrap.\n"
+         "@tsexample\n"
+         "animTexFrames = \"0-16 20 19 18 17 31-21\";\n"
+         "@endtsexample\n" );
+   endGroup("Animation");
 
 
    // Interpolation variables
    // Interpolation variables
-   addField( "colors", TYPEID< LinearColorF >(), Offset(colors, ParticleData), PDC_NUM_KEYS,
-      "@brief Particle RGBA color keyframe values.\n\n"
-      "The particle color will linearly interpolate between the color/time keys "
-      "over the lifetime of the particle." );
-   addProtectedField( "sizes", TYPEID< F32 >(), Offset(sizes, ParticleData), &protectedSetSizes, 
-      &defaultProtectedGetFn, PDC_NUM_KEYS,
-      "@brief Particle size keyframe values.\n\n"
-      "The particle size will linearly interpolate between the size/time keys "
-      "over the lifetime of the particle." );
-   addProtectedField( "times", TYPEID< F32 >(), Offset(times, ParticleData), &protectedSetTimes, 
-      &defaultProtectedGetFn, PDC_NUM_KEYS,
-      "@brief Time keys used with the colors and sizes keyframes.\n\n"
-      "Values are from 0.0 (particle creation) to 1.0 (end of lifespace)." );
+   addGroup("Over Time");
+      addProtectedField("times", TYPEID< F32 >(), Offset(times, ParticleData), &protectedSetTimes,
+         &defaultProtectedGetFn, PDC_NUM_KEYS,
+         "@brief Time keys used with the colors and sizes keyframes.\n\n"
+         "Values are from 0.0 (particle creation) to 1.0 (end of lifespace).");
+      addField( "colors", TYPEID< LinearColorF >(), Offset(colors, ParticleData), PDC_NUM_KEYS,
+         "@brief Particle RGBA color keyframe values.\n\n"
+         "The particle color will linearly interpolate between the color/time keys "
+         "over the lifetime of the particle." );
+      addProtectedField( "sizes", TYPEID< F32 >(), Offset(sizes, ParticleData), &protectedSetSizes, 
+         &defaultProtectedGetFn, PDC_NUM_KEYS,
+         "@brief Particle size keyframe values.\n\n"
+         "The particle size will linearly interpolate between the size/time keys "
+         "over the lifetime of the particle." );
+   endGroup("Over Time");
 
 
    addGroup("AFX");
    addGroup("AFX");
-   addProtectedField("textureExtName", TypeFilename, Offset(mTextureExtName,     ParticleData), _setTextureExtData, &defaultProtectedGetFn, "", AbstractClassRep::FIELD_HideInInspectors);
-   INITPERSISTFIELD_IMAGEASSET(TextureExt, ParticleData, "");
-   addField("constrainPos",         TypeBool,     Offset(constrain_pos,      ParticleData));
-   addField("angle",                TypeF32,      Offset(start_angle,        ParticleData));
-   addField("angleVariance",        TypeF32,      Offset(angle_variance,     ParticleData));
-   addField("sizeBias",             TypeF32,      Offset(sizeBias,           ParticleData));
-   addField("spinBias",             TypeF32,      Offset(spinBias,           ParticleData));
-   addField("randomizeSpinDir",     TypeBool,     Offset(randomizeSpinDir,   ParticleData));
+      addProtectedField("textureExtName", TypeFilename, Offset(mTextureExtName,     ParticleData), _setTextureExtData, &defaultProtectedGetFn, "", AbstractClassRep::FIELD_HideInInspectors);
+      INITPERSISTFIELD_IMAGEASSET(TextureExt, ParticleData, "");
+      addField("constrainPos",         TypeBool,     Offset(constrain_pos,      ParticleData));
+      addField("angle",                TypeF32,      Offset(start_angle,        ParticleData));
+      addField("angleVariance",        TypeF32,      Offset(angle_variance,     ParticleData));
+      addField("sizeBias",             TypeF32,      Offset(sizeBias,           ParticleData));
+      addField("spinBias",             TypeF32,      Offset(spinBias,           ParticleData));
+      addField("randomizeSpinDir",     TypeBool,     Offset(randomizeSpinDir,   ParticleData));
    endGroup("AFX"); 
    endGroup("AFX"); 
    Parent::initPersistFields();
    Parent::initPersistFields();
 }
 }

+ 241 - 237
Engine/source/materials/materialDefinition.cpp

@@ -252,151 +252,249 @@ void Material::initPersistFields()
 
 
    addArray("Stages", MAX_STAGES);
    addArray("Stages", MAX_STAGES);
 
 
-   addField("diffuseColor", TypeColorF, Offset(mDiffuse, Material), MAX_STAGES,
-      "This color is multiplied against the diffuse texture color.  If no diffuse texture "
-      "is present this is the material color.");
+   addGroup("Basic Texture Maps");
+      INITPERSISTFIELD_IMAGEASSET_ARRAY(DiffuseMap, MAX_STAGES, Material, "Albedo");
+      addField("diffuseColor", TypeColorF, Offset(mDiffuse, Material), MAX_STAGES,
+         "This color is multiplied against the diffuse texture color.  If no diffuse texture "
+         "is present this is the material color.");
+      addField("diffuseMapSRGB", TypeBool, Offset(mDiffuseMapSRGB, Material), MAX_STAGES,
+         "Enable sRGB for the diffuse color texture map.");
+
+      INITPERSISTFIELD_IMAGEASSET_ARRAY(NormalMap, MAX_STAGES, Material, "NormalMap");
+   endGroup("Basic Texture Maps");
+
+   addGroup("Light Influence Maps");
+      addField("roughness", TypeF32, Offset(mRoughness, Material), MAX_STAGES,
+         "The degree of roughness when not using a ORMConfigMap.");
+
+      addField("metalness", TypeF32, Offset(mMetalness, Material), MAX_STAGES,
+         "The degree of Metalness when not using a ORMConfigMap.");
+
+      addField("invertRoughness", TypeBool, Offset(mInvertRoughness, Material), MAX_STAGES,
+         "Treat Roughness as Roughness");
+
+      addField("AOChan", TypeF32, Offset(mAOChan, Material), MAX_STAGES,
+         "The input channel AO maps use.");
+      addField("roughnessChan", TypeF32, Offset(mRoughnessChan, Material), MAX_STAGES,
+         "The input channel roughness maps use.");
+      addField("metalChan", TypeF32, Offset(mMetalChan, Material), MAX_STAGES,
+         "The input channel metalness maps use.");
+
+      INITPERSISTFIELD_IMAGEASSET_ARRAY(ORMConfigMap, MAX_STAGES, Material, "AO|Roughness|metalness map");
+      addField("isSRGb", TypeBool, Offset(mIsSRGb, Material), MAX_STAGES,
+         "Substance Designer Workaround.");
+
+      INITPERSISTFIELD_IMAGEASSET_ARRAY(AOMap, MAX_STAGES, Material, "AOMap");
+      INITPERSISTFIELD_IMAGEASSET_ARRAY(RoughMap, MAX_STAGES, Material, "RoughMap (also needs MetalMap)");
+      INITPERSISTFIELD_IMAGEASSET_ARRAY(MetalMap, MAX_STAGES, Material, "MetalMap (also needs RoughMap)");
+      INITPERSISTFIELD_IMAGEASSET_ARRAY(GlowMap, MAX_STAGES, Material, "GlowMap (needs Albedo)");
+
+      addField("glowMul", TypeF32, Offset(mGlowMul, Material), MAX_STAGES,
+         "glow mask multiplier");
+   endGroup("Light Influence Maps");
+
+   addGroup("Advanced Texture Maps");
+      INITPERSISTFIELD_IMAGEASSET_ARRAY(DetailMap, MAX_STAGES, Material, "DetailMap");
+      addField("detailScale", TypePoint2F, Offset(mDetailScale, Material), MAX_STAGES,
+         "The scale factor for the detail map.");
+
+      INITPERSISTFIELD_IMAGEASSET_ARRAY(DetailNormalMap, MAX_STAGES, Material, "DetailNormalMap");
+      addField("detailNormalMapStrength", TypeF32, Offset(mDetailNormalMapStrength, Material), MAX_STAGES,
+         "Used to scale the strength of the detail normal map when blended with the base normal map.");
+
+      INITPERSISTFIELD_IMAGEASSET_ARRAY(OverlayMap, MAX_STAGES, Material, "Overlay");
+      INITPERSISTFIELD_IMAGEASSET_ARRAY(LightMap, MAX_STAGES, Material, "LightMap");
+      INITPERSISTFIELD_IMAGEASSET_ARRAY(ToneMap, MAX_STAGES, Material, "ToneMap");
+   endGroup("Advanced Texture Maps");
+   
+   addGroup("Accumulation Properties");
+      addProtectedField("accuEnabled", TYPEID< bool >(), Offset(mAccuEnabled, Material),
+         &_setAccuEnabled, &defaultProtectedGetFn, MAX_STAGES, "Accumulation texture.");
+
+      addField("accuScale", TypeF32, Offset(mAccuScale, Material), MAX_STAGES,
+         "The scale that is applied to the accu map texture. You can use this to fit the texture to smaller or larger objects.");
+
+      addField("accuDirection", TypeF32, Offset(mAccuDirection, Material), MAX_STAGES,
+         "The direction of the accumulation. Chose whether you want the accu map to go from top to bottom (ie. snow) or upwards (ie. mold).");
+
+      addField("accuStrength", TypeF32, Offset(mAccuStrength, Material), MAX_STAGES,
+         "The strength of the accu map. This changes the transparency of the accu map texture. Make it subtle or add more contrast.");
+
+      addField("accuCoverage", TypeF32, Offset(mAccuCoverage, Material), MAX_STAGES,
+         "The coverage ratio of the accu map texture. Use this to make the entire shape pick up some of the accu map texture or none at all.");
+
+      addField("accuSpecular", TypeF32, Offset(mAccuSpecular, Material), MAX_STAGES,
+         "Changes specularity to this value where the accumulated material is present.");
+   endGroup("Accumulation Properties");
+   
+   addGroup("Lighting Properties");
+      addField("receiveShadows", TypeBool, Offset(mReceiveShadows, Material), MAX_STAGES,
+         "Shadows being cast onto the material.");
+      addField("ignoreLighting", TypeBool, Offset(mIgnoreLighting, Material), MAX_STAGES,
+         "Enables emissive lighting for the material.");
+      addField("glow", TypeBool, Offset(mGlow, Material), MAX_STAGES,
+         "Enables rendering as glowing.");
+      addField("parallaxScale", TypeF32, Offset(mParallaxScale, Material), MAX_STAGES,
+         "Enables parallax mapping and defines the scale factor for the parallax effect.  Typically "
+         "this value is less than 0.4 else the effect breaks down.");
+
+      addField("useAnisotropic", TypeBool, Offset(mUseAnisotropic, Material), MAX_STAGES,
+         "Use anisotropic filtering for the textures of this stage.");
+
+      addField("vertLit", TypeBool, Offset(mVertLit, Material), MAX_STAGES,
+         "If true the vertex color is used for lighting.");
+      addField("vertColor", TypeBool, Offset(mVertColor, Material), MAX_STAGES,
+         "If enabled, vertex colors are premultiplied with diffuse colors.");
+
+      addField("subSurface", TypeBool, Offset(mSubSurface, Material), MAX_STAGES,
+         "Enables the subsurface scattering approximation.");
+      addField("minnaertConstant", TypeF32, Offset(mMinnaertConstant, Material), MAX_STAGES,
+         "The Minnaert shading constant value.  Must be greater than 0 to enable the effect.");
+      addField("subSurfaceColor", TypeColorF, Offset(mSubSurfaceColor, Material), MAX_STAGES,
+         "The color used for the subsurface scattering approximation.");
+      addField("subSurfaceRolloff", TypeF32, Offset(mSubSurfaceRolloff, Material), MAX_STAGES,
+         "The 0 to 1 rolloff factor used in the subsurface scattering approximation.");
+   endGroup("Lighting Properties");
+
+   addGroup("Animation Properties");
+      addField("animFlags", TYPEID< AnimType >(), Offset(mAnimFlags, Material), MAX_STAGES,
+         "The types of animation to play on this material.");
+
+      addField("scrollDir", TypePoint2F, Offset(mScrollDir, Material), MAX_STAGES,
+         "The scroll direction in UV space when scroll animation is enabled.");
+
+      addField("scrollSpeed", TypeF32, Offset(mScrollSpeed, Material), MAX_STAGES,
+         "The speed to scroll the texture in UVs per second when scroll animation is enabled.");
+
+      addField("rotSpeed", TypeF32, Offset(mRotSpeed, Material), MAX_STAGES,
+         "The speed to rotate the texture in degrees per second when rotation animation is enabled.");
+
+      addField("rotPivotOffset", TypePoint2F, Offset(mRotPivotOffset, Material), MAX_STAGES,
+         "The piviot position in UV coordinates to center the rotation animation.");
+
+      addField("waveType", TYPEID< WaveType >(), Offset(mWaveType, Material), MAX_STAGES,
+         "The type of wave animation to perform when wave animation is enabled.");
+
+      addField("waveFreq", TypeF32, Offset(mWaveFreq, Material), MAX_STAGES,
+         "The wave frequency when wave animation is enabled.");
+
+      addField("waveAmp", TypeF32, Offset(mWaveAmp, Material), MAX_STAGES,
+         "The wave amplitude when wave animation is enabled.");
+
+      addField("sequenceFramePerSec", TypeF32, Offset(mSeqFramePerSec, Material), MAX_STAGES,
+         "The number of frames per second for frame based sequence animations if greater than zero.");
+
+      addField("sequenceSegmentSize", TypeF32, Offset(mSeqSegSize, Material), MAX_STAGES,
+         "The size of each frame in UV units for sequence animations.");
+
+      // Texture atlasing
+      addField("cellIndex", TypePoint2I, Offset(mCellIndex, Material), MAX_STAGES,
+         "@internal");
+      addField("cellLayout", TypePoint2I, Offset(mCellLayout, Material), MAX_STAGES,
+         "@internal");
+      addField("cellSize", TypeS32, Offset(mCellSize, Material), MAX_STAGES,
+         "@internal");
+      addField("bumpAtlas", TypeBool, Offset(mNormalMapAtlas, Material), MAX_STAGES,
+         "@internal");
+   endGroup("Animation Properties");
 
 
-   INITPERSISTFIELD_IMAGEASSET_ARRAY(DiffuseMap, MAX_STAGES, Material, "Albedo");
-   INITPERSISTFIELD_IMAGEASSET_ARRAY(OverlayMap, MAX_STAGES, Material, "Overlay");
-   INITPERSISTFIELD_IMAGEASSET_ARRAY(LightMap, MAX_STAGES, Material, "LightMap");
-   INITPERSISTFIELD_IMAGEASSET_ARRAY(ToneMap, MAX_STAGES, Material, "ToneMap");
-   INITPERSISTFIELD_IMAGEASSET_ARRAY(DetailMap, MAX_STAGES, Material, "DetailMap");
-   INITPERSISTFIELD_IMAGEASSET_ARRAY(NormalMap, MAX_STAGES, Material, "NormalMap");
-   INITPERSISTFIELD_IMAGEASSET_ARRAY(ORMConfigMap, MAX_STAGES, Material, "AO|Roughness|metalness map");
-   INITPERSISTFIELD_IMAGEASSET_ARRAY(RoughMap, MAX_STAGES, Material, "RoughMap (also needs MetalMap)");
-   INITPERSISTFIELD_IMAGEASSET_ARRAY(AOMap, MAX_STAGES, Material, "AOMap");
-   INITPERSISTFIELD_IMAGEASSET_ARRAY(MetalMap, MAX_STAGES, Material, "MetalMap (also needs RoughMap)");
-   INITPERSISTFIELD_IMAGEASSET_ARRAY(GlowMap, MAX_STAGES, Material, "GlowMap (needs Albedo)");
-   INITPERSISTFIELD_IMAGEASSET_ARRAY(DetailNormalMap, MAX_STAGES, Material, "DetailNormalMap");
-
-   addField("diffuseMapSRGB", TypeBool, Offset(mDiffuseMapSRGB, Material), MAX_STAGES,
-      "Enable sRGB for the diffuse color texture map.");
-
-   addField("detailScale", TypePoint2F, Offset(mDetailScale, Material), MAX_STAGES,
-      "The scale factor for the detail map.");
-
-   addField("detailNormalMapStrength", TypeF32, Offset(mDetailNormalMapStrength, Material), MAX_STAGES,
-      "Used to scale the strength of the detail normal map when blended with the base normal map.");
-
-   addField("roughness", TypeF32, Offset(mRoughness, Material), MAX_STAGES,
-      "The degree of roughness when not using a ORMConfigMap.");
-
-   addField("metalness", TypeF32, Offset(mMetalness, Material), MAX_STAGES,
-      "The degree of Metalness when not using a ORMConfigMap.");
-
-   addField("glowMul", TypeF32, Offset(mGlowMul, Material), MAX_STAGES,
-      "glow mask multiplier");
-
-   addProtectedField("accuEnabled", TYPEID< bool >(), Offset(mAccuEnabled, Material),
-      &_setAccuEnabled, &defaultProtectedGetFn, MAX_STAGES, "Accumulation texture.");
-
-   addField("accuScale", TypeF32, Offset(mAccuScale, Material), MAX_STAGES,
-      "The scale that is applied to the accu map texture. You can use this to fit the texture to smaller or larger objects.");
-
-   addField("accuDirection", TypeF32, Offset(mAccuDirection, Material), MAX_STAGES,
-      "The direction of the accumulation. Chose whether you want the accu map to go from top to bottom (ie. snow) or upwards (ie. mold).");
-
-   addField("accuStrength", TypeF32, Offset(mAccuStrength, Material), MAX_STAGES,
-      "The strength of the accu map. This changes the transparency of the accu map texture. Make it subtle or add more contrast.");
-
-   addField("accuCoverage", TypeF32, Offset(mAccuCoverage, Material), MAX_STAGES,
-      "The coverage ratio of the accu map texture. Use this to make the entire shape pick up some of the accu map texture or none at all.");
-
-   addField("accuSpecular", TypeF32, Offset(mAccuSpecular, Material), MAX_STAGES,
-      "Changes specularity to this value where the accumulated material is present.");
-
-   addField("isSRGb", TypeBool, Offset(mIsSRGb, Material), MAX_STAGES,
-      "Substance Designer Workaround.");
-
-   addField("invertRoughness", TypeBool, Offset(mInvertRoughness, Material), MAX_STAGES,
-      "Treat Roughness as Roughness");
-
-   addField("roughnessChan", TypeF32, Offset(mRoughnessChan, Material), MAX_STAGES,
-      "The input channel roughness maps use.");
-
-   addField("AOChan", TypeF32, Offset(mAOChan, Material), MAX_STAGES,
-      "The input channel AO maps use.");
-   addField("metalChan", TypeF32, Offset(mMetalChan, Material), MAX_STAGES,
-      "The input channel metalness maps use.");
-
-   addField("glow", TypeBool, Offset(mGlow, Material), MAX_STAGES,
-      "Enables rendering as glowing.");
-
-   addField("parallaxScale", TypeF32, Offset(mParallaxScale, Material), MAX_STAGES,
-      "Enables parallax mapping and defines the scale factor for the parallax effect.  Typically "
-      "this value is less than 0.4 else the effect breaks down.");
-
-   addField("useAnisotropic", TypeBool, Offset(mUseAnisotropic, Material), MAX_STAGES,
-      "Use anisotropic filtering for the textures of this stage.");
-
-   addField("vertLit", TypeBool, Offset(mVertLit, Material), MAX_STAGES,
-      "If true the vertex color is used for lighting.");
-
-   addField("vertColor", TypeBool, Offset(mVertColor, Material), MAX_STAGES,
-      "If enabled, vertex colors are premultiplied with diffuse colors.");
-
-   addField("minnaertConstant", TypeF32, Offset(mMinnaertConstant, Material), MAX_STAGES,
-      "The Minnaert shading constant value.  Must be greater than 0 to enable the effect.");
-
-   addField("subSurface", TypeBool, Offset(mSubSurface, Material), MAX_STAGES,
-      "Enables the subsurface scattering approximation.");
-
-   addField("subSurfaceColor", TypeColorF, Offset(mSubSurfaceColor, Material), MAX_STAGES,
-      "The color used for the subsurface scattering approximation.");
-
-   addField("subSurfaceRolloff", TypeF32, Offset(mSubSurfaceRolloff, Material), MAX_STAGES,
-      "The 0 to 1 rolloff factor used in the subsurface scattering approximation.");
-
-   addField("receiveShadows", TypeBool, Offset(mReceiveShadows, Material), MAX_STAGES,
-      "Shadows being cast onto the material.");
-
-   addField("ignoreLighting", TypeBool, Offset(mIgnoreLighting, Material), MAX_STAGES,
-      "Enables emissive lighting for the material.");
-
-   addField("doubleSided", TypeBool, Offset(mDoubleSided, Material),
-      "Disables backface culling casing surfaces to be double sided. "
-      "Note that the lighting on the backside will be a mirror of the front "
-      "side of the surface.");
-
-   addField("animFlags", TYPEID< AnimType >(), Offset(mAnimFlags, Material), MAX_STAGES,
-      "The types of animation to play on this material.");
-
-   addField("scrollDir", TypePoint2F, Offset(mScrollDir, Material), MAX_STAGES,
-      "The scroll direction in UV space when scroll animation is enabled.");
-
-   addField("scrollSpeed", TypeF32, Offset(mScrollSpeed, Material), MAX_STAGES,
-      "The speed to scroll the texture in UVs per second when scroll animation is enabled.");
-
-   addField("rotSpeed", TypeF32, Offset(mRotSpeed, Material), MAX_STAGES,
-      "The speed to rotate the texture in degrees per second when rotation animation is enabled.");
-
-   addField("rotPivotOffset", TypePoint2F, Offset(mRotPivotOffset, Material), MAX_STAGES,
-      "The piviot position in UV coordinates to center the rotation animation.");
-
-   addField("waveType", TYPEID< WaveType >(), Offset(mWaveType, Material), MAX_STAGES,
-      "The type of wave animation to perform when wave animation is enabled.");
-
-   addField("waveFreq", TypeF32, Offset(mWaveFreq, Material), MAX_STAGES,
-      "The wave frequency when wave animation is enabled.");
-
-   addField("waveAmp", TypeF32, Offset(mWaveAmp, Material), MAX_STAGES,
-      "The wave amplitude when wave animation is enabled.");
-
-   addField("sequenceFramePerSec", TypeF32, Offset(mSeqFramePerSec, Material), MAX_STAGES,
-      "The number of frames per second for frame based sequence animations if greater than zero.");
-
-   addField("sequenceSegmentSize", TypeF32, Offset(mSeqSegSize, Material), MAX_STAGES,
-      "The size of each frame in UV units for sequence animations.");
+   endArray("Stages");
 
 
-   // Texture atlasing
-   addField("cellIndex", TypePoint2I, Offset(mCellIndex, Material), MAX_STAGES,
-      "@internal");
-   addField("cellLayout", TypePoint2I, Offset(mCellLayout, Material), MAX_STAGES,
-      "@internal");
-   addField("cellSize", TypeS32, Offset(mCellSize, Material), MAX_STAGES,
-      "@internal");
-   addField("bumpAtlas", TypeBool, Offset(mNormalMapAtlas, Material), MAX_STAGES,
-      "@internal");
+   addGroup("Advanced Properties (All Layers)");
+      addField("doubleSided", TypeBool, Offset(mDoubleSided, Material),
+         "Disables backface culling casing surfaces to be double sided. "
+         "Note that the lighting on the backside will be a mirror of the front "
+         "side of the surface.");
+      addField("castShadows", TypeBool, Offset(mCastShadows, Material),
+         "If set to false the lighting system will not cast shadows from this material.");
+
+      addField("planarReflection", TypeBool, Offset(mPlanarReflection, Material), "@internal");
+
+      addField("translucent", TypeBool, Offset(mTranslucent, Material),
+         "If true this material is translucent blended.");
+
+      addField("translucentBlendOp", TYPEID< BlendOp >(), Offset(mTranslucentBlendOp, Material),
+         "The type of blend operation to use when the material is translucent.");
+
+      addField("translucentZWrite", TypeBool, Offset(mTranslucentZWrite, Material),
+         "If enabled and the material is translucent it will write into the depth buffer.");
+
+      addField("alphaTest", TypeBool, Offset(mAlphaTest, Material),
+         "Enables alpha test when rendering the material.\n@see alphaRef\n");
+
+      addField("alphaRef", TypeS32, Offset(mAlphaRef, Material),
+         "The alpha reference value for alpha testing.  Must be between 0 to 255.\n@see alphaTest\n");
+
+      addField("cubemap", TypeRealString, Offset(mCubemapName, Material),
+         "The name of a CubemapData for environment mapping.");
+
+      addField("dynamicCubemap", TypeBool, Offset(mDynamicCubemap, Material),
+         "Enables the material to use the dynamic cubemap from the ShapeBase object its applied to.");
+   endGroup("Advanced Properties (All Layers)");
+
+   addGroup("Behavioral (All Layers)");
+      addField("showFootprints", TypeBool, Offset(mShowFootprints, Material),
+         "Whether to show player footprint decals on this material.\n\n"
+         "@see PlayerData::decalData");
+
+      addField("showDust", TypeBool, Offset(mShowDust, Material),
+         "Whether to emit dust particles from a shape moving over the material.  This is, for example, used by "
+         "vehicles or players to decide whether to show dust trails.");
+
+      addField("effectColor", TypeColorF, Offset(mEffectColor, Material), NUM_EFFECT_COLOR_STAGES,
+         "If #showDust is true, this is the set of colors to use for the ParticleData of the dust "
+         "emitter.\n\n"
+         "@see ParticleData::colors");
+
+      addField("footstepSoundId", TypeS32, Offset(mFootstepSoundId, Material),
+         "What sound to play from the PlayerData sound list when the player walks over the material.  -1 (default) to not play any sound.\n"
+         "\n"
+         "The IDs are:\n\n"
+         "- 0: PlayerData::FootSoftSound\n"
+         "- 1: PlayerData::FootHardSound\n"
+         "- 2: PlayerData::FootMetalSound\n"
+         "- 3: PlayerData::FootSnowSound\n"
+         "- 4: PlayerData::FootShallowSound\n"
+         "- 5: PlayerData::FootWadingSound\n"
+         "- 6: PlayerData::FootUnderwaterSound\n"
+         "- 7: PlayerData::FootBubblesSound\n"
+         "- 8: PlayerData::movingBubblesSound\n"
+         "- 9: PlayerData::waterBreathSound\n"
+         "- 10: PlayerData::impactSoftSound\n"
+         "- 11: PlayerData::impactHardSound\n"
+         "- 12: PlayerData::impactMetalSound\n"
+         "- 13: PlayerData::impactSnowSound\n"
+         "- 14: PlayerData::impactWaterEasy\n"
+         "- 15: PlayerData::impactWaterMedium\n"
+         "- 16: PlayerData::impactWaterHard\n"
+         "- 17: PlayerData::exitingWater\n");
+
+      INITPERSISTFIELD_SOUNDASSET(CustomFootstepSound, Material,
+         "The sound to play when the player walks over the material.  If this is set, it overrides #footstepSoundId.  This field is "
+         "useful for directly assigning custom footstep sounds to materials without having to rely on the PlayerData sound assignment.\n\n"
+         "@warn Be aware that materials are client-side objects.  This means that the SFXTracks assigned to materials must be client-side, too.");
+      addField("impactSoundId", TypeS32, Offset(mImpactSoundId, Material),
+         "What sound to play from the PlayerData sound list when the player impacts on the surface with a velocity equal or greater "
+         "than PlayerData::groundImpactMinSpeed.\n\n"
+         "For a list of IDs, see #footstepSoundId");
+      addField("ImpactFXIndex", TypeS32, Offset(mImpactFXIndex, Material),
+         "What FX to play from the PlayerData sound list when the player impacts on the surface with a velocity equal or greater "
+         "than PlayerData::groundImpactMinSpeed.\n\n"
+         "For a list of IDs, see #impactFXId");
+      INITPERSISTFIELD_SOUNDASSET(CustomImpactSound, Material,
+         "The sound to play when the player impacts on the surface with a velocity equal or greater than PlayerData::groundImpactMinSpeed.  "
+         "If this is set, it overrides #impactSoundId.  This field is useful for directly assigning custom impact sounds to materials "
+         "without having to rely on the PlayerData sound assignment.\n\n"
+         "@warn Be aware that materials are client-side objects.  This means that the SFXTracks assigned to materials must be client-side, too.");
+
+      //Deactivate these for the moment as they are not used.
+
+   #if 0
+      addField("friction", TypeF32, Offset(mFriction, Material));
+      addField("directSoundOcclusion", TypeF32, Offset(mDirectSoundOcclusion, Material));
+      addField("reverbSoundOcclusion", TypeF32, Offset(mReverbSoundOcclusion, Material));
+   #endif
+   endGroup("Behavioral (All Layers)");
 
 
    // For backwards compatibility.  
    // For backwards compatibility.  
    //
    //
@@ -419,100 +517,6 @@ void Material::initPersistFields()
       defaultProtectedSetNotEmptyFn, emptyStringProtectedGetFn, MAX_STAGES,
       defaultProtectedSetNotEmptyFn, emptyStringProtectedGetFn, MAX_STAGES,
       "For backwards compatibility.\n@see diffuseColor\n", AbstractClassRep::FIELD_HideInInspectors);
       "For backwards compatibility.\n@see diffuseColor\n", AbstractClassRep::FIELD_HideInInspectors);
 
 
-   endArray("Stages");
-
-   addField("castShadows", TypeBool, Offset(mCastShadows, Material),
-      "If set to false the lighting system will not cast shadows from this material.");
-
-   addField("planarReflection", TypeBool, Offset(mPlanarReflection, Material), "@internal");
-
-   addField("translucent", TypeBool, Offset(mTranslucent, Material),
-      "If true this material is translucent blended.");
-
-   addField("translucentBlendOp", TYPEID< BlendOp >(), Offset(mTranslucentBlendOp, Material),
-      "The type of blend operation to use when the material is translucent.");
-
-   addField("translucentZWrite", TypeBool, Offset(mTranslucentZWrite, Material),
-      "If enabled and the material is translucent it will write into the depth buffer.");
-
-   addField("alphaTest", TypeBool, Offset(mAlphaTest, Material),
-      "Enables alpha test when rendering the material.\n@see alphaRef\n");
-
-   addField("alphaRef", TypeS32, Offset(mAlphaRef, Material),
-      "The alpha reference value for alpha testing.  Must be between 0 to 255.\n@see alphaTest\n");
-
-   addField("cubemap", TypeRealString, Offset(mCubemapName, Material),
-      "The name of a CubemapData for environment mapping.");
-
-   addField("dynamicCubemap", TypeBool, Offset(mDynamicCubemap, Material),
-      "Enables the material to use the dynamic cubemap from the ShapeBase object its applied to.");
-
-   addGroup("Behavioral");
-
-   addField("showFootprints", TypeBool, Offset(mShowFootprints, Material),
-      "Whether to show player footprint decals on this material.\n\n"
-      "@see PlayerData::decalData");
-
-   addField("showDust", TypeBool, Offset(mShowDust, Material),
-      "Whether to emit dust particles from a shape moving over the material.  This is, for example, used by "
-      "vehicles or players to decide whether to show dust trails.");
-
-   addField("effectColor", TypeColorF, Offset(mEffectColor, Material), NUM_EFFECT_COLOR_STAGES,
-      "If #showDust is true, this is the set of colors to use for the ParticleData of the dust "
-      "emitter.\n\n"
-      "@see ParticleData::colors");
-
-   addField("footstepSoundId", TypeS32, Offset(mFootstepSoundId, Material),
-      "What sound to play from the PlayerData sound list when the player walks over the material.  -1 (default) to not play any sound.\n"
-      "\n"
-      "The IDs are:\n\n"
-      "- 0: PlayerData::FootSoftSound\n"
-      "- 1: PlayerData::FootHardSound\n"
-      "- 2: PlayerData::FootMetalSound\n"
-      "- 3: PlayerData::FootSnowSound\n"
-      "- 4: PlayerData::FootShallowSound\n"
-      "- 5: PlayerData::FootWadingSound\n"
-      "- 6: PlayerData::FootUnderwaterSound\n"
-      "- 7: PlayerData::FootBubblesSound\n"
-      "- 8: PlayerData::movingBubblesSound\n"
-      "- 9: PlayerData::waterBreathSound\n"
-      "- 10: PlayerData::impactSoftSound\n"
-      "- 11: PlayerData::impactHardSound\n"
-      "- 12: PlayerData::impactMetalSound\n"
-      "- 13: PlayerData::impactSnowSound\n"
-      "- 14: PlayerData::impactWaterEasy\n"
-      "- 15: PlayerData::impactWaterMedium\n"
-      "- 16: PlayerData::impactWaterHard\n"
-      "- 17: PlayerData::exitingWater\n");
-
-   INITPERSISTFIELD_SOUNDASSET(CustomFootstepSound, Material,
-      "The sound to play when the player walks over the material.  If this is set, it overrides #footstepSoundId.  This field is "
-      "useful for directly assigning custom footstep sounds to materials without having to rely on the PlayerData sound assignment.\n\n"
-      "@warn Be aware that materials are client-side objects.  This means that the SFXTracks assigned to materials must be client-side, too.");
-   addField("impactSoundId", TypeS32, Offset(mImpactSoundId, Material),
-      "What sound to play from the PlayerData sound list when the player impacts on the surface with a velocity equal or greater "
-      "than PlayerData::groundImpactMinSpeed.\n\n"
-      "For a list of IDs, see #footstepSoundId");
-   addField("ImpactFXIndex", TypeS32, Offset(mImpactFXIndex, Material),
-      "What FX to play from the PlayerData sound list when the player impacts on the surface with a velocity equal or greater "
-      "than PlayerData::groundImpactMinSpeed.\n\n"
-      "For a list of IDs, see #impactFXId");
-   INITPERSISTFIELD_SOUNDASSET(CustomImpactSound, Material,
-      "The sound to play when the player impacts on the surface with a velocity equal or greater than PlayerData::groundImpactMinSpeed.  "
-      "If this is set, it overrides #impactSoundId.  This field is useful for directly assigning custom impact sounds to materials "
-      "without having to rely on the PlayerData sound assignment.\n\n"
-      "@warn Be aware that materials are client-side objects.  This means that the SFXTracks assigned to materials must be client-side, too.");
-
-   //Deactivate these for the moment as they are not used.
-
-#if 0
-   addField("friction", TypeF32, Offset(mFriction, Material));
-   addField("directSoundOcclusion", TypeF32, Offset(mDirectSoundOcclusion, Material));
-   addField("reverbSoundOcclusion", TypeF32, Offset(mReverbSoundOcclusion, Material));
-#endif
-
-   endGroup("Behavioral");
-
    Parent::initPersistFields();
    Parent::initPersistFields();
 }
 }