ForwardPassVertexAndPixel.azsli 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #pragma once
  9. #ifndef ENABLE_DEBUG_MODIFY_OUTPUT
  10. #define ENABLE_DEBUG_MODIFY_OUTPUT 1
  11. #endif
  12. #include <Atom/Features/Pipeline/Forward/ForwardPassOutput.azsli>
  13. // --- Vertex Shader ---
  14. VsOutput VertexShader(VsInput IN, uint instanceId : SV_InstanceID)
  15. {
  16. VsSystemValues SV;
  17. SV.m_instanceId = instanceId;
  18. VsOutput OUT = EvaluateVertexGeometry(IN, SV, GetMaterialParameters());
  19. return OUT;
  20. }
  21. #if OUTPUT_SUBSURFACE
  22. float GetSubsurfaceScatteringFactorAndQuality(Surface surface)
  23. {
  24. // Pack factor and quality, drawback: because of precision limit of float16 cannot represent exact 1, maximum representable value is 0.9961
  25. uint factorAndQuality = dot(round(float2(saturate(surface.subsurfaceScatteringFactor), surface.subsurfaceScatteringQuality) * 255), float2(256, 1));
  26. return factorAndQuality * (o_enableSubsurfaceScattering ? 1.0 : -1.0);
  27. }
  28. #endif
  29. // --- Pixel Shader ---
  30. // TODO(MaterialPipeline): Probably replace this with FORCE_EARLY_DEPTH_STENCIL like how it's done in MultiViewForwardPassVertexAndPixel.azsli
  31. #if !OUTPUT_DEPTH
  32. [earlydepthstencil]
  33. #endif
  34. ForwardPassOutput PixelShader(VsOutput IN, bool isFrontFace : SV_IsFrontFace)
  35. {
  36. float3 views[MAX_SHADING_VIEWS];
  37. views[0] = ViewSrg::m_worldPosition.xyz; // Assume one view for forward pass for now
  38. // ------- Geometry -> Surface -> Lighting -------
  39. PixelGeometryData geoData = EvaluatePixelGeometry(IN, isFrontFace, GetMaterialParameters());
  40. Surface surface = EvaluateSurface(IN, geoData, GetMaterialParameters());
  41. LightingData lightingData = EvaluateLighting(surface, IN.position, views);
  42. // ------- Output -------
  43. ForwardPassOutput OUT;
  44. // --- Diffuse Lighting ---
  45. OUT.m_diffuseColor.rgb = lightingData.diffuseLighting;
  46. OUT.m_diffuseColor.a = -1; // Disable Subsurface Scattering
  47. // --- Specular Lighting ---
  48. OUT.m_specularColor.rgb = lightingData.specularLighting[0].rgb;
  49. OUT.m_specularColor.a = 1.0;
  50. // --- Roughness and Specular ---
  51. OUT.m_specularF0.rgb = surface.GetSpecularF0();
  52. OUT.m_specularF0.a = surface.roughnessLinear;
  53. // --- Albedo ---
  54. OUT.m_albedo.rgb = surface.albedo * lightingData.diffuseResponse * lightingData.diffuseAmbientOcclusion;
  55. OUT.m_albedo.a = lightingData.specularOcclusion;
  56. // --- Normal ---
  57. OUT.m_normal.rgb = EncodeNormalSignedOctahedron(surface.GetDefaultNormal());
  58. // --- Fullscreen Passes IBL & Multiscatter ---
  59. bool applyIblInFullscreenPasses = o_enableIBL;
  60. #if FORCE_IBL_IN_FORWARD_PASS
  61. applyIblInFullscreenPasses = false;
  62. #endif
  63. OUT.m_normal.a = EncodeUnorm2BitFlags(applyIblInFullscreenPasses, o_specularF0_enableMultiScatterCompensation);
  64. // --- Emissive ---
  65. // Sending to specular output for historical reasons until sending to diffuse can be validated
  66. OUT.m_specularColor.rgb += lightingData.emissiveLighting;
  67. // --- Subsurface ---
  68. #if OUTPUT_SUBSURFACE
  69. bool applySubsurfaceScattering = o_enableSubsurfaceScattering;
  70. if(applySubsurfaceScattering)
  71. {
  72. OUT.m_diffuseColor.a = GetSubsurfaceScatteringFactorAndQuality(surface);
  73. OUT.m_scatterDistance = surface.scatterDistance;
  74. }
  75. else
  76. {
  77. OUT.m_scatterDistance = float3(0, 0, 0);
  78. }
  79. #endif
  80. // --- Depth ---
  81. #if OUTPUT_DEPTH
  82. // Can be modified in Parallax calculations in EvaluatePixelGeometry
  83. OUT.m_depth = IN.position.z;
  84. #endif
  85. // --- Debug Output ---
  86. #if ENABLE_DEBUG_MODIFY_OUTPUT
  87. // TODO(MaterialPipeline): Turn this into an optional callback that the material type can provide, and just pass OUT, surface,
  88. // and geoData instead of the specific fields. That will provide better compatibility with material types that don't have
  89. // some of these fields, like tangents and bitangents for example.
  90. DebugModifyOutput(OUT.m_diffuseColor, OUT.m_specularColor, OUT.m_albedo, OUT.m_specularF0, surface.normal,
  91. geoData.tangents[0], geoData.bitangents[0],
  92. surface.baseColor, surface.albedo, surface.roughnessLinear, surface.metallic);
  93. #endif
  94. #if ENABLE_SHADER_DEBUGGING
  95. if(any(customDebugFloats))
  96. {
  97. OUT.m_diffuseColor.rgb *= customDebugFloats.rgb;
  98. }
  99. #endif
  100. return OUT;
  101. }