2
0
Эх сурвалжийг харах

Added Particle inputs in shadergraph

Clement Espeute 1 жил өмнө
parent
commit
07d9f6f3e4

+ 38 - 1
hide/view/shadereditor/ShaderEditor.hx

@@ -35,9 +35,10 @@ class PreviewShaderBase extends hxsl.Shader {
 			var position : Vec2;
 		};
 
+
 		@global var camera : {
 			var viewProj : Mat4;
-		}
+		};
 
 		var relativePosition : Vec3;
 		var transformedPosition : Vec3;
@@ -54,6 +55,37 @@ class PreviewShaderBase extends hxsl.Shader {
 			projectedPosition = vec4(input.position, 0.0, 0.0);
 			fakeNormal = vec3(0,0,-1);
 			transformedNormal = vec3(0,0,-1);
+
+
+		}
+
+
+	}
+}
+
+class PreviewShaderParticle extends hxsl.Shader {
+	static var SRC = {
+
+		@global var global : {
+			var time : Float;
+		};
+
+		var particleRandom : Float;
+        var particleLifeTime : Float;
+        var particleLife : Float;
+
+		function __init__() {
+			particleLife = mod(global.time, 1.0);
+			particleLifeTime = 1.0;
+			particleRandom = hash12(vec2(floor(global.time)));
+		}
+
+		function hash12(p: Vec2) : Float
+		{
+			p = sign(p)*(floor(abs(p))+floor(fract(abs(p))*1000.0)/1000.0);
+			var p3  = fract(vec3(p.xyx) * .1031);
+			p3 += dot(p3, p3.yzx + 33.33);
+			return fract((p3.x + p3.y) * p3.z);
 		}
 	}
 }
@@ -86,6 +118,7 @@ class Preview extends h2d.Bitmap {
 		this.blendMode = None;
 		var shaderBase = new PreviewShaderBase();
 		addShader(shaderBase);
+		addShader(new PreviewShaderParticle());
 		var props = new h3d.shader.pbr.PropsValues();
 		addShader(props);
 	}
@@ -515,6 +548,10 @@ class ShaderEditor extends hide.view.Graph {
 			var mesh = new h3d.scene.Mesh(sp);
 			obj = mesh;
 		}
+		for (m in obj.getMaterials()) {
+			var sh = new PreviewShaderParticle();
+			m.mainPass.addShader(sh);
+		}
 		if( prefabObj == null )
 			sceneEditor.scene.s3d.addChild(obj);
 		sceneEditor.resetCamera(1.05);

+ 4 - 4
hrt/shader/BaseEmitter.hx

@@ -12,7 +12,7 @@ class BaseEmitter extends hxsl.Shader {
 
         @const @param var billboardMode : Bool;
 
-        
+
         // Each particle as a random value asigned on spawn
         var particleRandom : Float;
         var particleLifeTime : Float;
@@ -33,15 +33,15 @@ class BaseEmitter extends hxsl.Shader {
                     vec4(camera.view[0].z, camera.view[1].z, camera.view[2].z, global.modelView[2].w),
                     vec4(0, 0, 0, 1)
                 );
-    
-                // scale 
+
+                // scale
                 newModelView = mat4(
                     vec4(length(global.modelView[0].xyz), 0.0, 0.0, 0.0),
                     vec4(0.0, length(global.modelView[1].xyz), 0.0, 0.0),
                     vec4(0.0, 0.0, length(global.modelView[2].xyz), 0.0),
                     vec4(0.0, 0.0, 0.0, 1.0)
                 ) * newModelView;
-    
+
                 transformedPosition = relativePosition * newModelView.mat3x4();
                 transformedNormal = (input.normal * newModelView.mat3()).normalize();
             }

+ 97 - 0
hrt/shgraph/ShaderParticleInput.hx

@@ -0,0 +1,97 @@
+package hrt.shgraph;
+
+using hxsl.Ast;
+
+@name("Particle Inputs")
+@description("Particle specific shader inputs")
+@group("Property")
+@color("#0e8826")
+class ShaderParticleInputs extends ShaderNode {
+	@prop("Variable") public var variable : String = "life";
+
+	// override public function getOutput(key : String) : TVar {
+	// 	return variable;
+	// }
+
+	// override public function build(key : String) : TExpr {
+	// 	return null;
+	// }
+
+	public function new(variable = "life") {
+		this.variable = variable;
+	}
+
+	override public function getAliases(name: String, group: String, description: String) {
+		var aliases = [];
+		for (key => input in hrt.shgraph.ShaderParticleInputs.availableInputs) {
+			aliases.push({
+				name : name + " - " + input.display,
+				group: group,
+				description: description,
+				args: [key],
+			});
+		}
+		return aliases;
+	}
+
+
+	override function getShaderDef(domain: ShaderGraph.Domain, getNewIdFn : () -> Int, ?inputTypes: Array<Type>):hrt.shgraph.ShaderGraph.ShaderNodeDef {
+		var pos : Position = {file: "", min: 0, max: 0};
+
+		var variable : ShaderNode.VariableDecl = availableInputs.get(this.variable);
+		if (variable == null)
+			throw "Unknown input variable " + this.variable;
+
+		var inVar : TVar = Reflect.copy(variable.v);
+		inVar.id = getNewIdFn();
+		var output : TVar = {name: "output", id: getNewIdFn(), type: variable.v.type, kind: Local, qualifiers: []};
+		var finalExpr : TExpr = {e: TBinop(OpAssign, {e:TVar(output), p:pos, t:output.type}, {e: TVar(inVar), p: pos, t: output.type}), p: pos, t: output.type};
+
+		return {expr: finalExpr, inVars: [{v:inVar, internal: true, isDynamic: false}], outVars:[{v:output, internal: false, isDynamic: false}], externVars: [], inits: []};
+	}
+
+	override function loadProperties(props:Dynamic) {
+		super.loadProperties(props);
+		var ivar : ShaderNode.VariableDecl = availableInputs.get(this.variable);
+		if (ivar == null) {
+			for (k => v in availableInputs) {
+				variable = k;
+				break;
+			}
+		}
+	}
+
+	public static var availableInputs : Map<String, ShaderNode.VariableDecl> = [
+		"life" => {display: "Particle Life", v: { parent: null, id: 0, kind: Local, name: "particleLife", type: TFloat }},
+		"lifetime" => {display: "Particle Life Time", v: { parent: null, id: 0, kind: Local, name: "particleLifeTime", type: TFloat }},
+		"random" => {display: "Particle Random", v: { parent: null, id: 0, kind: Local, name: "particleRandom", type: TFloat }},
+	];
+
+	#if editor
+	override public function getPropertiesHTML(width : Float) : Array<hide.Element> {
+		var elements = super.getPropertiesHTML(width);
+		var element = new hide.Element('<div style="width: 120px; height: 30px"></div>');
+		element.append(new hide.Element('<select id="variable"></select>'));
+
+		if (variable == null) {
+			variable = "position";
+		}
+
+		var input = element.children("select");
+		var indexOption = 0;
+		for (k => variable in availableInputs) {
+			input.append(new hide.Element('<option value="${k}">${variable.display}</option>'));
+		}
+		input.val(variable);
+
+		input.on("change", function(e) {
+			variable = input.val();
+		});
+
+		elements.push(element);
+
+		return elements;
+	}
+	#end
+
+}