[Unidad] Material transparente

objetivo de aprendizaje:

Materiales transparentes en el orden de renderizado de Unity Shader


Contenido de aprendizaje:

1. Prueba de transparencia

2. Fusión de transparencias

3. Cola de procesamiento

4. Modelo transparente


Motivo: en general, el orden de representación se determinará de acuerdo con el búfer de profundidad, pero debido a que el material transparente necesita cerrar la escritura de profundidad , debido a que el material transparente mezclará los colores de otros materiales en la cola, no se puede procesar con el método de materiales ordinarios. 1 y 2, respectivamente, hablan de dos formas de lograr la transparencia

1. Prueba de transparencia

        Pruebas más extremas, si la transparencia del fragmento no alcanza un cierto umbral, se descartará directamente, de lo contrario, se probará y escribirá en profundidad como fragmentos opacos, independientemente del problema de deshabilitar la escritura en profundidad, el resultado solo será completamente transparente u opaco.

2. Fusión de transparencias

Este método puede obtener un efecto translúcido real. La idea central es mezclar         su propia transparencia con el color que ya existe en el búfer de color. El punto clave de este método es recordar que si el objeto se procesa en el orden transparente -> opaco, luego renderice el objeto opaco primero y luego mezcle el color en el búfer de color con el fragmento transparente. Si lo contrario es opaco -> transparente, entonces el fragmento transparente no se procesará, por lo que la cola de procesamiento es muy importante.

3. Cola de procesamiento

        La cola de representación puede entenderse como varios vagones de tren, que se dividen en varios grupos, y se representarán de acuerdo con el número de índice de la cola. Cada cola tiene funciones específicas. 

Como mencionamos anteriormente, debido a que no se puede usar el almacenamiento en anillo profundo, el orden de procesamiento es muy importante, por lo que hay una cola de procesamiento

4. Modelo transparente

        Este proyecto es un modelo que viene con el libro, y el efecto real es el siguiente

        La parte transparente es la distribución de color específica de la textura. La visualización anterior se realiza utilizando el método de prueba de transparencia. Los dos extremos que se muestran desaparecen por completo o son visibles.

        el código se muestra a continuación

// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Unity Shaders Book/Chapter 8/Alpha Test" {
	Properties {
		_Color ("Color Tint", Color) = (1, 1, 1, 1)
		_MainTex ("Main Tex", 2D) = "white" {}
		_Cutoff ("Alpha Cutoff", Range(0, 1)) = 0.5
	}
	SubShader {
		Tags {"Queue"="AlphaTest" "IgnoreProjector"="True" "RenderType"="TransparentCutout"}//渲染队列名为AlphaTest,忽略投影器影响,规划到TransparentCutout这个组
		
		Pass {
			Tags { "LightMode"="ForwardBase" }//渲染模式是用前向渲染->还有一种叫延迟渲染
			
			CGPROGRAM
			
			#pragma vertex vert//顶点着色器
			#pragma fragment frag//片元着色器
			
			#include "Lighting.cginc"//添加内置变量
			
			fixed4 _Color;
			sampler2D _MainTex;
			float4 _MainTex_ST;
			fixed _Cutoff;
			
			struct a2v {//顶点着色器输入结构
				float4 vertex : POSITION;
				float3 normal : NORMAL;
				float4 texcoord : TEXCOORD0;
			};
			
			struct v2f {//顶点着色器输出结构
				float4 pos : SV_POSITION;
				float3 worldNormal : TEXCOORD0;
				float3 worldPos : TEXCOORD1;
				float2 uv : TEXCOORD2;
			};
			
			v2f vert(a2v v) {//顶点着色器
				v2f o;//顺序分别为切线空间、世界空间、世界坐标、纹理坐标进行变换最后返回
				o.pos = UnityObjectToClipPos(v.vertex);
				
				o.worldNormal = UnityObjectToWorldNormal(v.normal);
				
				o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
				
				o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
				
				return o;
			}
			
			fixed4 frag(v2f i) : SV_Target {
				fixed3 worldNormal = normalize(i.worldNormal);
				fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
				
				fixed4 texColor = tex2D(_MainTex, i.uv);//获取贴图坐标
				
				// Alpha test
				clip (texColor.a - _Cutoff);//如果不为负数则采用该片元,意义在于texColor为目标材质,Cutoff为材质参数,如果低于则表明为为透明材质
				// Equal to 
//				if ((texColor.a - _Cutoff) < 0.0) {
//					discard;//意义跟clip一样剔除掉该片元
//				}
				//计算环境光和漫反射将其计算后输出
				fixed3 albedo = texColor.rgb * _Color.rgb;
				
				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;
				
				fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(worldNormal, worldLightDir));
				
				return fixed4(ambient + diffuse, 1.0);
			}
			
			ENDCG
		}
	} 
	FallBack "Transparent/Cutout/VertexLit"
}

 Otro método es la mezcla de transparencias. La idea central es mezclar con el color en el búfer de color para obtener el color del fragmento transparente. El resultado es el siguiente, y la transparencia selecciona todo el material.

el código se muestra a continuación

// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Unity Shaders Book/Chapter 8/Alpha Blend" {
	Properties {
		_Color ("Color Tint", Color) = (1, 1, 1, 1)
		_MainTex ("Main Tex", 2D) = "white" {}
		_AlphaScale ("Alpha Scale", Range(0, 1)) = 1
	}
	SubShader {
		Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
		
		Pass {
			Tags { "LightMode"="ForwardBase" }

			ZWrite Off
			Blend SrcAlpha OneMinusSrcAlpha
			
			CGPROGRAM
			
			#pragma vertex vert
			#pragma fragment frag
			
			#include "Lighting.cginc"
			
			fixed4 _Color;
			sampler2D _MainTex;
			float4 _MainTex_ST;
			fixed _AlphaScale;
			
			struct a2v {
				float4 vertex : POSITION;
				float3 normal : NORMAL;
				float4 texcoord : TEXCOORD0;
			};
			
			struct v2f {
				float4 pos : SV_POSITION;
				float3 worldNormal : TEXCOORD0;
				float3 worldPos : TEXCOORD1;
				float2 uv : TEXCOORD2;
			};
			
			v2f vert(a2v v) {
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);
				
				o.worldNormal = UnityObjectToWorldNormal(v.normal);
				
				o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
				
				o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
				
				return o;
			}
			
			fixed4 frag(v2f i) : SV_Target {
				fixed3 worldNormal = normalize(i.worldNormal);
				fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
				
				fixed4 texColor = tex2D(_MainTex, i.uv);
				
				fixed3 albedo = texColor.rgb * _Color.rgb;
				
				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;
				
				fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(worldNormal, worldLightDir));
				
				return fixed4(ambient + diffuse, texColor.a * _AlphaScale);
			}
			
			ENDCG
		}
	} 
	FallBack "Transparent/VertexLit"
}

 


Resumir:

        Hay dos formas de lograr la transparencia, que son la prueba de transparencia y la mezcla de transparencia. La expresión central es 1. Si no es transparente, no se mostrará. 2. Primero renderice el objeto opaco y luego mezcle los datos en el búfer de color para obtener el color del objeto transparente. En general, ambos deben prestar atención al orden de renderizado.

Supongo que te gusta

Origin blog.csdn.net/hoxidohanabi/article/details/128345500
Recomendado
Clasificación