ShaderNode.hx 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. package hrt.shgraph;
  2. import Type as HaxeType;
  3. using hxsl.Ast;
  4. import h3d.scene.Mesh;
  5. using Lambda;
  6. using hrt.shgraph.Utils;
  7. import hrt.shgraph.AstTools.*;
  8. import hrt.shgraph.ShaderGraph;
  9. import hrt.shgraph.SgHxslVar.ShaderDefInput;
  10. #if editor
  11. import hide.view.GraphInterface;
  12. #end
  13. class AlphaPreview extends hxsl.Shader {
  14. static var SRC = {
  15. var pixelColor : Vec4;
  16. var screenUV : Vec2;
  17. function fragment() {
  18. var gray_lt = vec3(1.0);
  19. var gray_dk = vec3(229.0) / 255.0;
  20. var scale = 16.0;
  21. var localUV = screenUV * scale;
  22. var checkboard = floor(localUV.x) + floor(localUV.y);
  23. checkboard = fract(checkboard * 0.5) * 2.0;
  24. var alphaColor = vec3(checkboard * (gray_dk - gray_lt) + gray_lt);
  25. pixelColor.rgb = mix(pixelColor.rgb, alphaColor, 1.0 - pixelColor.a);
  26. pixelColor.a = 1.0;
  27. }
  28. }
  29. }
  30. typedef InputInfo = {name: String, type: SgType, ?def: ShaderDefInput};
  31. typedef OutputInfo = {name: String, type: SgType};
  32. typedef VariableDecl = {v: TVar, display: String, ?vertexOnly: Bool};
  33. typedef AliasInfo = {?nameSearch: String, ?nameOverride : String, ?description : String, ?args : Array<Dynamic>, ?group: String};
  34. @:autoBuild(hrt.shgraph.Macros.autoRegisterNode())
  35. @:keepSub
  36. @:keep
  37. class ShaderNode
  38. #if editor
  39. implements hide.view.GraphInterface.IGraphNode
  40. #end
  41. {
  42. public var id : Int;
  43. public var x : Float;
  44. public var y : Float;
  45. public var showPreview : Bool = true;
  46. @prop public var nameOverride : String;
  47. #if editor
  48. // IGraphNode Interface
  49. public function getInfo() : GraphNodeInfo {
  50. var metas = haxe.rtti.Meta.getType(HaxeType.getClass(this));
  51. return {
  52. name: nameOverride ?? (metas.name != null ? metas.name[0] : "undefined"),
  53. inputs: [
  54. for (i in getInputs()) {
  55. var defaultParam = null;
  56. switch (i.def) {
  57. case Const(intialValue):
  58. defaultParam = {
  59. get: () -> Std.string(Reflect.getProperty(defaults, i.name) ?? intialValue),
  60. set: setDefaultParam.bind(i.name),
  61. };
  62. default:
  63. }
  64. {
  65. name: i.name,
  66. color: getTypeColor(i.type),
  67. defaultParam: defaultParam,
  68. }
  69. }
  70. ],
  71. outputs: [
  72. for (o in getOutputs()) {
  73. {
  74. name: o.name,
  75. color: getTypeColor(o.type),
  76. }
  77. }
  78. ],
  79. preview: {
  80. getVisible: () -> showPreview,
  81. setVisible: (b:Bool) -> showPreview = b,
  82. fullSize: false,
  83. },
  84. width: metas.width != null ? metas.width[0] : null,
  85. noHeader: Reflect.hasField(metas, "noheader"),
  86. };
  87. }
  88. static function getTypeColor(type: SgType) : Int {
  89. return switch (type) {
  90. case SgFloat(1):
  91. 0x00ff73;
  92. case SgFloat(2):
  93. 0x5eff00;
  94. case SgFloat(3):
  95. 0xeeff00;
  96. case SgFloat(4):
  97. 0xfc6703;
  98. case SgInt:
  99. 0x00ffea;
  100. case SgSampler:
  101. 0x600aff;
  102. default:
  103. 0xc8c8c8;
  104. }
  105. }
  106. public function getId() : Int {
  107. return id;
  108. }
  109. public function getPos(p : h2d.col.Point) : Void {
  110. p.set(x,y);
  111. }
  112. public function setPos(p : h2d.col.Point) : Void {
  113. x = p.x;
  114. y = p.y;
  115. }
  116. public function getPropertiesHTML(width : Float) : Array<hide.Element> {
  117. return [];
  118. }
  119. public var editor : hide.view.GraphEditor;
  120. public function setDefaultParam(name: String, value: String) {
  121. Reflect.setField(defaults, name, Std.parseFloat(value));
  122. requestRecompile();
  123. }
  124. public function requestRecompile() {
  125. Std.downcast(editor.editor, hide.view.shadereditor.ShaderEditor)?.requestRecompile();
  126. }
  127. #end
  128. public function serializeToDynamic() : Dynamic {
  129. return {
  130. x: x,
  131. y: y,
  132. id: id,
  133. type: std.Type.getClassName(std.Type.getClass(this)),
  134. properties: saveProperties(),
  135. };
  136. }
  137. public static function createFromDynamic(data: Dynamic, graph: ShaderGraph) : ShaderNode {
  138. var type = std.Type.resolveClass(data.type);
  139. var inst = std.Type.createInstance(type, []);
  140. var shaderParam = Std.downcast(inst, ShaderParam);
  141. if (shaderParam != null) {
  142. shaderParam.shaderGraph = graph;
  143. }
  144. inst.x = data.x;
  145. inst.y = data.y;
  146. inst.id = data.id;
  147. inst.connections = [];
  148. inst.loadProperties(data.properties);
  149. return inst;
  150. }
  151. public var defaults : Dynamic = {};
  152. /**
  153. Declare all the inputs this node uses
  154. **/
  155. public function getInputs() : Array<InputInfo> {
  156. return [];
  157. }
  158. /**
  159. Declare all the outputs this node uses
  160. **/
  161. public function getOutputs() : Array<OutputInfo> {
  162. return [];
  163. }
  164. /**
  165. Generate the hxsl expressions and outputs of the node
  166. **/
  167. public function generate(ctx: NodeGenContext) : Void {
  168. throw "generate is not defined for class " + std.Type.getClassName(std.Type.getClass(this));
  169. }
  170. function getDef(name: String, def: Float) {
  171. var value : Any = Reflect.getProperty(defaults, name);
  172. if ( value == null )
  173. return def;
  174. if ( Std.isOfType(value, String) )
  175. return Std.parseFloat(value) ?? def;
  176. return cast(value, Float);
  177. }
  178. public function getAliases(name: String, group: String, description: String) : Array<AliasInfo> {
  179. var cl = HaxeType.getClass(this);
  180. var meta = haxe.rtti.Meta.getType(cl);
  181. var aliases : Array<AliasInfo> = [];
  182. if (meta.alias != null) {
  183. for (a in meta.alias) {
  184. aliases.push({nameOverride: '$a'});
  185. }
  186. }
  187. return aliases;
  188. }
  189. public var connections : Array<ShaderGraph.Connection> = [];
  190. public function setId(id : Int) {
  191. this.id = id;
  192. }
  193. public function loadProperties(props : Dynamic) {
  194. var fields = Reflect.fields(props);
  195. showPreview = props.showPreview ?? true;
  196. nameOverride = props.nameOverride;
  197. for (f in fields) {
  198. if (f == "defaults") {
  199. defaults = Reflect.field(props, f);
  200. }
  201. else {
  202. if (Reflect.hasField(this, f)) {
  203. Reflect.setField(this, f, Reflect.field(props, f));
  204. }
  205. }
  206. }
  207. }
  208. final public function shouldShowPreview() : Bool {
  209. return showPreview && canHavePreview();
  210. }
  211. public function canHavePreview() : Bool {
  212. return true;
  213. }
  214. public function saveProperties() : Dynamic {
  215. var parameters : Dynamic = {};
  216. var thisClass = std.Type.getClass(this);
  217. var fields = std.Type.getInstanceFields(thisClass);
  218. var metas = haxe.rtti.Meta.getFields(thisClass);
  219. var metaSuperClass = haxe.rtti.Meta.getFields(std.Type.getSuperClass(thisClass));
  220. for (f in fields) {
  221. var m = Reflect.field(metas, f);
  222. if (m == null) {
  223. m = Reflect.field(metaSuperClass, f);
  224. if (m == null)
  225. continue;
  226. }
  227. if (Reflect.hasField(m, "prop")) {
  228. var metaData : Array<String> = Reflect.field(m, "prop");
  229. if (metaData == null || metaData.length == 0 || metaData[0] != "macro") {
  230. Reflect.setField(parameters, f, Reflect.getProperty(this, f));
  231. }
  232. }
  233. }
  234. if (Reflect.fields(defaults).length > 0) {
  235. Reflect.setField(parameters, "defaults", defaults);
  236. }
  237. parameters.nameOverride = nameOverride;
  238. parameters.showPreview = showPreview;
  239. return parameters;
  240. }
  241. #if editor
  242. final public function getHTML(width: Float, config: hide.Config) {
  243. var props = getPropertiesHTML(width);
  244. return props;
  245. }
  246. static public var registeredNodes = new Map<String, Class<ShaderNode>>();
  247. static public function register(key : String, cl : Class<ShaderNode>) : Bool {
  248. registeredNodes.set(key, cl);
  249. return true;
  250. }
  251. #end
  252. }