写了个基于Height Map的Texture Mix的工具,应该还有提升的空间先看看效果
主要思路是通过splat_control这张贴图的四个通道控制_Splat0~_Splat3这四张贴图的混合,如果splat_control对应通道的值为1,那么这个通道对应的贴图就完全显示,为0则完全不显示,通过修改splat_control贴图就可以实现想要的混合效果了;
核心代码如下
fixed4 splat_control = tex2D (_Control, IN.uv_Control).rgba;
fixed3 lay1 = tex2D (_Splat0, IN.uv_Splat0);
fixed3 lay2 = tex2D (_Splat1, IN.uv_Splat1);
fixed3 lay3 = tex2D (_Splat2, IN.uv_Splat2);
fixed3 lay4 = tex2D (_Splat3, IN.uv_Splat3);
_Alpha = 0.0;
Albedo.rgb = (lay1 * splat_control.r + lay2 * splat_control.g + lay3 * splat_control.b+ lay4 * splat_control.a);
混合处
float3 blend(float3 lay1, float3 lay2, float4 splat_control)
{
float b1 = lay1.a * splat_control.r;
float b2 = lay2.a * splat_control.g;
float ma = max(b1,b2);
b1 = max(b1 - (ma – 0.3), 0) * splat_control.r;
b2 = max(b2 - (ma – 0.3), 0) * splat_control.g;
return (lay1.rgb * b1 + lay2.rgb * b2)/(b1 + b2);
}
下面是工具
using UnityEngine;
using System.Collections;
[ExecuteInEditMode]
[RequireComponent(typeof(MeshCollider))]
public class MeshPainter : MonoBehaviour {
void Start () {
}
void Update () {
}
}
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Collections;
[CustomEditor(typeof(MeshPainter))]
[CanEditMultipleObjects]
public class MeshPainterStyle : Editor
{
string contolTexName = "";
bool isPaint;
float brushSize = 16f;
float brushStronger = 0.5f;
Texture[] brushTex;
Texture[] texLayer;
int selBrush = 0;
int selTex = 0;
int brushSizeInPourcent;
Texture2D MaskTex;
void OnSceneGUI()
{
if (isPaint)
{
Painter();
}
}
public override void OnInspectorGUI()
{
if (Cheak())
{
GUIStyle boolBtnOn = new GUIStyle(GUI.skin.GetStyle("Button"));//得到Button样式
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
isPaint = GUILayout.Toggle(isPaint, EditorGUIUtility.IconContent("ClothInspector.PaintValue"), boolBtnOn, GUILayout.Width(35), GUILayout.Height(25));//编辑模式开关
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
brushSize = (int)EditorGUILayout.Slider("Brush Size", brushSize, 1, 36);//笔刷大小
brushStronger = EditorGUILayout.Slider("Brush Stronger", brushStronger, 0, 1f);//笔刷强度
IniBrush();
layerTex();
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
GUILayout.BeginHorizontal("box", GUILayout.Width(340));
selTex = GUILayout.SelectionGrid(selTex, texLayer, 4, "gridlist", GUILayout.Width(340), GUILayout.Height(86));
GUILayout.EndHorizontal();
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
GUILayout.BeginHorizontal("box", GUILayout.Width(318));
selBrush = GUILayout.SelectionGrid(selBrush, brushTex, 9, "gridlist", GUILayout.Width(340), GUILayout.Height(70));
GUILayout.EndHorizontal();
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
}
}
//获取材质球中的贴图
void layerTex()
{
Transform Select = Selection.activeTransform;
texLayer = new Texture[4];
texLayer[0] = AssetPreview.GetAssetPreview(Select.gameObject.GetComponent<MeshRenderer>().sharedMaterial.GetTexture("_Splat0")) as Texture;
texLayer[1] = AssetPreview.GetAssetPreview(Select.gameObject.GetComponent<MeshRenderer>().sharedMaterial.GetTexture("_Splat1")) as Texture;
texLayer[2] = AssetPreview.GetAssetPreview(Select.gameObject.GetComponent<MeshRenderer>().sharedMaterial.GetTexture("_Splat2")) as Texture;
texLayer[3] = AssetPreview.GetAssetPreview(Select.gameObject.GetComponent<MeshRenderer>().sharedMaterial.GetTexture("_Splat3")) as Texture;
}
//获取笔刷
void IniBrush()
{
string MeshPaintEditorFolder = "Assets/MeshPaint/Editor/";
ArrayList BrushList = new ArrayList();
Texture BrushesTL;
int BrushNum = 0;
do
{
BrushesTL = (Texture)AssetDatabase.LoadAssetAtPath(MeshPaintEditorFolder + "Brushes/Brush" + BrushNum + ".png", typeof(Texture));
if (BrushesTL)
{
BrushList.Add(BrushesTL);
}
BrushNum++;
} while (BrushesTL);
brushTex = BrushList.ToArray(typeof(Texture)) as Texture[];
}
//检查
bool Cheak()
{
bool Cheak = false;
Transform Select = Selection.activeTransform;
Texture ControlTex = Select.gameObject.GetComponent<MeshRenderer>().sharedMaterial.GetTexture("_Control");
if(Select.gameObject.GetComponent<MeshRenderer>().sharedMaterial.shader == Shader.Find("4Tex_Blend_Normal") || Select.gameObject.GetComponent<MeshRenderer>().sharedMaterial.shader == Shader.Find("zcxshaderlibrary/texBlendWithBump"))
{
if(ControlTex == null)
{
EditorGUILayout.HelpBox("当前模型材质球中未找到Control贴图,绘制功能不可用!", MessageType.Error);
if (GUILayout.Button("创建Control贴图"))
{
creatContolTex();
//Select.gameObject.GetComponent<MeshRenderer>().sharedMaterial.SetTexture("_Control", creatContolTex());
}
}
else
{
Cheak = true;
}
}
else
{
EditorGUILayout.HelpBox("当前模型shader错误!请更换!", MessageType.Error);
}
return Cheak;
}
//创建Contol贴图
void creatContolTex()
{
//创建一个新的Contol贴图
string ContolTexFolder = "Assets/MeshPaint/Controler/";
Texture2D newMaskTex = new Texture2D(512, 512, TextureFormat.ARGB32, true);
Color[] colorBase = new Color[512 * 512];
for(int t = 0; t< colorBase.Length; t++)
{
colorBase[t] = new Color(1, 0, 0, 0);
}
newMaskTex.SetPixels(colorBase);
//判断是否重名
bool exporNameSuccess = true;
for(int num = 1; exporNameSuccess; num++)
{
string Next = Selection.activeTransform.name +"_"+ num;
if (!File.Exists(ContolTexFolder + Selection.activeTransform.name + ".png"))
{
contolTexName = Selection.activeTransform.name;
exporNameSuccess = false;
}
else if (!File.Exists(ContolTexFolder + Next + ".png"))
{
contolTexName = Next;
exporNameSuccess = false;
}
}
string path = ContolTexFolder + contolTexName + ".png";
byte[] bytes = newMaskTex.EncodeToPNG();
File.WriteAllBytes(path, bytes);//保存
AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);//导入资源
//Contol贴图的导入设置
TextureImporter textureIm = AssetImporter.GetAtPath(path) as TextureImporter;
TextureImporterPlatformSettings texset = textureIm.GetDefaultPlatformTextureSettings();
texset.format = TextureImporterFormat.RGBA32;
//texset.maxTextureSize=512;
textureIm.SetPlatformTextureSettings(texset);
textureIm.isReadable = true;
textureIm.anisoLevel = 9;
textureIm.mipmapEnabled = false;
textureIm.wrapMode = TextureWrapMode.Clamp;
AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);//刷新
setContolTex(path);//设置Contol贴图
}
//设置Contol贴图
void setContolTex(string peth)
{
Texture2D ControlTex = (Texture2D)AssetDatabase.LoadAssetAtPath(peth, typeof(Texture2D));
Selection.activeTransform.gameObject.GetComponent<MeshRenderer>().sharedMaterial.SetTexture("_Control", ControlTex);
}
void Painter()
{
Transform CurrentSelect = Selection.activeTransform;
MeshFilter temp = CurrentSelect.GetComponent<MeshFilter>();//获取当前模型的MeshFilter
float orthographicSize = (brushSize * CurrentSelect.localScale.x) * (temp.sharedMesh.bounds.size.x / 200);//笔刷在模型上的正交大小
MaskTex = (Texture2D)CurrentSelect.gameObject.GetComponent<MeshRenderer>().sharedMaterial.GetTexture("_Control");//从材质球中获取Control贴图
brushSizeInPourcent = (int)Mathf.Round((brushSize * MaskTex.width) / 100);//笔刷在模型上的大小
bool ToggleF = false;
Event e = Event.current;//检测输入
HandleUtility.AddDefaultControl(0);
RaycastHit raycastHit = new RaycastHit();
Ray terrain = HandleUtility.GUIPointToWorldRay(e.mousePosition);//从鼠标位置发射一条射线
if (Physics.Raycast(terrain, out raycastHit, Mathf.Infinity, 1 << LayerMask.NameToLayer("ground")))//射线检测名为"ground"的层
{
Handles.color = new Color(1f, 1f, 0f, 1f);//颜色
Handles.DrawWireDisc(raycastHit.point, raycastHit.normal, orthographicSize);//根据笔刷大小在鼠标位置显示一个圆
//鼠标点击或按下并拖动进行绘制
if ((e.type == EventType.MouseDrag && e.alt == false && e.control == false && e.shift == false && e.button == 0) || (e.type == EventType.MouseDown && e.shift == false && e.alt == false && e.control == false && e.button == 0 && ToggleF == false))
{
//选择绘制的通道
Color targetColor = new Color(1f, 0f, 0f, 0f);
switch (selTex)
{
case 0:
targetColor = new Color(1f, 0f, 0f, 0f);
break;
case 1:
targetColor = new Color(0f, 1f, 0f, 0f);
break;
case 2:
targetColor = new Color(0f, 0f, 1f, 0f);
break;
case 3:
targetColor = new Color(0f, 0f, 0f, 1f);
break;
}
//targetColor = new Color(0f, 0f, 0f, 0f);
Vector2 pixelUV = raycastHit.textureCoord;
//计算笔刷所覆盖的区域
int PuX = Mathf.FloorToInt(pixelUV.x * MaskTex.width);
int PuY = Mathf.FloorToInt(pixelUV.y * MaskTex.height);
int x = Mathf.Clamp(PuX - brushSizeInPourcent / 2, 0, MaskTex.width - 1);
int y = Mathf.Clamp(PuY - brushSizeInPourcent / 2, 0, MaskTex.height - 1);
int width = Mathf.Clamp((PuX + brushSizeInPourcent / 2), 0, MaskTex.width) - x;
int height = Mathf.Clamp((PuY + brushSizeInPourcent / 2), 0, MaskTex.height) - y;
Color[] terrainBay = MaskTex.GetPixels(x, y, width, height, 0);//获取Control贴图被笔刷所覆盖的区域的颜色
Texture2D TBrush = brushTex[selBrush] as Texture2D;//获取笔刷性状贴图
float[] brushAlpha = new float[brushSizeInPourcent * brushSizeInPourcent];//笔刷透明度
//根据笔刷贴图计算笔刷的透明度
for (int i = 0; i < brushSizeInPourcent; i++)
{
for (int j = 0; j < brushSizeInPourcent; j++)
{
brushAlpha[j * brushSizeInPourcent + i] = TBrush.GetPixelBilinear(((float)i) / brushSizeInPourcent, ((float)j) / brushSizeInPourcent).a;
}
}
//计算绘制后的颜色
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
int index = (i * width) + j;
float Stronger = brushAlpha[Mathf.Clamp((y + i) - (PuY - brushSizeInPourcent / 2), 0, brushSizeInPourcent - 1) * brushSizeInPourcent + Mathf.Clamp((x + j) - (PuX - brushSizeInPourcent / 2), 0, brushSizeInPourcent - 1)] * brushStronger;
terrainBay[index] = Color.Lerp(terrainBay[index], targetColor, Stronger);
}
}
Undo.RegisterCompleteObjectUndo(MaskTex, "meshPaint");//保存历史记录以便撤销
MaskTex.SetPixels(x, y, width, height, terrainBay, 0);//把绘制后的Control贴图保存起来
MaskTex.Apply();
ToggleF = true;
}
if(e.type == EventType.MouseUp && e.alt == false && e.button == 0 && ToggleF == true)
{
SaveTexture();//绘制结束保存Control贴图
ToggleF = false;
}
}
}
public void SaveTexture()
{
var path = AssetDatabase.GetAssetPath(MaskTex);
var bytes = MaskTex.EncodeToPNG();
File.WriteAllBytes(path, bytes);
AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);//刷新
}
}
Shader模块
Shader "zcxshaderlibrary/texBlendWithBump"
{
Properties
{
_SpecularColor("SpecularColor",Color)=(1,1,1,1)
_Smoothness("Smoothness",range(0,20))=10
_Cutoff("Cutoff",float)=0.5
[Space(10)][Header(Layer)]
[Space(30)][Header(Layer1Map)]
_Splat0 ("Layer 1(RGBA)",2D) = "white"{}
_Splat0_Color("_Splat1 Color",Color) = (1,1,1,1)
_BumpSplat0 ("Layer 1 Normal(Bump)", 2D) = "Bump" {}
_BumpSplat0Scale("Layer 1 Normal Scale",float)=1
[Space(30)][Header(Layer2Map)]
_Splat1 ("Layer 2(RGBA)", 2D) = "white" {}
_Splat1_Color("_Splat2 Color",Color) = (1,1,1,1)
_BumpSplat1 ("Layer 2 Normal(Bump)", 2D) = "Bump" {}
_BumpSplat1Scale("Layer 2 Normal Scale",float)=1
[Space(30)][Header(Layer3Map)]
_Splat2 ("Layer 3(RGBA)", 2D) = "white" {}
_Splat2_Color("_Splat3 Color",Color) = (1,1,1,1)
_BumpSplat2 ("Layer 3 Normal(Bump)", 2D) = "Bump" {}
_BumpSplat2Scale("Layer 3 Normal Scale",float)=1
[Space(30)][Header(Layer4Map)]
_Splat3 ("Layer 4(RGBA)", 2D) = "white" {}
_Splat3_Color("_Splat4 Color",Color) = (1,1,1,1)
_BumpSplat3 ("Layer 4 Normal(Bump)", 2D) = "Bump" {}
_BumpSplat3Scale("Layer 4 Normal Scale",float)=1
[Space(30)][Header(Blend Texture)]
_Control ("Control (RGBA)", 2D) = "white" {}
_Weight("Blend Weight" , Range(0.001,1)) = 0.2
}
SubShader
{
Tags
{
"RenderPipeline"="UniversalPipeline"
"Queue"="Geometry"
"RenderType"="Opaque"
}
HLSLINCLUDE
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
CBUFFER_START(UnityPerMaterial)
float4 _BaseColor;
float4 _Splat0_ST;
float4 _Splat0_Color;
float4 _SpecularColor;
float4 _BumpSplat0_ST;
float4 _Splat1_ST;
float4 _Splat1_Color;
float4 _BumpSplat1_ST;
float4 _Splat2_ST;
float4 _Splat2_Color;
float4 _BumpSplat2_ST;
float4 _Splat3_ST;
float4 _Splat3_Color;
float4 _BumpSplat3_ST;
float4 _Control_ST;
//float _Control;
float _Weight;
float _Smoothness;
float _Cutoff;
float _BumpSplat0Scale;
float _BumpSplat1Scale;
float _BumpSplat2Scale;
float _BumpSplat3Scale;
TEXTURE2D(_Splat0);
SAMPLER(sampler_Splat0);
TEXTURE2D(_Splat1);
SAMPLER(sampler_Splat1);
TEXTURE2D(_Splat2);
SAMPLER(sampler_Splat2);
TEXTURE2D(_Splat3);
SAMPLER(sampler_Splat3);
TEXTURE2D(_Control);
SAMPLER(sampler_Control);
TEXTURE2D(_BumpSplat0);
SAMPLER(sampler_BumpSplat0);
TEXTURE2D(_BumpSplat1);
SAMPLER(sampler_BumpSplat1);
TEXTURE2D(_BumpSplat2);
SAMPLER(sampler_BumpSplat2);
TEXTURE2D(_BumpSplat3);
SAMPLER(sampler_BumpSplat3);
CBUFFER_END
float4 _BaseMap_ST;
ENDHLSL
Pass
{
Name "URPSimpleLit"
Tags{"LightMode"="UniversalForward"}
HLSLPROGRAM
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#pragma vertex vert
#pragma fragment frag
struct Attributes
{
float4 positionOS : POSITION;
float4 normalOS : NORMAL;
float4 tangentOS : TANGENT;
float2 uv0 : TEXCOORD0;
float2 uv1 : TEXCOORD1;
float2 uv2 : TEXCOORD2;
float2 uv3 : TEXCOORD3;
float2 uv4 : TEXCOORD4;
};
struct Varings
{
float4 positionCS : SV_POSITION;
float2 uv0 : TEXCOORD0;
float2 uv1 : TEXCOORD1;
float2 uv2 : TEXCOORD2;
float2 uv3 : TEXCOORD3;
float2 uv4 : TEXCOORD4;
float3 positionWS : TEXCOORD5;
float3 viewDirWS : TEXCOORD6;
float3 normalWS : NORMAL_WS;
//float3 normalWS1 : NORMAL_WS;
float4 tangentWS : TANGENT_WS;
};
inline float4 Blend(float depth1 ,float depth2,float depth3,float depth4 , float4 control)
{
float4 blend ;
blend.r =depth1 * control.r;
blend.g =depth2 * control.g;
blend.b =depth3 * control.b;
blend.a =depth4 * control.a;
float ma = max(blend.r, max(blend.g, max(blend.b, blend.a)));
blend = max(blend - ma +_Weight , 0) * control;
return blend/(blend.r + blend.g + blend.b + blend.a);
}
Varings vert(Attributes IN)
{
Varings OUT;
VertexPositionInputs positionInputs = GetVertexPositionInputs(IN.positionOS.xyz);
VertexNormalInputs normalInputs = GetVertexNormalInputs(IN.normalOS.xyz);
real sign = IN.tangentOS.w * GetOddNegativeScale();
OUT.positionCS = positionInputs.positionCS;
OUT.positionWS = positionInputs.positionWS;
OUT.viewDirWS = GetCameraPositionWS() - positionInputs.positionWS;
OUT.normalWS = normalInputs.normalWS;
OUT.tangentWS = real4(normalInputs.tangentWS, sign);
OUT.uv0=TRANSFORM_TEX(IN.uv0,_Splat0);
OUT.uv1=TRANSFORM_TEX(IN.uv1,_Splat1);
OUT.uv2=TRANSFORM_TEX(IN.uv2,_Splat2);
OUT.uv3=TRANSFORM_TEX(IN.uv3,_Splat3);
OUT.uv4=TRANSFORM_TEX(IN.uv4,_Control);
return OUT;
}
float4 frag(Varings IN):SV_Target
{
//
float4 splat_control = SAMPLE_TEXTURE2D(_Control, sampler_Control, IN.uv4);
//纹理贴图
float4 lay1 = SAMPLE_TEXTURE2D(_Splat0, sampler_Splat0, IN.uv0);
float4 lay2 = SAMPLE_TEXTURE2D(_Splat1, sampler_Splat1, IN.uv1);
float4 lay3 = SAMPLE_TEXTURE2D(_Splat2, sampler_Splat2, IN.uv2);
float4 lay4 = SAMPLE_TEXTURE2D(_Splat3, sampler_Splat3, IN.uv3);
//Bump贴图
float3 nor1TS = UnpackNormalScale(SAMPLE_TEXTURE2D (_BumpSplat0, sampler_BumpSplat0,IN.uv0),_BumpSplat0Scale);
float3 nor2TS = UnpackNormalScale(SAMPLE_TEXTURE2D (_BumpSplat1, sampler_BumpSplat1,IN.uv1),_BumpSplat1Scale);
float3 nor3TS = UnpackNormalScale(SAMPLE_TEXTURE2D (_BumpSplat2, sampler_BumpSplat2,IN.uv2),_BumpSplat2Scale);
float3 nor4TS = UnpackNormalScale(SAMPLE_TEXTURE2D (_BumpSplat3, sampler_BumpSplat3,IN.uv3),_BumpSplat3Scale);
//BaseColor附加到各个图层
lay1.rgb*=lay1.rgb*_Splat0_Color.rgb;
lay2.rgb*=lay2.rgb*_Splat1_Color.rgb;
lay3.rgb*=lay3.rgb*_Splat2_Color.rgb;
lay4.rgb*=lay4.rgb*_Splat3_Color.rgb;
//Normal计算
real sgn = IN.tangentWS.w;
real3 bitangent = sgn * cross(IN.normalWS.xyz, IN.tangentWS.xyz);
real3 nor1WS = mul(nor1TS, real3x3(IN.tangentWS.xyz, bitangent.xyz, IN.normalWS.xyz));
real3 nor2WS = mul(nor2TS, real3x3(IN.tangentWS.xyz, bitangent.xyz, IN.normalWS.xyz));
real3 nor3WS = mul(nor3TS, real3x3(IN.tangentWS.xyz, bitangent.xyz, IN.normalWS.xyz));
real3 nor4WS = mul(nor4TS, real3x3(IN.tangentWS.xyz, bitangent.xyz, IN.normalWS.xyz)); // 转换至世界空间
//计算混合
float4 blend = Blend(lay1.a,lay2.a,lay3.a,lay4.a,splat_control);
float3 blendNor = nor1WS*blend.r+nor2WS*blend.g+nor3WS*blend.b+nor4WS*blend.a;
//计算主光
Light light = GetMainLight();
float3 diffuse = LightingLambert(light.color, light.direction, IN.normalWS);
float3 specular = LightingSpecular(light.color, light.direction, normalize(blendNor), normalize(IN.viewDirWS), _SpecularColor, _Smoothness);
//计算附加光照
uint pixelLightCount = GetAdditionalLightsCount();
for (uint lightIndex = 0; lightIndex < pixelLightCount; ++lightIndex)
{
Light light = GetAdditionalLight(lightIndex, IN.positionWS);
diffuse += LightingLambert(light.color, light.direction, IN.normalWS);
specular += LightingSpecular(light.color, light.direction, normalize(blendNor), normalize(IN.viewDirWS), _SpecularColor, _Smoothness);
}
float3 basecolor=lay1.rgb *blend.r + lay2.rgb* blend.g + lay3.rgb * blend.b + lay4.rgb * blend.a;//混合
float4 ambient=float4(SampleSH(blendNor), 1.0)*(basecolor,0);
float3 diff=saturate(dot(light.direction,blendNor))*basecolor;
real3 viewDirectionWS = SafeNormalize(GetCameraPositionWS() - IN.positionWS); // safe防止分母为0
real3 h = SafeNormalize(viewDirectionWS + light.direction);
float3 color=diff*diffuse+specular+ambient.rgb;
clip(lay1.a*lay2.a*lay3.a*lay4.a-_Cutoff);
return float4(color,0);
}
ENDHLSL
}
Pass
{
Name "ShadowCaster"
Tags{"LightMode" = "ShadowCaster"}
ZWrite On
ZTest LEqual
Cull[_Cull]
HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma target 2.0
// -------------------------------------
// Material Keywords
#pragma shader_feature _ALPHATEST_ON
#pragma shader_feature _GLOSSINESS_FROM_BASE_ALPHA
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#pragma vertex ShadowPassVertex
#pragma fragment ShadowPassFragment
//由于这段代码中声明了自己的CBUFFER,与我们需要的不一样,所以我们注释掉他
//#include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.hlsl"
//它还引入了下面2个hlsl文件
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/ShadowCasterPass.hlsl"
ENDHLSL
}
}
}