Przeglądaj źródła

changing shaders preprocessing...

leonsal 8 lat temu
rodzic
commit
f2e8d9152f

+ 16 - 0
renderer/shaders/README.md

@@ -0,0 +1,16 @@
+This directory contains GLSL shaders used by the engine
+-------------------------------------------------------
+
+If any shader in this directory or include 'chunk' in the
+"include" subdirectory is modified or a new shader or chunk
+is added or removed it is necessary to execute:
+
+>go generate
+
+in this directory to update the "sources.go" file.
+It will invoke the "g3nshaders" command which will read
+the shaders and include files and generate the "sources.go" file.
+
+To install "g3nshaders" change to the "tools/g3nshaders" directory
+from the engine "root" and execute: "go install".
+

+ 2 - 2
renderer/shaders/include/material.glsl

@@ -6,8 +6,8 @@ uniform vec3 Material[6];
 // Each texture uses 3 vec2 elements.
 #define MatAmbientColor		Material[0]
 #define MatDiffuseColor     Material[1]
-#define MatEmissiveColor    Material[2]
-#define MatSpecularColor    Material[3]
+#define MatSpecularColor    Material[2]
+#define MatEmissiveColor    Material[3]
 #define MatShininess        Material[4].x
 #define MatOpacity          Material[4].y
 #define MatPointSize		Material[4].z

+ 33 - 0
renderer/shaders/include/phong_model.glsl

@@ -75,6 +75,39 @@ void phongModel(vec4 position, vec3 normal, vec3 camDir, vec3 matAmbient, vec3 m
     }
 #endif
 
+#if SPOT_LIGHTS>0
+    for (int i = 0; i < SPOT_LIGHTS; i++) {
+        // Calculates the direction and distance from the current vertex to this spot light.
+        vec3 lightDirection = SpotLightPosition(i) - 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(i) * lightDistance +
+            SpotLightQuadraticDecay(i) * 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(i)));
+        float cutoff = radians(clamp(SpotLightCutoffAngle(i), 0.0, 90.0));
+
+        if (angle < cutoff) {
+            float spotFactor = pow(dot(-lightDirection, SpotLightDirection(i)), SpotLightAngularDecay(i));
+
+            // Diffuse reflection
+            float dotNormal = max(dot(lightDirection, normal), 0.0);
+            diffuseTotal += SpotLightColor(i) * matDiffuse * dotNormal * attenuation * spotFactor;
+
+            // Specular reflection
+            vec3 ref = reflect(-lightDirection, normal);
+            if (dotNormal > 0.0) {
+                specularTotal += SpotLightColor(i) * MatSpecularColor * pow(max(dot(ref, camDir), 0.0), MatShininess) * attenuation * spotFactor;
+            }
+        }
+    }
+#endif
+
     // Sets output colors
     ambdiff = ambientTotal + MatEmissiveColor + diffuseTotal;
     spec = specularTotal;

+ 1 - 1
renderer/shaders/shaders.go

@@ -6,7 +6,7 @@
 package shaders
 
 // Generates shaders sources from this directory and include directory *.glsl files
-//go:generate g3nshaders -in=. -out=sources.go -pkg=shaders
+//go:generate g3nshaders -in=. -out=sources.go -pkg=shaders -v
 
 // ProgramInfo contains information for a registered shader program
 type ProgramInfo struct {

+ 35 - 2
renderer/shaders/sources.go

@@ -80,6 +80,39 @@ void phongModel(vec4 position, vec3 normal, vec3 camDir, vec3 matAmbient, vec3 m
     }
 #endif
 
+#if SPOT_LIGHTS>0
+    for (int i = 0; i < SPOT_LIGHTS; i++) {
+        // Calculates the direction and distance from the current vertex to this spot light.
+        vec3 lightDirection = SpotLightPosition(i) - 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(i) * lightDistance +
+            SpotLightQuadraticDecay(i) * 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(i)));
+        float cutoff = radians(clamp(SpotLightCutoffAngle(i), 0.0, 90.0));
+
+        if (angle < cutoff) {
+            float spotFactor = pow(dot(-lightDirection, SpotLightDirection(i)), SpotLightAngularDecay(i));
+
+            // Diffuse reflection
+            float dotNormal = max(dot(lightDirection, normal), 0.0);
+            diffuseTotal += SpotLightColor(i) * matDiffuse * dotNormal * attenuation * spotFactor;
+
+            // Specular reflection
+            vec3 ref = reflect(-lightDirection, normal);
+            if (dotNormal > 0.0) {
+                specularTotal += SpotLightColor(i) * MatSpecularColor * pow(max(dot(ref, camDir), 0.0), MatShininess) * attenuation * spotFactor;
+            }
+        }
+    }
+#endif
+
     // Sets output colors
     ambdiff = ambientTotal + MatEmissiveColor + diffuseTotal;
     spec = specularTotal;
@@ -96,8 +129,8 @@ uniform vec3 Material[6];
 // Each texture uses 3 vec2 elements.
 #define MatAmbientColor		Material[0]
 #define MatDiffuseColor     Material[1]
-#define MatEmissiveColor    Material[2]
-#define MatSpecularColor    Material[3]
+#define MatSpecularColor    Material[2]
+#define MatEmissiveColor    Material[3]
 #define MatShininess        Material[4].x
 #define MatOpacity          Material[4].y
 #define MatPointSize		Material[4].z

+ 36 - 16
tools/g3nshaders/main.go

@@ -2,6 +2,13 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// g3nshaders reads shaders files with ".glsl" extensions and generates
+// a Go file containing strings with the content of these files.
+// Also it builds maps associating include and shader names to its respective
+// source strings.
+// Usage:
+// 		g3nshaders -in=<input_dir> -out<output_gofile> -v
+// It is normally invoked by "go generate" inside the "shaders" directory
 package main
 
 import (
@@ -10,6 +17,7 @@ import (
 	"fmt"
 	"go/format"
 	"io/ioutil"
+	"log"
 	"os"
 	"path/filepath"
 	"strings"
@@ -96,13 +104,15 @@ type progInfo struct {
 
 // templInfo contains all information needed for the template expansion
 type templInfo struct {
-	Pkg      string
-	Includes []fileInfo
-	Shaders  []fileInfo
-	Programs map[string]progInfo
+	Count    int                 // number of shader files processed
+	Pkg      string              // name of the package for the generated output file
+	Includes []fileInfo          // list of include files found
+	Shaders  []fileInfo          // list of shader files found
+	Programs map[string]progInfo // map of shader programs found
 }
 
-var templData templInfo
+var templData templInfo // global template data
+var logger *log.Logger  // global logger
 
 func main() {
 
@@ -116,6 +126,9 @@ func main() {
 		return
 	}
 
+	// Creates logger
+	logger = log.New(os.Stdout, "G3NSHADERS ", log.Ldate|log.Ltime)
+
 	// Initialize template data
 	templData.Pkg = *oPackage
 	templData.Programs = make(map[string]progInfo)
@@ -123,6 +136,10 @@ func main() {
 	// Process the current directory and its subdirectories recursively
 	// appending information into templData
 	processDir(*oInp, false)
+	if templData.Count == 0 {
+		log.Print("No shader files found")
+		return
+	}
 
 	// Generates output file from TEMPLATE
 	generate(*oOut)
@@ -131,20 +148,20 @@ func main() {
 // processDir processes recursively all shaders files in the specified directory
 func processDir(dir string, include bool) {
 
-	// Open directory
+	// Open directory to process
 	f, err := os.Open(dir)
 	if err != nil {
 		panic(err)
 	}
 	defer f.Close()
 
-	// Read all fileinfos
+	// Read all file entries from the directory
 	finfos, err := f.Readdir(0)
 	if err != nil {
 		panic(err)
 	}
 
-	// Process subdirectory recursively or process file
+	// Process all directory entries.
 	for _, fi := range finfos {
 		if fi.IsDir() {
 			dirInclude := include
@@ -167,12 +184,13 @@ func processFile(file string, include bool) {
 	// Ignore file if it has not the shader extension
 	fext := filepath.Ext(file)
 	if fext != SHADEREXT {
-		if *oVerbose {
-			fmt.Printf("Ignored file (not shader): %s\n", file)
-		}
 		return
 	}
 
+	if *oVerbose {
+		logger.Printf("Processing: %s", file)
+	}
+
 	// Get the file base name and its name with the extension
 	fbase := filepath.Base(file)
 	fname := fbase[:len(fbase)-len(fext)]
@@ -182,12 +200,12 @@ func processFile(file string, include bool) {
 	if !include {
 		parts := strings.Split(string(fname), "_")
 		if len(parts) < 2 {
-			fmt.Printf("Ignored file (INVALID NAME): %s\n", file)
+			logger.Print("   IGNORED: file does not have a valid shader name")
 			return
 		}
 		stype := parts[len(parts)-1]
 		if !shaderTypes[stype] {
-			fmt.Printf("Ignored file (INVALID SHADER TYPE): %s\n", file)
+			logger.Print("   IGNORED: invalid shader type")
 			return
 		}
 		sname := strings.Join(parts[:len(parts)-1], "_")
@@ -229,14 +247,16 @@ func processFile(file string, include bool) {
 			Source: string(data),
 		})
 	}
-	if *oVerbose {
-		fmt.Printf("%s (%v bytes)\n", file, len(data))
-	}
+	templData.Count++
 }
 
 // generate generates output go file with shaders sources from TEMPLATE
 func generate(file string) {
 
+	if *oVerbose {
+		logger.Printf("Generating: %s", file)
+	}
+
 	// Parses the template
 	tmpl := template.New("tmpl")
 	tmpl, err := tmpl.Parse(TEMPLATE)