Selaa lähdekoodia

uniforms grouping...

leonsal 8 vuotta sitten
vanhempi
commit
66d07054a5
6 muutettua tiedostoa jossa 248 lisäystä ja 171 poistoa
  1. 82 43
      gls/uniform.go
  2. 19 14
      light/directional.go
  3. 28 30
      light/point.go
  4. 78 52
      light/spot.go
  5. 25 16
      renderer/shader/chunkLights.go
  6. 16 16
      renderer/shader/chunkPhongModel.go

+ 82 - 43
gls/uniform.go

@@ -35,7 +35,6 @@ func (uni *Uniform) LocationIdx(gs *GLS, idx int) int32 {
 		uni.nameidx = fmt.Sprintf("%s[%d]", uni.name, idx)
 		uni.idx = idx
 	}
-	//log.Debug("Location(%s, %d)", uni.name, idx)
 	loc := gs.prog.GetUniformLocation(uni.nameidx)
 	return loc
 }
@@ -437,6 +436,81 @@ func (uni *UniformMatrix4f) TransferIdx(gl *GLS, idx int) {
 	gl.UniformMatrix4fv(uni.LocationIdx(gl, idx), 1, false, &uni.v[0])
 }
 
+//
+// Type Uniform1fv is a uniform containing an array of float32 values
+//
+type Uniform1fv struct {
+	Uniform           // embedded uniform
+	v       []float32 // array of values
+}
+
+// NewUniform1fv creates and returns an uniform with array of float32 values
+// with the specified size
+func NewUniform1fv(name string, count int) *Uniform1fv {
+
+	uni := new(Uniform1fv)
+	uni.Init(name, count)
+	return uni
+}
+
+// Init initializes an Uniform1fv object with the specified name and count of float32 values.
+// It is normally used when the uniform is embedded in another object.
+func (uni *Uniform1fv) Init(name string, count int) {
+
+	uni.name = name
+	uni.v = make([]float32, count)
+}
+
+// SetVector3 sets the value of the elements of uniform starting at pos
+// from the specified Vector3 object.
+func (uni *Uniform1fv) SetVector3(pos int, v *math32.Vector3) {
+
+	uni.v[pos] = v.X
+	uni.v[pos+1] = v.Y
+	uni.v[pos+2] = v.Z
+}
+
+// GetVector3 gets the value of the elements of the uniform starting at
+// pos as a Vector3 object.
+func (uni *Uniform1fv) GetVector3(pos int) math32.Vector3 {
+
+	return math32.Vector3{uni.v[pos], uni.v[pos+1], uni.v[pos+2]}
+}
+
+// SetColor sets the value of the elements of the uniform starting at pos
+// from the specified Color object.
+func (uni *Uniform1fv) SetColor(pos int, color *math32.Color) {
+
+	uni.v[pos] = color.R
+	uni.v[pos+1] = color.G
+	uni.v[pos+2] = color.B
+}
+
+// GetColor gets the value of the elements of the uniform starting at pos
+// as a Color object.
+func (uni *Uniform1fv) GetColor(pos int) math32.Color {
+
+	return math32.Color{uni.v[pos], uni.v[pos+1], uni.v[pos+2]}
+}
+
+// Set sets the value of the element at the specified position
+func (uni *Uniform1fv) Set(pos int, v float32) {
+
+	uni.v[pos] = v
+}
+
+// Get gets the value of the element at the specified position
+func (uni *Uniform1fv) Get(pos int, v float32) float32 {
+
+	return uni.v[pos]
+}
+
+// TransferIdx transfer a block of 'count' values of this uniform starting at 'pos'.
+func (uni *Uniform1fv) TransferIdx(gl *GLS, pos, count int) {
+
+	gl.Uniform1fv(uni.LocationIdx(gl, pos), 1, uni.v[pos:])
+}
+
 //
 // Type Uniform3fv is a uniform containing an array of three float32 values
 //
@@ -467,9 +541,6 @@ func (uni *Uniform3fv) Init(name string, count int) {
 // Set sets the value of all elements of the specified group of 3 floats for this uniform array
 func (uni *Uniform3fv) Set(idx int, v0, v1, v2 float32) {
 
-	if idx < 0 || idx >= uni.count {
-		panic("Invalid index")
-	}
 	pos := idx * 3
 	uni.v[pos] = v0
 	uni.v[pos+1] = v1
@@ -479,9 +550,6 @@ func (uni *Uniform3fv) Set(idx int, v0, v1, v2 float32) {
 // Get gets the value of all elements of the specified group of 3 floats for this uniform array
 func (uni *Uniform3fv) Get(idx int) (v0, v1, v2 float32) {
 
-	if idx < 0 || idx >= uni.count {
-		panic("Invalid index")
-	}
 	pos := idx * 3
 	return uni.v[pos], uni.v[pos+1], uni.v[pos+2]
 }
@@ -490,9 +558,6 @@ func (uni *Uniform3fv) Get(idx int) (v0, v1, v2 float32) {
 // from the specified Vector3 object.
 func (uni *Uniform3fv) SetVector3(idx int, v *math32.Vector3) {
 
-	if idx < 0 || idx >= uni.count {
-		panic("Invalid index")
-	}
 	pos := idx * 3
 	uni.v[pos] = v.X
 	uni.v[pos+1] = v.Y
@@ -503,9 +568,6 @@ func (uni *Uniform3fv) SetVector3(idx int, v *math32.Vector3) {
 // as a Vector3 object.
 func (uni *Uniform3fv) GetVector3(idx int) math32.Vector3 {
 
-	if idx < 0 || idx >= uni.count {
-		panic("Invalid index")
-	}
 	pos := idx * 3
 	return math32.Vector3{uni.v[pos], uni.v[pos+1], uni.v[pos+2]}
 }
@@ -514,9 +576,6 @@ func (uni *Uniform3fv) GetVector3(idx int) math32.Vector3 {
 // form the specified Color object.
 func (uni *Uniform3fv) SetColor(idx int, color *math32.Color) {
 
-	if idx < 0 || idx >= uni.count {
-		panic("Invalid index")
-	}
 	pos := idx * 3
 	uni.v[pos] = color.R
 	uni.v[pos+1] = color.G
@@ -527,9 +586,6 @@ func (uni *Uniform3fv) SetColor(idx int, color *math32.Color) {
 // as a Color object.
 func (uni *Uniform3fv) GetColor(idx int) math32.Color {
 
-	if idx < 0 || idx >= uni.count {
-		panic("Invalid index")
-	}
 	pos := idx * 3
 	return math32.Color{uni.v[pos], uni.v[pos+1], uni.v[pos+2]}
 }
@@ -537,18 +593,12 @@ func (uni *Uniform3fv) GetColor(idx int) math32.Color {
 // SetPos sets the value at the specified position in the uniform array.
 func (uni *Uniform3fv) SetPos(pos int, v float32) {
 
-	if pos < 0 || pos >= len(uni.v) {
-		panic("Invalid index")
-	}
 	uni.v[pos] = v
 }
 
 // GetPos gets the value at the specified position in the uniform array.
 func (uni *Uniform3fv) GetPos(pos int) float32 {
 
-	if pos < 0 || pos >= len(uni.v) {
-		panic("Invalid index")
-	}
 	return uni.v[pos]
 }
 
@@ -558,6 +608,13 @@ func (uni *Uniform3fv) Transfer(gl *GLS) {
 	gl.Uniform3fv(uni.Location(gl), int32(uni.count), uni.v)
 }
 
+// Transfer transfers the current values of this uniform to a specified
+// start position in the target uniform array.
+func (uni *Uniform3fv) TransferIdx(gl *GLS, idx int) {
+
+	gl.Uniform3fv(uni.LocationIdx(gl, idx), int32(uni.count), uni.v)
+}
+
 //
 // Type Uniform4fv is a Uniform containing an array of four float32 values
 //
@@ -588,9 +645,6 @@ func (uni *Uniform4fv) Init(name string, count int) {
 // Set sets the value of all elements of the specified group of 4 floats for this uniform array
 func (uni *Uniform4fv) Set(idx int, v0, v1, v2, v3 float32) {
 
-	if idx < 0 || idx >= uni.count {
-		panic("Invalid index")
-	}
 	pos := idx * 4
 	uni.v[pos] = v0
 	uni.v[pos+1] = v1
@@ -601,9 +655,6 @@ func (uni *Uniform4fv) Set(idx int, v0, v1, v2, v3 float32) {
 // Get gets the value of all elements of the specified group of 4 floats for this uniform array
 func (uni *Uniform4fv) Get(idx int) (v0, v1, v2, v3 float32) {
 
-	if idx < 0 || idx >= uni.count {
-		panic("Invalid index")
-	}
 	pos := idx * 4
 	return uni.v[pos], uni.v[pos+1], uni.v[pos+2], uni.v[pos+3]
 }
@@ -612,9 +663,6 @@ func (uni *Uniform4fv) Get(idx int) (v0, v1, v2, v3 float32) {
 // from the specified Vector4 object.
 func (uni *Uniform4fv) SetVector4(idx int, v *math32.Vector4) {
 
-	if idx < 0 || idx >= uni.count {
-		panic("Invalid index")
-	}
 	pos := idx * 4
 	uni.v[pos] = v.X
 	uni.v[pos+1] = v.Y
@@ -626,9 +674,6 @@ func (uni *Uniform4fv) SetVector4(idx int, v *math32.Vector4) {
 // as a Vector4 object.
 func (uni *Uniform4fv) GetVector4(idx int) math32.Vector4 {
 
-	if idx < 0 || idx >= uni.count {
-		panic("Invalid index")
-	}
 	pos := idx * 4
 	return math32.Vector4{uni.v[pos], uni.v[pos+1], uni.v[pos+2], uni.v[pos+3]}
 }
@@ -637,9 +682,6 @@ func (uni *Uniform4fv) GetVector4(idx int) math32.Vector4 {
 // form the specified Color4 object.
 func (uni *Uniform4fv) SetColor4(idx int, color *math32.Color4) {
 
-	if idx < 0 || idx >= uni.count {
-		panic("Invalid index")
-	}
 	pos := idx * 4
 	uni.v[pos] = color.R
 	uni.v[pos+1] = color.G
@@ -651,9 +693,6 @@ func (uni *Uniform4fv) SetColor4(idx int, color *math32.Color4) {
 // as a Color4 object.
 func (uni *Uniform4fv) GetColor4(idx int) math32.Color4 {
 
-	if idx < 0 || idx >= uni.count {
-		panic("Invalid index")
-	}
 	pos := idx * 4
 	return math32.Color4{uni.v[pos], uni.v[pos+1], uni.v[pos+2], uni.v[pos+3]}
 }

+ 19 - 14
light/directional.go

@@ -11,13 +11,20 @@ import (
 )
 
 type Directional struct {
-	core.Node                // Embedded node
-	color      math32.Color  // Light color
-	intensity  float32       // Light intensity
-	uColor     gls.Uniform3f // Light color uniform (color * intensity)
-	uDirection gls.Uniform3f // Light direction uniform
+	core.Node                 // Embedded node
+	color     math32.Color    // Light color
+	intensity float32         // Light intensity
+	uni       *gls.Uniform3fv // uniform with light color and direction
 }
 
+const (
+	dirColor    = 0 // index of color triplet in uniform
+	dirPosition = 1 // index of position vector in uniform
+	dirUniSize  = 2 // uniform count of 3 float32
+)
+
+// NewDirectional creates and returns a pointer of a new directional light
+// the specified color and intensity.
 func NewDirectional(color *math32.Color, intensity float32) *Directional {
 
 	ld := new(Directional)
@@ -25,8 +32,7 @@ func NewDirectional(color *math32.Color, intensity float32) *Directional {
 
 	ld.color = *color
 	ld.intensity = intensity
-	ld.uColor.Init("DirLightColor")
-	ld.uDirection.Init("DirLightPosition")
+	ld.uni = gls.NewUniform3fv("DirLight", dirUniSize)
 	ld.SetColor(color)
 	return ld
 }
@@ -37,7 +43,7 @@ func (ld *Directional) SetColor(color *math32.Color) {
 	ld.color = *color
 	tmpColor := ld.color
 	tmpColor.MultiplyScalar(ld.intensity)
-	ld.uColor.SetColor(&tmpColor)
+	ld.uni.SetColor(dirColor, &tmpColor)
 }
 
 // Color returns the current color of this light
@@ -52,7 +58,7 @@ func (ld *Directional) SetIntensity(intensity float32) {
 	ld.intensity = intensity
 	tmpColor := ld.color
 	tmpColor.MultiplyScalar(ld.intensity)
-	ld.uColor.SetColor(&tmpColor)
+	ld.uni.SetColor(dirColor, &tmpColor)
 }
 
 // Intensity returns the current intensity of this light
@@ -64,14 +70,13 @@ func (ld *Directional) Intensity() float32 {
 // RenderSetup is called by the engine before rendering the scene
 func (ld *Directional) RenderSetup(gs *gls.GLS, rinfo *core.RenderInfo, idx int) {
 
-	// Sets color
-	ld.uColor.TransferIdx(gs, idx)
-
 	// Calculates and updates light direction uniform in camera coordinates
 	var pos math32.Vector3
 	ld.WorldPosition(&pos)
 	pos4 := math32.Vector4{pos.X, pos.Y, pos.Z, 0.0}
 	pos4.ApplyMatrix4(&rinfo.ViewMatrix)
-	ld.uDirection.SetVector3(&math32.Vector3{pos4.X, pos4.Y, pos4.Z})
-	ld.uDirection.TransferIdx(gs, idx)
+	ld.uni.SetVector3(dirPosition, &math32.Vector3{pos4.X, pos4.Y, pos4.Z})
+
+	// Transfer color and position uniform
+	ld.uni.TransferIdx(gs, idx*dirUniSize)
 }

+ 28 - 30
light/point.go

@@ -11,15 +11,20 @@ import (
 )
 
 type Point struct {
-	core.Node                     // Embedded node
-	color           math32.Color  // Light color
-	intensity       float32       // Light intensity
-	uColor          gls.Uniform3f // PointLightColor uniform
-	uPosition       gls.Uniform3f // PointLightPosition uniform
-	uLinearDecay    gls.Uniform1f // PointLightLinearDecay uniform
-	uQuadraticDecay gls.Uniform1f // PointLightQuadraticDecay uniform
+	core.Node                 // Embedded node
+	color     math32.Color    // Light color
+	intensity float32         // Light intensity
+	uni       *gls.Uniform3fv // Uniform with light properties
 }
 
+const (
+	pColor          = 0                // index of color vector in uniform (0,1,2)
+	pPosition       = 1                // index of position vector in uniform (3,4,5)
+	pLinearDecay    = 6                // position of scalar linear decay in uniform array
+	pQuadraticDecay = pLinearDecay + 1 // position of scalar linear decay in uniform array
+	pointUniSize    = 3                // uniform count of 3 float32
+)
+
 // NewPoint creates and returns a point light with the specified color and intensity
 func NewPoint(color *math32.Color, intensity float32) *Point {
 
@@ -28,17 +33,13 @@ func NewPoint(color *math32.Color, intensity float32) *Point {
 	lp.color = *color
 	lp.intensity = intensity
 
-	// Creates uniforms
-	lp.uColor.Init("PointLightColor")
-	lp.uPosition.Init("PointLightPosition")
-	lp.uLinearDecay.Init("PointLightLinearDecay")
-	lp.uQuadraticDecay.Init("PointLightQuadraticDecay")
-
-	// Set initial values
+	// Creates uniform and sets initial values
+	lp.uni = gls.NewUniform3fv("PointLight", pointUniSize)
 	lp.SetColor(color)
-	lp.uPosition.Set(0, 0, 0)
-	lp.uLinearDecay.Set(1.0)
-	lp.uQuadraticDecay.Set(1.0)
+	lp.SetIntensity(intensity)
+	lp.SetLinearDecay(1.0)
+	lp.SetQuadraticDecay(1.0)
+
 	return lp
 }
 
@@ -48,7 +49,7 @@ func (lp *Point) SetColor(color *math32.Color) {
 	lp.color = *color
 	tmpColor := lp.color
 	tmpColor.MultiplyScalar(lp.intensity)
-	lp.uColor.SetColor(&tmpColor)
+	lp.uni.SetColor(pColor, &tmpColor)
 }
 
 // Color returns the current color of this light
@@ -63,7 +64,7 @@ func (lp *Point) SetIntensity(intensity float32) {
 	lp.intensity = intensity
 	tmpColor := lp.color
 	tmpColor.MultiplyScalar(lp.intensity)
-	lp.uColor.SetColor(&tmpColor)
+	lp.uni.SetColor(pColor, &tmpColor)
 }
 
 // Intensity returns the current intensity of this light
@@ -75,40 +76,37 @@ func (lp *Point) Intensity() float32 {
 // SetLinearDecay sets the linear decay factor as a function of the distance
 func (lp *Point) SetLinearDecay(decay float32) {
 
-	lp.uLinearDecay.Set(decay)
+	lp.uni.SetPos(pLinearDecay, decay)
 }
 
 // LinearDecay returns the current linear decay factor
 func (lp *Point) LinearDecay() float32 {
 
-	return lp.uLinearDecay.Get()
+	return lp.uni.GetPos(pLinearDecay)
 }
 
 // SetQuadraticDecay sets the quadratic decay factor as a function of the distance
 func (lp *Point) SetQuadraticDecay(decay float32) {
 
-	lp.uQuadraticDecay.Set(decay)
+	lp.uni.SetPos(pQuadraticDecay, decay)
 }
 
 // QuadraticDecay returns the current quadratic decay factor
 func (lp *Point) QuadraticDecay() float32 {
 
-	return lp.uQuadraticDecay.Get()
+	return lp.uni.GetPos(pQuadraticDecay)
 }
 
 // RenderSetup is called by the engine before rendering the scene
 func (lp *Point) RenderSetup(gs *gls.GLS, rinfo *core.RenderInfo, idx int) {
 
-	// Transfer uniforms
-	lp.uColor.TransferIdx(gs, idx)
-	lp.uLinearDecay.TransferIdx(gs, idx)
-	lp.uQuadraticDecay.TransferIdx(gs, idx)
-
 	// Calculates and updates light position uniform in camera coordinates
 	var pos math32.Vector3
 	lp.WorldPosition(&pos)
 	pos4 := math32.Vector4{pos.X, pos.Y, pos.Z, 1.0}
 	pos4.ApplyMatrix4(&rinfo.ViewMatrix)
-	lp.uPosition.SetVector3(&math32.Vector3{pos4.X, pos4.Y, pos4.Z})
-	lp.uPosition.TransferIdx(gs, idx)
+	lp.uni.SetVector3(pPosition, &math32.Vector3{pos4.X, pos4.Y, pos4.Z})
+
+	// Transfer uniform
+	lp.uni.TransferIdx(gs, idx*pointUniSize)
 }

+ 78 - 52
light/spot.go

@@ -11,45 +11,66 @@ import (
 )
 
 type Spot struct {
-	core.Node                      // Embedded node
-	color           math32.Color   // Light color
-	intensity       float32        // Light intensity
-	direction       math32.Vector3 // Direction in world coordinates
-	uColor          gls.Uniform3f  // Uniform for light color
-	uPosition       gls.Uniform3f  // Uniform for position in camera coordinates
-	uDirection      gls.Uniform3f  // Uniform for direction in camera coordinates
-	uAngularDecay   gls.Uniform1f  // Uniform for angular attenuation exponent
-	uCutoffAngle    gls.Uniform1f  // Uniform for cutoff angle from 0 to 90 degrees
-	uLinearDecay    gls.Uniform1f  // Uniform for linear distance decay
-	uQuadraticDecay gls.Uniform1f  // Uniform for quadratic distance decay
-}
+	core.Node                 // Embedded node
+	color     math32.Color    // Light color
+	intensity float32         // Light intensity
+	direction math32.Vector3  // Direction in world coordinates
+	uni       *gls.Uniform3fv // Uniform with spot light properties
+
+	//uColor          gls.Uniform3f // Uniform for light color
+	//uPosition       gls.Uniform3f // Uniform for position in camera coordinates
+	//uDirection      gls.Uniform3f // Uniform for direction in camera coordinates
+	//uAngularDecay   gls.Uniform1f // Uniform for angular attenuation exponent
+	//uCutoffAngle    gls.Uniform1f // Uniform for cutoff angle from 0 to 90 degrees
+	//uLinearDecay    gls.Uniform1f // Uniform for linear distance decay
+	//uQuadraticDecay gls.Uniform1f // Uniform for quadratic distance decay
+}
+
+const (
+	sColor          = 0  // index of color vector in uniform (0,1,2)
+	sPosition       = 1  // index of position vector in uniform (3,4,5)
+	sDirection      = 2  // index of position vector in uniform (6,7,8)
+	sAngularDecay   = 9  // position of scalar angular decay in uniform array
+	sCutoffAngle    = 10 // position of cutoff angle in uniform array
+	sLinearDecay    = 11 // position of scalar linear decay in uniform array
+	sQuadraticDecay = 12 // position of scalar quadratic decay in uniform array
+	spotUniSize     = 5  // uniform count of 5 float32
+)
 
 // NewSpot creates and returns a spot light with the specified color and intensity
 func NewSpot(color *math32.Color, intensity float32) *Spot {
 
-	sp := new(Spot)
-	sp.Node.Init()
-
-	sp.color = *color
-	sp.intensity = intensity
+	sl := new(Spot)
+	sl.Node.Init()
 
-	// Creates uniforms
-	sp.uColor.Init("SpotLightColor")
-	sp.uPosition.Init("SpotLightPosition")
-	sp.uDirection.Init("SpotLightDirection")
-	sp.uAngularDecay.Init("SpotLightAngularDecay")
-	sp.uCutoffAngle.Init("SpotLightCutoffAngle")
-	sp.uLinearDecay.Init("SpotLightLinearDecay")
-	sp.uQuadraticDecay.Init("SpotQuadraticDecay")
+	sl.color = *color
+	sl.intensity = intensity
 
-	// Set initial values
-	sp.intensity = intensity
-	sp.SetColor(color)
-	sp.uAngularDecay.Set(15.0)
-	sp.uCutoffAngle.Set(45.0)
-	sp.uLinearDecay.Set(1.0)
-	sp.uQuadraticDecay.Set(1.0)
-	return sp
+	// Creates uniforms and set initial values
+	sl.uni = gls.NewUniform3fv("SpotLight", spotUniSize)
+	sl.SetColor(color)
+	sl.SetAngularDecay(15.0)
+	sl.SetCutoffAngle(45.0)
+	sl.SetLinearDecay(1.0)
+	sl.SetQuadraticDecay(1.0)
+
+	//	// Creates uniforms
+	//	sp.uColor.Init("SpotLightColor")
+	//	sp.uPosition.Init("SpotLightPosition")
+	//	sp.uDirection.Init("SpotLightDirection")
+	//	sp.uAngularDecay.Init("SpotLightAngularDecay")
+	//	sp.uCutoffAngle.Init("SpotLightCutoffAngle")
+	//	sp.uLinearDecay.Init("SpotLightLinearDecay")
+	//	sp.uQuadraticDecay.Init("SpotQuadraticDecay")
+	//
+	//	// Set initial values
+	//	sp.intensity = intensity
+	//	sp.SetColor(color)
+	//	sp.uAngularDecay.Set(15.0)
+	//	sp.uCutoffAngle.Set(45.0)
+	//	sp.uLinearDecay.Set(1.0)
+	//	sp.uQuadraticDecay.Set(1.0)
+	return sl
 }
 
 // SetColor sets the color of this light
@@ -58,7 +79,7 @@ func (sl *Spot) SetColor(color *math32.Color) {
 	sl.color = *color
 	tmpColor := sl.color
 	tmpColor.MultiplyScalar(sl.intensity)
-	sl.uColor.SetColor(&tmpColor)
+	sl.uni.SetColor(sColor, &tmpColor)
 }
 
 // Color returns the current color of this light
@@ -73,7 +94,7 @@ func (sl *Spot) SetIntensity(intensity float32) {
 	sl.intensity = intensity
 	tmpColor := sl.color
 	tmpColor.MultiplyScalar(sl.intensity)
-	sl.uColor.SetColor(&tmpColor)
+	sl.uni.SetColor(sColor, &tmpColor)
 }
 
 // Intensity returns the current intensity of this light
@@ -97,59 +118,59 @@ func (sp *Spot) Direction(direction *math32.Vector3) math32.Vector3 {
 // SetCutoffAngle sets the cutoff angle in degrees from 0 to 90
 func (sl *Spot) SetCutoffAngle(angle float32) {
 
-	sl.uCutoffAngle.Set(angle)
+	sl.uni.SetPos(sCutoffAngle, angle)
 }
 
 // CutoffAngle returns the current cutoff angle in degrees from 0 to 90
 func (sl *Spot) CutoffAngle() float32 {
 
-	return sl.uCutoffAngle.Get()
+	return sl.uni.GetPos(sCutoffAngle)
 }
 
 // SetAngularDecay sets the angular decay exponent
 func (sl *Spot) SetAngularDecay(decay float32) {
 
-	sl.uAngularDecay.Set(decay)
+	sl.uni.SetPos(sAngularDecay, decay)
 }
 
 // AngularDecay returns the current angular decay exponent
 func (sl *Spot) AngularDecay() float32 {
 
-	return sl.uAngularDecay.Get()
+	return sl.uni.GetPos(sAngularDecay)
 }
 
 // SetLinearDecay sets the linear decay factor as a function of the distance
 func (sl *Spot) SetLinearDecay(decay float32) {
 
-	sl.uLinearDecay.Set(decay)
+	sl.uni.SetPos(sLinearDecay, decay)
 }
 
 // LinearDecay returns the current linear decay factor
 func (sl *Spot) LinearDecay() float32 {
 
-	return sl.uLinearDecay.Get()
+	return sl.uni.GetPos(sLinearDecay)
 }
 
 // SetQuadraticDecay sets the quadratic decay factor as a function of the distance
 func (sl *Spot) SetQuadraticDecay(decay float32) {
 
-	sl.uQuadraticDecay.Set(decay)
+	sl.uni.SetPos(sQuadraticDecay, decay)
 }
 
 // QuadraticDecay returns the current quadratic decay factor
 func (sl *Spot) QuadraticDecay() float32 {
 
-	return sl.uQuadraticDecay.Get()
+	return sl.uni.GetPos(sQuadraticDecay)
 }
 
 // RenderSetup is called by the engine before rendering the scene
 func (sl *Spot) RenderSetup(gs *gls.GLS, rinfo *core.RenderInfo, idx int) {
 
-	sl.uColor.TransferIdx(gs, idx)
-	sl.uAngularDecay.TransferIdx(gs, idx)
-	sl.uCutoffAngle.TransferIdx(gs, idx)
-	sl.uLinearDecay.TransferIdx(gs, idx)
-	sl.uQuadraticDecay.TransferIdx(gs, idx)
+	//sl.uColor.TransferIdx(gs, idx)
+	//sl.uAngularDecay.TransferIdx(gs, idx)
+	//sl.uCutoffAngle.TransferIdx(gs, idx)
+	//sl.uLinearDecay.TransferIdx(gs, idx)
+	//sl.uQuadraticDecay.TransferIdx(gs, idx)
 
 	// Calculates and updates light position uniform in camera coordinates
 	var pos math32.Vector3
@@ -157,13 +178,18 @@ func (sl *Spot) RenderSetup(gs *gls.GLS, rinfo *core.RenderInfo, idx int) {
 	var pos4 math32.Vector4
 	pos4.SetVector3(&pos, 1.0)
 	pos4.ApplyMatrix4(&rinfo.ViewMatrix)
-	sl.uPosition.SetVector3(&math32.Vector3{pos4.X, pos4.Y, pos4.Z})
-	sl.uPosition.TransferIdx(gs, idx)
+	//sl.uPosition.SetVector3(&math32.Vector3{pos4.X, pos4.Y, pos4.Z})
+	//sl.uPosition.TransferIdx(gs, idx)
+	sl.uni.SetVector3(sPosition, &math32.Vector3{pos4.X, pos4.Y, pos4.Z})
 
 	// Calculates and updates light direction uniform in camera coordinates
 	pos4.SetVector3(&sl.direction, 0.0)
 	pos4.ApplyMatrix4(&rinfo.ViewMatrix)
 	// Normalize here ??
-	sl.uDirection.SetVector3(&math32.Vector3{pos4.X, pos4.Y, pos4.Z})
-	sl.uDirection.TransferIdx(gs, idx)
+	//sl.uDirection.SetVector3(&math32.Vector3{pos4.X, pos4.Y, pos4.Z})
+	//sl.uDirection.TransferIdx(gs, idx)
+	sl.uni.SetVector3(sDirection, &math32.Vector3{pos4.X, pos4.Y, pos4.Z})
+
+	// Transfer uniform
+	sl.uni.TransferIdx(gs, idx*spotUniSize)
 }

+ 25 - 16
renderer/shader/chunkLights.go

@@ -15,27 +15,36 @@ uniform vec3 AmbientLightColor[{{.AmbientLightsMax}}];
 {{end}}
 
 {{if .DirLightsMax}}
-// Directional lights uniforms
-uniform vec3  DirLightColor[{{.DirLightsMax}}];
-uniform vec3  DirLightPosition[{{.DirLightsMax}}];
+// Directional lights uniform array. Each directional light uses 2 elements
+uniform vec3  DirLight[2*{{.DirLightsMax}}];
+
+// Macros to access elements inside the DirectionalLight uniform array
+#define DirLightColor(a)		DirLight[2*a]
+#define DirLightPosition(a)		DirLight[2*a+1]
 {{end}}
 
 {{if .PointLightsMax}}
-// Point lights uniforms
-uniform vec3  PointLightColor[{{.PointLightsMax}}];
-uniform vec3  PointLightPosition[{{.PointLightsMax}}];
-uniform float PointLightLinearDecay[{{.PointLightsMax}}];
-uniform float PointLightQuadraticDecay[{{.PointLightsMax}}];
+// Point lights uniform array. Each point light uses 3 elements
+uniform vec3  PointLight[3*{{.PointLightsMax}}];
+
+// Macros to access elements inside the PointLight uniform array
+#define PointLightColor(a)			PointLight[3*a]
+#define PointLightPosition(a)		PointLight[3*a+1]
+#define PointLightLinearDecay(a)	PointLight[3*a+2].x
+#define PointLightQuadraticDecay(a)	PointLight[3*a+2].y
 {{end}}
 
 {{if .SpotLightsMax}}
-// Spot lights uniforms
-uniform vec3  SpotLightColor[{{.SpotLightsMax}}];
-uniform vec3  SpotLightPosition[{{.SpotLightsMax}}];
-uniform vec3  SpotLightDirection[{{.SpotLightsMax}}];
-uniform float SpotLightAngularDecay[{{.SpotLightsMax}}];
-uniform float SpotLightCutoffAngle[{{.SpotLightsMax}}];
-uniform float SpotLightLinearDecay[{{.SpotLightsMax}}];
-uniform float SpotLightQuadraticDecay[{{.SpotLightsMax}}];
+// Spot lights uniforms. Each spot light uses 5 elements
+uniform vec3  SpotLight[5*{{.SpotLightsMax}}];
+
+// Macros to access elements inside the PointLight uniform array
+#define SpotLightColor(a)			SpotLight[5*a]
+#define SpotLightPosition(a)		SpotLight[5*a+1]
+#define SpotLightDirection(a)		SpotLight[5*a+2]
+#define SpotLightAngularDecay(a)	SpotLight[5*a+3].x
+#define SpotLightCutoffAngle(a)		SpotLight[5*a+3].y
+#define SpotLightLinearDecay(a)		SpotLight[5*a+3].z
+#define SpotLightQuadraticDecay(a)	SpotLight[5*a+4].x
 {{end}}
 `

+ 16 - 16
renderer/shader/chunkPhongModel.go

@@ -44,16 +44,16 @@ void phongModel(vec4 position, vec3 normal, vec3 camDir, vec3 matAmbient, vec3 m
     {
         // Diffuse reflection
         // DirLightPosition is the direction of the current light
-        vec3 lightDirection = normalize(DirLightPosition[{{.}}]);
+        vec3 lightDirection = normalize(DirLightPosition({{.}}));
         // Calculates the dot product between the light direction and this vertex normal.
         float dotNormal = max(dot(lightDirection, normal), 0.0);
-        diffuseTotal += DirLightColor[{{.}}] * matDiffuse * dotNormal;
+        diffuseTotal += DirLightColor({{.}}) * matDiffuse * dotNormal;
 
         // Specular reflection
         // Calculates the light reflection vector 
         vec3 ref = reflect(-lightDirection, normal);
         if (dotNormal > 0.0) {
-            specularTotal += DirLightColor[{{.}}] * MatSpecularColor * pow(max(dot(ref, camDir), 0.0), MatShininess);
+            specularTotal += DirLightColor({{.}}) * MatSpecularColor * pow(max(dot(ref, camDir), 0.0), MatShininess);
         }
     }
     {{ end }}
@@ -61,23 +61,23 @@ void phongModel(vec4 position, vec3 normal, vec3 camDir, vec3 matAmbient, vec3 m
     {{ range loop .PointLightsMax }}
     {
         // Calculates the direction and distance from the current vertex to this point light.
-        vec3 lightDirection = PointLightPosition[{{.}}] - vec3(position);
+        vec3 lightDirection = PointLightPosition({{.}}) - vec3(position);
         float lightDistance = length(lightDirection);
         // Normalizes the lightDirection
         lightDirection = lightDirection / lightDistance;
         // Calculates the attenuation due to the distance of the light
-        float attenuation = 1.0 / (1.0 + PointLightLinearDecay[{{.}}] * lightDistance +
-            PointLightQuadraticDecay[{{.}}] * lightDistance * lightDistance);
+        float attenuation = 1.0 / (1.0 + PointLightLinearDecay({{.}}) * lightDistance +
+            PointLightQuadraticDecay({{.}}) * lightDistance * lightDistance);
 
         // Diffuse reflection
         float dotNormal = max(dot(lightDirection, normal), 0.0);
-        diffuseTotal += PointLightColor[{{.}}] * matDiffuse * dotNormal * attenuation;
+        diffuseTotal += PointLightColor({{.}}) * matDiffuse * dotNormal * attenuation;
         
         // Specular reflection
         // Calculates the light reflection vector 
         vec3 ref = reflect(-lightDirection, normal);
         if (dotNormal > 0.0) {
-            specularTotal += PointLightColor[{{.}}] * MatSpecularColor *
+            specularTotal += PointLightColor({{.}}) * MatSpecularColor *
                 pow(max(dot(ref, camDir), 0.0), MatShininess) * attenuation;
         }
     }
@@ -86,31 +86,31 @@ void phongModel(vec4 position, vec3 normal, vec3 camDir, vec3 matAmbient, vec3 m
     {{ range loop .SpotLightsMax }}
     {
         // Calculates the direction and distance from the current vertex to this spot light.
-        vec3 lightDirection = SpotLightPosition[{{.}}] - vec3(position);
+        vec3 lightDirection = SpotLightPosition({{.}}) - vec3(position);
         float lightDistance = length(lightDirection);
         lightDirection = lightDirection / lightDistance;
 
         // Calculates the attenuation due to the distance of the light
-        float attenuation = 1.0 / (1.0 + SpotLightLinearDecay[{{.}}] * lightDistance +
-            SpotLightQuadraticDecay[{{.}}] * lightDistance * lightDistance);
+        float attenuation = 1.0 / (1.0 + SpotLightLinearDecay({{.}}) * lightDistance +
+            SpotLightQuadraticDecay({{.}}) * lightDistance * lightDistance);
 
         // Calculates the angle between the vertex direction and spot direction
         // If this angle is greater than the cutoff the spotlight will not contribute
         // to the final color.
-        float angle = acos(dot(-lightDirection, SpotLightDirection[{{.}}]));
-        float cutoff = radians(clamp(SpotLightCutoffAngle[{{.}}], 0.0, 90.0));
+        float angle = acos(dot(-lightDirection, SpotLightDirection({{.}})));
+        float cutoff = radians(clamp(SpotLightCutoffAngle({{.}}), 0.0, 90.0));
 
         if (angle < cutoff) {
-            float spotFactor = pow(dot(-lightDirection, SpotLightDirection[{{.}}]), SpotLightAngularDecay[{{.}}]);
+            float spotFactor = pow(dot(-lightDirection, SpotLightDirection({{.}})), SpotLightAngularDecay({{.}}));
 
             // Diffuse reflection
             float dotNormal = max(dot(lightDirection, normal), 0.0);
-            diffuseTotal += SpotLightColor[{{.}}] * matDiffuse * dotNormal * attenuation * spotFactor;
+            diffuseTotal += SpotLightColor({{.}}) * matDiffuse * dotNormal * attenuation * spotFactor;
 
             // Specular reflection
             vec3 ref = reflect(-lightDirection, normal);
             if (dotNormal > 0.0) {
-                specularTotal += SpotLightColor[{{.}}] * MatSpecularColor * pow(max(dot(ref, camDir), 0.0), MatShininess) * attenuation * spotFactor;
+                specularTotal += SpotLightColor({{.}}) * MatSpecularColor * pow(max(dot(ref, camDir), 0.0), MatShininess) * attenuation * spotFactor;
             }
         }
     }