Sébastien Vandenberghe преди 9 години
родител
ревизия
7173e8c34a

+ 11 - 0
materialsLibrary/config.json

@@ -91,6 +91,17 @@
         "materials/sky/sky.fragment.fx"
         "materials/sky/sky.fragment.fx"
       ],
       ],
       "output": "babylon.skyMaterial.js"
       "output": "babylon.skyMaterial.js"
+    },
+    {
+      "file": "materials/grid/babylon.gridMaterial.ts",
+      "shaderFiles": [
+        "materials/grid/grid.vertex.fx",
+        "materials/grid/grid.fragment.fx",
+        "materials/grid/legacygrid.vertex.fx",
+        "materials/grid/legacygrid.fragment.fx"
+      ],
+      "output": "babylon.gridMaterial.js",
+      "declarationFilename": "babylon.gridMaterial.d.ts"
     }
     }
   ],
   ],
   "build": {
   "build": {

Файловите разлики са ограничени, защото са твърде много
+ 178 - 0
materialsLibrary/dist/babylon.gridMaterial.js


Файловите разлики са ограничени, защото са твърде много
+ 1 - 0
materialsLibrary/dist/babylon.gridMaterial.min.js


Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
materialsLibrary/dist/babylon.pbrMaterial.js


Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
materialsLibrary/dist/babylon.pbrMaterial.min.js


+ 55 - 0
materialsLibrary/dist/dts/babylon.gridMaterial.d.ts

@@ -0,0 +1,55 @@
+/// <reference path="../../../dist/preview release/babylon.d.ts" />
+declare module BABYLON {
+    /**
+     * The grid materials allows you to wrap any shape with a grid.
+     * Colors are customizable.
+     */
+    class GridMaterial extends BABYLON.Material {
+        /**
+         * Main color of the grid (e.g. between lines)
+         */
+        mainColor: Color3;
+        /**
+         * Color of the grid lines.
+         */
+        lineColor: Color3;
+        /**
+         * The scale of the grid compared to unit.
+         */
+        gridRatio: number;
+        /**
+         * The frequency of thicker lines.
+         */
+        majorUnitFrequency: number;
+        /**
+         * The visibility of minor units in the grid.
+         */
+        minorUnitVisibility: number;
+        /**
+         * The grid opacity outside of the lines.
+         */
+        opacity: number;
+        private _gridControl;
+        private _renderId;
+        private _defines;
+        private _cachedDefines;
+        /**
+         * constructor
+         * @param name The name given to the material in order to identify it afterwards.
+         * @param scene The scene the material is used in.
+         */
+        constructor(name: string, scene: Scene);
+        /**
+         * Returns wehter or not the grid requires alpha blending.
+         */
+        needAlphaBlending(): boolean;
+        private _checkCache(scene, mesh?, useInstances?);
+        isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean;
+        bindOnlyWorldMatrix(world: Matrix): void;
+        bind(world: Matrix, mesh?: Mesh): void;
+        dispose(forceDisposeEffect?: boolean): void;
+        clone(name: string): GridMaterial;
+        serialize(): any;
+        static Parse(source: any, scene: Scene, rootUrl: string): GridMaterial;
+    }
+}

+ 194 - 0
materialsLibrary/materials/grid/babylon.gridmaterial.ts

@@ -0,0 +1,194 @@
+/// <reference path="../../../dist/preview release/babylon.d.ts"/>
+
+module BABYLON {
+    class GRIDMaterialDefines extends MaterialDefines {
+        public TRANSPARENT = false;
+
+        constructor() {
+            super();
+            this._keys = Object.keys(this);
+        }
+    }
+    
+    /**
+     * The grid materials allows you to wrap any shape with a grid.
+     * Colors are customizable.
+     */
+    export class GridMaterial extends BABYLON.Material {
+        
+        /**
+         * Main color of the grid (e.g. between lines)
+         */
+        @serializeAsColor3()
+        public mainColor = Color3.White();
+        
+        /**
+         * Color of the grid lines.
+         */
+        @serializeAsColor3()
+        public lineColor = Color3.Black();
+        
+        /**
+         * The scale of the grid compared to unit.
+         */
+        @serialize()
+        public gridRatio = 1.0;
+        
+        /**
+         * The frequency of thicker lines.
+         */
+        @serialize()
+        public majorUnitFrequency = 10;
+        
+        /**
+         * The visibility of minor units in the grid.
+         */
+        @serialize()
+        public minorUnitVisibility = 0.33;
+        
+        /**
+         * The grid opacity outside of the lines.
+         */
+        @serialize()
+        public opacity = 1.0;
+        
+        private _gridControl: Vector4 = new Vector4(this.gridRatio, this.majorUnitFrequency, this.minorUnitVisibility, this.opacity);
+        
+        private _renderId: number;
+        private _defines = new GRIDMaterialDefines();
+        private _cachedDefines: GRIDMaterialDefines = new GRIDMaterialDefines();
+        
+        /**
+         * constructor
+         * @param name The name given to the material in order to identify it afterwards.
+         * @param scene The scene the material is used in.
+         */
+        constructor(name: string, scene: Scene) {
+            super(name, scene);
+            
+            // Forces cache to be different on first creation.
+            this._cachedDefines.TRANSPARENT = true;
+        }
+        
+        /**
+         * Returns wehter or not the grid requires alpha blending.
+         */
+        public needAlphaBlending(): boolean {
+            return this.opacity < 1.0;
+        }
+          
+        private _checkCache(scene: Scene, mesh?: AbstractMesh, useInstances?: boolean): boolean {
+            if (!mesh) {
+                return true;
+            }
+
+            if (mesh._materialDefines && mesh._materialDefines.isEqual(this._defines)) {
+                return true;
+            }
+
+            return false;
+        }
+
+        public isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean {
+            if (this.checkReadyOnlyOnce) {
+                if (this._wasPreviouslyReady) {
+                    return true;
+                }
+            }
+
+            var scene = this.getScene();
+
+            if (!this.checkReadyOnEveryCall) {
+                if (this._renderId === scene.getRenderId()) {
+                    if (this._checkCache(scene, mesh, useInstances)) {
+                        return true;
+                    }
+                }
+            }
+
+            var engine = scene.getEngine();
+            var needNormals = true;
+
+            this._defines.reset();
+
+            if (this.opacity < 1.0) {
+                this._defines.TRANSPARENT = true;
+            }
+
+            // Get correct effect      
+            if (!this._defines.isEqual(this._cachedDefines)) {
+                this._defines.cloneTo(this._cachedDefines);
+
+                scene.resetCachedMaterial();
+
+                // Attributes
+                var attribs = [VertexBuffer.PositionKind, VertexBuffer.NormalKind];
+
+                // Effect
+                var shaderName = scene.getEngine().getCaps().standardDerivatives ? "grid" : "legacygrid";
+                
+                // Defines
+                var join = this._defines.toString();
+                this._effect = scene.getEngine().createEffect(shaderName,
+                    attribs,
+                    ["worldViewProjection", "mainColor", "lineColor", "gridControl"],
+                    [],
+                    join, 
+                    null, 
+                    this.onCompiled, 
+                    this.onError);
+            }
+            
+            if (!this._effect.isReady()) {
+                return false;
+            }
+
+            this._renderId = scene.getRenderId();
+            this._wasPreviouslyReady = true;
+
+            return true;
+        }
+        
+        public bindOnlyWorldMatrix(world: Matrix): void {
+            var scene = this.getScene();
+
+            this._effect.setMatrix("worldViewProjection", world.multiply(scene.getTransformMatrix()));
+        }
+
+        public bind(world: Matrix, mesh?: Mesh): void {
+            var scene = this.getScene();
+
+            // Matrices        
+            this.bindOnlyWorldMatrix(world);
+            
+            // Uniforms
+            if (scene.getCachedMaterial() !== (<BABYLON.Material>this)) {
+                this._effect.setColor3("mainColor", this.mainColor);
+                this._effect.setColor3("lineColor", this.lineColor);
+                
+                this._gridControl.x = this.gridRatio;
+                this._gridControl.y = Math.round(this.majorUnitFrequency);
+                this._gridControl.z = this.minorUnitVisibility;
+                this._gridControl.w = this.opacity;
+                this._effect.setVector4("gridControl", this._gridControl);
+            }
+            super.bind(world, mesh);
+        }
+        
+        public dispose(forceDisposeEffect?: boolean): void {
+            super.dispose(forceDisposeEffect);
+        }
+        
+        public clone(name: string): GridMaterial {
+            return SerializationHelper.Clone(() => new GridMaterial(name, this.getScene()), this);
+        }
+
+        public serialize(): any {
+            return SerializationHelper.Serialize(this);
+        }
+
+        public static Parse(source: any, scene: Scene, rootUrl: string): GridMaterial {
+            return SerializationHelper.Parse(() => new GridMaterial(source.name, scene), source, scene, rootUrl);
+        }
+    }
+}

+ 94 - 0
materialsLibrary/materials/grid/grid.fragment.fx

@@ -0,0 +1,94 @@
+#extension GL_OES_standard_derivatives : enable
+
+#define SQRT2 1.41421356
+#define PI 3.14159
+
+precision highp float;
+
+uniform vec3 mainColor;
+uniform vec3 lineColor;
+uniform vec4 gridControl;
+
+// Varying
+varying vec3 vPosition;
+varying vec3 vNormal;
+
+float getVisibility(float position) {
+    // Major grid line every Frequency defined in material.
+    float majorGridFrequency = gridControl.y;
+    if (floor(position + 0.5) == floor(position / majorGridFrequency + 0.5) * majorGridFrequency)
+    {
+        return 1.0;
+    }  
+    
+    return gridControl.z;
+}
+
+float getAnisotropicAttenuation(float differentialLength) {
+    const float maxNumberOfLines = 10.0;
+    return clamp(1.0 / (differentialLength + 1.0) - 1.0 / maxNumberOfLines, 0.0, 1.0);
+}
+
+float isPointOnLine(float position, float differentialLength) {
+    float fractionPartOfPosition = position - floor(position + 0.5); // fract part around unit [-0.5; 0.5]
+    fractionPartOfPosition /= differentialLength; // adapt to the screen space size it takes
+    fractionPartOfPosition = clamp(fractionPartOfPosition, -1., 1.);
+    
+    float result = 0.5 + 0.5 * cos(fractionPartOfPosition * PI); // Convert to 0-1 for antialiasing.
+    return result;    
+}
+
+float contributionOnAxis(float position) {
+    float differentialLength = length(vec2(dFdx(position), dFdy(position)));
+    differentialLength *= SQRT2;  // Multiply by SQRT2 for diagonal length
+    
+    // Is the point on the line.
+    float result = isPointOnLine(position, differentialLength);
+    
+    // Add dynamic visibility.
+    float visibility = getVisibility(position);
+    result *= visibility;
+    
+    // Anisotropic filtering.
+    float anisotropicAttenuation = getAnisotropicAttenuation(differentialLength);
+    result *= anisotropicAttenuation;
+    
+    return result;
+}
+
+float normalImpactOnAxis(float x) {
+    float normalImpact = clamp(1.0 - 2.8 * abs(x * x * x), 0.0, 1.0);
+    return normalImpact;
+}
+
+void main(void) {
+    
+    // Scale position to the requested ratio.
+    float gridRatio = gridControl.x;
+    vec3 gridPos = vPosition / gridRatio;
+    
+    // Find the contribution of each coords.
+    float x = contributionOnAxis(gridPos.x);
+    float y = contributionOnAxis(gridPos.y);
+    float z = contributionOnAxis(gridPos.z); 
+    
+    // Find the normal contribution.
+    vec3 normal = normalize(vNormal);
+    x *= normalImpactOnAxis(normal.x);
+    y *= normalImpactOnAxis(normal.y);
+    z *= normalImpactOnAxis(normal.z);
+    
+    // Create the grid value by combining axis.
+    float grid = clamp(x + y + z, 0., 1.);
+    
+    // Create the color.
+    vec3 gridColor = mix(mainColor, lineColor, grid);
+
+#ifdef TRANSPARENT
+    float opacity = clamp(grid, 0.08, gridControl.w);
+    gl_FragColor = vec4(gridColor.rgb, opacity);
+#else
+    // Apply the color.
+    gl_FragColor = vec4(gridColor.rgb, 1.0);
+#endif
+}

+ 19 - 0
materialsLibrary/materials/grid/grid.vertex.fx

@@ -0,0 +1,19 @@
+precision highp float;
+
+// Attributes
+attribute vec3 position;
+attribute vec3 normal;
+
+// Uniforms
+uniform mat4 worldViewProjection;
+
+// Varying
+varying vec3 vPosition;
+varying vec3 vNormal;
+
+void main(void) {
+    gl_Position = worldViewProjection * vec4(position, 1.0);
+
+    vPosition = position;
+    vNormal = normal;
+}

+ 3 - 0
materialsLibrary/materials/grid/legacygrid.fragment.fx

@@ -0,0 +1,3 @@
+void main(void) {
+    gl_FragColor = vec4(1, 1, 1, 0.1);
+}

+ 11 - 0
materialsLibrary/materials/grid/legacygrid.vertex.fx

@@ -0,0 +1,11 @@
+precision highp float;
+
+// Attributes
+attribute vec3 position;
+
+// Uniforms
+uniform mat4 worldViewProjection;
+
+void main(void) {
+    gl_Position = worldViewProjection * vec4(position, 1.0);
+}

+ 1 - 1
materialsLibrary/materials/pbr/pbr.vertex.fx

@@ -61,7 +61,7 @@ uniform mat4 reflectivityMatrix;
 
 
 #ifdef BUMP
 #ifdef BUMP
 varying vec2 vBumpUV;
 varying vec2 vBumpUV;
-uniform vec2 vBumpInfos;
+uniform vec3 vBumpInfos;
 uniform mat4 bumpMatrix;
 uniform mat4 bumpMatrix;
 #endif
 #endif
 
 

+ 65 - 0
materialsLibrary/test/add/addgrid.js

@@ -0,0 +1,65 @@
+window.prepareGrid = function() {
+	var grid = new BABYLON.GridMaterial("grid", scene);
+
+	registerRangeUI("grid", "LineColorR", 0, 1, function(value) {
+		grid.lineColor.r = value;
+	}, function() {
+		return grid.lineColor.r;
+	});
+    
+    registerRangeUI("grid", "LineColorG", 0, 1, function(value) {
+		grid.lineColor.g = value;
+	}, function() {
+		return grid.lineColor.g;
+	});
+    
+    registerRangeUI("grid", "LineColorB", 0, 1, function(value) {
+		grid.lineColor.b = value;
+	}, function() {
+		return grid.lineColor.b;
+	});
+    
+    registerRangeUI("grid", "MainColorR", 0, 1, function(value) {
+		grid.mainColor.r = value;
+	}, function() {
+		return grid.mainColor.r;
+	});
+    
+    registerRangeUI("grid", "MainColorG", 0, 1, function(value) {
+		grid.mainColor.g = value;
+	}, function() {
+		return grid.mainColor.g;
+	});
+    
+    registerRangeUI("grid", "MainColorB", 0, 1, function(value) {
+		grid.mainColor.b = value;
+	}, function() {
+		return grid.mainColor.b;
+	});
+    
+    registerRangeUI("grid", "GridRatio", 0, 10, function(value) {
+		grid.gridRatio = value;
+	}, function() {
+		return grid.gridRatio;
+	});
+    
+    registerRangeUI("grid", "MajorUnitFrequency", 1, 10, function(value) {
+		grid.majorUnitFrequency = value;
+	}, function() {
+		return grid.majorUnitFrequency;
+	});
+    
+    registerRangeUI("grid", "MinorUnitVisibility", 0, 1, function(value) {
+		grid.minorUnitVisibility = value;
+	}, function() {
+		return grid.minorUnitVisibility;
+	});
+    
+    registerRangeUI("grid", "Opacity", 0, 1, function(value) {
+		grid.opacity = value;
+	}, function() {
+		return grid.opacity;
+	});
+
+	return grid;
+}

+ 8 - 1
materialsLibrary/test/index.html

@@ -15,6 +15,7 @@
 	<script src="../dist/babylon.triPlanarMaterial.js"></script>
 	<script src="../dist/babylon.triPlanarMaterial.js"></script>
 	<script src="../dist/babylon.gradientMaterial.js"></script>
 	<script src="../dist/babylon.gradientMaterial.js"></script>
 	<script src="../dist/babylon.skyMaterial.js"></script>
 	<script src="../dist/babylon.skyMaterial.js"></script>
+	<script src="../dist/babylon.gridMaterial.js"></script>
 
 
 	<style>
 	<style>
 		html, body {
 		html, body {
@@ -59,6 +60,7 @@
 	<script src="add/addtriplanar.js"></script>
 	<script src="add/addtriplanar.js"></script>
 	<script src="add/addgradient.js"></script>
 	<script src="add/addgradient.js"></script>
 	<script src="add/addsky.js"></script>
 	<script src="add/addsky.js"></script>
+	<script src="add/addgrid.js"></script>
 	
 	
 	<script>
 	<script>
 		if (BABYLON.Engine.isSupported()) {
 		if (BABYLON.Engine.isSupported()) {
@@ -204,13 +206,15 @@
 				var triPlanar = prepareTriPlanar();
 				var triPlanar = prepareTriPlanar();
 				
 				
 				var sky = prepareSky();
 				var sky = prepareSky();
+                
+                var grid = prepareGrid();
 				
 				
 				// Default to std
 				// Default to std
 				var currentMaterial = std;
 				var currentMaterial = std;
 				sphere.material = std;				
 				sphere.material = std;				
 				sphere.receiveShadows = true;
 				sphere.receiveShadows = true;
 
 
-				gui.add(options, 'material', ['standard', 'simple', 'water', 'fire', 'lava', 'normal', 'terrain', 'pbr', 'fur', 'triPlanar', 'gradient', 'sky']).onFinishChange(function () {
+				gui.add(options, 'material', ['standard', 'simple', 'water', 'fire', 'lava', 'normal', 'terrain', 'pbr', 'fur', 'triPlanar', 'gradient', 'sky', 'grid']).onFinishChange(function () {
 					water.enableRenderTargets(false);
 					water.enableRenderTargets(false);
 					skybox.material = skyboxMaterial;
 					skybox.material = skyboxMaterial;
 					currentMesh.isVisible = true;
 					currentMesh.isVisible = true;
@@ -254,6 +258,9 @@
 							skybox.setEnabled(true);
 							skybox.setEnabled(true);
 							skybox.material = sky;
 							skybox.material = sky;
 							break;
 							break;
+                        case "grid":
+                            currentMaterial = grid;
+                            break;
 						default:
 						default:
 							currentMaterial = std;
 							currentMaterial = std;
 							break;
 							break;

Файловите разлики са ограничени, защото са твърде много
+ 9017 - 9002
materialsLibrary/test/refs/babylon.max.js