暫無描述
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SpeedTree8Passes.hlsl 22KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  1. #ifndef UNIVERSAL_SPEEDTREE8_PASSES_INCLUDED
  2. #define UNIVERSAL_SPEEDTREE8_PASSES_INCLUDED
  3. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
  4. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityGBuffer.hlsl"
  5. #include "SpeedTreeUtility.hlsl"
  6. #if defined(LOD_FADE_CROSSFADE)
  7. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl"
  8. #endif
  9. struct SpeedTreeVertexInput
  10. {
  11. float4 vertex : POSITION;
  12. float3 normal : NORMAL;
  13. float4 tangent : TANGENT;
  14. float4 texcoord : TEXCOORD0;
  15. float4 texcoord1 : TEXCOORD1;
  16. float4 texcoord2 : TEXCOORD2;
  17. float4 texcoord3 : TEXCOORD3;
  18. float4 color : COLOR;
  19. UNITY_VERTEX_INPUT_INSTANCE_ID
  20. };
  21. struct SpeedTreeVertexOutput
  22. {
  23. half2 uv : TEXCOORD0;
  24. half4 color : TEXCOORD1;
  25. half4 fogFactorAndVertexLight : TEXCOORD2; // x: fogFactor, yzw: vertex light
  26. #ifdef EFFECT_BUMP
  27. half4 normalWS : TEXCOORD3; // xyz: normal, w: viewDir.x
  28. half4 tangentWS : TEXCOORD4; // xyz: tangent, w: viewDir.y
  29. half4 bitangentWS : TEXCOORD5; // xyz: bitangent, w: viewDir.z
  30. #else
  31. half3 normalWS : TEXCOORD3;
  32. half3 viewDirWS : TEXCOORD4;
  33. #endif
  34. #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
  35. float4 shadowCoord : TEXCOORD6;
  36. #endif
  37. float3 positionWS : TEXCOORD7;
  38. DECLARE_LIGHTMAP_OR_SH(lightmapUV, vertexSH, 8);
  39. float4 clipPos : SV_POSITION;
  40. UNITY_VERTEX_INPUT_INSTANCE_ID
  41. UNITY_VERTEX_OUTPUT_STEREO
  42. };
  43. struct SpeedTreeVertexDepthOutput
  44. {
  45. half2 uv : TEXCOORD0;
  46. half4 color : TEXCOORD1;
  47. half3 viewDirWS : TEXCOORD2;
  48. float4 clipPos : SV_POSITION;
  49. UNITY_VERTEX_INPUT_INSTANCE_ID
  50. UNITY_VERTEX_OUTPUT_STEREO
  51. };
  52. struct SpeedTreeVertexDepthNormalOutput
  53. {
  54. half2 uv : TEXCOORD0;
  55. half4 color : TEXCOORD1;
  56. #ifdef EFFECT_BUMP
  57. half4 normalWS : TEXCOORD2; // xyz: normal, w: viewDir.x
  58. half4 tangentWS : TEXCOORD3; // xyz: tangent, w: viewDir.y
  59. half4 bitangentWS : TEXCOORD4; // xyz: bitangent, w: viewDir.z
  60. #else
  61. half3 normalWS : TEXCOORD2;
  62. half3 viewDirWS : TEXCOORD3;
  63. #endif
  64. float4 clipPos : SV_POSITION;
  65. UNITY_VERTEX_INPUT_INSTANCE_ID
  66. UNITY_VERTEX_OUTPUT_STEREO
  67. };
  68. struct SpeedTreeDepthNormalFragmentInput
  69. {
  70. SpeedTreeVertexDepthNormalOutput interpolated;
  71. #ifdef EFFECT_BACKSIDE_NORMALS
  72. FRONT_FACE_TYPE facing : FRONT_FACE_SEMANTIC;
  73. #endif
  74. };
  75. struct SpeedTreeFragmentInput
  76. {
  77. SpeedTreeVertexOutput interpolated;
  78. #ifdef EFFECT_BACKSIDE_NORMALS
  79. FRONT_FACE_TYPE facing : FRONT_FACE_SEMANTIC;
  80. #endif
  81. };
  82. void InitializeData(inout SpeedTreeVertexInput input, float lodValue)
  83. {
  84. #if defined(LOD_FADE_PERCENTAGE) && (!defined(LOD_FADE_CROSSFADE) && !defined(EFFECT_BILLBOARD))
  85. input.vertex.xyz = lerp(input.vertex.xyz, input.texcoord2.xyz, lodValue);
  86. #endif
  87. // wind
  88. #if defined(ENABLE_WIND) && !defined(_WINDQUALITY_NONE)
  89. if (_WindEnabled > 0)
  90. {
  91. float3 rotatedWindVector = mul(_ST_WindVector.xyz, (float3x3)UNITY_MATRIX_M);
  92. float windLength = length(rotatedWindVector);
  93. if (windLength < 1e-5)
  94. {
  95. // sanity check that wind data is available
  96. return;
  97. }
  98. rotatedWindVector /= windLength;
  99. float3 treePos = float3(UNITY_MATRIX_M[0].w, UNITY_MATRIX_M[1].w, UNITY_MATRIX_M[2].w);
  100. float3 windyPosition = input.vertex.xyz;
  101. #ifndef EFFECT_BILLBOARD
  102. // geometry type
  103. float geometryType = (int)(input.texcoord3.w + 0.25);
  104. bool leafTwo = false;
  105. if (geometryType > GEOM_TYPE_FACINGLEAF)
  106. {
  107. geometryType -= 2;
  108. leafTwo = true;
  109. }
  110. // leaves
  111. if (geometryType > GEOM_TYPE_FROND)
  112. {
  113. // remove anchor position
  114. float3 anchor = float3(input.texcoord1.zw, input.texcoord2.w);
  115. windyPosition -= anchor;
  116. if (geometryType == GEOM_TYPE_FACINGLEAF)
  117. {
  118. // face camera-facing leaf to camera
  119. float offsetLen = length(windyPosition);
  120. windyPosition = mul(windyPosition.xyz, (float3x3)UNITY_MATRIX_IT_MV); // inv(MV) * windyPosition
  121. windyPosition = normalize(windyPosition) * offsetLen; // make sure the offset vector is still scaled
  122. }
  123. // leaf wind
  124. #if defined(_WINDQUALITY_FAST) || defined(_WINDQUALITY_BETTER) || defined(_WINDQUALITY_BEST)
  125. #ifdef _WINDQUALITY_BEST
  126. bool bBestWind = true;
  127. #else
  128. bool bBestWind = false;
  129. #endif
  130. float leafWindTrigOffset = anchor.x + anchor.y;
  131. windyPosition = LeafWind(bBestWind, leafTwo, windyPosition, input.normal, input.texcoord3.x, float3(0,0,0), input.texcoord3.y, input.texcoord3.z, leafWindTrigOffset, rotatedWindVector);
  132. #endif
  133. // move back out to anchor
  134. windyPosition += anchor;
  135. }
  136. // frond wind
  137. bool bPalmWind = false;
  138. #ifdef _WINDQUALITY_PALM
  139. bPalmWind = true;
  140. if (geometryType == GEOM_TYPE_FROND)
  141. {
  142. windyPosition = RippleFrond(windyPosition, input.normal, input.texcoord.x, input.texcoord.y, input.texcoord3.x, input.texcoord3.y, input.texcoord3.z);
  143. }
  144. #endif
  145. // branch wind (applies to all 3D geometry)
  146. #if defined(_WINDQUALITY_BETTER) || defined(_WINDQUALITY_BEST) || defined(_WINDQUALITY_PALM)
  147. float3 rotatedBranchAnchor = normalize(mul(_ST_WindBranchAnchor.xyz, (float3x3)UNITY_MATRIX_M)) * _ST_WindBranchAnchor.w;
  148. windyPosition = BranchWind(bPalmWind, windyPosition, treePos, float4(input.texcoord.zw, 0, 0), rotatedWindVector, rotatedBranchAnchor);
  149. #endif
  150. #endif // !EFFECT_BILLBOARD
  151. // global wind
  152. float globalWindTime = _ST_WindGlobal.x;
  153. #if defined(EFFECT_BILLBOARD) && defined(UNITY_INSTANCING_ENABLED)
  154. globalWindTime += UNITY_ACCESS_INSTANCED_PROP(STWind, _GlobalWindTime);
  155. #endif
  156. windyPosition = GlobalWind(windyPosition, treePos, true, rotatedWindVector, globalWindTime);
  157. input.vertex.xyz = windyPosition;
  158. }
  159. #endif
  160. #if defined(EFFECT_BILLBOARD)
  161. float3 treePos = float3(UNITY_MATRIX_M[0].w, UNITY_MATRIX_M[1].w, UNITY_MATRIX_M[2].w);
  162. // crossfade faces
  163. bool topDown = (input.texcoord.z > 0.5);
  164. float3 viewDir = UNITY_MATRIX_IT_MV[2].xyz;
  165. float3 cameraDir = normalize(mul((float3x3)UNITY_MATRIX_M, _WorldSpaceCameraPos - treePos));
  166. float viewDot = max(dot(viewDir, input.normal), dot(cameraDir, input.normal));
  167. viewDot *= viewDot;
  168. viewDot *= viewDot;
  169. viewDot += topDown ? 0.38 : 0.18; // different scales for horz and vert billboards to fix transition zone
  170. // if invisible, avoid overdraw
  171. if (viewDot < 0.3333)
  172. {
  173. input.vertex.xyz = float3(0, 0, 0);
  174. }
  175. input.color = float4(1, 1, 1, clamp(viewDot, 0, 1));
  176. // adjust lighting on billboards to prevent seams between the different faces
  177. if (topDown)
  178. {
  179. input.normal += cameraDir;
  180. }
  181. else
  182. {
  183. half3 binormal = cross(input.normal, input.tangent.xyz) * input.tangent.w;
  184. float3 right = cross(cameraDir, binormal);
  185. input.normal = cross(binormal, right);
  186. }
  187. input.normal = normalize(input.normal);
  188. #endif
  189. }
  190. SpeedTreeVertexOutput SpeedTree8Vert(SpeedTreeVertexInput input)
  191. {
  192. SpeedTreeVertexOutput output = (SpeedTreeVertexOutput)0;
  193. UNITY_SETUP_INSTANCE_ID(input);
  194. UNITY_TRANSFER_INSTANCE_ID(input, output);
  195. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
  196. // handle speedtree wind and lod
  197. InitializeData(input, unity_LODFade.x);
  198. output.uv = input.texcoord.xy;
  199. output.color = input.color;
  200. // color already contains (ao, ao, ao, blend)
  201. // put hue variation amount in there
  202. #ifdef EFFECT_HUE_VARIATION
  203. float3 treePos = float3(UNITY_MATRIX_M[0].w, UNITY_MATRIX_M[1].w, UNITY_MATRIX_M[2].w);
  204. float hueVariationAmount = frac(treePos.x + treePos.y + treePos.z);
  205. output.color.g = saturate(hueVariationAmount * _HueVariationColor.a);
  206. #endif
  207. VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
  208. half3 normalWS = TransformObjectToWorldNormal(input.normal);
  209. half3 vertexLight = VertexLighting(vertexInput.positionWS, normalWS);
  210. half fogFactor = 0.0;
  211. #if !defined(_FOG_FRAGMENT)
  212. fogFactor = ComputeFogFactor(vertexInput.positionCS.z);
  213. #endif
  214. output.fogFactorAndVertexLight = half4(fogFactor, vertexLight);
  215. half3 viewDirWS = GetWorldSpaceNormalizeViewDir(vertexInput.positionWS);
  216. #ifdef EFFECT_BUMP
  217. real sign = input.tangent.w * GetOddNegativeScale();
  218. output.normalWS.xyz = normalWS;
  219. output.tangentWS.xyz = TransformObjectToWorldDir(input.tangent.xyz);
  220. output.bitangentWS.xyz = cross(output.normalWS.xyz, output.tangentWS.xyz) * sign;
  221. // View dir packed in w.
  222. output.normalWS.w = viewDirWS.x;
  223. output.tangentWS.w = viewDirWS.y;
  224. output.bitangentWS.w = viewDirWS.z;
  225. #else
  226. output.normalWS = normalWS;
  227. output.viewDirWS = viewDirWS;
  228. #endif
  229. output.positionWS = vertexInput.positionWS;
  230. #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
  231. output.shadowCoord = GetShadowCoord(vertexInput);
  232. #endif
  233. output.clipPos = vertexInput.positionCS;
  234. OUTPUT_SH4(vertexInput.positionWS, output.normalWS.xyz, GetWorldSpaceNormalizeViewDir(vertexInput.positionWS), output.vertexSH, output.probeOcclusion);
  235. return output;
  236. }
  237. SpeedTreeVertexDepthOutput SpeedTree8VertDepth(SpeedTreeVertexInput input)
  238. {
  239. SpeedTreeVertexDepthOutput output = (SpeedTreeVertexDepthOutput)0;
  240. UNITY_SETUP_INSTANCE_ID(input);
  241. UNITY_TRANSFER_INSTANCE_ID(input, output);
  242. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
  243. // handle speedtree wind and lod
  244. InitializeData(input, unity_LODFade.x);
  245. output.uv = input.texcoord.xy;
  246. output.color = input.color;
  247. VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
  248. output.viewDirWS = GetWorldSpaceNormalizeViewDir(vertexInput.positionWS);
  249. #ifdef SHADOW_CASTER
  250. half3 normalWS = TransformObjectToWorldNormal(input.normal);
  251. #if _CASTING_PUNCTUAL_LIGHT_SHADOW
  252. float3 lightDirectionWS = normalize(_LightPosition - vertexInput.positionWS);
  253. #else
  254. float3 lightDirectionWS = _LightDirection;
  255. #endif
  256. float4 positionCS = TransformWorldToHClip(ApplyShadowBias(vertexInput.positionWS, normalWS, lightDirectionWS));
  257. output.clipPos = positionCS;
  258. #else
  259. output.clipPos = vertexInput.positionCS;
  260. #endif
  261. return output;
  262. }
  263. void InitializeInputData(SpeedTreeFragmentInput input, half3 normalTS, out InputData inputData)
  264. {
  265. inputData = (InputData)0;
  266. inputData.positionWS = input.interpolated.positionWS.xyz;
  267. inputData.positionCS = input.interpolated.clipPos;
  268. #ifdef EFFECT_BUMP
  269. inputData.normalWS = TransformTangentToWorld(normalTS, half3x3(input.interpolated.tangentWS.xyz, input.interpolated.bitangentWS.xyz, input.interpolated.normalWS.xyz));
  270. inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS);
  271. inputData.viewDirectionWS = half3(input.interpolated.normalWS.w, input.interpolated.tangentWS.w, input.interpolated.bitangentWS.w);
  272. #else
  273. inputData.normalWS = NormalizeNormalPerPixel(input.interpolated.normalWS);
  274. inputData.viewDirectionWS = input.interpolated.viewDirWS;
  275. #endif
  276. inputData.viewDirectionWS = SafeNormalize(inputData.viewDirectionWS);
  277. #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
  278. inputData.shadowCoord = input.interpolated.shadowCoord;
  279. #elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)
  280. inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS);
  281. #else
  282. inputData.shadowCoord = float4(0, 0, 0, 0);
  283. #endif
  284. inputData.fogCoord = InitializeInputDataFog(float4(input.interpolated.positionWS, 1.0), input.interpolated.fogFactorAndVertexLight.x);
  285. inputData.vertexLighting = input.interpolated.fogFactorAndVertexLight.yzw;
  286. #if !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2))
  287. inputData.bakedGI = SAMPLE_GI(input.interpolated.vertexSH,
  288. GetAbsolutePositionWS(inputData.positionWS),
  289. inputData.normalWS,
  290. inputData.viewDirectionWS,
  291. inputData.positionCS.xy,
  292. input.probeOcclusion,
  293. inputData.shadowMask);
  294. #else
  295. inputData.bakedGI = SAMPLE_GI(NOT_USED, input.interpolated.vertexSH, inputData.normalWS);
  296. #endif
  297. inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.interpolated.clipPos);
  298. inputData.shadowMask = half4(1, 1, 1, 1); // No GI currently.
  299. #if defined(DEBUG_DISPLAY) && !defined(LIGHTMAP_ON)
  300. inputData.vertexSH = input.interpolated.vertexSH;
  301. #endif
  302. #if defined(_NORMALMAP)
  303. inputData.tangentToWorld = half3x3(input.interpolated.tangentWS.xyz, input.interpolated.bitangentWS.xyz, input.interpolated.normalWS.xyz);
  304. #endif
  305. }
  306. #ifdef GBUFFER
  307. FragmentOutput SpeedTree8Frag(SpeedTreeFragmentInput input)
  308. #else
  309. half4 SpeedTree8Frag(SpeedTreeFragmentInput input) : SV_Target
  310. #endif
  311. {
  312. UNITY_SETUP_INSTANCE_ID(input.interpolated);
  313. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input.interpolated);
  314. half2 uv = input.interpolated.uv;
  315. half4 diffuse = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex)) * _Color;
  316. half alpha = diffuse.a * input.interpolated.color.a;
  317. alpha = AlphaDiscard(alpha, 0.3333);
  318. #ifdef LOD_FADE_CROSSFADE
  319. LODFadeCrossFade(input.interpolated.clipPos);
  320. #endif
  321. half3 albedo = diffuse.rgb;
  322. half3 emission = 0;
  323. half metallic = 0;
  324. half smoothness = 0;
  325. half occlusion = 0;
  326. half3 specular = 0;
  327. // hue variation
  328. #ifdef EFFECT_HUE_VARIATION
  329. half3 shiftedColor = lerp(albedo, _HueVariationColor.rgb, input.interpolated.color.g);
  330. // preserve vibrance
  331. half maxBase = max(albedo.r, max(albedo.g, albedo.b));
  332. half newMaxBase = max(shiftedColor.r, max(shiftedColor.g, shiftedColor.b));
  333. maxBase /= newMaxBase;
  334. maxBase = maxBase * 0.5f + 0.5f;
  335. shiftedColor.rgb *= maxBase;
  336. albedo = saturate(shiftedColor);
  337. #endif
  338. // normal
  339. #ifdef EFFECT_BUMP
  340. half3 normalTs = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap));
  341. #else
  342. half3 normalTs = half3(0, 0, 1);
  343. #endif
  344. // flip normal on backsides
  345. #ifdef EFFECT_BACKSIDE_NORMALS
  346. normalTs.z = IS_FRONT_VFACE(input.facing, normalTs.z, -normalTs.z);
  347. #endif
  348. // adjust billboard normals to improve GI and matching
  349. #ifdef EFFECT_BILLBOARD
  350. normalTs.z *= 0.5;
  351. normalTs = normalize(normalTs);
  352. #endif
  353. // extra
  354. #ifdef EFFECT_EXTRA_TEX
  355. half4 extra = tex2D(_ExtraTex, uv);
  356. smoothness = extra.r;
  357. metallic = extra.g;
  358. occlusion = extra.b * input.interpolated.color.r;
  359. #else
  360. smoothness = _Glossiness;
  361. metallic = _Metallic;
  362. occlusion = input.interpolated.color.r;
  363. #endif
  364. InputData inputData;
  365. InitializeInputData(input, normalTs, inputData);
  366. SETUP_DEBUG_TEXTURE_DATA(inputData, input.interpolated.uv);
  367. #if defined(GBUFFER) || defined(EFFECT_SUBSURFACE)
  368. Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, inputData.shadowMask);
  369. #endif
  370. // subsurface (hijack emissive)
  371. #ifdef EFFECT_SUBSURFACE
  372. half fSubsurfaceRough = 0.7 - smoothness * 0.5;
  373. half fSubsurface = D_GGX(clamp(-dot(mainLight.direction.xyz, inputData.viewDirectionWS.xyz), 0, 1), fSubsurfaceRough);
  374. float4 shadowCoord = TransformWorldToShadowCoord(inputData.positionWS);
  375. half realtimeShadow = MainLightRealtimeShadow(shadowCoord);
  376. float3 tintedSubsurface = tex2D(_SubsurfaceTex, uv).rgb * _SubsurfaceColor.rgb;
  377. float3 directSubsurface = tintedSubsurface.rgb * mainLight.color.rgb * fSubsurface * realtimeShadow;
  378. float3 indirectSubsurface = tintedSubsurface.rgb * inputData.bakedGI.rgb * _SubsurfaceIndirect;
  379. emission = directSubsurface + indirectSubsurface;
  380. #endif
  381. #ifdef GBUFFER
  382. // in LitForwardPass GlobalIllumination (and temporarily LightingPhysicallyBased) are called inside UniversalFragmentPBR
  383. // in Deferred rendering we store the sum of these values (and of emission as well) in the GBuffer
  384. BRDFData brdfData;
  385. InitializeBRDFData(albedo, metallic, specular, smoothness, alpha, brdfData);
  386. MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, inputData.shadowMask);
  387. half3 color = GlobalIllumination(brdfData, inputData.bakedGI, occlusion, inputData.positionWS, inputData.normalWS, inputData.viewDirectionWS);
  388. return BRDFDataToGbuffer(brdfData, inputData, smoothness, emission + color, occlusion);
  389. #else
  390. SurfaceData surfaceData;
  391. surfaceData.albedo = albedo;
  392. surfaceData.specular = specular;
  393. surfaceData.metallic = metallic;
  394. surfaceData.smoothness = smoothness;
  395. surfaceData.normalTS = normalTs;
  396. surfaceData.emission = emission;
  397. surfaceData.occlusion = occlusion;
  398. surfaceData.alpha = alpha;
  399. surfaceData.clearCoatMask = 0;
  400. surfaceData.clearCoatSmoothness = 1;
  401. #if defined(DEBUG_DISPLAY)
  402. inputData.uv = uv;
  403. #endif
  404. half4 color = UniversalFragmentPBR(inputData, surfaceData);
  405. color.rgb = MixFog(color.rgb, inputData.fogCoord);
  406. color.a = OutputAlpha(color.a, _Surface);
  407. return color;
  408. #endif
  409. }
  410. half4 SpeedTree8FragDepth(SpeedTreeVertexDepthOutput input) : SV_Target
  411. {
  412. UNITY_SETUP_INSTANCE_ID(input);
  413. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  414. half2 uv = input.uv;
  415. half4 diffuse = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex)) * _Color;
  416. half alpha = diffuse.a * input.color.a;
  417. AlphaDiscard(alpha, 0.3333);
  418. #ifdef LOD_FADE_CROSSFADE
  419. LODFadeCrossFade(input.clipPos);
  420. #endif
  421. #if defined(SCENESELECTIONPASS)
  422. // We use depth prepass for scene selection in the editor, this code allow to output the outline correctly
  423. return half4(_ObjectId, _PassValue, 1.0, 1.0);
  424. #else
  425. return half4(input.clipPos.z, 0, 0, 0);
  426. #endif
  427. }
  428. SpeedTreeVertexDepthNormalOutput SpeedTree8VertDepthNormal(SpeedTreeVertexInput input)
  429. {
  430. SpeedTreeVertexDepthNormalOutput output = (SpeedTreeVertexDepthNormalOutput)0;
  431. UNITY_SETUP_INSTANCE_ID(input);
  432. UNITY_TRANSFER_INSTANCE_ID(input, output);
  433. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
  434. // handle speedtree wind and lod
  435. InitializeData(input, unity_LODFade.x);
  436. output.uv = input.texcoord.xy;
  437. output.color = input.color;
  438. VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
  439. half3 normalWS = TransformObjectToWorldNormal(input.normal);
  440. half3 viewDirWS = GetWorldSpaceNormalizeViewDir(vertexInput.positionWS);
  441. #ifdef EFFECT_BUMP
  442. real sign = input.tangent.w * GetOddNegativeScale();
  443. output.normalWS.xyz = normalWS;
  444. output.tangentWS.xyz = TransformObjectToWorldDir(input.tangent.xyz);
  445. output.bitangentWS.xyz = cross(output.normalWS.xyz, output.tangentWS.xyz) * sign;
  446. // View dir packed in w.
  447. output.normalWS.w = viewDirWS.x;
  448. output.tangentWS.w = viewDirWS.y;
  449. output.bitangentWS.w = viewDirWS.z;
  450. #else
  451. output.normalWS = normalWS;
  452. output.viewDirWS = viewDirWS;
  453. #endif
  454. output.clipPos = vertexInput.positionCS;
  455. return output;
  456. }
  457. half4 SpeedTree8FragDepthNormal(SpeedTreeDepthNormalFragmentInput input) : SV_Target
  458. {
  459. UNITY_SETUP_INSTANCE_ID(input.interpolated);
  460. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input.interpolated);
  461. half2 uv = input.interpolated.uv;
  462. half4 diffuse = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex)) * _Color;
  463. half alpha = diffuse.a * input.interpolated.color.a;
  464. AlphaDiscard(alpha, 0.3333);
  465. #ifdef LOD_FADE_CROSSFADE
  466. LODFadeCrossFade(input.interpolated.clipPos);
  467. #endif
  468. // normal
  469. #if defined(EFFECT_BUMP)
  470. half3 normalTs = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap));
  471. #else
  472. half3 normalTs = half3(0, 0, 1);
  473. #endif
  474. // flip normal on backsides
  475. #ifdef EFFECT_BACKSIDE_NORMALS
  476. if (input.facing < 0.5)
  477. {
  478. normalTs.z = -normalTs.z;
  479. }
  480. #endif
  481. // adjust billboard normals to improve GI and matching
  482. #if defined(EFFECT_BILLBOARD)
  483. normalTs.z *= 0.5;
  484. normalTs = normalize(normalTs);
  485. #endif
  486. #if defined(EFFECT_BUMP)
  487. float3 normalWS = TransformTangentToWorld(normalTs, half3x3(input.interpolated.tangentWS.xyz, input.interpolated.bitangentWS.xyz, input.interpolated.normalWS.xyz));
  488. return half4(NormalizeNormalPerPixel(normalWS), 0.0h);
  489. #else
  490. return half4(NormalizeNormalPerPixel(input.interpolated.normalWS), 0.0h);
  491. #endif
  492. }
  493. #endif