123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- /*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
- #pragma once
- #ifndef ENABLE_DEBUG_MODIFY_OUTPUT
- #define ENABLE_DEBUG_MODIFY_OUTPUT 1
- #endif
- #include <Atom/Features/Pipeline/Forward/ForwardPassOutput.azsli>
- // --- Vertex Shader ---
- VsOutput VertexShader(VsInput IN, uint instanceId : SV_InstanceID)
- {
- VsSystemValues SV;
- SV.m_instanceId = instanceId;
- VsOutput OUT = EvaluateVertexGeometry(IN, SV, GetMaterialParameters());
- return OUT;
- }
- #if OUTPUT_SUBSURFACE
- float GetSubsurfaceScatteringFactorAndQuality(Surface surface)
- {
- // Pack factor and quality, drawback: because of precision limit of float16 cannot represent exact 1, maximum representable value is 0.9961
- uint factorAndQuality = dot(round(float2(saturate(surface.subsurfaceScatteringFactor), surface.subsurfaceScatteringQuality) * 255), float2(256, 1));
- return factorAndQuality * (o_enableSubsurfaceScattering ? 1.0 : -1.0);
- }
- #endif
- // --- Pixel Shader ---
- // TODO(MaterialPipeline): Probably replace this with FORCE_EARLY_DEPTH_STENCIL like how it's done in MultiViewForwardPassVertexAndPixel.azsli
- #if !OUTPUT_DEPTH
- [earlydepthstencil]
- #endif
- ForwardPassOutput PixelShader(VsOutput IN, bool isFrontFace : SV_IsFrontFace)
- {
- float3 views[MAX_SHADING_VIEWS];
- views[0] = ViewSrg::m_worldPosition.xyz; // Assume one view for forward pass for now
- // ------- Geometry -> Surface -> Lighting -------
- PixelGeometryData geoData = EvaluatePixelGeometry(IN, isFrontFace, GetMaterialParameters());
- Surface surface = EvaluateSurface(IN, geoData, GetMaterialParameters());
- LightingData lightingData = EvaluateLighting(surface, IN.position, views);
- // ------- Output -------
- ForwardPassOutput OUT;
- // --- Diffuse Lighting ---
- OUT.m_diffuseColor.rgb = lightingData.diffuseLighting;
- OUT.m_diffuseColor.a = -1; // Disable Subsurface Scattering
- // --- Specular Lighting ---
- OUT.m_specularColor.rgb = lightingData.specularLighting[0].rgb;
- OUT.m_specularColor.a = 1.0;
- // --- Roughness and Specular ---
- OUT.m_specularF0.rgb = surface.GetSpecularF0();
- OUT.m_specularF0.a = surface.roughnessLinear;
- // --- Albedo ---
- OUT.m_albedo.rgb = surface.albedo * lightingData.diffuseResponse * lightingData.diffuseAmbientOcclusion;
- OUT.m_albedo.a = lightingData.specularOcclusion;
- // --- Normal ---
- OUT.m_normal.rgb = EncodeNormalSignedOctahedron(surface.GetDefaultNormal());
- // --- Fullscreen Passes IBL & Multiscatter ---
- bool applyIblInFullscreenPasses = o_enableIBL;
- #if FORCE_IBL_IN_FORWARD_PASS
- applyIblInFullscreenPasses = false;
- #endif
- OUT.m_normal.a = EncodeUnorm2BitFlags(applyIblInFullscreenPasses, o_specularF0_enableMultiScatterCompensation);
- // --- Emissive ---
- // Sending to specular output for historical reasons until sending to diffuse can be validated
- OUT.m_specularColor.rgb += lightingData.emissiveLighting;
- // --- Subsurface ---
- #if OUTPUT_SUBSURFACE
- bool applySubsurfaceScattering = o_enableSubsurfaceScattering;
- if(applySubsurfaceScattering)
- {
- OUT.m_diffuseColor.a = GetSubsurfaceScatteringFactorAndQuality(surface);
- OUT.m_scatterDistance = surface.scatterDistance;
- }
- else
- {
- OUT.m_scatterDistance = float3(0, 0, 0);
- }
- #endif
- // --- Depth ---
- #if OUTPUT_DEPTH
- // Can be modified in Parallax calculations in EvaluatePixelGeometry
- OUT.m_depth = IN.position.z;
- #endif
- // --- Debug Output ---
- #if ENABLE_DEBUG_MODIFY_OUTPUT
- // TODO(MaterialPipeline): Turn this into an optional callback that the material type can provide, and just pass OUT, surface,
- // and geoData instead of the specific fields. That will provide better compatibility with material types that don't have
- // some of these fields, like tangents and bitangents for example.
- DebugModifyOutput(OUT.m_diffuseColor, OUT.m_specularColor, OUT.m_albedo, OUT.m_specularF0, surface.normal,
- geoData.tangents[0], geoData.bitangents[0],
- surface.baseColor, surface.albedo, surface.roughnessLinear, surface.metallic);
- #endif
- #if ENABLE_SHADER_DEBUGGING
- if(any(customDebugFloats))
- {
- OUT.m_diffuseColor.rgb *= customDebugFloats.rgb;
- }
- #endif
- return OUT;
- }
|