En unity shader dot(lightCoord, lightCoord).rr
#ifdef USING_DIRECTIONAL_LIGHT
atención fija = 1.0;
#else
float3 lightCoord = mul(_LightMatrix0, float4(i.worldPos) , 1)).xyz;
aten fijo = tex2D(_LightTexture0, dot(lightCoord, lightCoord).rr).UNITY_ATTEN_CHANNEL;
#endif
_LightMatrix0 : Esta variable se describe en la tabla de la página P184 del libro y en la documentación oficial. Se define en una macro específica en el archivo AutoLight.cginc incorporado y se puede utilizar para transformar puntos del espacio mundial al espacio local. de la fuente de luz. Por lo tanto, la primera oración del código anterior "mul(_LightMatrix0, float4(i.worldPos, 1)).xyz" es transformar las coordenadas del vértice en coordenadas en el espacio de la fuente de luz. Esto también se explica en el libro.
_LightTexture0: Similar a _LightMatrix0, también se define bajo una macro específica en el archivo integrado AutoLight.cginc, siguiendo la definición de _LightMatrix0. Es una textura de atenuación que contiene información de atenuación de la fuente de luz. Podemos procesar aún más las coordenadas obtenidas en la primera oración del código para obtener las coordenadas de muestreo de la textura de atenuación. Dado que Unity no tiene una explicación oficial del significado del rango numérico específico de _LightMatrix0, podemos especular (el método de especulación puede ser usar el método en la sección de color falso para generar esta variable como un color El rango del módulo de coordenadas obtenido por _LightMatrix0). será [0, 1], es decir, el punto coincidente con la fuente de luz es (0, 0, 0) y el valor del módulo es 1 en el límite del rango de la fuente de luz. En cuanto a dot(lightCoord, lightCoord).rr, en primer lugar, la distancia al cuadrado de la fuente de luz se obtiene del producto escalar, que es un escalar. Nuestra operación .rr en esta variable es equivalente a construir un vector bidimensional. de este vector bidimensional Los valores de los componentes son todos este valor escalar, obteniendo así una coordenada de muestreo bidimensional. Esta operación es una operación de cambio común en los sombreadores y también se explica en el sitio web oficial de Cg. Luego usamos estas coordenadas bidimensionales para muestrear la textura de atenuación de la luz _LightTexture0 y obtener el valor de atenuación. Sobre _LightTexture0 hablaremos del sistema más adelante.
Este código no está lo suficientemente estandarizado: el libro dice que el código en esta sección no se puede usar directamente en el proyecto, solo se usa para explicar los principios, pero si desea usar este código para directamente publique el proyecto, es necesario revisarlo porque no estaba lo suficientemente estandarizado cuando lo escribí. La razón es que hay un problema con las condiciones de juicio de palabras clave de este código, lo que hace que _LightTexture0 o _LightMatrix0 no estén definidos. Podemos reemplazar el código original con el siguiente código (el nuevo código también se envió a github): #ifdef USING_DIRECTIONAL_LIGHT
fixed atten = 1.0;
#else
#if definido (PUNTO)
// Convierte las coordenadas del punto en el espacio de coordenadas de la fuente de luz del punto _LightMatrix0 se calcula mediante el código del motor y se pasa al sombreador. la fuente de luz puntual Para el cálculo, consulte el código fuente del motor Unity para obtener más detalles.
Después de la transformación _LightMatrix0, el lightCoord en el centro de la fuente de luz puntual es (0, 0, 0) y el módulo lightCoord en el borde de la fuente de luz puntual es 1
float3 lightCoord = mul(_LightMatrix0 , float4(i. worldPos, 1)).xyz;
// Utilice el punto cuadrado (lightCoord, lightCoord) de la distancia desde el punto al centro de la fuente de luz para formar un punto bidimensional. Coordenada de muestreo y muestreo de la textura de atenuación _LightTexture0. La apariencia específica de la textura _LightTexture0 se puede ver en el siguiente contenido
// UNITY_ATTEN_CHANNEL es el canal de textura donde se encuentra el valor de atenuación, que se puede ver en el archivo HLSLSupport.cginc incorporado. Generalmente, UNITY_ATTEN_CHANNEL es el canal r para PC y plataformas host, y es un canal para plataformas móviles.
fixed atten = tex2D(_LightTexture0, dot(lightCoord, lightCoord).rr).UNITY_ATTEN_CHANNEL; p>
#elif definido (SPOT)
// Convierte las coordenadas del punto en el espacio de coordenadas del foco _LightMatrix0 se calcula mediante el código del motor y se pasa al sombreador. el alcance y el ángulo del foco. Para obtener más información, consulte el código fuente del motor Unity. Después de la transformación _LightMatrix0, el lightCoord en el centro de la fuente de luz del foco o fuera del alcance del foco es (0, 0, 0), y el módulo lightCoord en el borde de la fuente de luz puntual es 1
float4 lightCoord = mul(_LightMatrix0 , float4(i.worldPos, 1));
// A diferencia de las fuentes de luz puntuales, dado que los focos tienen más ángulos y otros requisitos, para obtener el valor de atenuación, en Además de muestrear la textura de atenuación, es necesario juzgar el alcance, el ángulo y la dirección del foco
// En este momento, la textura de atenuación se almacena en _LightTextureB0. Esta textura es equivalente a _LightTexture0 en el. fuente de luz puntual
// El _LightTexture0 del foco ya no almacena una textura de atenuación basada en la distancia, sino una textura de atenuación basada en el rango del ángulo de apertura
fixed atten = (lightCoord.z gt; 0) * tex2D (_LightTexture0, lightCoord.xy/lightCoord.w 0.5).w *tex2D(_LightTextureB0, dot(lightCoord, lightCoord).rr).UNITY_ATTEN_CHANNEL;
#else
fixed atten = 1.0;
#endif
#endif
Lo anterior determina la condición de la palabra clave con mayor precisión para garantizar que el código que accede al La textura de atenuación solo se ejecuta en el momento correcto. _LightTexture0 y _LightMatrix0 solo se definirán bajo ciertas condiciones, como PUNTO, SPOT, POINT_COOKIE, DIRECTIONAL_COOKIE, etc., que podemos encontrar en AutoLight.cginc.
Pero debido a que no hubo un juicio estricto en el código original, Unity compilará estrictamente Unity Shader para generar el programa de sombreado correspondiente en función de diferentes palabras clave cuando se publique. En este momento, descubrirá nuestros errores.