Jump to content
The Dark Mod Forums

Recommended Posts

Posted

Every material consists of global keywords and stages.

Stages are classified into ambient stages and interaction stages (diffuse, specular, bump, parallax).
Interaction stages are partitioned into interaction groups. Each group is rendered as single draw call with interaction shader, its stages supply various settings (e.g. diffuse texture is taken from diffuse stage, specular texture from specular stage, etc.).
Ambient stages are all extracted into separate list and rendered in their respective order. But this always happens after all interactions are rendered.

In 2.12 and earlier, interaction groups were detected dynamically during rendering. There was some preprocessing code which was static (sorting stages, adding implicit bumpmap) and some additional detection in rendering code which was dynamic because it checked conditions.

In the recent TDM version (hopefully in 2.13 too), the old approach is replaced with two new ways to detect interaction groups: implicit and explicit. Both ways are fully static and implemented straight during material parsing.

Implicit detection.
We go through stages in their definition order and add each new stage into the last interaction group. If the last interaction group already contains a stage of same type, then we finish that group and start a new one with the current stage. For instance, if we see interaction stages DSBBDDSBSD (abbreviated by first letters), it will get split into [DSB][BD][DSB][SD] groups.

This should work fine for simple materials with one stage of each kind.
It should also work fine for vertex-blended materials because they should have each group starting from bump stage (and hopefully they don't have duplicate diffuse stages).

Explicit detection.
There is new material keyword: interactionSeparator. If at least one such keyword is present in material, then explicit detection is used.

Each interaction group consists of all the stages located between two consecutive interaction separators. The stages before first separator are put into a group too (if any), same applies to the stages after the last separator. Note that disabled stages are ignored during runtime, so it is possible to have several stages of the same kind in an interaction group, as long as at most one of them is enabled at any time.

Explicit approach can be used for non-trivial cases, especially when stages are enabled by condition (like e.g. animated textures).

Posted

Let's consider the case from:

Here is how it looks with explicit interaction groups:

textures/darkmod/map_specific/grass4_dirt_01_blend
{
	qer_editorimage textures/darkmod/nature/grass/grass4_ed
	surftype15
	description "grass"

	// interactionSeparator   --- the one at start is optional
      
	{
		blend diffusemap
		map textures/darkmod/nature/grass/grass4
		vertexColor
	}
	{
		blend bumpmap
		map textures/darkmod/nature/grass/grass4_local
		vertexColor
	}
  
	interactionSeparator
      
	{
		blend diffusemap
		map textures/darkmod/nature/dirt/dry_earth_muddy
		inverseVertexColor
	}
	{
		blend bumpmap
		map textures/darkmod/nature/dirt/dry_earth_muddy_local
		inverseVertexColor
	}
  
	// interactionSeparator   --- the one at end is optional    
}

The separator in the middle is important here, since it splits the stages into two groups.

Note that this specific case should work fine now even without any separators (i.e. with implicit detection).
The implicit partitioning will break first group when it detects second diffuse stage.

  • Thanks 1
Posted

Another example from:

Should now work fine with explicit groups:

Spoiler
water_animatedA
{
	...

	interactionSeparator

	{	
		blend	specularmap
		map _white
		rgb 0.15
	}
	
	{
		if ( (time * 30) % 59 == 0 )
		vertexProgram		heatHazeWithAlphaDepth.vfp
		vertexParm	0	time * 0 , time * 0 // scroll
		vertexParm	1	(( parm6 + 2.5) - (( parm6 || 0) * 2.5)) //magnitude
		fragmentMap	0 	_currentRender
		fragmentMap	1	textures/water_source/water_animatedA/0001.png
		fragmentMap 2 textures/water_source/vp_water
		fragmentMap 3 _currentDepth
	}
	...
	{
		if ( (time * 30) % 59 == 59 )
		vertexProgram		heatHazeWithAlphaDepth.vfp
		vertexParm	0	time * 0 , time * 0 // scroll
		vertexParm	1	(( parm6 + 2.5) - (( parm6 || 0) * 2.5)) //magnitude
		fragmentMap	0 	_currentRender
		fragmentMap	1	textures/water_source/water_animatedA/0060.png
		fragmentMap 2 textures/water_source/vp_water
		fragmentMap 3 _currentDepth
	}

	{
		blend diffusemap
		map textures/water_source/water_cyan
		colored
		RGB 1
	}

	{
		if ( (time * 30) % 59 == 0 )

		blend bumpmap
		map	textures/water_source/water_animatedA/0001.png
	}
  	...
	{
		if ( (time * 30) % 59 == 59 )

		blend bumpmap
		map	textures/water_source/water_animatedA/0060.png
	}

  	interactionSeparator

	{
		forceHighQuality
		blend gl_dst_alpha, gl_one
		CubeMap env/gen1
		texgen reflect
		RGB .15
	}
}


The sequence of stages here is SDBBB...BBB (ignoring ambient stages).
Implicit groups detection will see many bump stages and partition as [SDB][B][B][B]...[B][B][B].

While interaction separators at material start/end are optional in terms of splitting the groups, they do switch from implicit detection to explicit detection --- that's all we need. Since separators are only at start/end, all the stages will get into single group with many bump stages. As long as conditions are correct, we will get exactly one bump stage active at each moment.

  • Like 1
  • stgatilov changed the title to [2.13] Interaction groups in materials: new behavior
Posted

Moved this topic from development forums, since it covers a potentially important behavior change in 2.13.

Luckily, its important is countered by the rarity of such complicated materials.
I hope that this change has not broken existing materials. And even if it had broken any, we will be able to fix them manually...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recent Status Updates

    • JackFarmer

      On a lighter note, thanks to my cat-like reflexes, my superior puzzle skills and my perfect memory, I was able to beat the remastered version of "Tomb Raider: The Last Revelation" in a new superhuman record time of 23 h : 35 m, worship me!
      · 3 replies
    • Goblin of Akenash

      My mapping discord if anyone is interested, its more of a general modding thing rather than just for TDM 
      https://discord.gg/T4Jt4DdmUb

       
      · 0 replies
    • nbohr1more

      2.13 Moddb Article is up: https://www.moddb.com/mods/the-dark-mod/news/the-dark-mod-213-is-here
      · 1 reply
    • snatcher

      Modpack 5.0 released! Introducing the Light Stones.
      · 0 replies
    • Goblin of Akenash

      Goblin-Secrets episode 2 is out now!
       
      · 3 replies
×
×
  • Create New...