Shader Replacement and Surface Shaders

Hi all.

Using a surface shader as the replacement shader results like if it were applying the normal and bump maps to the whole RenderTexture.

In documentation of Shader Replacement says that

"If replacementTag is not empty, then for each object that would be rendered:
* The real object’s shader is queried for the tag value.
* If it does not have that tag, object is not rendered.
* A subshader is found in the replacement shader that has a given tag with the found value. If no such subshader is found, object is not rendered.
* Now that subshader is used to render the object. "

So I am a bit confused with results.

Can you explain in more detail what you are doing? Screen shots of results, along with an explanation of what you want, will help.

Course Daniel.

It is a puzzle game in which we must join pieces of the same color. Once joined, they disappear. To create the effect for destruction, I am applying a blur and glow by shader replacement. Basically when I want enable the effect of destruction I change the shader of the material for one with a specific tag used in the script attached to the camera.

This is some code of the camera script:

public void OnPreRender()
    {
        if (!enabled || !gameObject.active || !shader)
            return;
        
        //Release effects texture
        if (effectsTexture != null) {
            RenderTexture.ReleaseTemporary (effectsTexture);
            effectsTexture = null;
        }        
        
        //Create effects camera if doesn't exists
        if(!effectsCamera)
        {
            effectsCamera = new GameObject("EffectsCamera", typeof(Camera));            
            effectsCamera.camera.enabled = false;
            effectsCamera.hideFlags = HideFlags.HideAndDontSave;
        }
        
        //Gets effects texture
        Camera auxCam = effectsCamera.camera;
        auxCam.camera.CopyFrom(camera);                        
        auxCam.camera.clearFlags = CameraClearFlags.SolidColor;
        effectsTexture = RenderTexture.GetTemporary(Screen.width, Screen.height,1);
        auxCam.camera.targetTexture = effectsTexture;        
        auxCam.camera.backgroundColor = Color.clear;        
        auxCam.camera.RenderWithShader(shader, "RenderType");                                                                        
    }
    
    
    public void OnRenderImage(RenderTexture source, RenderTexture destination)
    {                    
        RenderTexture buffer = RenderTexture.GetTemporary(source.width, source.height, 0);
        RenderTexture buffer2 = RenderTexture.GetTemporary(source.width, source.height, 0);
        
        // Copy things mask to the 4x4 smaller texture.
        this.downSample(effectsTexture, buffer);
        
        // Blur the small texture
        var oddEven = true;
        for(var i = 0; i < iterations; i++)
        {
            if( oddEven ) 
                FourTapCone(buffer, buffer2, i);                            
            else                        
                FourTapCone(buffer2, buffer, i);
            
            oddEven = !oddEven;            
        }
        Material compositeMat = this.getCompositeMaterial();
        compositeMat.SetTexture("_BlurTex2", oddEven ? buffer : buffer2);        
            
        ImageEffects.BlitWithMaterial(compositeMat, source, destination);
        
        RenderTexture.ReleaseTemporary(buffer);
        RenderTexture.ReleaseTemporary(buffer2);
        
        if (effectsTexture != null) {
            RenderTexture.ReleaseTemporary (effectsTexture);
            effectsTexture = null;
        }
    }

That is the shader applied to to the piece to enable the effect

Shader "PostProcess/Transparent" {



Properties {

    _Color ("Main Color", Color) = (1,1,1,1)

}

SubShader {

    Tags { "RenderType"="PostProcess" }

    Pass { 

        

        //Wont be rendered at scene camera

        AlphaTest Never 0

    }    

}

}

Ok, if I now use for example the following shader as the replacement shader the results are like I expected:

Shader "PostProcess/Replacement" {

Properties {

    _Color ("Main Color", Color) = (1,1,1,1)

    _SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1)

    _Shininess ("Shininess", Range (0.03, 1)) = 0.078125

    _MainTex ("Base (RGB) Gloss (A)", 2D) = "white" {}

    _BumpMap ("Normalmap", 2D) = "bump" {}

}

SubShader { 

    Tags {"RenderType" = "PostProcess" }

    Pass{

        Fog { Mode Off }

             Color [_Color]

        }

    }

}

This is the normal scene camera:
460507--16107--$scene.png

This the effects camera (when destruction effect is enabled):
460507--16108--$simple_effect.png

And this is the scene resulting from combining the two cameras:
460507--16109--$compoundedscene.png

Untill now everithing seems ok, but I want to render the pieces like Bumped Specular when effect is applied. So if I change the replacement shader for the following (built in Bumped Specular source changing the tag):

Shader "PostProcess/Replacement" {

Properties {

	_Color ("Main Color", Color) = (1,1,1,1)

	_SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1)

	_Shininess ("Shininess", Range (0.03, 1)) = 0.078125

	_MainTex ("Base (RGB) Gloss (A)", 2D) = "white" {}

	_BumpMap ("Normalmap", 2D) = "bump" {}

}

SubShader { 

	Tags {"RenderType" = "PostProcess" }

	LOD 400

	

CGPROGRAM

#pragma surface surf BlinnPhong



sampler2D _MainTex;

sampler2D _BumpMap;

float4 _Color;

float _Shininess;



struct Input {

	float2 uv_MainTex;

	float2 uv_BumpMap;

};



void surf (Input IN, inout SurfaceOutput o) {

	half4 tex = tex2D(_MainTex, IN.uv_MainTex);

	o.Albedo = tex.rgb * _Color.rgb;

	o.Gloss = tex.a;

	o.Alpha = tex.a * _Color.a;

	o.Specular = _Shininess;

	o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));			

}

ENDCG

}



FallBack "Specular"

}

The resulting effect camera rendering is:
460507--16110--$wtf.png

460507--16111--$wtf.jpg

I don’t see any light usage there.
As such you can overcome it by just not using surface shaders (if you don’t use lights and beast lightmaps, they are primarily an overkill, not a gain). You can use the surface shader as base, take its compiled output and create a new shader from that one which is, if required, cleaned from unneeded “garbage”