소스 검색

Merge pull request #812 from julien-moreau/master

Materials Library, added specular color support to water material
Raanan Weber 9 년 전
부모
커밋
b7e2f601fd

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 1
materialsLibrary/dist/babylon.fireMaterial.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 24 - 4
materialsLibrary/dist/babylon.waterMaterial.js


+ 3 - 3
materialsLibrary/materials/fire/fire.fragment.fx

@@ -108,13 +108,13 @@ void main(void) {
 	
 	vec4 opacityColor = texture2D(opacitySampler, perturbedBaseCoords.xy);
 	
-	baseColor = texture2D(diffuseSampler, perturbedBaseCoords.xy) * 2.0;
-	baseColor *= opacityColor;
-
 #ifdef ALPHATEST
 	if (opacityColor.r < 0.1)
 		discard;
 #endif
+	
+	baseColor = texture2D(diffuseSampler, perturbedBaseCoords.xy) * 2.0;
+	baseColor *= opacityColor;
 
 	baseColor.rgb *= vDiffuseInfos.y;
 #endif

+ 26 - 2
materialsLibrary/materials/water/babylon.waterMaterial.ts

@@ -53,6 +53,7 @@ module BABYLON {
         public BONES4 = false;
         public BonesPerMesh = 0;
         public INSTANCES = false;
+        public SPECULARTERM = false;
 
         constructor() {
             super();
@@ -66,6 +67,8 @@ module BABYLON {
 		*/
         public bumpTexture: BaseTexture;
         public diffuseColor = new Color3(1, 1, 1);
+        public specularColor = new Color3(0, 0, 0);
+        public specularPower = 64;
         public disableLighting = false;
         
         /**
@@ -96,6 +99,11 @@ module BABYLON {
         * @param {number}: Represents the maximum length of a wave
         */
 		public waveLength: number = 0.1;
+        
+        /**
+        * @param {number}: Defines the waves speed
+        */
+        public waveSpeed: number = 1.0;
 		
 		/*
 		* Private members
@@ -111,6 +119,7 @@ module BABYLON {
 		private _lastTime: number = 0;
         
         private _scaledDiffuse = new Color3();
+        private _scaledSpecular = new Color3();
         private _renderId: number;
 
         private _defines = new WaterMaterialDefines();
@@ -287,6 +296,11 @@ module BABYLON {
                     }
 
                     this._defines[type] = true;
+                    
+                    // Specular
+                    if (!light.specular.equalsFloats(0, 0, 0)) {
+                        this._defines.SPECULARTERM = true;
+                    }
 
                     // Shadows
                     if (scene.shadowsEnabled) {
@@ -421,7 +435,7 @@ module BABYLON {
 				
                 this._effect = scene.getEngine().createEffect(shaderName,
                     attribs,
-                    ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor",
+                    ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vDiffuseColor", "vSpecularColor",
                         "vLightData0", "vLightDiffuse0", "vLightSpecular0", "vLightDirection0", "vLightGround0", "lightMatrix0",
                         "vLightData1", "vLightDiffuse1", "vLightSpecular1", "vLightDirection1", "vLightGround1", "lightMatrix1",
                         "vLightData2", "vLightDiffuse2", "vLightSpecular2", "vLightDirection2", "vLightGround2", "lightMatrix2",
@@ -433,7 +447,7 @@ module BABYLON {
                         "shadowsInfo0", "shadowsInfo1", "shadowsInfo2", "shadowsInfo3",
 						// Water
 						"worldReflectionViewProjection", "windDirection", "waveLength", "time", "windForce",
-						"cameraPosition", "bumpHeight", "waveHeight", "waterColor", "colorBlendFactor"
+						"cameraPosition", "bumpHeight", "waveHeight", "waterColor", "colorBlendFactor", "waveSpeed"
                     ],
                     ["normalSampler",
                         "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3",
@@ -499,6 +513,10 @@ module BABYLON {
             }
 
             this._effect.setColor4("vDiffuseColor", this._scaledDiffuse, this.alpha * mesh.visibility);
+            
+            if (this._defines.SPECULARTERM) {
+                this._effect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
+            }
 
             if (scene.lightsEnabled && !this.disableLighting) {
                 var lightIndex = 0;
@@ -529,6 +547,11 @@ module BABYLON {
 
                     light.diffuse.scaleToRef(light.intensity, this._scaledDiffuse);
                     this._effect.setColor4("vLightDiffuse" + lightIndex, this._scaledDiffuse, light.range);
+                    
+                    if (this._defines.SPECULARTERM) {
+                        light.specular.scaleToRef(light.intensity, this._scaledSpecular);
+                        this._effect.setColor3("vLightSpecular" + lightIndex, this._scaledSpecular);
+                    }
 
                     // Shadows
                     if (scene.shadowsEnabled) {
@@ -576,6 +599,7 @@ module BABYLON {
             this._effect.setFloat("bumpHeight", this.bumpHeight);
 			this._effect.setColor4("waterColor", this.waterColor, 1.0);
 			this._effect.setFloat("colorBlendFactor", this.colorBlendFactor);
+            this._effect.setFloat("waveSpeed", this.waveSpeed);
 
             super.bind(world, mesh);
 		}

+ 131 - 26
materialsLibrary/materials/water/water.fragment.fx

@@ -4,6 +4,10 @@ precision highp float;
 uniform vec3 vEyePosition;
 uniform vec4 vDiffuseColor;
 
+#ifdef SPECULARTERM
+uniform vec4 vSpecularColor;
+#endif
+
 // Input
 varying vec3 vPositionW;
 
@@ -19,6 +23,9 @@ varying vec4 vColor;
 #ifdef LIGHT0
 uniform vec4 vLightData0;
 uniform vec4 vLightDiffuse0;
+#ifdef SPECULARTERM
+uniform vec3 vLightSpecular0;
+#endif
 #ifdef SHADOW0
 #if defined(SPOTLIGHT0) || defined(DIRLIGHT0)
 varying vec4 vPositionFromLight0;
@@ -39,6 +46,9 @@ uniform vec3 vLightGround0;
 #ifdef LIGHT1
 uniform vec4 vLightData1;
 uniform vec4 vLightDiffuse1;
+#ifdef SPECULARTERM
+uniform vec3 vLightSpecular1;
+#endif
 #ifdef SHADOW1
 #if defined(SPOTLIGHT1) || defined(DIRLIGHT1)
 varying vec4 vPositionFromLight1;
@@ -59,6 +69,9 @@ uniform vec3 vLightGround1;
 #ifdef LIGHT2
 uniform vec4 vLightData2;
 uniform vec4 vLightDiffuse2;
+#ifdef SPECULARTERM
+uniform vec3 vLightSpecular2;
+#endif
 #ifdef SHADOW2
 #if defined(SPOTLIGHT2) || defined(DIRLIGHT2)
 varying vec4 vPositionFromLight2;
@@ -79,6 +92,9 @@ uniform vec3 vLightGround2;
 #ifdef LIGHT3
 uniform vec4 vLightData3;
 uniform vec4 vLightDiffuse3;
+#ifdef SPECULARTERM
+uniform vec3 vLightSpecular3;
+#endif
 #ifdef SHADOW3
 #if defined(SPOTLIGHT3) || defined(DIRLIGHT3)
 varying vec4 vPositionFromLight3;
@@ -313,9 +329,12 @@ float CalcFogFactor()
 struct lightingInfo
 {
 	vec3 diffuse;
+#ifdef SPECULARTERM
+	vec3 specular;
+#endif
 };
 
-lightingInfo computeLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData, vec3 diffuseColor, float range) {
+lightingInfo computeLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData, vec3 diffuseColor, vec3 specularColor, float range, float glossiness, vec3 bumpColor) {
 	lightingInfo result;
 
 	vec3 lightVectorW;
@@ -336,10 +355,23 @@ lightingInfo computeLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData,
 	float ndl = max(0., dot(vNormal, lightVectorW));
 	result.diffuse = ndl * diffuseColor * attenuation;
 
+	// Specular
+#ifdef SPECULARTERM
+	vec3 angleW = normalize(vEyePosition - lightVectorW);
+	vec2 perturbation = bumpHeight * (bumpColor.rg - 0.5);
+	
+	vec3 upVector = vec3(0.0, 1.0, 0.0);
+	float fresnelTerm = max(dot(angleW, upVector), 0.0);
+	
+	vec3 halfvec = normalize(angleW + lightVectorW + vec3(perturbation.x * fresnelTerm, perturbation.y * fresnelTerm, 0.0) * max(1., glossiness));
+	float temp = pow(dot(halfvec, vNormal), max(1., glossiness));
+	result.specular = specularColor * temp * attenuation;
+#endif
+
 	return result;
 }
 
-lightingInfo computeSpotLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData, vec4 lightDirection, vec3 diffuseColor, float range) {
+lightingInfo computeSpotLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData, vec4 lightDirection, vec3 specularColor, vec3 diffuseColor, float range, float glossiness, vec3 bumpColor) {
 	lightingInfo result;
 
 	vec3 direction = lightData.xyz - vPositionW;
@@ -359,20 +391,49 @@ lightingInfo computeSpotLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightDa
 		float ndl = max(0., dot(vNormal, -lightDirection.xyz));
 		result.diffuse = ndl * spotAtten * diffuseColor * attenuation;
 
+		// Specular
+#ifdef SPECULARTERM		
+		vec3 angleW = normalize(vEyePosition - lightVectorW);
+		vec2 perturbation = bumpHeight * (bumpColor.rg - 0.5);
+		
+		vec3 upVector = vec3(0.0, 1.0, 0.0);
+		float fresnelTerm = max(dot(angleW, upVector), 0.0);
+		
+		vec3 halfvec = normalize(angleW + lightVectorW + vec3(perturbation.x * fresnelTerm, perturbation.y * fresnelTerm, 0.0) * max(1., glossiness));
+		float temp = pow(dot(halfvec, vNormal), max(1., glossiness));
+		result.specular = specularColor * temp * spotAtten * attenuation;
+#endif
 		return result;
 	}
 
 	result.diffuse = vec3(0.);
+#ifdef SPECULARTERM
+	result.specular = vec3(0.);
+#endif
 
 	return result;
 }
 
-lightingInfo computeHemisphericLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData, vec3 diffuseColor, vec3 groundColor) {
+lightingInfo computeHemisphericLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData, vec3 diffuseColor, vec3 specularColor, vec3 groundColor, float glossiness, vec3 bumpColor) {
 	lightingInfo result;
 
 	// Diffuse
 	float ndl = dot(vNormal, lightData.xyz) * 0.5 + 0.5;
 	result.diffuse = mix(groundColor, diffuseColor, ndl);
+	
+	// Specular
+#ifdef SPECULARTERM
+	vec3 lightVectorW = normalize(vec3(0.1, 0.6, 0.5));
+	vec3 angleW = normalize(viewDirectionW - lightVectorW);
+	vec2 perturbation = bumpHeight * (bumpColor.rg - 0.5);
+	
+	vec3 upVector = vec3(0.0, 1.0, 0.0);
+	float fresnelTerm = max(dot(angleW, upVector), 0.0);
+	
+	vec3 halfvec = normalize(angleW + lightVectorW + vec3(perturbation.x * fresnelTerm, perturbation.y * fresnelTerm, 0.0) * max(1., glossiness));
+	float temp = pow(dot(halfvec, vNormal), max(1., glossiness));
+	result.specular = specularColor * temp;
+#endif
 
 	return result;
 }
@@ -389,12 +450,20 @@ void main(void) {
 	// Base color
 	vec4 baseColor = vec4(1., 1., 1., 1.);
 	vec3 diffuseColor = vDiffuseColor.rgb;
+	
+#ifdef SPECULARTERM
+	float glossiness = vSpecularColor.a;
+	vec3 specularColor = vSpecularColor.rgb;
+#else
+	float glossiness = 0.;
+#endif
 
 	// Alpha
 	float alpha = vDiffuseColor.a;
 
 #ifdef BUMP
 	baseColor = texture2D(normalSampler, vNormalUV);
+	vec3 bumpColor = baseColor.rgb;
 
 #ifdef ALPHATEST
 	if (baseColor.a < 0.4)
@@ -402,15 +471,26 @@ void main(void) {
 #endif
 
 	baseColor.rgb *= vNormalInfos.y;
+#else
+	vec3 bumpColor = vec3(1.0);
 #endif
 
 #ifdef VERTEXCOLOR
 	baseColor.rgb *= vColor.rgb;
 #endif
 
+	// Bump
+#ifdef NORMAL
+	vec3 normalW = normalize(vNormalW);
+	vec2 perturbation = bumpHeight * (baseColor.rg - 0.5);
+#else
+	vec3 normalW = vec3(1.0, 1.0, 1.0);
+	vec2 perturbation = bumpHeight * (vec2(1.0, 1.0) - 0.5);
+#endif
+
 #ifdef REFLECTION
 	// Water
-	vec2 perturbation = bumpHeight * (baseColor.rg - 0.5);
+	vec3 eyeVector = normalize(vEyePosition - vPosition);
 	
 	vec2 projectedRefractionTexCoords = clamp(vRefractionMapTexCoord.xy / vRefractionMapTexCoord.z + perturbation, 0.0, 1.0);
 	vec4 refractiveColor = texture2D(refractionSampler, projectedRefractionTexCoords);
@@ -418,7 +498,6 @@ void main(void) {
 	vec2 projectedReflectionTexCoords = clamp(vReflectionMapTexCoord.xy / vReflectionMapTexCoord.z + perturbation, 0.0, 1.0);
 	vec4 reflectiveColor = texture2D(reflectionSampler, projectedReflectionTexCoords);
 	
-	vec3 eyeVector = normalize(vEyePosition - vPosition);
 	vec3 upVector = vec3(0.0, 1.0, 0.0);
 	
 	float fresnelTerm = max(dot(eyeVector, upVector), 0.0);
@@ -428,26 +507,25 @@ void main(void) {
 	baseColor = colorBlendFactor * waterColor + (1.0 - colorBlendFactor) * combinedColor;
 #endif
 
-	// Bump
-#ifdef NORMAL
-	vec3 normalW = normalize(vNormalW);
-#else
-	vec3 normalW = vec3(1.0, 1.0, 1.0);
-#endif
-
-		// Lighting
+	// Lighting
 	vec3 diffuseBase = vec3(0., 0., 0.);
+#ifdef SPECULARTERM
+	vec3 specularBase = vec3(0., 0., 0.);
+#endif
 	float shadow = 1.;
 
 #ifdef LIGHT0
+#ifndef SPECULARTERM
+	vec3 vLightSpecular0 = vec3(0.0);
+#endif
 #ifdef SPOTLIGHT0
-	lightingInfo info = computeSpotLighting(viewDirectionW, normalW, vLightData0, vLightDirection0, vLightDiffuse0.rgb, vLightDiffuse0.a);
+	lightingInfo info = computeSpotLighting(viewDirectionW, normalW, vLightData0, vLightDirection0, vLightDiffuse0.rgb, vLightSpecular0, vLightDiffuse0.a, glossiness, bumpColor);
 #endif
 #ifdef HEMILIGHT0
-	lightingInfo info = computeHemisphericLighting(viewDirectionW, normalW, vLightData0, vLightDiffuse0.rgb, vLightGround0);
+	lightingInfo info = computeHemisphericLighting(viewDirectionW, normalW, vLightData0, vLightDiffuse0.rgb, vLightSpecular0, vLightGround0, glossiness, bumpColor);
 #endif
 #if defined(POINTLIGHT0) || defined(DIRLIGHT0)
-	lightingInfo info = computeLighting(viewDirectionW, normalW, vLightData0, vLightDiffuse0.rgb, vLightDiffuse0.a);
+	lightingInfo info = computeLighting(viewDirectionW, normalW, vLightData0, vLightDiffuse0.rgb, vLightSpecular0, vLightDiffuse0.a, glossiness, bumpColor);
 #endif
 #ifdef SHADOW0
 #ifdef SHADOWVSM0
@@ -471,17 +549,23 @@ void main(void) {
 	shadow = 1.;
 #endif
 	diffuseBase += info.diffuse * shadow;
+#ifdef SPECULARTERM
+	specularBase += info.specular * shadow;
+#endif
 #endif
 
 #ifdef LIGHT1
+#ifndef SPECULARTERM
+	vec3 vLightSpecular1 = vec3(0.0);
+#endif
 #ifdef SPOTLIGHT1
-	info = computeSpotLighting(viewDirectionW, normalW, vLightData1, vLightDirection1, vLightDiffuse1.rgb, vLightDiffuse1.a);
+	info = computeSpotLighting(viewDirectionW, normalW, vLightData1, vLightDirection1, vLightDiffuse1.rgb, vLightSpecular1, vLightDiffuse1.a, glossiness, bumpColor);
 #endif
 #ifdef HEMILIGHT1
-	info = computeHemisphericLighting(viewDirectionW, normalW, vLightData1, vLightDiffuse1.rgb, vLightGround1.a);
+	info = computeHemisphericLighting(viewDirectionW, normalW, vLightData1, vLightDiffuse1.rgb, vLightSpecular1, vLightGround1.a, glossiness, bumpColor);
 #endif
 #if defined(POINTLIGHT1) || defined(DIRLIGHT1)
-	info = computeLighting(viewDirectionW, normalW, vLightData1, vLightDiffuse1.rgb, vLightDiffuse1.a);
+	info = computeLighting(viewDirectionW, normalW, vLightData1, vLightDiffuse1.rgb, vLightSpecular1, vLightDiffuse1.a, glossiness, bumpColor);
 #endif
 #ifdef SHADOW1
 #ifdef SHADOWVSM1
@@ -505,17 +589,23 @@ void main(void) {
 	shadow = 1.;
 #endif
 	diffuseBase += info.diffuse * shadow;
+#ifdef SPECULARTERM
+	specularBase += info.specular * shadow;
+#endif
 #endif
 
 #ifdef LIGHT2
+#ifndef SPECULARTERM
+	vec3 vLightSpecular2 = vec3(0.0);
+#endif
 #ifdef SPOTLIGHT2
-	info = computeSpotLighting(viewDirectionW, normalW, vLightData2, vLightDirection2, vLightDiffuse2.rgb, vLightDiffuse2.a);
+	info = computeSpotLighting(viewDirectionW, normalW, vLightData2, vLightDirection2, vLightDiffuse2.rgb, vLightSpecular2, vLightDiffuse2.a, glossiness, bumpColor);
 #endif
 #ifdef HEMILIGHT2
-	info = computeHemisphericLighting(viewDirectionW, normalW, vLightData2, vLightDiffuse2.rgb, vLightGround2);
+	info = computeHemisphericLighting(viewDirectionW, normalW, vLightData2, vLightDiffuse2.rgb, vLightSpecular2, vLightGround2, glossiness, bumpColor);
 #endif
 #if defined(POINTLIGHT2) || defined(DIRLIGHT2)
-	info = computeLighting(viewDirectionW, normalW, vLightData2, vLightDiffuse2.rgb, vLightDiffuse2.a);
+	info = computeLighting(viewDirectionW, normalW, vLightData2, vLightDiffuse2.rgb, vLightSpecular2, vLightDiffuse2.a, glossiness, bumpColor);
 #endif
 #ifdef SHADOW2
 #ifdef SHADOWVSM2
@@ -539,17 +629,23 @@ void main(void) {
 	shadow = 1.;
 #endif
 	diffuseBase += info.diffuse * shadow;
+#ifdef SPECULARTERM
+	specularBase += info.specular * shadow;
+#endif
 #endif
 
 #ifdef LIGHT3
+#ifndef SPECULARTERM
+	vec3 vLightSpecular3 = vec3(0.0);
+#endif
 #ifdef SPOTLIGHT3
-	info = computeSpotLighting(viewDirectionW, normalW, vLightData3, vLightDirection3, vLightDiffuse3.rgb, vLightDiffuse3.a);
+	info = computeSpotLighting(viewDirectionW, normalW, vLightData3, vLightDirection3, vLightDiffuse3.rgb, vLightSpecular3, vLightDiffuse3.a, glossiness, bumpColor);
 #endif
 #ifdef HEMILIGHT3
-	info = computeHemisphericLighting(viewDirectionW, normalW, vLightData3, vLightDiffuse3.rgb, vLightGround3);
+	info = computeHemisphericLighting(viewDirectionW, normalW, vLightData3, vLightDiffuse3.rgb, vLightSpecular3, vLightGround3, glossiness, bumpColor);
 #endif
 #if defined(POINTLIGHT3) || defined(DIRLIGHT3)
-	info = computeLighting(viewDirectionW, normalW, vLightData3, vLightDiffuse3.rgb, vLightDiffuse3.a);
+	info = computeLighting(viewDirectionW, normalW, vLightData3, vLightDiffuse3.rgb, vLightSpecular3, vLightDiffuse3.a, glossiness, bumpColor);
 #endif
 #ifdef SHADOW3
 #ifdef SHADOWVSM3
@@ -573,16 +669,25 @@ void main(void) {
 	shadow = 1.;
 #endif
 	diffuseBase += info.diffuse * shadow;
+#ifdef SPECULARTERM
+	specularBase += info.specular * shadow;
+#endif
 #endif
 
 #ifdef VERTEXALPHA
 	alpha *= vColor.a;
 #endif
 
+#ifdef SPECULARTERM
+	vec3 finalSpecular = specularBase * specularColor;
+#else
+	vec3 finalSpecular = vec3(0.0);
+#endif
+
 	vec3 finalDiffuse = clamp(diffuseBase * diffuseColor, 0.0, 1.0) * baseColor.rgb;
 
 	// Composition
-	vec4 color = vec4(finalDiffuse, alpha);
+	vec4 color = vec4(finalDiffuse + finalSpecular, alpha);
 
 #ifdef FOG
 	float fog = CalcFogFactor();

+ 3 - 2
materialsLibrary/materials/water/water.vertex.fx

@@ -92,6 +92,7 @@ uniform float waveLength;
 uniform float time;
 uniform float windForce;
 uniform float waveHeight;
+uniform float waveSpeed;
 
 // Water varyings
 varying vec3 vPosition;
@@ -184,8 +185,8 @@ void main(void) {
 #endif
 
 	vec3 p = position;
-	float newY = (sin(((p.x / 0.05) + time * windForce) * windDirection.x) * waveHeight * 5.0)
-			   + (cos(((p.z / 0.05) + time * windForce) * windDirection.y) * waveHeight * 5.0);
+	float newY = (sin(((p.x / 0.05) + time * waveSpeed * windForce) * windDirection.x) * waveHeight * 5.0)
+			   + (cos(((p.z / 0.05) + time * waveSpeed * windForce) * windDirection.y) * waveHeight * 5.0);
 	p.y += abs(newY);
 	
 	gl_Position = viewProjection * finalWorld * vec4(p, 1.0);