How to evaluate a binary expression tree in hlsl without recursion or a stack

I’m currently working on a dual contouring implementation for which I want to create procedural terrain based on layers of noise. Both, the terrain generation and the mesh creation via dual contouring run on the GPU in compute shaders.

For configurating the terrain generation I previously changed the specific compute shader’s source code itself to generate different layers of FBM noise and combine them with various CSG operations (e.g. union, intersection, difference) to arrive at the final terrain. But this offers very little flexibility, e.g. I cannot change the terrain generation at runtime.

So in order to get more flexiblity for configuring the terrain generation, I’ve started implementing a graph tool (similiar to ShaderLab) using XNode: enter image description here Red (leaf) nodes are operands, grey (internal) nodes are operators (either binary or unary) and the green (root) node is simple the output node. On the GPU side each operator (internal node) equals a function, e.g. a function that creates the output of the noise node.

The idea is that I can visually create a binary expression tree (with additional unary operators), upload it to the GPU using a StructuredBuffer<NoiseGraphNode> where NoiseGraphNode is

struct NoiseGraphNode {     uint leftNodeIndex;     uint rightNodeIndex;     uint nodeType;     uint dataIndex;         // Index used in conjunction with nodeType                              // to access a node's data located in a                              // nodeType-specific StructuredBuffer, e.g.                              // the noise parameters in case of a noise node. }; 

and have that graph evaluated by the GPU’s compute shader for generating the noise that represents the final terrain. Normally such a graph would be evaluated using a recursive approach, something like:

evaluate(node) {      if(node has children){           left_val = evaluate(node->left);           right_val = evaluate(node->right);            // find operation symbol for node and use it as           // val = left_val operation right_val            return val;      }      else {           return node_value;      } } 

Pseudo-code taken from https://stackoverflow.com/questions/10769174/evaluating-expression-trees.

HLSL doesn’t support recursion though! Another way would be to emulate the recursive implementation using a stack and a while loop (after all recursion is leveraging the call stack). But creating a stack structure in HLSL like so

struct NoiseGraphStack {     uint buffer[20];     uint count;      void Push(uint number)     {         buffer[count++] = number;   // Doesn't work because an array reference                                      // cannot be used as an l-value.     }      float Pop()     {         return buffer[--count];     }      static NoiseGraphStack Create()     {         NoiseGraphStack stack;         stack.count = 0;          return stack;     } }; 

doesn’t work either because it requires the while loop to be unrolled which isn’t possible.

Note: The exact error message referred to in the code above is "array reference cannot be used as an l-value; not natively addressable, forcing loop to unroll."

So is it possible to evaluate a binary expression tree without recursion or a stack? Can I perhaps somehow preprocess the necessary steps for evaluating such a tree on the CPU (where I can use recursion just fine) first and linearize them before I send them to the GPU?

Does the Fire Elementa’s Touch attack’s ongoing damage stack with itself? [duplicate]

If a fire elemental uses the Touch attack:

Melee Weapon Attack: +6 to hit, reach 5 ft., one target. Hit: 10 (2d6 + 3) fire damage. If the target is a creature or a flammable object, it ignites. Until a creature takes an action to douse the fire, the target takes 5 (1d10) fire damage at the start of each of its turns.

And then hits a creature twice, how would the emphasized text work? Would the creature have two instances of it and take 2d10 damage at the start of the turn or only one? If they would have it twice would they be able to put both out by dousing the fire?

Do the Fire Elemental’s Fire Form trait’s and Touch attack’s ongoing fire damage stack with each other?

Inspired by the following:

  • Does the Fire Elementa's Touch attack's ongoing damage stack with itself?

I realized that my own answer to that question hinges on the idea of features having the same name, but the Fire Elemental actually has two different features that cause extremely similar effects.

Notably it has the Fire Form trait and the Touch attack which state:

[…] In addition, the elemental can enter a hostile creature’s space and stop there. The first time it enters a creature’s space on a turn, that creature takes 5 (1d10) fire damage and catches fire; until someone takes an action to douse the fire, the creature takes 5 (1d10) fire damage at the start of each of its turns.

[…] If the target is a creature or a flammable object, it ignites. Until a creature takes an action to douse the fire, the target takes 5 (1d10) fire damage at the start of each of its turns.

Do these two ongoing effects stack with each other?

How does the ranger’s DPR stack up against other martial classes?

While there have been many attempts to revise the ranger, the base class offers a lot of ways for the ranger to boost their damage. Paladins can spend a 1st level spell for a 2d8 smite, but ranger’s can spend a 1st level spell for +1d6 extra damage on all weapon attacks for an hour.

I’d like to ask for a comparison of the ranger’s DPR with other martial classes, but particularly the fighter. Some parameters:

  • Characters should be assumed to have max out their attack stat (STR or DEX) as early as possible.
  • Rangers, fighters, and paladins should be assumed to have the Dueling fighting style and using a longsword or a rapier. Other martial classes should use their most effective weapon.
  • No feats.

These restrictions preclude extensive character optimization. Nonetheless, characters should be assumed to be optimizing tactically. A barbarian should be raging, a rogue should be sneak attacking, a paladin should be smiting (although that’s a very limited resource), and a fighter should be action surging when possible. So this might require some comparison of first fight of the day, last fight before a short rest, and last fight before a long rest. Importantly, the ranger should be assumed to be making use of 3rd level subclass damage boosting powers when possible (Colossus Slayer, Slayer’s Prey, etc.) and using Hunter’s Mark whenever they have a 1st level spell slot available.

Comparing DPR at key levels/tiers of play would be helpful.

Do multiple baldric, bane items stack?

Following up on my question about if baldric, bane would grant early access to bane and greater bane for an inquisitor (it does), now I wonder if two such items stack? If you had a baldric, bane and a slotless baldric, bane, would you be considered 10 levels higher for the purposes of bane?

Baldric, Bane

If the wearer is an inquisitor, she is treated as five levels higher when using her bane and greater bane abilities . If the wearer is not an inquisitor, she gains the bane ability of a 5th-level inquisitor, but must first attune a light or one-handed melee weapon to the baldric by hanging it from the cloth for 24 hours, and can only use the bane ability with the attuned weapon. Attuning a new weapon to the baldric ends the attunement for the previous weapon.

Does a buckler stack with the AC from the feat Shielded Gauntlet Master?

The biggest advantage of a buckler is that you keep a hand free while still gaining a shield bonus. You are also able to wear a gauntlet (normal, locked, or spiked) while keeping that hand free. Lets assume that the buckler is a +1 buckler so its providing a +2 shield bonus, and the gauntlet is just a +2.

The feat Shielded Gauntlet Master says

While using Shield Gauntlet Style, you no longer lose your shield bonus to AC when you attack with your gauntlet (or spiked gauntlet) or use it to hold a weapon. In addition, you add your gauntlet’s enhancement bonus to the shield bonus to AC granted by this feat as if it were a shield enhancement bonus.

So, does the bucklers shield bonus stack with the bonus from the feat? Since both would provide +2, is the final shield AC +2 or +4?

Does the racial trait from Innistrad Provincial Origin, Stensia and the feat Tough stack?

The Player’s Handbook feat Tough:

Your hit point maximum increases by an amount equal to twice your level when you gain this feat. Whenever you gain a level thereafter, your hit point maximum increases by an additional 2 hit points

and the Innistrad human provincial origin Stensia racial trait Tough:

Tough. Your hit point maximum increases by 2, and it increases by 2 every time you gain a level.

Seems to have the same name and effect. Do they stack?

Does Unarmored Defense stack with a staff of power and the Bladesong class feature?

I’m playing a level 10 blade singer wizard with one level into barbarian for unarmored defense. I have a +5 Dex modifier, a +5 Int modifier, and a +4 Con modifier. I also have a staff of power that gives +2 to AC.

My total AC would be 4+5+10=19 from Unarmored Defense, +2 from the staff of power, and +5 from the Blade Singer arcane tradition, for a total of 19+2+5= 26 AC. Is my math correct?

Does plant growth’s 8 hour effect stack? [duplicate]

If you cast Plant Growth for its 8-hour version to

[…] enrich the land. All plants in a half-mile radius centered on a point within range become enriched for 1 year. The plants yield twice the normal amount of food when harvested.

and then come back the next day and cast it again the same way for the third time, would the total crops harvested be doubled, and then, quadrupled, and then octupled?
The campaign I am in is measured in years, so the impact of a druid (or in this case, nature cleric) who can spend 8 hours to double a 1/2 mile radius circle of food would be super helpful, but I need to know if I can prioritize one spot to make the growth exponential, vs going and casting in a different spot every day to just have a net double.