// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. // // http://go.microsoft.com/fwlink/?LinkId=248929 Texture2D AlbedoTexture : register(t0); Texture2D NormalTexture : register(t1); Texture2D RMATexture : register(t2); Texture2D EmissiveTexture : register(t3); TextureCube RadianceTexture : register(t4); TextureCube IrradianceTexture : register(t5); sampler SurfaceSampler : register(s0); sampler IBLSampler : register(s1); cbuffer Constants : register(b0) { float3 EyePosition : packoffset(c0); float4x4 World : packoffset(c1); float3x3 WorldInverseTranspose : packoffset(c5); float4x4 WorldViewProj : packoffset(c8); float4x4 PrevWorldViewProj : packoffset(c12); float3 LightDirection[3] : packoffset(c16); float3 LightColor[3] : packoffset(c19); // "Specular and diffuse light" in PBR float3 ConstantAlbedo : packoffset(c22); // Constant values if not a textured effect float Alpha : packoffset(c22.w); float ConstantMetallic : packoffset(c23.x); float ConstantRoughness : packoffset(c23.y); int NumRadianceMipLevels : packoffset(c23.z); // Size of render target float TargetWidth : packoffset(c23.w); float TargetHeight : packoffset(c24.x); }; #include "Structures.fxh" #include "PBRCommon.fxh" #include "Utilities.fxh" // Vertex shader: pbr VSOutputPixelLightingTx VSConstant(VSInputNmTx vin) { VSOutputPixelLightingTx vout; CommonVSOutputPixelLighting cout = ComputeCommonVSOutputPixelLighting(vin.Position, vin.Normal); vout.PositionPS = cout.Pos_ps; vout.PositionWS = float4(cout.Pos_ws, 1); vout.NormalWS = cout.Normal_ws; vout.Diffuse = float4(ConstantAlbedo, Alpha); vout.TexCoord = vin.TexCoord; return vout; } // Vertex shader: pbr + velocity VSOut_Velocity VSConstantVelocity(VSInputNmTx vin) { VSOut_Velocity vout; CommonVSOutputPixelLighting cout = ComputeCommonVSOutputPixelLighting(vin.Position, vin.Normal); vout.current.PositionPS = cout.Pos_ps; vout.current.PositionWS = float4(cout.Pos_ws, 1); vout.current.NormalWS = cout.Normal_ws; vout.current.Diffuse = float4(ConstantAlbedo, Alpha); vout.current.TexCoord = vin.TexCoord; vout.prevPosition = mul(vin.Position, PrevWorldViewProj); return vout; } // Vertex shader: pbr (biased normal) VSOutputPixelLightingTx VSConstantBn(VSInputNmTx vin) { VSOutputPixelLightingTx vout; float3 normal = BiasX2(vin.Normal); CommonVSOutputPixelLighting cout = ComputeCommonVSOutputPixelLighting(vin.Position, normal); vout.PositionPS = cout.Pos_ps; vout.PositionWS = float4(cout.Pos_ws, 1); vout.NormalWS = cout.Normal_ws; vout.Diffuse = float4(ConstantAlbedo, Alpha); vout.TexCoord = vin.TexCoord; return vout; } // Vertex shader: pbr + velocity (biased normal) VSOut_Velocity VSConstantVelocityBn(VSInputNmTx vin) { VSOut_Velocity vout; float3 normal = BiasX2(vin.Normal); CommonVSOutputPixelLighting cout = ComputeCommonVSOutputPixelLighting(vin.Position, normal); vout.current.PositionPS = cout.Pos_ps; vout.current.PositionWS = float4(cout.Pos_ws, 1); vout.current.NormalWS = cout.Normal_ws; vout.current.Diffuse = float4(ConstantAlbedo, Alpha); vout.current.TexCoord = vin.TexCoord; vout.prevPosition = mul(vin.Position, PrevWorldViewProj); return vout; } // Pixel shader: pbr (constants) + image-based lighting float4 PSConstant(PSInputPixelLightingTx pin) : SV_Target0 { // vectors const float3 V = normalize(EyePosition - pin.PositionWS.xyz); // view vector const float3 N = normalize(pin.NormalWS); // surface normal const float AO = 1; // ambient term float3 color = LightSurface(V, N, 3, LightColor, LightDirection, ConstantAlbedo, ConstantRoughness, ConstantMetallic, AO); return float4(color, Alpha); } // Pixel shader: pbr (textures) + image-based lighting float4 PSTextured(PSInputPixelLightingTx pin) : SV_Target0 { const float3 V = normalize(EyePosition - pin.PositionWS.xyz); // view vector const float3 L = normalize(-LightDirection[0]); // light vector ("to light" opposite of light's direction) // Before lighting, peturb the surface's normal by the one given in normal map. float3 localNormal = TwoChannelNormalX2(NormalTexture.Sample(SurfaceSampler, pin.TexCoord).xy); float3 N = PeturbNormal(localNormal, pin.PositionWS.xyz, pin.NormalWS, pin.TexCoord); // Get albedo float4 albedo = AlbedoTexture.Sample(SurfaceSampler, pin.TexCoord); // Get roughness, metalness, and ambient occlusion float3 RMA = RMATexture.Sample(SurfaceSampler, pin.TexCoord); // glTF2 defines metalness as B channel, roughness as G channel, and occlusion as R channel // Shade surface float3 color = LightSurface(V, N, 3, LightColor, LightDirection, albedo.rgb, RMA.g, RMA.b, RMA.r); return float4(color, albedo.w * Alpha); } // Pixel shader: pbr (textures) + emissive + image-based lighting float4 PSTexturedEmissive(PSInputPixelLightingTx pin) : SV_Target0 { const float3 V = normalize(EyePosition - pin.PositionWS.xyz); // view vector const float3 L = normalize(-LightDirection[0]); // light vector ("to light" opposite of light's direction) // Before lighting, peturb the surface's normal by the one given in normal map. float3 localNormal = TwoChannelNormalX2(NormalTexture.Sample(SurfaceSampler, pin.TexCoord).xy); float3 N = PeturbNormal(localNormal, pin.PositionWS.xyz, pin.NormalWS, pin.TexCoord); // Get albedo float4 albedo = AlbedoTexture.Sample(SurfaceSampler, pin.TexCoord); // Get roughness, metalness, and ambient occlusion float3 RMA = RMATexture.Sample(SurfaceSampler, pin.TexCoord); // glTF2 defines metalness as B channel, roughness as G channel, and occlusion as R channel // Shade surface float3 color = LightSurface(V, N, 3, LightColor, LightDirection, albedo.rgb, RMA.g, RMA.b, RMA.r); color += EmissiveTexture.Sample(SurfaceSampler, pin.TexCoord).rgb; return float4(color, albedo.w * Alpha); } // Pixel shader: pbr (textures) + image-based lighting + velocity #include "PixelPacking_Velocity.hlsli" struct PSOut_Velocity { float4 color : SV_Target0; packed_velocity_t velocity : SV_Target1; }; PSOut_Velocity PSTexturedVelocity(VSOut_Velocity pin) { PSOut_Velocity output; const float3 V = normalize(EyePosition - pin.current.PositionWS.xyz); // view vector const float3 L = normalize(-LightDirection[0]); // light vector ("to light" opposite of light's direction) // Before lighting, peturb the surface's normal by the one given in normal map. float3 localNormal = TwoChannelNormalX2(NormalTexture.Sample(SurfaceSampler, pin.current.TexCoord).xy); float3 N = PeturbNormal(localNormal, pin.current.PositionWS.xyz, pin.current.NormalWS, pin.current.TexCoord); // Get albedo float4 albedo = AlbedoTexture.Sample(SurfaceSampler, pin.current.TexCoord); // Get roughness, metalness, and ambient occlusion float3 RMA = RMATexture.Sample(SurfaceSampler, pin.current.TexCoord); // glTF2 defines metalness as B channel, roughness as G channel, and occlusion as R channel // Shade surface float3 color = LightSurface(V, N, 3, LightColor, LightDirection, albedo.rgb, RMA.g, RMA.b, RMA.r); output.color = float4(color, albedo.w * Alpha); // Calculate velocity of this point float4 prevPos = pin.prevPosition; prevPos.xyz /= prevPos.w; prevPos.xy *= float2(0.5f, -0.5f); prevPos.xy += 0.5f; prevPos.xy *= float2(TargetWidth, TargetHeight); output.velocity = PackVelocity(prevPos.xyz - pin.current.PositionPS.xyz); return output; } PSOut_Velocity PSTexturedEmissiveVelocity(VSOut_Velocity pin) { PSOut_Velocity output; const float3 V = normalize(EyePosition - pin.current.PositionWS.xyz); // view vector const float3 L = normalize(-LightDirection[0]); // light vector ("to light" opposite of light's direction) // Before lighting, peturb the surface's normal by the one given in normal map. float3 localNormal = TwoChannelNormalX2(NormalTexture.Sample(SurfaceSampler, pin.current.TexCoord).xy); float3 N = PeturbNormal(localNormal, pin.current.PositionWS.xyz, pin.current.NormalWS, pin.current.TexCoord); // Get albedo float4 albedo = AlbedoTexture.Sample(SurfaceSampler, pin.current.TexCoord); // Get roughness, metalness, and ambient occlusion float3 RMA = RMATexture.Sample(SurfaceSampler, pin.current.TexCoord); // glTF2 defines metalness as B channel, roughness as G channel, and occlusion as R channel // Shade surface float3 color = LightSurface(V, N, 3, LightColor, LightDirection, albedo.rgb, RMA.g, RMA.b, RMA.r); color += EmissiveTexture.Sample(SurfaceSampler, pin.current.TexCoord).rgb; output.color = float4(color, albedo.w * Alpha); // Calculate velocity of this point float4 prevPos = pin.prevPosition; prevPos.xyz /= prevPos.w; prevPos.xy *= float2(0.5f, -0.5f); prevPos.xy += 0.5f; prevPos.xy *= float2(TargetWidth, TargetHeight); output.velocity = PackVelocity(prevPos.xyz - pin.current.PositionPS.xyz); return output; }