leonsal преди 8 години
родител
ревизия
1589153925
променени са 5 файла, в които са добавени 200 реда и са изтрити 0 реда
  1. 15 0
      material/material.go
  2. 172 0
      material/pbr_mr.go
  3. 1 0
      renderer/renderer.go
  4. 5 0
      renderer/shaman.go
  5. 7 0
      texture/texture2D.go

+ 15 - 0
material/material.go

@@ -74,6 +74,7 @@ type Material struct {
 	lineWidth        float32              // line width for lines and mesh wireframe
 	polyOffsetFactor float32              // polygon offset factor
 	polyOffsetUnits  float32              // polygon offset units
+	defines          map[string]string    // shader defines
 	textures         []*texture.Texture2D // List of textures
 }
 
@@ -97,6 +98,7 @@ func (mat *Material) Init() *Material {
 	mat.lineWidth = 1.0
 	mat.polyOffsetFactor = 0
 	mat.polyOffsetUnits = 0
+	mat.defines = make(map[string]string)
 	mat.textures = make([]*texture.Texture2D, 0)
 
 	return mat
@@ -216,6 +218,19 @@ func (mat *Material) SetPolygonOffset(factor, units float32) {
 	mat.polyOffsetUnits = units
 }
 
+// SetShaderDefine defines a name with the specified value which will
+// be passed to this material shader.
+func (mat *Material) SetShaderDefine(name, value string) {
+
+	mat.defines[name] = value
+}
+
+// ShaderDefines returns a map with the shader defines.
+func (mat *Material) ShaderDefines() map[string]string {
+
+	return mat.defines
+}
+
 func (mat *Material) RenderSetup(gs *gls.GLS) {
 
 	// Sets triangle side view mode

+ 172 - 0
material/pbr_mr.go

@@ -0,0 +1,172 @@
+// Copyright 2016 The G3N Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package material
+
+import (
+	"unsafe"
+
+	"github.com/g3n/engine/gls"
+	"github.com/g3n/engine/math32"
+	"github.com/g3n/engine/texture"
+)
+
+// PbrMr is a physically based rendered material which uses the metallic-roughness model.
+type PbrMr struct {
+	Material                                // Embedded material
+	baseColorTex         *texture.Texture2D // Optional base color texture
+	metallicRoughnessTex *texture.Texture2D // Optional metallic-roughness
+	normalTex            *texture.Texture2D // Optional normal texture
+	occlusionTex         *texture.Texture2D // Optional occlusion texture
+	emissiveTex          *texture.Texture2D // Optional emissive texture
+	uni                  gls.Uniform        // Uniform location cache
+	udata                struct {           // Combined uniform data
+		baseColorFactor math32.Color4
+		emissiveFactor  math32.Color4
+		metallicFactor  float32
+		roughnessFactor float32
+	}
+}
+
+// Number of glsl shader vec4 elements used by uniform data
+const pbrMrVec4Count = 3
+
+// NewPbrMr creates and returns a pointer to a new PbrMr material.
+func NewPbrMr() *PbrMr {
+
+	m := new(PbrMr)
+	m.Material.Init()
+	m.SetShader("pbr_mr")
+
+	// Creates uniform and set defaulf values
+	m.uni.Init("Material")
+	m.udata.baseColorFactor = math32.Color4{1, 1, 1, 1}
+	m.udata.emissiveFactor = math32.Color4{0, 0, 0, 0}
+	m.udata.metallicFactor = 1.0
+	m.udata.roughnessFactor = 1.0
+	return m
+}
+
+// SetBaseColorFactor sets this material base color.
+// Its default value is {1,1,1,1}.
+// Returns pointer to this updated material.
+func (m *PbrMr) SetBaseColorFactor(c *math32.Color4) *PbrMr {
+
+	m.udata.baseColorFactor = *c
+	return m
+}
+
+// SetBaseColorTexture sets this material optional texture base color.
+// Returns pointer to this updated material.
+func (m *PbrMr) SetBaseColorTexture(tex *texture.Texture2D) *PbrMr {
+
+	m.baseColorTex = tex
+	if m.baseColorTex != nil {
+		m.baseColorTex.SetUniformNames("uBaseColorSampler", "uBaseColorTexParams")
+		m.SetShaderDefine("HAS_BASECOLORMAP", "")
+	}
+	return m
+}
+
+// SetEmissiveFactor sets the emissive color of the material.
+// Its default is {0, 0, 0}.
+// Returns pointer to this updated material.
+func (m *PbrMr) SetEmissiveFactor(c *math32.Color) *PbrMr {
+
+	m.udata.emissiveFactor.R = c.R
+	m.udata.emissiveFactor.G = c.G
+	m.udata.emissiveFactor.B = c.B
+	return m
+}
+
+// SetMetallicFactor sets this material metallic factor.
+// Its default value is 1.0
+// Returns pointer to this updated material.
+func (m *PbrMr) SetMetallicFactor(v float32) *PbrMr {
+
+	m.udata.metallicFactor = v
+	return m
+}
+
+// SetMetallicRoughnessTexture sets this material optional metallic-roughness texture.
+// Returns pointer to this updated material.
+func (m *PbrMr) SetMetallicRoughnessTexture(tex *texture.Texture2D) *PbrMr {
+
+	m.metallicRoughnessTex = tex
+	if m.metallicRoughnessTex != nil {
+		m.metallicRoughnessTex.SetUniformNames("uMetallicRoughnessSampler", "uMetallicRoughnessTexParams")
+		m.SetShaderDefine("HAS_METALROUGHNESSMAP", "")
+	}
+	return m
+}
+
+// SetNormalTexture sets this material optional normal texture.
+// Returns pointer to this updated material.
+func (m *PbrMr) SetNormalTexture(tex *texture.Texture2D) *PbrMr {
+
+	m.normalTex = tex
+	if m.normalTex != nil {
+		m.normalTex.SetUniformNames("uNormalSampler", "uNormalSamplerTexParams")
+		m.SetShaderDefine("HAS_NORMALMAP", "")
+	}
+	return m
+}
+
+// SetOcclusionTexture sets this material optional occlusion texture.
+// Returns pointer to this updated material.
+func (m *PbrMr) SetOcclusionTexture(tex *texture.Texture2D) *PbrMr {
+
+	m.occlusionTex = tex
+	if m.occlusionTex != nil {
+		m.occlusionTex.SetUniformNames("uOcclusionSampler", "uOcclusionTexParams")
+		m.SetShaderDefine("HAS_OCCLUSIONMAP", "")
+	}
+	return m
+}
+
+// SetEmissiveTexture sets this material optional emissive texture.
+// Returns pointer to this updated material.
+func (m *PbrMr) SetEmissiveTexture(tex *texture.Texture2D) *PbrMr {
+
+	m.emissiveTex = tex
+	if m.emissiveTex != nil {
+		m.emissiveTex.SetUniformNames("uEmissiveSampler", "uEmissiveSamplerTexParams")
+		m.SetShaderDefine("HAS_EMISSIVEMAP", "")
+	}
+	return m
+}
+
+// SetRoughnessFactor sets this material roughness factor.
+// Its default value is 1.0
+// Returns pointer to this updated material.
+func (m *PbrMr) SetRoughnessFactor(v float32) *PbrMr {
+
+	m.udata.roughnessFactor = v
+	return m
+}
+
+// RenderSetup transfer this material uniforms and textures to the shader
+func (m *PbrMr) RenderSetup(gl *gls.GLS) {
+
+	m.Material.RenderSetup(gl)
+	location := m.uni.Location(gl)
+	gl.Uniform4fvUP(location, pbrMrVec4Count, unsafe.Pointer(&m.udata))
+
+	// Transfer optional textures
+	if m.baseColorTex != nil {
+		m.baseColorTex.RenderSetup(gl, 0)
+	}
+	if m.metallicRoughnessTex != nil {
+		m.metallicRoughnessTex.RenderSetup(gl, 0)
+	}
+	if m.normalTex != nil {
+		m.normalTex.RenderSetup(gl, 0)
+	}
+	if m.occlusionTex != nil {
+		m.occlusionTex.RenderSetup(gl, 0)
+	}
+	if m.emissiveTex != nil {
+		m.emissiveTex.RenderSetup(gl, 0)
+	}
+}

+ 1 - 0
renderer/renderer.go

@@ -269,6 +269,7 @@ func (r *Renderer) renderScene(iscene core.INode, icam camera.ICamera) error {
 		r.specs.ShaderUnique = mat.ShaderUnique()
 		r.specs.UseLights = mat.UseLights()
 		r.specs.MatTexturesMax = mat.TextureCount()
+		r.specs.Defines = mat.ShaderDefines()
 		_, err := r.shaman.SetProgram(&r.specs)
 		if err != nil {
 			return err

+ 5 - 0
renderer/shaman.go

@@ -34,6 +34,7 @@ type ShaderSpecs struct {
 	PointLightsMax   int                // Current Number of point lights
 	SpotLightsMax    int                // Current Number of spot lights
 	MatTexturesMax   int                // Current Number of material textures
+	Defines          map[string]string  // Additional shader defines
 }
 
 type ProgSpecs struct {
@@ -179,6 +180,10 @@ func (sm *Shaman) GenProgram(specs *ShaderSpecs) (*gls.Program, error) {
 	defines["POINT_LIGHTS"] = strconv.FormatUint(uint64(specs.PointLightsMax), 10)
 	defines["SPOT_LIGHTS"] = strconv.FormatUint(uint64(specs.SpotLightsMax), 10)
 	defines["MAT_TEXTURES"] = strconv.FormatUint(uint64(specs.MatTexturesMax), 10)
+	// Adds additional material defines from the specs parameter
+	for name, value := range specs.Defines {
+		defines[name] = value
+	}
 
 	// Get vertex shader source
 	vertexSource, ok := sm.shadersm[progInfo.Vertex]

+ 7 - 0
texture/texture2D.go

@@ -127,6 +127,13 @@ func (t *Texture2D) Dispose() {
 	}
 }
 
+// SetUniformNames sets the names of the uniforms in the shader for sampler and texture info.
+func (t *Texture2D) SetUniformNames(sampler, info string) {
+
+	t.uniUnit.Init(sampler)
+	t.uniInfo.Init(info)
+}
+
 // SetImage sets a new image for this texture
 func (t *Texture2D) SetImage(imgfile string) error {