Преглед изворни кода

Add distortion
Update decal

ShiroSmith пре 6 година
родитељ
комит
282a264c38

+ 6 - 0
h3d/mat/PbrMaterial.hx

@@ -6,6 +6,7 @@ package h3d.mat;
 	var Overlay = "Overlay";
 	var Decal = "Decal";
 	var BeforeTonemapping = "BeforeTonemapping";
+	var Distortion = "Distortion";
 }
 
 @:enum abstract PbrBlend(String) {
@@ -99,6 +100,9 @@ class PbrMaterial extends Material {
 			var e = mainPass.getShader(h3d.shader.Emissive);
 			if( e == null ) e = mainPass.addShader(new h3d.shader.Emissive(props.emissive));
 			e.emissive = props.emissive;
+		case Distortion:
+			mainPass.setPassName("Distortion");
+			mainPass.depthWrite = false;
 		case Overlay:
 			mainPass.setPassName("overlay");
 		case Decal:
@@ -226,6 +230,8 @@ class PbrMaterial extends Material {
 						<option value="BeforeTonemapping">Before Tonemapping</option>
 						<option value="Albedo">Albedo</option>
 						<option value="Overlay">Overlay</option>
+						<option value="Distortion">Distortion</option>
+						<option value="Decal">Decal</option>
 					</select>
 				</dd>
 				<dt>Blend</dt>

+ 14 - 5
h3d/scene/pbr/Renderer.hx

@@ -61,6 +61,7 @@ class Renderer extends h3d.scene.Renderer {
 	public var exposure(get,set) : Float;
 	public var debugMode = 0;
 
+
 	static var ALPHA : hxsl.Output = Swiz(Value("output.color"),[W]);
 	var output = new h3d.pass.Output("mrt",[
 		Value("output.color"),
@@ -288,16 +289,24 @@ class Renderer extends h3d.scene.Renderer {
 
 		apply(AfterHdr);
 
+		var distortion = allocTarget("distortion", true, 1.0, RGBA16F);
+		distortion.clear(0x000000);
+		setTarget(distortion);
+		draw("Distortion");
+
 		var ldr = allocTarget("ldrOutput");
 		setTarget(ldr);
 		var bloom = ctx.getGlobal("bloom");
 		tonemap.shader.bloom = bloom;
 		tonemap.shader.hasBloom = bloom != null;
-		tonemap.shader.mode = switch( toneMode ) {
-		case Linear: 0;
-		case Reinhard: 1;
-		default: 0;
-		};
+		tonemap.shader.distortion = distortion;
+		tonemap.shader.hasDistortion = distortion != null;
+		tonemap.shader.pixelSize = new Vector(1.0/ctx.engine.width, 1.0/ctx.engine.height);
+		tonemap.shader.mode =	switch( toneMode ) {
+									case Linear: 0;
+									case Reinhard: 1;
+									default: 0;
+								};
 		tonemap.shader.hdrTexture = hdr;
 		tonemap.render();
 

+ 1 - 1
h3d/shader/Emissive.hx

@@ -7,7 +7,7 @@ class Emissive extends hxsl.Shader {
 		@param var emissive : Float;
 
 		function fragment() {
-			pixelColor.rgb += pixelColor.rgb * emissive * pixelColor.a;
+			pixelColor.rgb = max(pixelColor.rgb, pixelColor.rgb + pixelColor.rgb * emissive * pixelColor.a);
 		}
 
 	};

+ 40 - 10
h3d/shader/VolumeDecal.hx

@@ -6,12 +6,17 @@ class VolumeDecal extends hxsl.Shader {
 
 		@:import BaseMesh;
 
+		@const var isCentered : Bool;
 		@global var depthMap : Channel;
 
 		@param var scale : Vec2;
 		@param var normal : Vec3;
 		@param var tangent : Vec3;
-		@const var isCentered : Bool = true;
+
+		@param var min : Vec3;
+		@param var max : Vec3;
+		@param var maxAngle : Float;
+
 		var calculatedUV : Vec2;
 		var transformedTangent : Vec4;
 
@@ -20,23 +25,48 @@ class VolumeDecal extends hxsl.Shader {
 			transformedTangent = vec4((tangent * global.modelView.mat3()).normalize(),1.);
 		}
 
+		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() : Bool {
+			return (pixelTransformedPosition.x < min.x || pixelTransformedPosition.x > max.x ||
+					pixelTransformedPosition.y < min.y || pixelTransformedPosition.y > max.y ||
+			 		pixelTransformedPosition.z < min.z || pixelTransformedPosition.z > max.z );
+		}
+
 		function fragment() {
+
 			var matrix = camera.inverseViewProj * global.modelViewInverse;
 			var screenPos = projectedPosition.xy / projectedPosition.w;
-			var ruv = vec4(
-				screenPos,
-				depthMap.get(screenToUv(screenPos)),
-				1
-			);
+			var depth = depthMap.get(screenToUv(screenPos));
+			var ruv = vec4( screenPos, depth, 1 );
 			var wpos = ruv * matrix;
 			var ppos = ruv * camera.inverseViewProj;
+
+			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));
+			//transformedNormal = worldNormal;
+
+			var angle = acos(dot(worldNormal, normal));
+			if( angle > maxAngle )
+				discard;
+
 			pixelTransformedPosition = ppos.xyz / ppos.w;
 			calculatedUV = scale * (wpos.xy / wpos.w);
-			if( isCentered ) calculatedUV += 0.5;
-			if( min(min(calculatedUV.x, calculatedUV.y), min(1 - calculatedUV.x, 1 - calculatedUV.y)) < 0 )
+
+			if( isCentered )
+				calculatedUV += 0.5;
+
+			if(	outsideBounds() )
 				discard;
 		}
-
 	};
 
 	public function new( objectWidth : Float, objectHeight : Float ) {
@@ -44,6 +74,6 @@ class VolumeDecal extends hxsl.Shader {
 		normal.set(0, 0, 1);
 		tangent.set(1, 0, 0);
 		scale.set(1/objectWidth, 1/objectHeight);
+		isCentered = true;
 	}
-
 }

+ 15 - 0
h3d/shader/pbr/Distortion.hx

@@ -0,0 +1,15 @@
+package h3d.shader.pbr;
+
+class Distortion extends h3d.shader.ScreenShader {
+
+	static var SRC = {
+
+		@param var distortion : Sampler2D;
+
+		function fragment() {
+			var baseUV = calculatedUV;
+			var distortionVal = distortion.get(calculatedUV).rg;
+			calculatedUV = baseUV + distortionVal;
+		}
+	};
+}

+ 28 - 0
h3d/shader/pbr/DistortionAcc.hx

@@ -0,0 +1,28 @@
+package shader;
+
+/* Need a RG16F or RG32F Target*/
+
+class Distortion extends hxsl.Shader {
+
+	static var SRC = {
+
+		@input var input : {
+			var uv : Vec2;
+		};
+
+		@param var distortionDir : Sampler2D;
+		@param var intensity : Float;
+
+		var calculatedUV : Vec2;
+		var pixelColor : Vec4;
+
+		function vertex() {
+			calculatedUV = input.uv;
+		}
+
+		function fragment() {
+			var dir = normalize(((distortionDir.get(calculatedUV).xyz - 0.5) * 2.0)).xy * intensity;
+			pixelColor = vec4(dir, 0, 1);
+		}
+	};
+}

+ 12 - 0
h3d/shader/pbr/ToneMapping.hx

@@ -12,8 +12,18 @@ class ToneMapping extends ScreenShader {
 
 		@const var hasBloom : Bool;
 		@param var bloom : Sampler2D;
+		@const var hasDistortion : Bool;
+		@param var distortion : Sampler2D;
+		@param var pixelSize : Vec2;
 
 		function fragment() {
+
+			if(hasDistortion){
+				var baseUV = calculatedUV;
+				var distortionVal = distortion.get(baseUV).rg;
+				calculatedUV = baseUV + distortionVal ;
+			}
+
 			var color = hdrTexture.get(calculatedUV);
 			if( hasBloom )
 				color += bloom.get(calculatedUV);
@@ -40,6 +50,8 @@ class ToneMapping extends ScreenShader {
 	public function new() {
 		super();
 		exposure = 0;
+		hasDistortion = false;
+		hasBloom = false;
 	}
 
 	function set_exposure(v) {