Cartelera de Shaderlab

Tome Sprite en el espacio 3D como
ejemplo :

  • Gira el objeto a la posición adecuada.
  • Necesita conocer el punto (x, y, z) en el espacio modelo y el valor (i, j, k) del vector de dirección del sistema de coordenadas rotado en el espacio modelo original.
  • El nuevo punto es xi + yj + zk en el espacio modelo.

Nota:
i, j, k anteriores son vectores, x, y, z son escalares y
todos se realizan en el espacio modelo original del objeto.

  1. El punto donde el Sprite mira hacia la cámara.
    Para más detalles, consulte el código completo y los comentarios a continuación.
    Insertar descripción de la imagen aquí
  2. Sprite es paralelo al plano de la pantalla, grande cerca y pequeño lejos (similar a la barra de salud, implementación de parches de objetos en Don’t Starve)
    Insertar descripción de la imagen aquí

Código central del sombreador de punto fijo

//化简版
float3 forwardDir = UNITY_MATRIX_MV[2].xyz;
float3 upDir      = UNITY_MATRIX_MV[1].xyz;
float3 rightDir   = UNITY_MATRIX_MV[0].xyz;

//完整版
//float3 forwardDir = mul(UNITY_MATRIX_T_MV, float4(0, 0, 1, 1)).xyz;
//float3 upDir      = mul(UNITY_MATRIX_T_MV, float4(0, 1, 0, 1)).xyz;
//float3 rightDir   = mul(UNITY_MATRIX_T_MV, float4(1, 0, 0, 1)).xyz;

UNITY_MATRIX_MV representa la matriz de transformación del espacio modelo al espacio de observación.
UNITY_MATRIX_T_MV representa la matriz de transformación del espacio de observación al espacio modelo. Es la matriz transpuesta de UNITY_MATRIX_MV. La versión completa representa la transformación del vector de dirección en el espacio de observación al espacio modelo.

El siguiente es el contenido relacionado con la conversión del sistema de coordenadas, de "Introducción a Unity Shader"
Insertar descripción de la imagen aquí

Insertar descripción de la imagen aquí

La primera parte del código proviene del Capítulo 11 de "Introducción a Unity Shader".

Shader "Test/Billboard" {
    
    
	Properties {
    
    
		_MainTex ("Main Tex", 2D) = "white" {
    
    }
		_Color ("Color Tint", Color) = (1, 1, 1, 1)
		_VerticalBillboarding ("Vertical Restraints", Range(0, 1)) = 1 

	}
	SubShader {
    
    
		// Need to disable batching because of the vertex animation
		Tags {
    
    "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "DisableBatching"="True"}
		
		Pass {
    
     
			Tags {
    
     "LightMode"="ForwardBase" }
			
			ZWrite Off
			Blend SrcAlpha OneMinusSrcAlpha
			Cull Off
		
			CGPROGRAM
			
			#pragma vertex vert
			#pragma fragment frag
			
			#include "Lighting.cginc"
			

			struct a2v {
    
    
				float4 vertex : POSITION;
				float4 texcoord : TEXCOORD0;
			};
			
			struct v2f {
    
    
				float4 pos : SV_POSITION;
				float2 uv : TEXCOORD0;
			};

			sampler2D _MainTex;
			float4 _MainTex_ST;
			fixed4 _Color;
			fixed _VerticalBillboarding;
			
			
			v2f vert (a2v v) {
    
    
				v2f o;
				
				// 在这修改中心点
				float3 center = float3(0, 0, 0);
				// 摄像机的位置(模型空间)
				float3 viewer = mul(unity_WorldToObject,float4(_WorldSpaceCameraPos, 1));
				
				// 总体思路是将模型旋转,使其面对摄像机,则求得旋转后的方向向量,再结合模型坐标求出结果
				// 向前的向量 由模型指向摄像机
				float3 normalDir = viewer - center;

				normalDir.y = normalDir.y * _VerticalBillboarding;
				normalDir = normalize(normalDir);
				// Get the approximate up dir
				// If normal dir is already towards up, then the up dir is towards front
				float3 upDir = abs(normalDir.y) > 0.999 ? float3(0, 0, 1) : float3(0, 1, 0);
				float3 rightDir = normalize(cross(upDir, normalDir));
				upDir = normalize(cross(normalDir, rightDir));

				//上面的是始终面对摄像机这个点,下面三行是始终平行于摄像机的平面(屏幕),适合制作血条
				//float3 normalDir = UNITY_MATRIX_MV[2].xyz;
				//float3 upDir = UNITY_MATRIX_MV[1].xyz;
				//float3 rightDir = cross(upDir, normalDir);
				
				// Use the three vectors to rotate the quad
				float3 centerOffs = v.vertex.xyz - center;
				float3 localPos = center + rightDir * centerOffs.x + upDir * centerOffs.y + normalDir * centerOffs.z;
              
				//o.pos = UnityObjectToClipPos(float4(localPos, 1));
				o.pos = UnityObjectToClipPos(float4(localPos, 1));
				o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);

				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target {
    
    
				fixed4 c = tex2D (_MainTex, i.uv);
				c.rgb *= _Color.rgb;
				
				return c;
			}
			
			ENDCG
		}
	} 
	FallBack "Transparent/VertexLit"
}

Shader "Test/Test" {
    
    
	Properties {
    
    
		_MainTex ("Main Tex", 2D) = "white" {
    
    }

	}
	SubShader {
    
    	
		Pass {
    
     
			CGPROGRAM
			
			#pragma vertex vert
			#pragma fragment frag	
			#include "Lighting.cginc"

			struct a2v {
    
    
				float4 vertex : POSITION;
				float4 texcoord : TEXCOORD0;
			};
			
			struct v2f {
    
    
				float4 pos : SV_POSITION;
				float2 uv : TEXCOORD0;
			};

			sampler2D _MainTex;
			float4 _MainTex_ST;
			
			
			v2f vert (a2v v) {
    
    
				v2f o;
				

//化简版
				float3 forwardDir = UNITY_MATRIX_MV[2].xyz;
				float3 upDir      = UNITY_MATRIX_MV[1].xyz;
				float3 rightDir   = UNITY_MATRIX_MV[0].xyz;

				//完整版
				//float3 forwardDir = mul(UNITY_MATRIX_T_MV, float4(0, 0, 1, 1)).xyz;
				//float3 upDir      = mul(UNITY_MATRIX_T_MV, float4(0, 1, 0, 1)).xyz;
				//float3 rightDir   = mul(UNITY_MATRIX_T_MV, float4(1, 0, 0, 1)).xyz;

				float3 localPos = rightDir * v.vertex.x + upDir * v.vertex.y + forwardDir * v.vertex.z;
              
				o.pos = UnityObjectToClipPos(float4(localPos, 1));
				//o.pos = UnityObjectToClipPos(v.vertex);
				o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);

				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target {
    
    
				fixed4 c = tex2D (_MainTex, i.uv);
				
				return c;
			}
			
			ENDCG
		}
	} 
	FallBack "Transparent/VertexLit"
}


Supongo que te gusta

Origin blog.csdn.net/qq_41225779/article/details/107295788
Recomendado
Clasificación