physical.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. // Copyright 2016 The G3N Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package material
  5. import (
  6. "github.com/g3n/engine/gls"
  7. "github.com/g3n/engine/math32"
  8. "github.com/g3n/engine/texture"
  9. )
  10. // Physical is a physically based rendered material which uses the metallic-roughness model.
  11. type Physical struct {
  12. Material // Embedded material
  13. baseColorTex *texture.Texture2D // Optional base color texture
  14. metallicRoughnessTex *texture.Texture2D // Optional metallic-roughness
  15. normalTex *texture.Texture2D // Optional normal texture
  16. occlusionTex *texture.Texture2D // Optional occlusion texture
  17. emissiveTex *texture.Texture2D // Optional emissive texture
  18. uni gls.Uniform // Uniform location cache
  19. udata struct { // Combined uniform data
  20. baseColorFactor math32.Color4
  21. emissiveFactor math32.Color4
  22. metallicFactor float32
  23. roughnessFactor float32
  24. }
  25. }
  26. // Number of glsl shader vec4 elements used by uniform data
  27. const physicalVec4Count = 3
  28. // NewPhysical creates and returns a pointer to a new Physical material.
  29. func NewPhysical() *Physical {
  30. m := new(Physical)
  31. m.Material.Init()
  32. m.SetShader("physical")
  33. // Creates uniform and set default values
  34. m.uni.Init("Material")
  35. m.udata.baseColorFactor = math32.Color4{1, 1, 1, 1}
  36. m.udata.emissiveFactor = math32.Color4{0, 0, 0, 1}
  37. m.udata.metallicFactor = 1
  38. m.udata.roughnessFactor = 1
  39. return m
  40. }
  41. // SetBaseColorFactor sets this material base color.
  42. // Its default value is {1,1,1,1}.
  43. // Returns pointer to this updated material.
  44. func (m *Physical) SetBaseColorFactor(c *math32.Color4) *Physical {
  45. m.udata.baseColorFactor = *c
  46. return m
  47. }
  48. // SetMetallicFactor sets this material metallic factor.
  49. // Its default value is 1.
  50. // Returns pointer to this updated material.
  51. func (m *Physical) SetMetallicFactor(v float32) *Physical {
  52. m.udata.metallicFactor = v
  53. return m
  54. }
  55. // SetRoughnessFactor sets this material roughness factor.
  56. // Its default value is 1.
  57. // Returns pointer to this updated material.
  58. func (m *Physical) SetRoughnessFactor(v float32) *Physical {
  59. m.udata.roughnessFactor = v
  60. return m
  61. }
  62. // SetEmissiveFactor sets the emissive color of the material.
  63. // Its default is {1, 1, 1}.
  64. // Returns pointer to this updated material.
  65. func (m *Physical) SetEmissiveFactor(c *math32.Color) *Physical {
  66. m.udata.emissiveFactor.R = c.R
  67. m.udata.emissiveFactor.G = c.G
  68. m.udata.emissiveFactor.B = c.B
  69. return m
  70. }
  71. // SetBaseColorMap sets this material optional texture base color.
  72. // Returns pointer to this updated material.
  73. func (m *Physical) SetBaseColorMap(tex *texture.Texture2D) *Physical {
  74. m.baseColorTex = tex
  75. if m.baseColorTex != nil {
  76. m.baseColorTex.SetUniformNames("uBaseColorSampler", "uBaseColorTexParams")
  77. m.ShaderDefines.Set("HAS_BASECOLORMAP", "")
  78. m.AddTexture(m.baseColorTex)
  79. } else {
  80. m.ShaderDefines.Unset("HAS_BASECOLORMAP")
  81. m.RemoveTexture(m.baseColorTex)
  82. }
  83. return m
  84. }
  85. // SetMetallicRoughnessMap sets this material optional metallic-roughness texture.
  86. // Returns pointer to this updated material.
  87. func (m *Physical) SetMetallicRoughnessMap(tex *texture.Texture2D) *Physical {
  88. m.metallicRoughnessTex = tex
  89. if m.metallicRoughnessTex != nil {
  90. m.metallicRoughnessTex.SetUniformNames("uMetallicRoughnessSampler", "uMetallicRoughnessTexParams")
  91. m.ShaderDefines.Set("HAS_METALROUGHNESSMAP", "")
  92. m.AddTexture(m.metallicRoughnessTex)
  93. } else {
  94. m.ShaderDefines.Unset("HAS_METALROUGHNESSMAP")
  95. m.RemoveTexture(m.metallicRoughnessTex)
  96. }
  97. return m
  98. }
  99. // SetNormalMap sets this material optional normal texture.
  100. // Returns pointer to this updated material.
  101. // TODO add SetNormalMap (and SetSpecularMap) to StandardMaterial.
  102. func (m *Physical) SetNormalMap(tex *texture.Texture2D) *Physical {
  103. m.normalTex = tex
  104. if m.normalTex != nil {
  105. m.normalTex.SetUniformNames("uNormalSampler", "uNormalTexParams")
  106. m.ShaderDefines.Set("HAS_NORMALMAP", "")
  107. m.AddTexture(m.normalTex)
  108. } else {
  109. m.ShaderDefines.Unset("HAS_NORMALMAP")
  110. m.RemoveTexture(m.normalTex)
  111. }
  112. return m
  113. }
  114. // SetOcclusionMap sets this material optional occlusion texture.
  115. // Returns pointer to this updated material.
  116. func (m *Physical) SetOcclusionMap(tex *texture.Texture2D) *Physical {
  117. m.occlusionTex = tex
  118. if m.occlusionTex != nil {
  119. m.occlusionTex.SetUniformNames("uOcclusionSampler", "uOcclusionTexParams")
  120. m.ShaderDefines.Set("HAS_OCCLUSIONMAP", "")
  121. m.AddTexture(m.occlusionTex)
  122. } else {
  123. m.ShaderDefines.Unset("HAS_OCCLUSIONMAP")
  124. m.RemoveTexture(m.occlusionTex)
  125. }
  126. return m
  127. }
  128. // SetEmissiveMap sets this material optional emissive texture.
  129. // Returns pointer to this updated material.
  130. func (m *Physical) SetEmissiveMap(tex *texture.Texture2D) *Physical {
  131. m.emissiveTex = tex
  132. if m.emissiveTex != nil {
  133. m.emissiveTex.SetUniformNames("uEmissiveSampler", "uEmissiveTexParams")
  134. m.ShaderDefines.Set("HAS_EMISSIVEMAP", "")
  135. m.AddTexture(m.emissiveTex)
  136. } else {
  137. m.ShaderDefines.Unset("HAS_EMISSIVEMAP")
  138. m.RemoveTexture(m.emissiveTex)
  139. }
  140. return m
  141. }
  142. // RenderSetup transfer this material uniforms and textures to the shader
  143. func (m *Physical) RenderSetup(gl *gls.GLS) {
  144. m.Material.RenderSetup(gl)
  145. location := m.uni.Location(gl)
  146. gl.Uniform4fv(location, physicalVec4Count, &m.udata.baseColorFactor.R)
  147. }