您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

186 行
6.2 KiB

// Example shader for a scriptable render loop that calculates multiple lights
// in a single forward-rendered shading pass.
// The parameters and inspector of the shader are the same as Standard shader,
// for easier experimentation.
Shader "RenderLoop/Basic/Standard"
{
// Properties is just a copy of Standard.shader. Our example shader does not use all of them,
// but the inspector UI expects all these to exist.
Properties
{
_Color("Color", Color) = (1,1,1,1)
_MainTex("Albedo", 2D) = "white" {}
_Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
_Glossiness("Smoothness", Range(0.0, 1.0)) = 0.5
_GlossMapScale("Smoothness Scale", Range(0.0, 1.0)) = 1.0
[Enum(Metallic Alpha,0,Albedo Alpha,1)] _SmoothnessTextureChannel ("Smoothness texture channel", Float) = 0
[Gamma] _Metallic("Metallic", Range(0.0, 1.0)) = 0.0
_MetallicGlossMap("Metallic", 2D) = "white" {}
[ToggleOff] _SpecularHighlights("Specular Highlights", Float) = 1.0
[ToggleOff] _GlossyReflections("Glossy Reflections", Float) = 1.0
_BumpScale("Scale", Float) = 1.0
_BumpMap("Normal Map", 2D) = "bump" {}
_Parallax ("Height Scale", Range (0.005, 0.08)) = 0.02
_ParallaxMap ("Height Map", 2D) = "black" {}
_OcclusionStrength("Strength", Range(0.0, 1.0)) = 1.0
_OcclusionMap("Occlusion", 2D) = "white" {}
_EmissionColor("Color", Color) = (0,0,0)
_EmissionMap("Emission", 2D) = "white" {}
_DetailMask("Detail Mask", 2D) = "white" {}
_DetailAlbedoMap("Detail Albedo x2", 2D) = "grey" {}
_DetailNormalMapScale("Scale", Float) = 1.0
_DetailNormalMap("Normal Map", 2D) = "bump" {}
[Enum(UV0,0,UV1,1)] _UVSec("UV Set for secondary textures", Float) = 0
[HideInInspector] _Mode("__mode", Float) = 0.0
[HideInInspector] _SrcBlend("__src", Float) = 1.0
[HideInInspector] _DstBlend("__dst", Float) = 0.0
[HideInInspector] _ZWrite("__zw", Float) = 1.0
}
SubShader
{
Tags { "RenderType" = "Opaque" "PerformanceChecks" = "False" }
LOD 300
// Include forward (base + additive) pass from regular Standard shader.
// They are not used by the scriptable render loop; only here so that
// if we turn off our example loop, then regular forward rendering kicks in
// and objects look just like with a Standard shader.
UsePass "Standard/FORWARD"
UsePass "Standard/FORWARD_DELTA"
// Multiple lights at once pass, for our example Basic render loop.
Pass
{
Tags { "LightMode" = "BasicPass" }
// Use same blending / depth states as Standard shader
Blend[_SrcBlend][_DstBlend]
ZWrite[_ZWrite]
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
// Global lighting data (setup from C# code once per frame).
CBUFFER_START(GlobalLightData)
// The variables are very similar to built-in unity_LightColor, unity_LightPosition,
// unity_LightAtten, unity_SpotDirection as used by the VertexLit shaders, except here
// we use world space positions instead of view space.
half4 globalLightColor[8];
float4 globalLightPos[8];
float4 globalLightSpotDir[8];
float4 globalLightAtten[8];
int4 globalLightCount;
// Global ambient/SH probe, similar to unity_SH* built-in variables.
float4 globalSH[7];
CBUFFER_END
struct v2f
{
float2 uv : TEXCOORD0;
float3 positionWS : TEXCOORD1;
float3 normalWS : TEXCOORD2;
float4 hpos : SV_POSITION;
};
float4 _MainTex_ST;
v2f vert(appdata_base v)
{
v2f o;
o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);
o.hpos = UnityObjectToClipPos(v.vertex);
o.positionWS = mul(unity_ObjectToWorld, v.vertex).xyz;
o.normalWS = UnityObjectToWorldNormal(v.normal);
return o;
}
// Compute illumination from one light, given attenuation
half3 ComputeLighting(int idx, half3 dirToLight, half3 normalWS, half4 diffuseAlbedo, float atten)
{
half NdotL = max(dot(normalWS, dirToLight), 0.0);
// diffuse
half3 color = NdotL * diffuseAlbedo.rgb * globalLightColor[idx].rgb;
return color * atten;
}
// Compute attenuation & illumination from one light
half3 ComputeOneLight(int idx, float3 positionWS, half3 normalWS, half4 diffuseAlbedo)
{
float3 dirToLight = globalLightPos[idx].xyz;
dirToLight -= positionWS * globalLightPos[idx].w;
// distance attenuation
float att = 1.0;
float distSqr = dot(dirToLight, dirToLight);
att /= (1.0 + globalLightAtten[idx].z * distSqr);
if (globalLightPos[idx].w != 0 && distSqr > globalLightAtten[idx].w) att = 0.0; // set to 0 if outside of range
distSqr = max(distSqr, 0.000001); // don't produce NaNs if some vertex position overlaps with the light
dirToLight *= rsqrt(distSqr);
// spot angle attenuation
float rho = max(dot(dirToLight, globalLightSpotDir[idx].xyz), 0.0);
float spotAtt = (rho - globalLightAtten[idx].x) * globalLightAtten[idx].y;
att *= saturate(spotAtt);
return min(ComputeLighting(idx, dirToLight, normalWS, diffuseAlbedo, att), 1.0);
}
// Evaluate 2nd order spherical harmonics, given normalized world space direction.
// Similar to ShadeSH9 in UnityCG.cginc
half3 EvaluateSH(half3 n)
{
half3 res;
half4 normal = half4(n, 1);
// Linear (L1) + constant (L0) polynomial terms
res.r = dot(globalSH[0], normal);
res.g = dot(globalSH[1], normal);
res.b = dot(globalSH[2], normal);
// 4 of the quadratic (L2) polynomials
half4 vB = normal.xyzz * normal.yzzx;
res.r += dot(globalSH[3], vB);
res.g += dot(globalSH[4], vB);
res.b += dot(globalSH[5], vB);
// Final (5th) quadratic (L2) polynomial
half vC = normal.x*normal.x - normal.y*normal.y;
res += globalSH[6].rgb * vC;
return res;
}
sampler2D _MainTex;
// Main pixel shader
half4 frag(v2f i) : SV_Target
{
half4 diffuseAlbedo = tex2D(_MainTex, i.uv);
// Ambient lighting
half4 color = half4(0,0,0, diffuseAlbedo.a);
color.rgb += EvaluateSH(i.normalWS) * diffuseAlbedo.rgb;
// Add illumination from all lights
for (int il = 0; il < globalLightCount.x; ++il)
{
color.rgb += ComputeOneLight(il, i.positionWS, i.normalWS, diffuseAlbedo);
}
return color;
}
ENDCG
}
}
CustomEditor "StandardShaderGUI"
}