opengl - Calling Material.setPass con sombreados de sombreado personalizados GL-Unity
unity3d (1)
Aquí está mi shader, que reemplaza un color por otro:
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"
}
Aquí hay un script de prueba adjunto a gameobject que contiene la cámara principal. En él intento renderizar una línea y un quad texturizado.
mat
está asignado con SwapColors
con una textura.
sprite_mat
se le asigna un sombreador de sprites predeterminado con la misma textura.
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();
}
}
Cuando renderizo el quad con sprite_mat
, todo está bien.
Cuando uso mat
, no solo el quad desaparece, sino también la línea , a pesar de que se representa con sprite_mat
.
Si creo otro quad en editor y establezco su material en mat
, se renderiza correctamente.
Mi pregunta principal es cómo puede setPass
afectar la geometría representada después de otro setPass
no setPass
.
Proyecto de ejemplo: forum.unity3d.com/attachments/errorgl-7z.138105/
Editar: Encontré un sombreador de sprites de Unity predeterminado y lo comparé con mi. El quad desapareció porque estaba orientado en sentido opuesto a la cámara. Lo arregla Cull Off
.
Si agrego línea
float4 color:COLOR;
a la estructura VertexInput
, el material con mi shader deja de afectar la geometría con otros materiales. No entiendo lo que está pasando.
No creo que puedas SetPass(0)
dos veces entre GL.Begin(..)
y GL.End(..)
.
Puede establecer varias pasadas con SetPass(0); [..] SetPass(1);
SetPass(0); [..] SetPass(1);
pero mirando tu sombreador, no creo que sea eso lo que quieres hacer.
Entonces, ¿estás tratando de dibujar el quad con 2 pases? ¿Uno con el material Sprite predeterminado y el otro con tu material personalizado? ¿O simplemente dibujarlo dos veces?
No entiendo completamente qué quieres hacer aquí.