5
\$\begingroup\$

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 

  CGPROGRAM
  //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) {
    o.Alpha=1;

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


    #ifdef UseClipInstruction
    clip(fragSliceValue - _SliceAmount);
    #else
    //TODO: look for an alternative to this
    if (fragSliceValue - _SliceAmount<0)
        o.Alpha=0;
    #endif

    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);
  }
  ENDCG
} 
Fallback "Diffuse"
}

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

Smoothstep Lerp

\$\endgroup\$

1 Answer 1

6
\$\begingroup\$

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.

\$\endgroup\$
1
  • \$\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\$
    – PeeC
    Commented Feb 4, 2014 at 16:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .