Nicolas Cannasse 8 лет назад
Родитель
Сommit
8854396323
1 измененных файлов с 205 добавлено и 0 удалено
  1. 205 0
      samples/Pbr.hx

+ 205 - 0
samples/Pbr.hx

@@ -0,0 +1,205 @@
+
+class PbrShader extends hxsl.Shader {
+
+	static var SRC = {
+
+		@:import h3d.shader.BaseMesh;
+
+		@param var exposure : Float;
+
+		@param var dirLight : Vec3;
+
+		@const var specularMode : Bool;
+		@param var specularPower : Float;
+
+		@param var roughness : Float;
+
+		function fragment() {
+
+			var color = pixelColor.rgb;
+
+			var dirLight = (-dirLight).normalize();
+			var normal = transformedNormal.normalize();
+			var view = (camera.position - transformedPosition).normalize();
+
+
+			var lambert = dirLight.dot(normal).max(0.);
+
+			if( specularMode ) {
+
+				var r = reflect(-dirLight, normal).normalize();
+				var specValue = r.dot(view).max(0.).pow(specularPower);
+				color *= (lambert + specValue);
+
+			} else {
+
+				color *= lambert;
+
+
+				var alpha = roughness.pow(2);
+
+				// GGX (Trowbridge-Reitz)
+
+				// var D = alpha.pow(2) / (PI * ( n.dot(m).pow(2) * (alpha.pow(2) - 1.) + 1).pow(2));
+
+
+				// reinhard tonemapping
+				color *= exp(exposure);
+				color = color / (color + vec3(1.));
+
+				// gamma correct
+				color = color.pow(vec3(1 / 2.2));
+
+			}
+
+
+			pixelColor.rgb = color;
+		}
+
+	}
+
+	public function new() {
+		super();
+		exposure = 0;
+		specularMode = true;
+		specularPower = 40;
+		dirLight.set(0.5, -0.5, -1);
+	}
+
+}
+
+class Pbr extends hxd.App {
+
+	var fui : h2d.Flow;
+	var cameraRot = Math.PI / 4;
+	var cameraDist = 5.5;
+	var font : h2d.Font;
+
+	override function init() {
+
+		font = hxd.res.DefaultFont.get();
+
+		var sp = new h3d.prim.Sphere(1, 128, 128);
+		sp.addNormals();
+		sp.addUVs();
+		var sphere = new h3d.scene.Mesh(sp, s3d);
+		var shader = sphere.material.mainPass.addShader(new PbrShader());
+
+		fui = new h2d.Flow(s2d);
+		fui.y = 5;
+		fui.verticalSpacing = 5;
+		fui.isVertical = true;
+
+		var g = new h3d.scene.Graphics(s3d);
+		g.lineStyle(1, 0xFF0000);
+		g.moveTo(0, 0, 0);
+		g.lineTo(2, 0, 0);
+		g.lineStyle(1, 0x00FF00);
+		g.moveTo(0, 0, 0);
+		g.lineTo(0, 2, 0);
+		g.lineStyle(1, 0x0000FF);
+		g.moveTo(0, 0, 0);
+		g.lineTo(0, 0, 2);
+		g.lineStyle();
+
+		addCheck("Specular", function() return shader.specularMode, function(b) { trace(b); shader.specularMode = b; });
+		addSlider("Specular Power", 0, 30, function() return shader.specularPower, function(v) shader.specularPower = v);
+		addSlider("Exposure", -3, 3, function() return shader.exposure, function(v) shader.exposure = v);
+
+		s2d.addEventListener(onEvent);
+	}
+
+	function onEvent(e:hxd.Event) {
+		switch( e.kind ) {
+		case EPush:
+			var px = e.relX;
+			s2d.startDrag(function(e2) {
+				switch( e2.kind ) {
+				case EMove:
+					var dx = e2.relX - px;
+					px += dx;
+					cameraRot += dx * 0.01;
+				case ERelease:
+					s2d.stopDrag();
+				default:
+				}
+			});
+		case EWheel:
+			cameraDist *= Math.pow(1.1, e.wheelDelta);
+		default:
+		}
+	}
+
+	function addCheck( text, get : Void -> Bool, set : Bool -> Void ) {
+
+
+		var i = new h2d.Interactive(80, font.lineHeight, fui);
+		i.backgroundColor = 0xFF808080;
+
+		fui.getProperties(i).paddingLeft = 20;
+
+		var t = new h2d.Text(font, i);
+		t.maxWidth = i.width;
+		t.text = text+":"+(get()?"ON":"OFF");
+		t.textAlign = Center;
+
+		i.onClick = function(_) {
+			var v = !get();
+			trace(v);
+			set(v);
+			t.text = text + ":" + (v?"ON":"OFF");
+		};
+		i.onOver = function(_) {
+			t.textColor = 0xFFFFFF;
+		};
+		i.onOut = function(_) {
+			t.textColor = 0xEEEEEE;
+		};
+		i.onOut(null);
+	}
+
+	function addSlider( text, min : Float, max : Float, get : Void -> Float, set : Float -> Void ) {
+		var f = new h2d.Flow(fui);
+
+		f.horizontalSpacing = 5;
+
+		var tf = new h2d.Text(font, f);
+		tf.text = text;
+		tf.maxWidth = 100;
+		tf.textAlign = Right;
+
+		var sli = new h2d.Slider(100, 10, f);
+		sli.minValue = min;
+		sli.maxValue = max;
+		sli.value = get();
+
+		var tf = new h2d.TextInput(font, f);
+		tf.text = "" + hxd.Math.fmt(sli.value);
+		sli.onChange = function() {
+			set(sli.value);
+			tf.text = "" + hxd.Math.fmt(sli.value);
+			f.needReflow = true;
+		};
+		tf.onChange = function() {
+			var v = Std.parseFloat(tf.text);
+			if( Math.isNaN(v) ) return;
+			sli.value = v;
+			set(v);
+		};
+	}
+
+	override function update(dt:Float) {
+		s3d.camera.pos.set(Math.cos(cameraRot) * cameraDist, Math.sin(cameraRot) * cameraDist, cameraDist * 2 / 3);
+	}
+
+	static function main() {
+		#if hl
+		@:privateAccess {
+			hxd.System.windowWidth = 1280;
+			hxd.System.windowHeight = 800;
+		}
+		#end
+		new Pbr();
+	}
+
+}