Game Development Stack Exchange is a question and answer site for professional and independent game developers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm trying to create a simple burn shader. See here for more info on the method I'm using. However, I don't get why replacing the smoothstep with a lerp results in completely different results. Am I missing something from my knowledge of maths? As far as I know they should return similar values given the same parameters.

// clips materials, using an image as guidance.
// use clouds or random noise as the slice guide for best results.
Shader "Custom/Dissolving" {
Properties {
  _MainTex ("Texture (RGB)", 2D) = "white" {}
  _BorderTex ("Border Texture (RGBA)", 2D) = "white" {}

  _EdgeColor ("Edge Color", Color) = (1,0,0)
  _EdgeSize ("Edge Size", float) = 0.1

  _SliceGuide ("Slice Guide (RGB)", 2D) = "white" {}
  _SliceAmount ("Slice Amount", Range(0.0, 1)) = 0.2

  [MaterialToggle] UseClipInstruction ("Use Clip Instruction", Float) = 0
SubShader {
  Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
  //Cull Off
  Blend SrcAlpha OneMinusSrcAlpha 

  //if you're not planning on using shadows, remove "addshadow" for better performance
  #pragma surface surf Lambert alpha addshadow

  struct Input {
      float2 uv_MainTex : TEXCOORD0;
      float2 uv_SliceGuide : TEXCOORD1;
      float _SliceAmount;

  sampler2D _MainTex;
  sampler2D _BorderTex;
  sampler2D _SliceGuide;
  half _SliceAmount;
  half _EdgeSize;
  half3 _EdgeColor;

  void surf (Input IN, inout SurfaceOutput o) {

    //Green is a good color for estimating grayscale values
    half fragSliceValue = tex2D(_SliceGuide, IN.uv_SliceGuide).g;

    #ifdef UseClipInstruction
    clip(fragSliceValue - _SliceAmount);
    //TODO: look for an alternative to this
    if (fragSliceValue - _SliceAmount<0)

    half rampX = smoothstep(_SliceAmount,_SliceAmount + _EdgeSize, fragSliceValue);
    half3 ramp = tex2D(_BorderTex,half2( rampX,0) ) * _EdgeColor.rgb;
    o.Emission = ramp * (1-rampX);

    o.Albedo = tex2D(_MainTex,IN.uv_MainTex);
Fallback "Diffuse"

Left is the result of smoothstep (the provided code), right is what happens when I replace smooth with lerp.

Smoothstep Lerp

share|improve this question
up vote 6 down vote accepted

They are very different:

smoothstep(x, y, z);

basically does saturate((z-x)/(y-x)) and then smoothes the result to start and end smoothly. The result always lies between 0 and 1.

lerp(x, y, z);

returns z*y+(1-z)*x As long as x lies between 0 and 1 the result lies between x and y.

What you want is saturate((z-x)/(y-x)) which gives you the same range as smoothstep but without the smoothing.

share|improve this answer
Thanks. I've seen lerp and smoothstep used interchangeably in a lot of implementations and the documentation wasn't clear on the returned results. – Pedro Caetano Feb 4 '14 at 16:55

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.