Search Unity

RenderWithShader not working right.

Discussion in 'Shaders' started by ChristmasEve, Dec 22, 2021.

  1. ChristmasEve

    ChristmasEve

    Joined:
    Apr 21, 2015
    Posts:
    45
    I'm not sure if anyone is familiar with the UMA project. Whether you are or not won't matter but it would make it a littler easier to understand my situation. When UMA generates a human, it has 3 materials generated at runtime that all use the Unity Standard Shader.

    The body has a render mode of opaque.
    The hair has a render mode of cutout.
    The eyelashes have a render mode of fade.

    When I generate an image from my UMA character for his/her paperdoll and when I generate a headshot, I do it on-the-fly from the actual character in the scene but with an unlit shader using RenderWithShader:


    camera.RenderWithShader(Shader.Find("Unlit/Dim"), "RenderType");


    At first, I did not specify a replacement shader but then I noticed the eyelashes were messed up. The render mode of "fade" was not working right with my unlit shader so I just wanted to go without the eyelashes for paperdolls and head portraits, to make it simple.

    Looking at the docs, it sounded like I needed to use RenderType for it, as I did above, and then add a tag to my shader:


    Shader "Unlit/Dim" {
    Properties {
    _MainTex ("Base", 2D) = "white" {}
    }

    SubShader {
    Tags { "RenderType"="Opaque" }
    LOD 100
    ...


    When I specify Opaque, I only get the body, which doesn't make sense. I expected to see all 3 materials since they are all using the opaque standard shader. Here is a snipped from the standard Unity shader:

    SubShader
    {
    Tags { "RenderType"="Opaque" "PerformanceChecks"="False" }
    LOD 300


    Even if this worked right, it wouldn't have solved my problem, obviously, because I wouldn't have eliminated the eyelashes. But, because of this, I REALLY don't understand this now and I couldn't attempt to solve my problem (by possibly making copies of the standard shader and change the tags on each one: have a transparent and cutout version, go into the UMA code and have it use the respective shaders and then I'd be able to filter on it and use only the shaders with the tags I want).

    If anyone may know why I'm only getting the body, or if you have a better solution to not render the eyelashes (or have them work right with my unlit shader), please let me know. As you can see above, the body only differs from the hair and eyelashes by the render MODE. I'm not sure what that would have to do with the Render TYPE tag. I'm still lost about why the hair disappeared too. PLEASE HELP :)

    EDIT: Here is my entire shader for generating headshots and paperdolls:

    Shader "Unlit/Dim" {
    Properties {
    _MainTex ("Base", 2D) = "white" {}
    }

    SubShader {
    Tags { "RenderType"="Opaque" }
    LOD 100

    Pass {
    CGPROGRAM
    #pragma vertex vert
    #pragma fragment frag
    #pragma target 2.0
    #pragma multi_compile_fog

    #include "UnityCG.cginc"

    struct appdata_t {
    float4 vertex : POSITION;
    float2 texcoord : TEXCOORD0;
    UNITY_VERTEX_INPUT_INSTANCE_ID
    };

    struct v2f {
    float4 vertex : SV_POSITION;
    float2 texcoord : TEXCOORD0;
    UNITY_FOG_COORDS(1)
    UNITY_VERTEX_OUTPUT_STEREO
    };

    sampler2D _MainTex;
    float4 _MainTex_ST;

    v2f vert (appdata_t v)
    {
    v2f o;
    UNITY_SETUP_INSTANCE_ID(v);
    UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
    o.vertex = UnityObjectToClipPos(v.vertex);
    o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
    UNITY_TRANSFER_FOG(o,o.vertex);
    return o;
    }

    fixed4 frag (v2f i) : SV_Target
    {
    fixed4 col = tex2D(_MainTex, i.texcoord);
    UNITY_APPLY_FOG(i.fogCoord, col);
    UNITY_OPAQUE_ALPHA(col.a);
    col.r *= 0.7;
    col.g *= 0.6;
    col.b *= 0.6;
    return col;
    }
    ENDCG
    }
    }

    }
     
    Last edited: Dec 22, 2021
  2. Scriptwonder

    Scriptwonder

    Joined:
    Apr 24, 2021
    Posts:
    1
    So basically using Renderwithshader with a render type as the second parameter, only render types mentioned in your shader scripts will get rendered; so in your case, only Opaque objects will be rendered because there is only one subpass and its render type is Opaque. Write two sub shaders in your shader script, one for opaque and one for cutout, that could solve your eyelashes problem.
    There are still two problems though, one is that fade is not a render type, so you'll have to find eyelashes' render type to exclude it from the rendering process; second is this process will exclude all objects with the same render type as the eyelash, so be aware of more modifications.