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


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.

  • \$\begingroup\$ Thanks. I've seen lerp and smoothstep used interchangeably in a lot of implementations and the documentation wasn't clear on the returned results. \$\endgroup\$ – Pedro Caetano Feb 4 '14 at 16:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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