فهرست منبع

Materials Library improved fur to high level

luaacro 9 سال پیش
والد
کامیت
c1e0cf684a

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 36 - 4
materialsLibrary/dist/babylon.furMaterial.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1 - 1
materialsLibrary/dist/babylon.furMaterial.min.js


+ 8 - 0
materialsLibrary/dist/dts/babylon.furMaterial.d.ts

@@ -7,10 +7,17 @@ declare module BABYLON {
         furLength: number;
         furAngle: number;
         furColor: Color3;
+        furOffset: number;
+        furSpacing: number;
+        furGravity: Vector3;
+        furSpeed: number;
+        furTexture: DynamicTexture;
         disableLighting: boolean;
+        highLevelFur: boolean;
         private _worldViewProjectionMatrix;
         private _scaledDiffuse;
         private _renderId;
+        private _furTime;
         private _defines;
         private _cachedDefines;
         constructor(name: string, scene: Scene);
@@ -26,5 +33,6 @@ declare module BABYLON {
         clone(name: string): FurMaterial;
         serialize(): any;
         static Parse(source: any, scene: Scene, rootUrl: string): FurMaterial;
+        static GenerateTexture(name: string, scene: Scene): DynamicTexture;
     }
 }

+ 47 - 3
materialsLibrary/materials/fur/babylon.furMaterial.ts

@@ -52,6 +52,7 @@ module BABYLON {
         public BONES4 = false;
         public BonesPerMesh = 0;
         public INSTANCES = false;
+        public HIGHLEVEL = false;
 
         constructor() {
             super();
@@ -63,14 +64,25 @@ module BABYLON {
         public diffuseTexture: BaseTexture;
         public heightTexture: BaseTexture;
         public diffuseColor = new Color3(1, 1, 1);
+        
         public furLength: number = 1;
         public furAngle: number = 0;
         public furColor = new Color3(0.44,0.21,0.02);
+        
+        public furOffset: number = 0.9;
+        public furSpacing: number = 12;
+        public furGravity = new Vector3(0, 0, 0);
+        public furSpeed: number = 100;
+        public furTexture: DynamicTexture;
+        
         public disableLighting = false;
+        public highLevelFur: boolean = false;
 
         private _worldViewProjectionMatrix = Matrix.Zero();
         private _scaledDiffuse = new Color3(1.,1.,1.);
         private _renderId: number;
+        
+        private _furTime: number = 0;
 
         private _defines = new FurMaterialDefines();
         private _cachedDefines = new FurMaterialDefines();
@@ -171,6 +183,11 @@ module BABYLON {
             if (scene.fogEnabled && mesh && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE && this.fogEnabled) {
                 this._defines.FOG = true;
             }
+            
+            // High level
+            if (this.highLevelFur) {
+                this._defines.HIGHLEVEL = true;
+            }
 
             var lightIndex = 0;
             if (scene.lightsEnabled && !this.disableLighting) {
@@ -366,11 +383,11 @@ module BABYLON {
                         "mBones",
                         "vClipPlane", "diffuseMatrix",
                         "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3",
-                        "furLength", "furAngle", "furColor"
+                        "furLength", "furAngle", "furColor", "furOffset", "furGravity", "furTime", "furSpacing"
                     ],
                     ["diffuseSampler",
                         "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3",
-                        "heightTexture"
+                        "heightTexture", "furTexture"
                     ],
                     join, fallbacks, this.onCompiled, this.onError);
             }
@@ -498,7 +515,17 @@ module BABYLON {
             this._effect.setFloat("furLength", this.furLength);
             this._effect.setFloat("furAngle", this.furAngle);
             this._effect.setColor4("furColor", this.furColor, 1.0);
-
+            
+            if (this.highLevelFur) {
+                this._effect.setVector3("furGravity", this.furGravity);
+                this._effect.setFloat("furOffset", this.furOffset);
+                this._effect.setFloat("furSpacing", this.furSpacing);
+                
+                this._furTime += this.getScene().getEngine().getDeltaTime() / this.furSpeed;
+                this._effect.setFloat("furTime", this._furTime);
+                
+                this._effect.setTexture("furTexture", this.furTexture);
+            }
  
             super.bind(world, mesh);
         }
@@ -596,6 +623,23 @@ module BABYLON {
 
             return material;
         }
+        
+        public static GenerateTexture(name: string, scene: Scene): DynamicTexture {
+            // Generate fur textures
+            var texture = new DynamicTexture("FurTexture " + name, 256, scene, true);
+            var context = texture.getContext();
+            
+            for ( var i = 0; i < 20000; ++i ) {
+                context.fillStyle = "rgba(255, " + Math.floor(Math.random() * 255) + ", " + Math.floor(Math.random() * 255) + ", 1)";
+                context.fillRect((Math.random() * texture.getSize().width), (Math.random() * texture.getSize().height), 2, 2);
+            }
+            
+            texture.update(false);
+            texture.wrapU = Texture.WRAP_ADDRESSMODE;
+            texture.wrapV = Texture.WRAP_ADDRESSMODE;
+            
+            return texture;
+        }
     }
 } 
 

+ 32 - 3
materialsLibrary/materials/fur/fur.fragment.fx

@@ -105,6 +105,14 @@ uniform sampler2D diffuseSampler;
 uniform vec2 vDiffuseInfos;
 #endif
 
+// Fur uniforms
+#ifdef HIGHLEVEL
+uniform float furOffset;
+uniform sampler2D furTexture;
+
+varying vec2 vFurUV;
+#endif
+
 // Shadows
 #ifdef SHADOWS
 
@@ -384,8 +392,11 @@ void main(void) {
 	float alpha = vDiffuseColor.a;
 
 #ifdef DIFFUSE
+	#ifdef HIGHLEVEL
+	baseColor = vec4(0.0, 0.0, 0.0, 0.0);
+	#else
 	baseColor = texture2D(diffuseSampler, vDiffuseUV);
-
+	#endif
 #ifdef ALPHATEST
 	if (baseColor.a < 0.4)
 		discard;
@@ -405,6 +416,21 @@ void main(void) {
 	vec3 normalW = vec3(1.0, 1.0, 1.0);
 #endif
 
+	#ifdef HIGHLEVEL
+	// Fur
+	vec4 furTextureColor = texture2D(furTexture, vec2(vFurUV.x, vFurUV.y));
+	
+	#ifdef DIFFUSE
+	baseColor = texture2D(diffuseSampler, vec2(vFurUV.x * 0.2, vFurUV.y * 0.2)) * 2.0;
+	#endif
+	
+	if (furTextureColor.a <= 0.0 || furTextureColor.g < furOffset) {
+		discard;
+	}
+	
+	baseColor = vec4(furColor.xyz * baseColor.xyz, 1.1 - furOffset);
+	#endif
+
 	// Lighting
 	vec3 diffuseBase = vec3(0., 0., 0.);
 	float shadow = 1.;
@@ -552,10 +578,13 @@ void main(void) {
 	vec3 finalDiffuse = clamp(diffuseBase * diffuseColor, 0.0, 1.0) * baseColor.rgb;
 
 	// Composition
-	//float r = Rand(vPositionW) * 0.5;
+	#ifdef HIGHLEVEL
+	vec4 color = vec4(finalDiffuse, alpha);
+	#else
 	float r = vfur_length * 0.5;
 	vec4 color = vec4(finalDiffuse * (0.5 + r), alpha);
-
+	#endif
+	
 #ifdef FOG
 	float fog = CalcFogFactor();
 	color.rgb = fog * color.rgb + (1.0 - fog) * vFogColor;

+ 47 - 9
materialsLibrary/materials/fur/fur.vertex.fx

@@ -22,10 +22,20 @@ attribute vec4 matricesWeights;
 // Uniforms
 uniform float furLength;
 uniform float furAngle;
+#ifdef HIGHLEVEL
+uniform float furOffset;
+uniform vec3 furGravity;
+uniform float furTime;
+uniform float furSpacing;
+#endif
 #ifdef HEIGHTMAP
 uniform sampler2D heightTexture;
 #endif
 
+#ifdef HIGHLEVEL
+varying vec2 vFurUV;
+#endif
+
 #ifdef INSTANCES
 attribute vec4 world0;
 attribute vec4 world1;
@@ -118,6 +128,7 @@ void main(void) {
 #endif 
 
 #endif
+
 //FUR
 float r = Rand(position);
 #ifdef HEIGHTMAP	
@@ -127,13 +138,40 @@ float r = Rand(position);
 #endif
 	vec3 tangent1 = vec3(normal.y, -normal.x, 0);
 	vec3 tangent2 = vec3(-normal.z, 0, normal.x);
-	r = Rand(tangent1*r);
-	float J = (2.0 + 4.0* r);
+	r = Rand(tangent1 * r);
+	float J = (2.0 + 4.0 * r);
 	r = Rand(tangent2*r);
-	float K = (2.0 + 2.0* r);
-	tangent1 = tangent1*J + tangent2*K;
+	float K = (2.0 + 2.0 * r);
+	tangent1 = tangent1*J + tangent2 * K;
 	tangent1 = normalize(tangent1);
-    vec3 newPosition = position + normal * vfur_length*cos(furAngle) + tangent1*vfur_length*sin(furAngle);
+	
+    vec3 newPosition = position + normal * vfur_length*cos(furAngle) + tangent1 * vfur_length * sin(furAngle);
+	
+	#ifdef HIGHLEVEL
+	// Compute fur data passed to the pixel shader
+	vec3 forceDirection = vec3(0.0, 0.0, 0.0);
+	forceDirection.x = sin(furTime + position.x * 0.05) * 0.2;
+	forceDirection.y = cos(furTime * 0.7 + position.y * 0.04) * 0.2;
+	forceDirection.z = sin(furTime * 0.7 + position.z * 0.04) * 0.2;
+	
+	vec3 displacement = vec3(0.0, 0.0, 0.0);
+	displacement = furGravity + forceDirection;
+	
+	float displacementFactor = pow(furOffset, 3.0);
+	
+	vec3 aNormal = normal;
+	aNormal.xyz += displacement * displacementFactor;
+	
+	newPosition = vec3(newPosition.x, newPosition.y, newPosition.z) + (normalize(aNormal) * furOffset * furSpacing);
+	#endif
+	
+	#ifdef NORMAL
+	#ifdef HIGHLEVEL
+	vNormalW = normalize(normal * aNormal);
+	#else
+	vNormalW = normalize(vec3(finalWorld * vec4(normal, 0.0)));
+	#endif
+	#endif
 	
 //END FUR
 	gl_Position = viewProjection * finalWorld * vec4(newPosition, 1.0);
@@ -141,10 +179,6 @@ float r = Rand(position);
 	vec4 worldPos = finalWorld * vec4(newPosition, 1.0);
 	vPositionW = vec3(worldPos);
 
-#ifdef NORMAL
-	vNormalW = normalize(vec3(finalWorld * vec4(normal, 0.0)));
-#endif
-
 	// Texture coordinates
 #ifndef UV1
 	vec2 uv = vec2(0., 0.);
@@ -153,6 +187,10 @@ float r = Rand(position);
 	vec2 uv2 = vec2(0., 0.);
 #endif
 
+	#ifdef HIGHLEVEL
+	vFurUV = uv * 20.0;
+	#endif
+
 #ifdef DIFFUSE
 	if (vDiffuseInfos.x == 0.)
 	{

+ 2 - 2
materialsLibrary/materials/sky/babylon.skyMaterial.ts

@@ -13,7 +13,7 @@ module BABYLON {
             this._keys = Object.keys(this);
         }
     }
-
+    
     export class SkyMaterial extends Material {
         // Public members
         public luminance: number = 1.0;
@@ -120,7 +120,7 @@ module BABYLON {
                 if (this._defines.FOG) {
                     fallbacks.addFallback(1, "FOG");
                 }
-
+                
                 //Attributes
                 var attribs = [VertexBuffer.PositionKind];
 

+ 116 - 23
materialsLibrary/test/add/addfur.js

@@ -1,20 +1,84 @@
 window.prepareFur = function() {
-	var fur = new BABYLON.FurMaterial("fur", scene);
-	fur.furLength = 1;
+	var shells = 30;
+	
+	var materials = [];
+	var meshes = [];
+	
+	var diffuseTexture = new BABYLON.Texture("textures/leopard_fur.jpg", scene);
+	var heightTexture = new BABYLON.Texture("textures/speckles.jpg", scene);
+	var furTexture = BABYLON.FurMaterial.GenerateTexture("furTexture", scene);
+	
+	var fur = new BABYLON.FurMaterial("fur0", scene);
+	fur.furLength = 4;
 	fur.furAngle = 0;
-    fur.furColor = new BABYLON.Color3(0.44,0.21,0.02);
-
+	fur.furColor = new BABYLON.Color3(0.2, 0.2, 0.2);
+	fur.diffuseTexture = diffuseTexture;
+	fur.furOffset = 0;
+	fur.furTexture = furTexture;
+	
+	var setValue = function(property, value) {
+		for (var i=0; i < materials.length; i++) {
+			materials[i][property] = value;
+		}
+	}
+	
+	var resetFur = function() {
+		for (var i=1; i < materials.length; i++) {
+			materials[i].dispose();
+		}
+		for (var i=1; i < meshes.length; i++) {
+			meshes[i].dispose();
+		}
+		
+		materials = [];
+		meshes = [];
+	};
+	
+	var setMeshesVisible = function(visible) {
+		for (var i=1; i < meshes.length; i++) {
+			meshes[i].isVisible = visible;
+		}
+	}
+	
+	var configureFur = function(mesh, apply) {
+		meshes = [mesh];
+		materials = [fur];
+		
+		mesh.material = fur;
+		
+		for (var i = 1; i < shells; i++) {
+			var offsetFur = new BABYLON.FurMaterial("fur" + i, scene);
+			offsetFur.furLength = 4;
+			offsetFur.furAngle = 0;
+			offsetFur.furColor = new BABYLON.Color3(0.2, 0.2, 0.2);
+			offsetFur.diffuseTexture = diffuseTexture;
+			offsetFur.furOffset = i / shells;
+			offsetFur.furTexture = furTexture;
+			offsetFur.highLevelFur = fur.highLevelFur;
+			materials.push(offsetFur);
+			
+			var offsetMesh = mesh.clone(mesh.name + i);
+			offsetMesh.isVisible = fur.highLevelFur && apply;
+			offsetMesh.material = offsetFur;
+			offsetMesh.skeleton = mesh.skeleton;
+			meshes.push(offsetMesh);
+		}
+		
+		for (var i=0; i < scene.skeletons.length; i++) {
+			scene.beginAnimation(scene.skeletons[i], 0, 100, true, 0.8);
+		}
+	}
 
-// fur length
-    registerRangeUI("fur", "Fur length", 0, 15, function(value) {
-        fur.furLength = value;
+	// fur length
+    registerRangeUI("fur", "Fur length", 0, 45, function(value) {
+		setValue("furLength", value);
     }, function() {
         return fur.furLength;
     });
 	
 	// fur angle
     registerRangeUI("fur", "Fur angle", 0, Math.PI/2, function(value) {
-        fur.furAngle = value;
+		setValue("furAngle", value);
     }, function() {
         return fur.furAngle;
     });
@@ -31,24 +95,53 @@ window.prepareFur = function() {
 	var DTON = false;
 	registerButtonUI("fur", "Tgl Diffuse Tex", function() {
 		DTON = !DTON;
-		if(DTON) {
-			fur.diffuseTexture = new BABYLON.Texture("textures/leopard_fur.jpg", scene);
-		}
-		else {
-			fur.diffuseTexture = null;
-		}
-	})
+		setValue("diffuseTexture", DTON ? diffuseTexture : null);
+	});
 	
 	var HTON = false;
 	registerButtonUI("fur", "Tgl Height Tex", function() {
 		HTON = !HTON;
-		if(HTON) {
-			fur.heightTexture = new BABYLON.Texture("textures/speckles.jpg", scene);
-		}
-		else {
-			fur.heightTexture = null;
-		}
-	})
+		setValue("heightTexture", HTON ? heightTexture : null);
+	});
+	
+	registerRangeUI("fur", "Hight Level fur", false, true, function(value) {
+		setValue("highLevelFur", value);
+		setMeshesVisible(value);
+    }, function() {
+        return fur.highLevelFur;
+    });
+	
+	registerRangeUI("fur", "Fur Gravity", 0, 1, function(value) {
+		setValue("furGravity", new BABYLON.Vector3(value, value,value));
+    }, function() {
+        return fur.furGravity.x;
+    });
+	
+	// fur animation speed
+    registerRangeUI("fur", "Fur speed", 1, 1000, function(value) {
+		setValue("furSpeed", value);
+    }, function() {
+        return fur.furSpeed;
+    });
+	
+	// fur animation speed
+    registerRangeUI("fur", "Fur Spacing", 0, 20, function(value) {
+		setValue("furSpacing", value);
+    }, function() {
+        return fur.furSpacing;
+    });
     
-    return fur;
+    return {
+		/*
+		materials: furs,
+		meshes: meshes
+		*/
+		material: fur,
+		resetFur: function() {
+			resetFur();
+		},
+		configureFur: function(mesh, apply) {
+			configureFur(mesh, apply);
+		}
+	};
 };

+ 10 - 2
materialsLibrary/test/index.html

@@ -186,7 +186,7 @@
 				var normal = prepareNormal();
 
 				var gradient = prepareGradient();
-				
+								
 				var fur = prepareFur();
 				
 				var water = prepareWater();
@@ -213,6 +213,8 @@
 				gui.add(options, 'material', ['standard', 'simple', 'water', 'fire', 'lava', 'normal', 'terrain', 'pbr', 'fur', 'triPlanar', 'gradient', 'sky']).onFinishChange(function () {
 					water.enableRenderTargets(false);
 					skybox.material = skyboxMaterial;
+					currentMesh.isVisible = true;
+					fur.resetFur();
 					
 					switch (options.material) {
 						case "simple":
@@ -239,7 +241,8 @@
 							currentMaterial = pbr;
 							break;
 						case "fur":
-							currentMaterial = fur;
+							currentMaterial = fur.material;
+							fur.configureFur(currentMesh, true);
 							break;
 						case "triPlanar":
 							currentMaterial = triPlanar;
@@ -288,6 +291,11 @@
 					currentMesh.material = currentMaterial;
 					
 					water.mesh = currentMesh;
+					
+					if (currentMaterial === fur.material) {
+						fur.resetFur();
+						fur.configureFur(currentMesh, currentMaterial === fur.material);
+					}
 				});
 
 				var f1 = gui.addFolder('lights');