Material.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /******************************************************************************
  2. Use 'Material' to specify custom mesh material parameters.
  3. 'Materials' are usually created in the 'Material Editor' tool, and used by 'Meshes'.
  4. /******************************************************************************/
  5. enum MATERIAL_TECHNIQUE : Byte // Material Techniques
  6. {
  7. MTECH_DEFAULT , // standard rendering of solid (opaque) materials
  8. MTECH_ALPHA_TEST , // indicates that textures alpha channel will be used as models transparency (this is slightly slower than Default as alpha testing may disable some hardware-level optimizations)
  9. MTECH_FUR , // mesh will be rendered with fur effect, the mesh will be wrapped with additional fur imitating textures, in this technique "detail scale" specifies fur intensity, "detail power" specifies fur length, supported only in Deferred Renderer
  10. MTECH_GRASS , // mesh vertexes will bend on the wind like grass, bending intensity is determined by mesh vertex source Y position, which should be in the range from 0 to 1
  11. MTECH_LEAF , // mesh vertexes will bend on the wind like tree leafs, to use this technique mesh must also contain leaf attachment positions, which can be generated in the Model Editor tool through menu options
  12. MTECH_BLEND , // mesh will be smoothly blended on the screen using alpha values, mesh will not be affected by lighting or shadowing
  13. MTECH_BLEND_LIGHT , // works like Blend technique except that mesh will be affected by lighting or shadowing, however only the most significant directional light will be used (all other lights are ignored), due to additional lighting calculations this is slower than Blend technique
  14. MTECH_BLEND_LIGHT_GRASS , // combination of Blend Light and Grass techniques
  15. MTECH_BLEND_LIGHT_LEAF , // combination of Blend Light and Leaf techniques
  16. MTECH_TEST_BLEND_LIGHT , // works like MTECH_BLEND_LIGHT with additional Alpha-Testing and Depth-Writing which enables correct Depth-Sorting
  17. MTECH_TEST_BLEND_LIGHT_GRASS, // works like MTECH_BLEND_LIGHT_GRASS with additional Alpha-Testing and Depth-Writing which enables correct Depth-Sorting
  18. MTECH_TEST_BLEND_LIGHT_LEAF , // works like MTECH_BLEND_LIGHT_LEAF with additional Alpha-Testing and Depth-Writing which enables correct Depth-Sorting
  19. MTECH_NUM , // number of Material Techniques
  20. };
  21. /******************************************************************************/
  22. struct MaterialParams // Material Parameters
  23. {
  24. Vec4 color ; // color (0,0,0,0) .. (1,1,1,1), default=(1,1,1,1)
  25. Vec ambient ; // ambient (0,0,0) .. (1,1,1) , default=(0,0,0)
  26. Flt specular , // specular 0 .. 1 , default=0
  27. sss , // sub-surface scattering 0 .. 1 , default=0
  28. glow , // glow amount 0 .. 1 , default=0
  29. rough , // roughness 0 .. 1 , default=1
  30. bump , // bumpiness 0 .. 0.09 , default=0.03
  31. tex_scale, // texture scale 0 .. Inf , default=1, this is used mainly for World terrain textures scaling
  32. det_scale, // detail scale 0 .. Inf , default=4
  33. det_power, // detail power 0 .. 1 , default=0.3
  34. reflect ; // reflection 0 .. 1 , default=0.2
  35. };
  36. STRUCT(Material , MaterialParams) // Mesh Rendering Material - contains render parameters and textures
  37. //{
  38. ImagePtr base_0 , // base texture #0 , default=null, this texture contains data packed in following channel order: RGB, Alpha/Bump
  39. base_1 , // base texture #1 , default=null, this texture contains data packed in following channel order: NormalX, NormalY, Specular, Alpha/Glow
  40. detail_map , // detail texture , default=null
  41. macro_map , // macro texture , default=null
  42. reflection_map , // reflection texture , default=null
  43. light_map ; // light map texture , default=null
  44. Int user_shader , // user shader enum element index, default=0
  45. user_type ; // user type enum element index, default=0
  46. Str8 user_shader_name, // user shader enum element name , default=""
  47. user_type_name ; // user type enum element name , default=""
  48. Bool cull ; // face culling , default=true
  49. MATERIAL_TECHNIQUE technique ; // material technique , default=MTECH_DEFAULT
  50. // get
  51. Bool wantTanBin()C; // if this Material needs tangent/binormals
  52. // operations
  53. Material& validate(); // this needs to be called after manually changing the parameters/textures
  54. Material& reset (); // reset to default values (automatically calls 'validate')
  55. // io
  56. Bool save(C Str &name)C; // save, false on fail
  57. Bool load(C Str &name) ; // load, false on fail
  58. Bool save(File &f, CChar *path=null)C; // save, 'path'=path at which resource is located (this is needed so that the sub-resources can be accessed with relative path), false on fail
  59. Bool load(File &f, CChar *path=null) ; // load, 'path'=path at which resource is located (this is needed so that the sub-resources can be accessed with relative path), false on fail
  60. #if EE_PRIVATE
  61. Bool saveData(File &f, CChar *path=null)C; // save binary, 'path'=path at which resource is located (this is needed so that the sub-resources can be accessed with relative path), false on fail
  62. Bool loadData(File &f, CChar *path=null) ; // load binary, 'path'=path at which resource is located (this is needed so that the sub-resources can be accessed with relative path), false on fail
  63. Bool saveTxt (FileText &f, CChar *path=null)C; // save text , 'path'=path at which resource is located (this is needed so that the sub-resources can be accessed with relative path), false on fail
  64. Bool loadTxt (FileText &f, CChar *path=null) ; // load text , 'path'=path at which resource is located (this is needed so that the sub-resources can be accessed with relative path), false on fail
  65. Bool saveTxt (C Str &name )C; // save text , false on fail
  66. Bool loadTxt (C Str &name ) ; // load text , false on fail
  67. #endif
  68. Material();
  69. ~Material();
  70. #if EE_PRIVATE
  71. Bool hasAlpha ()C; // if material technique involves Alpha Blending or Testing
  72. Bool hasAlphaBlend ()C; // if material technique involves Alpha Blending
  73. Bool hasAlphaTest ()C {return _has_alpha_test;} // if material technique involves Alpha Testing
  74. Bool hasAlphaBlendLight()C; // if material technique involves Alpha Blending with Light
  75. Bool hasGrass ()C; // if material technique involves Grass Bending
  76. Bool hasLeaf ()C; // if material technique involves Leaf Bending
  77. Bool alphaInBase0()C {return hasAlpha() && !base_1;}
  78. void setSolid ( )C;
  79. void setAmbient ( )C;
  80. void setBlend ( )C;
  81. void setBlendForce( )C;
  82. void setOutline ( )C;
  83. void setBehind ( )C;
  84. void setShadow ( )C;
  85. void setMulti (Int i)C;
  86. void setAuto ( )C;
  87. #endif
  88. #if !EE_PRIVATE
  89. private:
  90. #endif
  91. Bool _depth_write, _has_alpha_test;
  92. Color _alpha_factor;
  93. struct Multi
  94. {
  95. Vec4 color, normal_mul, normal_add;
  96. Flt tex_scale, det_scale, det_mul, det_add, bump, macro, reflect;
  97. }_multi;
  98. struct MaterialShader // Material->Shader link
  99. {
  100. ShaderBase *shader; // keep this as first member, because it's used most often
  101. Int next_material_shader, // index of the next shader for this material in 'MaterialShaders' container
  102. shader_material ; // index of 'ShaderMaterial'
  103. #if EE_PRIVATE
  104. void clear () {shader=null; next_material_shader=shader_material=-1;}
  105. void unlink() {shader=null; /*next_material_shader=-1;*/} // clearing 'next_material_shader' is not needed, because we check it only when "shader!=null"
  106. Bool empty ()C {return shader==null;}
  107. #endif
  108. }mutable _solid_material_shader, _shadow_material_shader; // have to keep 2 separate, because in forward renderer we queue solid draw calls, but before we draw them, we process shadows first. These store information about the first shader for this material (most materials will use only one shader during rendering), but if there are more shaders needed, then they contain indexes to next shaders in 'MaterialShaders' container
  109. #if COUNT_MATERIAL_USAGE
  110. mutable Int _usage;
  111. #endif
  112. #if EE_PRIVATE
  113. #if COUNT_MATERIAL_USAGE
  114. void clearUsage()C {_usage=0;}
  115. void incUsage()C {_usage++;}
  116. void decUsage()C {_usage--;}
  117. Bool emptyUsage()C {return !_usage;}
  118. #else
  119. void clearUsage()C {}
  120. void incUsage()C {}
  121. void decUsage()C {}
  122. Bool emptyUsage()C {return true;}
  123. #endif
  124. void clearSolid ()C { _solid_material_shader.clear();}
  125. void clearShadow()C {_shadow_material_shader.clear();}
  126. void clear ()C {clearSolid(); clearShadow(); clearUsage();}
  127. void unlinkSolid ()C { _solid_material_shader.unlink();}
  128. void unlinkShadow()C {_shadow_material_shader.unlink();}
  129. void unlink ()C {unlinkSolid(); unlinkShadow();}
  130. Bool canBeRemoved()C {return _solid_material_shader.empty() && _shadow_material_shader.empty() && emptyUsage();}
  131. #endif
  132. public:
  133. void _adjustParams(UInt old_base_tex, UInt new_base_tex);
  134. };
  135. #if EE_PRIVATE
  136. extern Material
  137. MaterialDefault , // Default Material
  138. MaterialDefaultNoCull; // Default Material with no culling
  139. extern const Material
  140. *MaterialLast , // Last set Material
  141. *MaterialLast4[4] ; // Last set Material (multi materials)
  142. #endif
  143. /******************************************************************************/
  144. #if EE_PRIVATE
  145. // unique combination of 4 materials
  146. struct UniqueMultiMaterialKey
  147. {
  148. C Material *m[4];
  149. UniqueMultiMaterialKey() {}
  150. UniqueMultiMaterialKey(C Material *a, C Material *b, C Material *c, C Material *d) {m[0]=a; m[1]=b; m[2]=c; m[3]=d;}
  151. };
  152. struct UniqueMultiMaterialData
  153. {
  154. Material::MaterialShader material_shader;
  155. void clear () {material_shader.clear ();}
  156. void unlink() {material_shader.unlink();}
  157. UniqueMultiMaterialData() {clear();}
  158. };
  159. #endif
  160. /******************************************************************************/
  161. DECLARE_CACHE(Material, Materials, MaterialPtr); // 'Materials' cache storing 'Material' objects which can be accessed by 'MaterialPtr' pointer
  162. extern Enum *MaterialUserShader , // Material's User Shader enum, default=Enums.get("Enum/material_user_shader.enum")
  163. *MaterialUserType ; // Material's User Type enum, default=Enums.get("Enum/material_user_type.enum" )
  164. #if EE_PRIVATE
  165. extern MaterialPtr MaterialNull;
  166. extern ThreadSafeMap<UniqueMultiMaterialKey, UniqueMultiMaterialData> UniqueMultiMaterialMap;
  167. #endif
  168. /******************************************************************************/
  169. #if EE_PRIVATE
  170. void MaterialClear();
  171. void ShutMaterial();
  172. void InitMaterial();
  173. INLINE C Material& GetMaterial (C Material *material ) {return material ? *material : MaterialDefault;}
  174. INLINE C Material& GetShadowMaterial(C Material *material, Bool reuse_default) {return reuse_default ? (material && !material->cull) ? MaterialDefaultNoCull : MaterialDefault : GetMaterial(material);}
  175. #endif
  176. /******************************************************************************/
  177. enum BASE_TEX
  178. {
  179. BT_COLOR =1<<0, // base texture contains color
  180. BT_ALPHA =1<<1, // base texture contains alpha
  181. BT_BUMP =1<<2, // base texture contains bump
  182. BT_NORMAL =1<<3, // base texture contains normal
  183. BT_SPECULAR=1<<4, // base texture contains specular
  184. BT_GLOW =1<<5, // base texture contains glow
  185. };
  186. UInt CreateBaseTextures (Image &base_0, Image &base_1, C Image &col, C Image &alpha, C Image &bump, C Image &normal, C Image &specular, C Image &glow, Bool resize_to_pow2=true, Bool flip_normal_y=false, FILTER_TYPE filter=FILTER_BEST); // create 'base_0' and 'base_1' base material textures from given images, textures will be created as IMAGE_R8G8B8A8 IMAGE_SOFT, 'flip_normal_y'=if flip normal map Y channel, returns bit combination of BASE_TEX enums of what the base textures have
  187. void CreateDetailTexture(Image &detail, C Image &col, C Image &bump, C Image &normal, Bool resize_to_pow2=true, Bool flip_normal_y=false, FILTER_TYPE filter=FILTER_BEST); // create 'detail' material texture from given images, texture will be created as IMAGE_R8G8B8A8 IMAGE_SOFT, 'flip_normal_y'=if flip normal map Y channel
  188. Bool CreateBumpFromColor(Image &bump , C Image &col, Flt min_blur_range=-1, Flt max_blur_range=-1, Threads *threads=null ); // create 'bump' texture from color image , texture will be created as IMAGE_F32 IMAGE_SOFT, 'min_blur_range' and 'max_blur_range' are minimum and maximum blur ranges used for creating the bump map, use -1 for auto values, 'threads'=optional threads allowing to perform the operation on multiple threads
  189. Bool MergeBaseTextures (Image &base_0, C Material &material, Int image_type=-1, Int max_image_size=-1, C Vec *light_dir=&NoTemp(!Vec(1, -1, 1)), Flt light_power=0.77f, Flt spec_mul=1.0f, FILTER_TYPE filter=FILTER_BEST); // create 'base_0' simplified base material texture out of existing 'material' textures, this works by merging the two base textures into one (thus removing bump, normal, specular and glow maps, and keeping only color and alpha maps), 'image_type'=new desired IMAGE_TYPE for texture (-1=don't modify and use existing type), 'max_image_size'=limit maximum texture resolution (value of <=0 does not apply any limit), 'light_dir'=specify direction of the light for baking the normal map onto the color map (use null for no baking), 'light_power'=intensity of light (0..1) used during baking the normal map on the color map (ignored if 'light_dir' is set to null), 'spec_mul'=specular multiplier (ignored if 'light_dir' is set to null), returns true if base textures were merged and the new image was created, returns false if the material does not use two base textures (in such case the 'base_0' is left unmodified)
  190. /******************************************************************************/