ModelViewerPS.hlsl 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. // RUN: %dxc -E main -T ps_6_0 %s | FileCheck %s
  2. // CHECK: sample
  3. // CHECK: textureLoad
  4. // CHECK: dot3
  5. // CHECK: Sqrt
  6. // CHECK: FMax
  7. // CHECK: Saturate
  8. // CHECK: Log
  9. // CHECK: Exp
  10. // CHECK: sampleCmpLevelZero
  11. //
  12. // Copyright (c) Microsoft. All rights reserved.
  13. // This code is licensed under the MIT License (MIT).
  14. // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
  15. // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
  16. // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
  17. // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
  18. //
  19. // Developed by Minigraph
  20. //
  21. // Author(s): James Stanard
  22. // Alex Nankervis
  23. //
  24. #include "ModelViewerRS.hlsli"
  25. struct VSOutput
  26. {
  27. float4 position : SV_Position;
  28. float2 texcoord0 : texcoord0;
  29. float3 viewDir : texcoord1;
  30. float3 shadowCoord : texcoord2;
  31. float3 normal : normal;
  32. float3 tangent : tangent;
  33. float3 bitangent : bitangent;
  34. };
  35. Texture2D<float3> texDiffuse : register(t0);
  36. Texture2D<float3> texSpecular : register(t1);
  37. //Texture2D<float4> texEmissive : register(t2);
  38. Texture2D<float3> texNormal : register(t3);
  39. //Texture2D<float4> texLightmap : register(t4);
  40. //Texture2D<float4> texReflection : register(t5);
  41. Texture2D<float> texSSAO : register(t64);
  42. Texture2D<float> texShadow : register(t65);
  43. cbuffer PSConstants : register(b0)
  44. {
  45. float3 SunDirection;
  46. float3 SunColor;
  47. float3 AmbientColor;
  48. uint _pad;
  49. float ShadowTexelSize;
  50. }
  51. SamplerState sampler0 : register(s0);
  52. SamplerComparisonState shadowSampler : register(s1);
  53. // Apply fresnel to modulate the specular albedo
  54. void FSchlick( inout float3 specular, inout float3 diffuse, float3 lightDir, float3 halfVec )
  55. {
  56. float fresnel = pow(1.0 - saturate(dot(lightDir, halfVec)), 5.0);
  57. specular = lerp(specular, 1, fresnel);
  58. diffuse = lerp(diffuse, 0, fresnel);
  59. }
  60. float3 ApplyAmbientLight(
  61. float3 diffuse, // Diffuse albedo
  62. float ao, // Pre-computed ambient-occlusion
  63. float3 lightColor // Radiance of ambient light
  64. )
  65. {
  66. return ao * diffuse * lightColor;
  67. }
  68. float GetShadow( float3 ShadowCoord )
  69. {
  70. #ifdef SINGLE_SAMPLE
  71. float result = ShadowMap.SampleCmpLevelZero( ShadowSampler, ShadowCoord.xy, ShadowCoord.z );
  72. #else
  73. const float Dilation = 2.0;
  74. float d1 = Dilation * ShadowTexelSize * 0.125;
  75. float d2 = Dilation * ShadowTexelSize * 0.875;
  76. float d3 = Dilation * ShadowTexelSize * 0.625;
  77. float d4 = Dilation * ShadowTexelSize * 0.375;
  78. float result = (
  79. 2.0 * texShadow.SampleCmpLevelZero( shadowSampler, ShadowCoord.xy, ShadowCoord.z ) +
  80. texShadow.SampleCmpLevelZero( shadowSampler, ShadowCoord.xy + float2(-d2, d1), ShadowCoord.z ) +
  81. texShadow.SampleCmpLevelZero( shadowSampler, ShadowCoord.xy + float2(-d1, -d2), ShadowCoord.z ) +
  82. texShadow.SampleCmpLevelZero( shadowSampler, ShadowCoord.xy + float2( d2, -d1), ShadowCoord.z ) +
  83. texShadow.SampleCmpLevelZero( shadowSampler, ShadowCoord.xy + float2( d1, d2), ShadowCoord.z ) +
  84. texShadow.SampleCmpLevelZero( shadowSampler, ShadowCoord.xy + float2(-d4, d3), ShadowCoord.z ) +
  85. texShadow.SampleCmpLevelZero( shadowSampler, ShadowCoord.xy + float2(-d3, -d4), ShadowCoord.z ) +
  86. texShadow.SampleCmpLevelZero( shadowSampler, ShadowCoord.xy + float2( d4, -d3), ShadowCoord.z ) +
  87. texShadow.SampleCmpLevelZero( shadowSampler, ShadowCoord.xy + float2( d3, d4), ShadowCoord.z )
  88. ) / 10.0;
  89. #endif
  90. return result * result;
  91. }
  92. float3 ApplyDirectionalLight(
  93. float3 diffuseColor, // Diffuse albedo
  94. float3 specularColor, // Specular albedo
  95. float specularMask, // Where is it shiny or dingy?
  96. float gloss, // Specular power
  97. float3 normal, // World-space normal
  98. float3 viewDir, // World-space vector from eye to point
  99. float3 lightDir, // World-space vector from point to light
  100. float3 lightColor, // Radiance of directional light
  101. float3 shadowCoord // Shadow coordinate (Shadow map UV & light-relative Z)
  102. )
  103. {
  104. // normal and lightDir are assumed to be pre-normalized
  105. float nDotL = dot(normal, lightDir);
  106. if (nDotL <= 0)
  107. return 0;
  108. // viewDir is also assumed normalized
  109. float3 halfVec = normalize(lightDir - viewDir);
  110. float nDotH = max(0, dot(halfVec, normal));
  111. FSchlick( diffuseColor, specularColor, lightDir, halfVec );
  112. float specularFactor = specularMask * pow(nDotH, gloss) * (gloss + 2) / 8;
  113. float shadow = GetShadow(shadowCoord);
  114. return shadow * nDotL * lightColor * (diffuseColor + specularFactor * specularColor);
  115. }
  116. void AntiAliasSpecular( inout float3 texNormal, inout float gloss )
  117. {
  118. float norm = length(texNormal);
  119. texNormal /= norm;
  120. gloss = lerp(1, gloss, norm);
  121. }
  122. [RootSignature(ModelViewer_RootSig)]
  123. float3 main(VSOutput vsOutput) : SV_Target0
  124. {
  125. float3 diffuseAlbedo = texDiffuse.Sample(sampler0, vsOutput.texcoord0);
  126. float3 specularAlbedo = float3( 0.56, 0.56, 0.56 );//float3(1.0, 0.71, 0.29);
  127. float specularMask = texSpecular.Sample(sampler0, vsOutput.texcoord0).g;
  128. float3 normal = texNormal.Sample(sampler0, vsOutput.texcoord0) * 2.0 - 1.0;
  129. float gloss = 128.0;
  130. float ao = texSSAO[uint2(vsOutput.position.xy)];
  131. float3 viewDir = normalize(vsOutput.viewDir);
  132. AntiAliasSpecular(normal, gloss);
  133. float3x3 tbn = float3x3(normalize(vsOutput.tangent), normalize(vsOutput.bitangent), normalize(vsOutput.normal));
  134. normal = normalize(mul(normal, tbn));
  135. float3 ambientContribution = ApplyAmbientLight( diffuseAlbedo, ao, AmbientColor );
  136. float3 sunlightContribution = ApplyDirectionalLight( diffuseAlbedo, specularAlbedo, specularMask, gloss, normal, viewDir, SunDirection, SunColor, vsOutput.shadowCoord );
  137. return ambientContribution + sunlightContribution;
  138. }