2015-05-10 6 views
9

Ecco il mio Shader, che sostituisce un colore con un altro:Calling Material.setPass con Shader personalizzati rompe GL - Unità

Shader "Custom/SwapColors" 
{ 
    Properties 
    { 
     _MainTex("Texture",2D)="white"{} 
     swap_from("Swap From",COLOR)=(1,1,1,1) 
     swap_to("Swap To",COLOR)=(1,1,1,1) 
     threshold("Threshold",Float)=0.00001 
    } 
    SubShader 
    { 
     Tags 
     { 
      "Queue"="Transparent" 
     } 
     Pass 
     { 
      Blend SrcAlpha OneMinusSrcAlpha 
      CGPROGRAM 
      #pragma vertex vert 
      #pragma fragment frag 

      sampler2D _MainTex; 
      float4 swap_from; 
      float4 swap_to; 
      float threshold; 

      struct VertexInput 
      { 
       float4 pos:POSITION; 
       float2 uv:TEXCOORD0; 
      }; 
      struct FragmentInput 
      { 
       float4 pos:SV_POSITION; 
       float2 uv:TEXCOORD0; 
      }; 

      FragmentInput vert(VertexInput data) 
      { 
       FragmentInput res; 
       res.pos=mul(UNITY_MATRIX_MVP,data.pos); 
       res.uv=data.uv; 
       return res; 
      } 
      bool eq(fixed f,fixed s) 
      { 
       return abs(f-s)<threshold; 
      } 
      float4 frag(FragmentInput data):COLOR 
      { 
       float4 res=tex2D(_MainTex,data.uv.xy).rgba; 
       if(eq(res.r,swap_from.r)&&eq(res.g,swap_from.g)&&eq(res.b,swap_from.b)) 
        res.rgb=swap_to.rgb; 
       return res; 
      } 
      ENDCG 
     } 
    } 
    Fallback "Diffuse" 
} 

Ecco uno script di test collegato a gameobject che contiene fotocamera principale. In esso provo a rendere una linea e un quad strutturato.

mat viene assegnato con SwapColors con una trama.

sprite_mat viene assegnato con lo sprite shader predefinito con la stessa trama.

using UnityEngine; 
using System.Collections; 

public class Test : MonoBehaviour 
{ 
    [SerializeField] 
    Material mat; 
    [SerializeField] 
    Material sprite_mat; 
    void OnPostRender() 
    { 


     GL.PushMatrix(); 
     GL.LoadProjectionMatrix(Camera.main.projectionMatrix); 
     GL.modelview=Camera.main.worldToCameraMatrix; 

     GL.Begin(GL.LINES); 
     sprite_mat.SetPass(0); 
     GL.Vertex(new Vector3(0,0)); 
     GL.Vertex(new Vector3(5,0)); 
     GL.End(); 


     GL.Begin(GL.QUADS); 
     sprite_mat.SetPass(0); 

     mat.SetPass(0);//<------------------------------------ PROBLEM 

     GL.TexCoord(new Vector3(0,0)); 
     GL.Vertex(new Vector2(0,0)); 

     GL.TexCoord(new Vector3(1,0)); 
     GL.Vertex(new Vector2(1,0)); 

     GL.TexCoord(new Vector3(1,1)); 
     GL.Vertex(new Vector2(1,1)); 

     GL.TexCoord(new Vector3(0,1)); 
     GL.Vertex(new Vector2(0,1)); 
     GL.End(); 


     GL.PopMatrix(); 
    } 
} 

Quando mi rendo il quad con sprite_mat, tutto è ok.

Quando uso mat, non solo il quad scomparire, ma la linea troppo, nonostante la sua resa con sprite_mat.

Se creo un altro quad nell'editor e ne imposto il materiale su mat, il rendering è corretto.

La mia domanda principale è come può setPass influenzare la geometria resa dopo un altro setPass non correlato.

progetto Esempio: forum.unity3d.com/attachments/errorgl-7z.138105/


Edit: ho trovato un'unità di shader di default sprite e confrontato con il mio. Il quad scomparve perché era rivolto nella direzione opposta rispetto alla telecamera. È stato risolto da Cull Off.

Se aggiungo linea

float4 color:COLOR;

al VertexInput struttura, materiale con il mio Shader smette di influenzare la geometria con altri materiali. Non capisco cosa sta succedendo.

+1

Prima di ottenere il progetto e provare a riprodurre il problema, è possibile fornire la versione di Unity che si sta utilizzando? – itchee

+0

5.0.1f1 Personal – user2136963

risposta

0

Non penso che sia possibile SetPass(0) due volte tra GL.Begin(..) e GL.End(..).

È possibile impostare vari passaggi con SetPass(0); [..] SetPass(1); ma guardando il proprio shader non penso che sia quello che si vuole fare.

Quindi stai cercando di disegnare il quad con 2 passaggi? Uno con il materiale Sprite predefinito e l'altro con il tuo materiale personalizzato? Oppure disegnalo due volte?

Non capisco perfettamente cosa vuoi fare qui.

+0

sprite_mat.SetPass (0) cab essere rimosso, e il problema rimane. mat.SetPass (0) influenza ancora la geometria in ** altro ** blocco Gl.Begin()/GL.End(), a meno che "float4 color: COLOR;" sia aggiunto all'input del vertex shader. – user2136963