Skip to content

Commit c56554b

Browse files
authored
Merge pull request #454 from dbastienMS/master
Adding fast configurable shader
2 parents 32c3be5 + 9c9f1b4 commit c56554b

File tree

5 files changed

+454
-0
lines changed

5 files changed

+454
-0
lines changed

Assets/HoloToolkit/Utilities/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@ Provides dynamic Text to Speech. Speech is generated using the UWP SpeechSynthes
5757

5858
### [Shaders](Shaders)
5959

60+
### FastConfigurable.shader
61+
Very fast shader that uses the Unity light system. Compiles down to only performing the operations you're actually using. Uses material property drawers rather than a custom editor for ease of maintenance.
62+
63+
#### HoloToolkitCommon.cginc
64+
Common shader functionality
65+
6066
#### LambertianConfigurable.cginc
6167
Code shared between LambertianConfigurable.shader and LambertianConfigurableTransparent.shader.
6268

@@ -66,6 +72,9 @@ Feature configurable per-pixel lambertian shader. Use when higher quality light
6672
#### LambertianConfigurableTransparent.shader
6773
Feature configurable per-pixel lambertian transparent shader. Use when higher quality lighting and transparency are desired, but specular highlights are not needed.
6874

75+
#### macro.cginc
76+
Preprocessor macros to support shaders
77+
6978
#### StandardFast.shader
7079
Higher performance drop-in replacement for the Unity Standard Shader. Use when very high quality lighting (including reflections) is needed.
7180

Lines changed: 360 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,360 @@
1+
// Very fast shader that uses the Unity light system.
2+
// Compiles down to only performing the operations you're actually using.
3+
// Uses material property drawers rather than a custom editor for ease of maintenance.
4+
5+
// Textured ambient+diffuse:
6+
// Stats for Vertex shader:
7+
// d3d11: 24 avg math (9..44)
8+
// Stats for Fragment shader:
9+
// d3d11: 2 avg math (1..5), 0 avg texture (0..2)
10+
11+
Shader "HoloToolkit/Fast Configurable"
12+
{
13+
Properties
14+
{
15+
[Header(Base Texture and Color)]
16+
[Indent]
17+
[Toggle] _UseVertexColor("Vertex Color Enabled?", Float) = 0
18+
[Toggle] _UseMainColor("Main Color Enabled?", Float) = 0
19+
_Color("Main Color", Color) = (1,1,1,1)
20+
[Toggle] _UseMainTex("Main Texture Enabled?", Float) = 0
21+
[NoScaleOffset]_MainTex("Main Texture", 2D) = "red" {}
22+
[Toggle] _UseOcclusionMap("Occlusion/Detail Texture Enabled?", Float) = 0
23+
[NoScaleOffset]_OcclusionMap("Occlusion/Detail Texture", 2D) = "blue" {}
24+
[Dedent]
25+
26+
[Space(12)]
27+
[Header(Lighting)]
28+
[Indent]
29+
[Toggle] _UseAmbient("Ambient Lighting Enabled?", Float) = 1
30+
[Toggle] _UseDiffuse("Diffuse Lighting Enabled?", Float) = 1
31+
[Toggle] _UseSpecular("Specular Lighting Enabled?", Float) = 0
32+
[Toggle] _Shade4("Use additional lighting data? (Expensive!)", Float) = 0
33+
_SpecularColor("Specular Color", Color) = (0.5, 0.5, 0.5, 1)
34+
[PowerSlider(5.0)]_SpecularPower("Specular Power", Range(1.0, 100.0)) = 10.0
35+
_SpecularScale("Specular Scale", Range(0.1, 10.0)) = 1.0
36+
[Toggle] _UseBumpMap("Normal Map Enabled? (Expensive!)", Float) = 0
37+
[NoScaleOffset][Normal] _BumpMap("Normal Map", 2D) = "bump" {}
38+
[Dedent]
39+
40+
[Space(12)]
41+
[Header(Emission)]
42+
[Indent]
43+
[Toggle] _UseEmissionColor("Emission Color Enabled?", Float) = 0
44+
_EmissionColor("Emission Color", Color) = (1,1,1,1)
45+
[Toggle] _UseEmissionTex("Emission Texture Enabled?", Float) = 0
46+
[NoScaleOffset] _EmissionTex("Emission Texture", 2D) = "blue" {}
47+
[Dedent]
48+
49+
[Space(12]
50+
[Header(Texture Scale and Offset)]
51+
[Indent]
52+
[Toggle] _MainTex_SCALE("Use Texture Scale? (Applies to all textures)", Float) = 0
53+
[Toggle] _MainTex_OFFSET("Use Texture Offset? (Applies to all textures)", Float) = 0
54+
_TextureScaleOffset("Texture Scale (XY) and Offset (ZW)", Vector) = (1, 1, 0, 0)
55+
[Dedent]
56+
57+
[Space(12)]
58+
[Header(Alpha Blending)]
59+
[Indent]
60+
[Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend("SrcBlend", Float) = 1 //"One"
61+
[Enum(UnityEngine.Rendering.BlendMode)] _DstBlend("DestBlend", Float) = 0 //"Zero"
62+
[Enum(UnityEngine.Rendering.BlendOp)] _BlendOp("BlendOp", Float) = 0 //"Add"
63+
[Dedent]
64+
65+
[Space(12)]
66+
[Header(Misc.)]
67+
[Indent]
68+
[Enum(UnityEngine.Rendering.CullMode)] _Cull("Cull", Float) = 2 //"Back"
69+
[Enum(UnityEngine.Rendering.CompareFunction)] _ZTest("ZTest", Float) = 4 //"LessEqual"
70+
[Enum(Off,0,On,1)] _ZWrite("ZWrite", Float) = 1 //"On"
71+
[Enum(UnityEngine.Rendering.ColorWriteMask)] _ColorWriteMask("ColorWriteMask", Float) = 15 //"All"
72+
}
73+
74+
SubShader
75+
{
76+
Tags { "RenderType"="Opaque" "PerformanceChecks"="False" }
77+
LOD 100
78+
Blend[_SrcBlend][_DstBlend]
79+
BlendOp[_BlendOp]
80+
ZTest[_ZTest]
81+
ZWrite[_ZWrite]
82+
Cull[_Cull]
83+
ColorMask[_ColorWriteMask]
84+
85+
Pass
86+
{
87+
Name "FORWARD"
88+
Tags { "LightMode" = "ForwardBase" }
89+
90+
CGPROGRAM
91+
#pragma vertex vert
92+
#pragma fragment frag
93+
94+
//compiles all variants needed by ForwardBase (forward rendering base) pass type. The variants deal with different lightmap types and main directional light having shadows on or off.
95+
#pragma multi_compile_fwdbase
96+
97+
//expands to several variants to handle different fog types
98+
#pragma multi_compile_fog
99+
100+
#pragma fragmentoption ARB_precision_hint_fastest
101+
102+
// We only target the HoloLens (and the Unity editor), so take advantage of shader model 5.
103+
#pragma target 5.0
104+
#pragma only_renderers d3d11
105+
106+
//shader features are only compiled if a material uses them
107+
#pragma shader_feature _USEMAINCOLOR_ON
108+
#pragma shader_feature _USEMAINTEX_ON
109+
#pragma shader_feature _USESOCCLUSIONMAP_ON
110+
#pragma shader_feature _USEBUMPMAP_ON
111+
#pragma shader_feature _USEAMBIENT_ON
112+
#pragma shader_feature _USEDIFFUSE_ON
113+
#pragma shader_feature _USESPECULAR_ON
114+
#pragma shader_feature _SHADE4_ON
115+
#pragma shader_feature _USEEMISSIONCOLOR_ON
116+
#pragma shader_feature _USEEMISSIONTEX_ON
117+
118+
//scale and offset will apply to all
119+
#pragma shader_feature _MainTex_SCALE_ON
120+
#pragma shader_feature _MainTex_OFFSET_ON
121+
122+
//may be set from script so generate both paths
123+
#pragma multi_compile __ _NEAR_PLANE_FADE_ON
124+
125+
#include "HLSLSupport.cginc"
126+
#include "UnityCG.cginc"
127+
#include "Lighting.cginc"
128+
#include "AutoLight.cginc"
129+
130+
#include "HoloToolkitCommon.cginc"
131+
#include "macro.cginc"
132+
133+
#if _USEMAINCOLOR_ON
134+
float4 _Color;
135+
#endif
136+
137+
#if _USEMAINTEX_ON
138+
UNITY_DECLARE_TEX2D(_MainTex);
139+
#endif
140+
141+
#if _USEMAINTEX_ON
142+
UNITY_DECLARE_TEX2D(_SecondaryTex);
143+
#endif
144+
145+
#if _USEBUMPMAP_ON
146+
UNITY_DECLARE_TEX2D(_BumpMap);
147+
#endif
148+
149+
#if _USESPECULAR_ON
150+
float3 _SpecularColor;
151+
float _SpecularPower;
152+
float _SpecularScale;
153+
#endif
154+
155+
#if _USEEMISSIONCOLOR_ON
156+
float4 _EmissionColor;
157+
#endif
158+
159+
#if _USEEMISSIONTEX_ON
160+
UNITY_DECLARE_TEX2D(_EmissionTex);
161+
#endif
162+
163+
float4 _TextureScaleOffset;
164+
165+
struct a2v
166+
{
167+
float4 vertex : POSITION;
168+
169+
#if _USEBUMPMAP_ON
170+
#else
171+
float3 normal : NORMAL;
172+
#endif
173+
174+
#if _USEVERTEXCOLOR_ON
175+
float4 color : COLOR;
176+
#endif
177+
#if _USEMAINTEX_ON || _USEOCCLUSIONMAP_ON || _USEEMISSIONTEX_ON || _USEBUMPMAP_ON
178+
float2 texcoord : TEXCOORD0;
179+
#endif
180+
181+
UNITY_VERTEX_INPUT_INSTANCE_ID
182+
};
183+
184+
struct v2f
185+
{
186+
float4 pos : SV_POSITION;
187+
188+
#if _USEVERTEXCOLOR_ON
189+
float4 color : COLOR;
190+
#endif
191+
192+
#if _USEMAINTEX_ON || _USEOCCLUSIONMAP_ON || _USEEMISSIONTEX_ON || _USEBUMPMAP_ON || _NEAR_PLANE_FADE_ON
193+
float3 texXYFadeZ : TEXCOORD0;
194+
#endif
195+
196+
#if LIGHTMAP_ON
197+
float2 lmap : TEXCOORD1;
198+
#else
199+
float3 vertexLighting : TEXCOORD1;
200+
#endif
201+
202+
#if _USEBUMPMAP_ON && (_USESPECULAR_ON || _SHADE4_ON)
203+
float3 worldPos: TEXCOORD2;
204+
#endif
205+
206+
LIGHTING_COORDS(3, 4)
207+
UNITY_FOG_COORDS(5)
208+
UNITY_VERTEX_OUTPUT_STEREO
209+
};
210+
211+
v2f vert(a2v v)
212+
{
213+
v2f o;
214+
UNITY_SETUP_INSTANCE_ID(v);
215+
UNITY_INITIALIZE_OUTPUT(v2f, o);
216+
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
217+
218+
o.pos = UnityObjectToClipPos(v.vertex);
219+
220+
#if _USEVERTEXCOLOR_ON
221+
#if _USEMAINCOLOR_ON
222+
o.color = v.color * _Color;
223+
#else
224+
o.color = v.color;
225+
#endif
226+
#endif
227+
228+
#if (_USESPECULAR_ON && _USEBUMPMAP_ON) || _SHADE4_ON
229+
float4 worldPos = mul(unity_ObjectToWorld, v.vertex);
230+
#endif
231+
232+
#if _USEBUMPMAP_ON && (_USESPECULAR_ON || _SHADE4_ON)
233+
o.worldPos = worldPos;
234+
#endif
235+
236+
#if _USEMAINTEX_ON || _USEOCCLUSIONMAP_ON || _USEEMISSIONTEX_ON || _USEBUMPMAP_ON
237+
o.texXYFadeZ.xy = TRANSFORM_TEX_MAINTEX(v.texcoord.xy, _TextureScaleOffset);
238+
#endif
239+
240+
#if LIGHTMAP_ON
241+
o.lmap.xy = v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
242+
#else
243+
#if _USEBUMPMAP_ON
244+
//no bump maps, do per-vertex lighting
245+
#else
246+
float3 normalWorld = UnityObjectToWorldNormal(v.normal);
247+
#if _USEAMBIENT_ON
248+
//grab ambient color from Unity's spherical harmonics
249+
o.vertexLighting += ShadeSH9(float4(normalWorld, 1.0));
250+
#endif
251+
#if _USEDIFFUSE_ON
252+
o.vertexLighting += HoloTKLightingLambertian(normalWorld, _WorldSpaceLightPos0.xyz, _LightColor0.rgb);
253+
#endif
254+
#if _USESPECULAR_ON
255+
o.vertexLighting += HoloTKLightingBlinnPhong(normalWorld, _WorldSpaceLightPos0.xyz, _LightColor0.rgb, UnityWorldSpaceViewDir(mul(unity_ObjectToWorld, v.vertex)), _SpecularPower, _SpecularScale, _SpecularColor);
256+
#endif
257+
258+
#if _SHADE4_ON
259+
//handles point and spot lights
260+
o.vertexLighting += Shade4PointLights(unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0,
261+
unity_LightColor[0].rgb, unity_LightColor[1].rgb, unity_LightColor[2].rgb, unity_LightColor[3].rgb,
262+
unity_4LightAtten0, worldPos, normalWorld);
263+
#endif
264+
#endif
265+
#endif
266+
267+
//fade away objects closer to the camera
268+
#if _NEAR_PLANE_FADE_ON
269+
o.texXYFadeZ.z = ComputeNearPlaneFadeLinear(v.vertex);
270+
#endif
271+
272+
TRANSFER_VERTEX_TO_FRAGMENT(o);
273+
UNITY_TRANSFER_FOG(o, o.pos);
274+
return o;
275+
}
276+
277+
float4 frag(v2f IN) : SV_Target
278+
{
279+
#if _USEMAINTEX_ON
280+
float4 color = UNITY_SAMPLE_TEX2D(_MainTex, IN.texXYFadeZ.xy);
281+
#else
282+
float4 color = 1;
283+
#endif
284+
285+
#if _USEOCCLUSIONMAP_ON
286+
color *= UNITY_SAMPLE_TEX2D(_OcclusionMap, IN.texXYFadeZ.xy);
287+
#endif
288+
289+
#if _USEVERTEXCOLOR_ON
290+
color *= IN.color;
291+
//if vertex color is on, we've already scaled it by the main color if needed in the vertex shader
292+
#elif _USEMAINCOLOR_ON
293+
color *= _Color;
294+
#endif
295+
296+
//light attenuation from shadows cast onto the object
297+
float lightAttenuation = SHADOW_ATTENUATION(IN);
298+
float3 lightColorShadowAttenuated = 0;
299+
300+
#if LIGHTMAP_ON
301+
float3 lightmapResult = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, IN.lmap.xy));
302+
#ifdef SHADOWS_SCREEN
303+
lightColorShadowAttenuated = min(lightmapResult, lightAttenuation * 2);
304+
#else
305+
lightColorShadowAttenuated = lightmapResult;
306+
#endif
307+
#else //not using lightmapping
308+
#if _USEBUMPMAP_ON
309+
//if a normal map is on, it makes sense to do most calculations per-pixel
310+
//unpack can be expensive if normal map is dxt5
311+
float3 normalObject = UnpackNormal(UNITY_SAMPLE_TEX2D(_BumpMap, IN.texXYFadeZ.xy));
312+
float3 normalWorld = UnityObjectToWorldNormal(normalObject);
313+
#if _USEAMBIENT_ON
314+
//grab ambient color from Unity's spherical harmonics
315+
lightColorShadowAttenuated += ShadeSH9(float4(normalWorld, 1.0));
316+
#endif
317+
#if _USEDIFFUSE_ON
318+
lightColorShadowAttenuated += HoloTKLightingLambertian(normalWorld, _WorldSpaceLightPos0.xyz, _LightColor0.rgb);
319+
#endif
320+
#if _USESPECULAR_ON
321+
lightColorShadowAttenuated += HoloTKLightingBlinnPhong(normalWorld, _WorldSpaceLightPos0.xyz, _LightColor0.rgb, UnityWorldSpaceViewDir(IN.worldPos), _SpecularPower, _SpecularScale, _SpecularColor);
322+
#endif
323+
#if _SHADE4_ON
324+
//This handles point and directional lights
325+
lightColorShadowAttenuated += Shade4PointLights(unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0,
326+
unity_LightColor[0].rgb, unity_LightColor[1].rgb, unity_LightColor[2].rgb, unity_LightColor[3].rgb,
327+
unity_4LightAtten0, IN.worldPos, normalWorld);
328+
#endif
329+
#else
330+
//no normal map, so vertex lighting is sufficient
331+
lightColorShadowAttenuated = IN.vertexLighting;
332+
#endif
333+
//could save some work here in the 0 case
334+
lightColorShadowAttenuated *= lightAttenuation;
335+
#endif
336+
337+
color.rgb *= lightColorShadowAttenuated;
338+
339+
#if _USEEMISSIONTEX_ON
340+
color.rgb += UNITY_SAMPLE_TEX2D(_EmissionTex, IN.texXYFadeZ.xy);
341+
#endif
342+
343+
#if _USEEMISSIONCOLOR_ON
344+
color.rgb += _EmissionColor;
345+
#endif
346+
347+
#if _NEAR_PLANE_FADE_ON
348+
color.rgb *= IN.texXYFadeZ.z;
349+
#endif
350+
351+
UNITY_APPLY_FOG(IN.fogCoord, color);
352+
353+
return color;
354+
}
355+
356+
ENDCG
357+
}
358+
}
359+
Fallback "VertexLit" //for shadows
360+
}

Assets/HoloToolkit/Utilities/Shaders/FastConfigurable.shader.meta

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)