physical.go 5.4 KB

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