فهرست منبع

Decals: Support normal fading

trethaller 2 سال پیش
والد
کامیت
b5484377ae
1فایلهای تغییر یافته به همراه87 افزوده شده و 68 حذف شده
  1. 87 68
      h3d/shader/pbr/VolumeDecal.hx

+ 87 - 68
h3d/shader/pbr/VolumeDecal.hx

@@ -1,6 +1,7 @@
 package h3d.shader.pbr;
 package h3d.shader.pbr;
 
 
-class DecalOverlay extends hxsl.Shader {
+
+class BaseDecal extends hxsl.Shader {
 	static var SRC = {
 	static var SRC = {
 
 
 		@global var global : {
 		@global var global : {
@@ -13,35 +14,78 @@ class DecalOverlay extends hxsl.Shader {
 			var inverseViewProj : Mat4;
 			var inverseViewProj : Mat4;
 		};
 		};
 
 
-		var output : {
-			color : Vec4
-		};
-
-		@const var CENTERED : Bool;
-		@const var GAMMA_CORRECT : Bool;
-		@const var AUTO_ALPHA : Bool = true;
+		@const var USE_NORMAL_FADE : Bool;
 
 
 		@global var depthMap : Channel;
 		@global var depthMap : Channel;
 
 
 		@param var fadePower : Float;
 		@param var fadePower : Float;
 		@param var fadeStart : Float;
 		@param var fadeStart : Float;
 		@param var fadeEnd : Float;
 		@param var fadeEnd : Float;
-		@param var emissive : Float;
 
 
-		@param var colorTexture : Sampler2D;
+		@param var normalFadeStart : Float;
+		@param var normalFadeEnd : Float;
+
 
 
 		var calculatedUV : Vec2;
 		var calculatedUV : Vec2;
-		var pixelColor : Vec4;
+		var transformedTangent : Vec4;
+		var transformedNormal : Vec3;
 		var pixelTransformedPosition : Vec3;
 		var pixelTransformedPosition : Vec3;
 		var projectedPosition : Vec4;
 		var projectedPosition : Vec4;
-		var localPos : Vec3;
+		var pixelColor : Vec4;
 		var fadeFactor : Float;
 		var fadeFactor : Float;
 
 
-		function outsideBounds() : Bool {
+		function normalFade(worldNormal: Vec3) {
+			var z = normalize(vec3(0,0,1) * global.modelView.mat3());
+			var angle = 1 - abs(acos(z.dot(worldNormal)) / PI);
+			var f = saturate((angle - normalFadeStart) / (normalFadeEnd - normalFadeStart));
+			fadeFactor *= f;
+		}
+
+		function getWorlPos( pos : Vec2 ) : Vec3{
+			var depth = depthMap.get(screenToUv(pos)).r;
+			var ruv = vec4( pos, depth, 1 );
+			var wpos = ruv * camera.inverseViewProj * global.modelViewInverse;
+			var result = (wpos.xyz / wpos.w);
+			return result;
+		}
+
+		function getWorldNormal() : Vec3 {
+			var screenPos = projectedPosition.xy / projectedPosition.w;
+			var worldPos = getWorlPos(screenPos);
+			var ddx = worldPos - getWorlPos(screenPos + vec2(global.pixelSize.x, 0));
+			var ddy = worldPos - getWorlPos(screenPos + vec2(0, global.pixelSize.y));
+			return normalize(cross(ddy, ddx));
+		}
+
+		function outsideBounds(localPos : Vec3) : Bool {
 			return ( localPos.x > 0.5 || localPos.x < -0.5 || localPos.y > 0.5 || localPos.y < -0.5 || localPos.z > 0.5 || localPos.z < -0.5 );
 			return ( localPos.x > 0.5 || localPos.x < -0.5 || localPos.y > 0.5 || localPos.y < -0.5 || localPos.z > 0.5 || localPos.z < -0.5 );
 		}
 		}
 
 
+	}
+}
+
+class DecalOverlay extends BaseDecal {
+	static var SRC = {
+
+
+		var output : {
+			color : Vec4
+		};
+
+		@const var CENTERED : Bool;
+		@const var GAMMA_CORRECT : Bool;
+		@const var AUTO_ALPHA : Bool = true;
+
+		@param var emissive : Float;
+
+		@param var colorTexture : Sampler2D;
+
+
 		function __init__fragment() {
 		function __init__fragment() {
+		}
+
+		function fragment() {
+
 			{
 			{
 				var matrix = camera.inverseViewProj * global.modelViewInverse;
 				var matrix = camera.inverseViewProj * global.modelViewInverse;
 				var screenPos = projectedPosition.xy / projectedPosition.w;
 				var screenPos = projectedPosition.xy / projectedPosition.w;
@@ -51,19 +95,23 @@ class DecalOverlay extends hxsl.Shader {
 				var ppos = ruv * camera.inverseViewProj;
 				var ppos = ruv * camera.inverseViewProj;
 
 
 				pixelTransformedPosition = ppos.xyz / ppos.w;
 				pixelTransformedPosition = ppos.xyz / ppos.w;
-				localPos = (wpos.xyz / wpos.w);
+				var localPos = (wpos.xyz / wpos.w);
 				calculatedUV = localPos.xy;
 				calculatedUV = localPos.xy;
 				fadeFactor = 1 - clamp( pow( max( 0.0, abs(localPos.z * 2) - fadeStart) / (fadeEnd - fadeStart), fadePower), 0, 1);
 				fadeFactor = 1 - clamp( pow( max( 0.0, abs(localPos.z * 2) - fadeStart) / (fadeEnd - fadeStart), fadePower), 0, 1);
 
 
 				if( CENTERED )
 				if( CENTERED )
 					calculatedUV += 0.5;
 					calculatedUV += 0.5;
 
 
-				if(	outsideBounds() )
+				if(	outsideBounds(localPos) )
 					discard;
 					discard;
 			}
 			}
-		}
 
 
-		function fragment() {
+
+			if(USE_NORMAL_FADE) {
+				var worldNormal = getWorldNormal();
+				normalFade(worldNormal);
+			}
+
 			var color = colorTexture.get(calculatedUV);
 			var color = colorTexture.get(calculatedUV);
 			pixelColor.rgb *= color.rgb;
 			pixelColor.rgb *= color.rgb;
 			if( GAMMA_CORRECT ) pixelColor.rgb *= pixelColor.rgb;
 			if( GAMMA_CORRECT ) pixelColor.rgb *= pixelColor.rgb;
@@ -80,20 +128,10 @@ class DecalOverlay extends hxsl.Shader {
 	}
 	}
 }
 }
 
 
-class DecalPBR extends hxsl.Shader {
+class DecalPBR extends BaseDecal {
 
 
 	static var SRC = {
 	static var SRC = {
 
 
-		@global var global : {
-			var pixelSize : Vec2;
-			@perObject var modelView : Mat4;
-			@perObject var modelViewInverse : Mat4;
-		};
-
-		@global var camera : {
-			var inverseViewProj : Mat4;
-		};
-
 		var output : {
 		var output : {
 			albedoStrength : Float,
 			albedoStrength : Float,
 			normalStrength : Float,
 			normalStrength : Float,
@@ -110,27 +148,13 @@ class DecalPBR extends hxsl.Shader {
 		@param var pbrStrength : Float;
 		@param var pbrStrength : Float;
 		@param var emissiveStrength : Float;
 		@param var emissiveStrength : Float;
 
 
-		@global var depthMap : Channel;
-
 		@param var normal : Vec3;
 		@param var normal : Vec3;
 		@param var tangent : Vec3;
 		@param var tangent : Vec3;
 
 
-		@param var fadePower : Float;
-		@param var fadeStart : Float;
-		@param var fadeEnd : Float;
-
 		@param var albedoTexture : Sampler2D;
 		@param var albedoTexture : Sampler2D;
 		@param var normalTexture : Sampler2D;
 		@param var normalTexture : Sampler2D;
 		@param var pbrTexture : Sampler2D;
 		@param var pbrTexture : Sampler2D;
 
 
-		var calculatedUV : Vec2;
-		var transformedTangent : Vec4;
-		var transformedNormal : Vec3;
-		var pixelTransformedPosition : Vec3;
-		var projectedPosition : Vec4;
-		var pixelColor : Vec4;
-		var fadeFactor : Float;
-
 
 
 		function __init__vertex() {
 		function __init__vertex() {
 			transformedNormal = (normal * global.modelView.mat3()).normalize();
 			transformedNormal = (normal * global.modelView.mat3()).normalize();
@@ -142,51 +166,39 @@ class DecalPBR extends hxsl.Shader {
 			output.normalStrength = USE_NORMAL ? normalStrength * pixelColor.a * fadeFactor : 0.0;
 			output.normalStrength = USE_NORMAL ? normalStrength * pixelColor.a * fadeFactor : 0.0;
 			output.pbrStrength = pbrStrength * pixelColor.a * fadeFactor;
 			output.pbrStrength = pbrStrength * pixelColor.a * fadeFactor;
 			output.emissiveStrength = emissiveStrength * pixelColor.a * fadeFactor;
 			output.emissiveStrength = emissiveStrength * pixelColor.a * fadeFactor;
+		}
+
 
 
+		function fragment() {
 			{
 			{
-				var matrix = camera.inverseViewProj * global.modelViewInverse;
+				var matrix = camera.inverseViewProj;
 				var screenPos = projectedPosition.xy / projectedPosition.w;
 				var screenPos = projectedPosition.xy / projectedPosition.w;
+
 				var depth = depthMap.get(screenToUv(screenPos));
 				var depth = depthMap.get(screenToUv(screenPos));
 				var ruv = vec4( screenPos, depth, 1 );
 				var ruv = vec4( screenPos, depth, 1 );
 				var wpos = ruv * matrix;
 				var wpos = ruv * matrix;
 
 
 				var localPos = (wpos.xyz / wpos.w);
 				var localPos = (wpos.xyz / wpos.w);
-				calculatedUV = localPos.xy;
-				fadeFactor = 1 - clamp( pow( max( 0.0, abs(localPos.z * 2) - fadeStart) / (fadeEnd - fadeStart), fadePower), 0, 1);
-
-				if( CENTERED )
-					calculatedUV += 0.5;
-
 				if(	outsideBounds(localPos) )
 				if(	outsideBounds(localPos) )
 					discard;
 					discard;
-			}
-		}
 
 
-		function getWorlPos( pos : Vec2 ) : Vec3{
-			var depth = depthMap.get(screenToUv(pos)).r;
-			var ruv = vec4( pos, depth, 1 );
-			var wpos = ruv * camera.inverseViewProj;
-			var result = (wpos.xyz / wpos.w);
-			return result;
-		}
-
-		function outsideBounds( localPos : Vec3 ) : Bool {
-			return ( localPos.x > 0.5 || localPos.x < -0.5 || localPos.y > 0.5 || localPos.y < -0.5 || localPos.z > 0.5 || localPos.z < -0.5 );
-		}
+				calculatedUV = localPos.xy;
+				fadeFactor = 1 - clamp( pow( max( 0.0, abs(localPos.z * 2) - fadeStart) / (fadeEnd - fadeStart), fadePower), 0, 1);
+			}
 
 
-		function fragment() {
+			if( CENTERED )
+				calculatedUV += 0.5;
 
 
 			if( USE_ALBEDO ) {
 			if( USE_ALBEDO ) {
 				var albedo = albedoTexture.get(calculatedUV);
 				var albedo = albedoTexture.get(calculatedUV);
 				pixelColor *= albedo;
 				pixelColor *= albedo;
 			}
 			}
 
 
+			var worldNormal = vec3(0);
+			if(USE_NORMAL || USE_NORMAL_FADE)
+				worldNormal = getWorldNormal();
+
 			if( USE_NORMAL ) {
 			if( USE_NORMAL ) {
-				var screenPos = projectedPosition.xy / projectedPosition.w;
-				var worldPos = getWorlPos(screenPos);
-				var ddx = worldPos - getWorlPos(screenPos + vec2(global.pixelSize.x, 0));
-				var ddy = worldPos - getWorlPos(screenPos + vec2(0, global.pixelSize.y));
-				var worldNormal = normalize(cross(ddy, ddx));
 				var worldTangent = cross(worldNormal, vec3(0,1,0));
 				var worldTangent = cross(worldNormal, vec3(0,1,0));
 				var normal = normalTexture.get(calculatedUV).rgba;
 				var normal = normalTexture.get(calculatedUV).rgba;
 				var n = worldNormal;
 				var n = worldNormal;
@@ -195,6 +207,13 @@ class DecalPBR extends hxsl.Shader {
 				var tanY = n.cross(tanX) * -1;
 				var tanY = n.cross(tanX) * -1;
 				transformedNormal = (nf.x * tanX + nf.y * tanY + nf.z * n).normalize();
 				transformedNormal = (nf.x * tanX + nf.y * tanY + nf.z * n).normalize();
 			}
 			}
+
+			if(USE_NORMAL_FADE) {
+				var z = vec3(0,0,1) * global.modelView.mat3();
+				var angle = acos(z.dot(worldNormal)) / PI;
+				fadeFactor = 1;
+				pixelColor = vec4(1);
+			}
 		}
 		}
 	};
 	};