Smoothly transitioning from one texture to another back-and-forth in-game

Noelle

L1: Registered
Jan 29, 2022
4
0
I'm trying to recreate an effect seen in Deltarune in a TF2 map - to be more specific, the scene where Kris and Susie first encounter the closet (see here: https://imgur.com/a/EZ6gOND )

The door opens with a sound effect, then music begins to play and the colours gradually shift from yellow/red to purple/blue.

So far I managed to get the sound effect, the door opening and the music working
(see here https://imgur.com/a/12J6ktW ) but I'm unsure on how to tackle the texturework.

For specifics, I'm using a logic_auto entity with an OnMultiNewRound Output to achieve what I want to do. I haven't created the shifted textures yet, as I'm unsure if I would need one vtf with both textures, two seperate vtf's with something that allows a gradual shift between them, or something else.

I found an entity called env_texturetoggle ( https://developer.valvesoftware.com/wiki/Env_texturetoggle ), which says that it only works on brushes with "the ToggleTexture proxy defined and pointing to an animated VTF file with at least two frames.", which I understand what it means, but I don't understand how I would implement it for this situation.

There's a list of related material proxies here ( https://developer.valvesoftware.com/wiki/List_Of_Material_Proxies#Texture_manipulation ) which might be helpful!

Thank you!
 
Last edited:

fubarFX

The "raw" in "nodraw"
aa
Jun 1, 2009
1,721
1,985
So, you can make a material pulse like that by using proxies and the sine function, you may be familiar with the $color vmt parameters, it allows us to tint materials.

Code:
So, you can make a material pulse like that by using proxies and the sine function

"lightmappedGeneric"
{
    "$basetexture" "..."
 
    "$color" "[1 1 0.5]"
 
    "Proxies"
    {
        "Sine"
        {
            "sineperiod" "6"
            "resultVar" "$color[0]"
        }
        "Sine"
        {
            "sineperiod" "6"
            "resultVar" "$color[1]"
        }
        "Sine"
        {
            "sineperiod" "6"
            "sinemin" "0.5"
            "sinemax" "1"
            "resultVar" "$color[2]"
        }
    } 
}

You have a sine function to oscillate each components of RGB separately. in this example,
- both R and B oscillate from 0 to 1.
- B oscillates between 0.5 and 1, see "sinemin/sinemax".
- "sineperiod" controls how fast you material will pulse.

You will still need something like env_texture toggle to swap between the pulsing vmt and non-pulsing vmt but that's always a little jank. If you can, I always recommend using models and using input to switch their skin.
 

Noelle

L1: Registered
Jan 29, 2022
4
0
So, you can make a material pulse like that by using proxies and the sine function, you may be familiar with the $color vmt parameters, it allows us to tint materials.

Code:
So, you can make a material pulse like that by using proxies and the sine function

"lightmappedGeneric"
{
    "$basetexture" "..."

    "$color" "[1 1 0.5]"

    "Proxies"
    {
        "Sine"
        {
            "sineperiod" "6"
            "resultVar" "$color[0]"
        }
        "Sine"
        {
            "sineperiod" "6"
            "resultVar" "$color[1]"
        }
        "Sine"
        {
            "sineperiod" "6"
            "sinemin" "0.5"
            "sinemax" "1"
            "resultVar" "$color[2]"
        }
    }
}

You have a sine function to oscillate each components of RGB separately. in this example,
- both R and B oscillate from 0 to 1.
- B oscillates between 0.5 and 1, see "sinemin/sinemax".
- "sineperiod" controls how fast you material will pulse.

You will still need something like env_texture toggle to swap between the pulsing vmt and non-pulsing vmt but that's always a little jank. If you can, I always recommend using models and using input to switch their skin.

Thank you, I'm wondering: how would I make the walls/floors into models? would they still function as walls and stuff?
 

fubarFX

The "raw" in "nodraw"
aa
Jun 1, 2009
1,721
1,985
Thank you, I'm wondering: how would I make the walls/floors into models? would they still function as walls and stuff?
Models can have collision, but it's a separate invisible model. Alternatively you can simply use nodraw brushes to act as collision.
 

Da Spud Lord

Occasionally I make maps
aa
Mar 23, 2017
1,338
996
So, you can make a material pulse like that by using proxies and the sine function, you may be familiar with the $color vmt parameters, it allows us to tint materials.

Code:
So, you can make a material pulse like that by using proxies and the sine function

"lightmappedGeneric"
{
    "$basetexture" "..."

    "$color" "[1 1 0.5]"

    "Proxies"
    {
        "Sine"
        {
            "sineperiod" "6"
            "resultVar" "$color[0]"
        }
        "Sine"
        {
            "sineperiod" "6"
            "resultVar" "$color[1]"
        }
        "Sine"
        {
            "sineperiod" "6"
            "sinemin" "0.5"
            "sinemax" "1"
            "resultVar" "$color[2]"
        }
    }
}

You have a sine function to oscillate each components of RGB separately. in this example,
- both R and B oscillate from 0 to 1.
- B oscillates between 0.5 and 1, see "sinemin/sinemax".
- "sineperiod" controls how fast you material will pulse.

You will still need something like env_texture toggle to swap between the pulsing vmt and non-pulsing vmt but that's always a little jank. If you can, I always recommend using models and using input to switch their skin.
env_texturetoggle does not let you toggle between VMTs, you can only switch between different frames in a single VMT/VTF.

For something like this, I would recommend material_modify_control, which allows much greater control over materials by letting you manipulate nearly any material variable (not just the frame), and even having a built-in linear interpolation function which would be perfect for a crossfade. You could either create all the intermediate frames of the animation manually, create an animated texture using them, and use material_modify_control to activate the animation; or if you're just manipulating color, use three material_modify_control entities linked to three material variables that manipulate the $color of the material, like this:
Code:
"LightmappedGeneric" {
    $basetexture "foo/bar"
    $color "[1 1 1]"
   
    // Can't manipulate the $color variable directly since its an array,
    // instead create individual material variables for each value in $color.
    // You'll need one material_modify_control for each of these.
    $color_red 1
    $color_green 1
    $color_blue 1
  
    Proxies {
        // Copy the values from our custom variables into the $color variable
        Equals {
            srcVar1 "$color_red"
            resultVar "$color[0]"
        }
        Equals {
            srcVar1 "$color_green"
            resultVar "$color[1]"
        }
        Equals {
            srcVar1 "$color_blue"
            resultVar "$color[2]"
        }
      
        MaterialModify {
            "dummy" 0
        }
    }
}
Both of these methods will work without creating a model for the material.