280 lines
7.9 KiB
HLSL
280 lines
7.9 KiB
HLSL
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
|
|
|
|
#include "Lib.hlsl"
|
|
#include "LibColor.hlsl"
|
|
#include "LibDepth.hlsl"
|
|
#include "LibLighting.hlsl"
|
|
#include "LibVertex.hlsl"
|
|
#include "SimpleMesh.inc.hlsl"
|
|
|
|
CBUFFER(0, UB_SimplePerFrame, g_ubSimplePerFrame)
|
|
CBUFFER(1, UB_SimplePerMaterialFS, g_ubSimplePerMaterialFS)
|
|
CBUFFER(2, UB_SimplePerMeshVS, g_ubSimplePerMeshVS)
|
|
CBUFFER(3, UB_SimpleSkeletonVS, g_ubSimpleSkeletonVS)
|
|
VK_PUSH_CONSTANT
|
|
CBUFFER(4, UB_SimplePerObject, g_ubSimplePerObject)
|
|
|
|
Texture2D g_texA : REG(t1, space1, t0);
|
|
SamplerState g_samA : REG(s1, space1, s0);
|
|
Texture2D g_texX : REG(t2, space1, t1);
|
|
SamplerState g_samX : REG(s2, space1, s1);
|
|
Texture2D g_texShadowCmp : REG(t3, space1, t2);
|
|
SamplerComparisonState g_samShadowCmp : REG(s3, space1, s2);
|
|
|
|
struct VSI
|
|
{
|
|
// Binding 0:
|
|
VK_LOCATION_POSITION int4 pos : POSITION;
|
|
VK_LOCATION_NORMAL float3 nrm : NORMAL;
|
|
VK_LOCATION(8) int2 tc0 : TEXCOORD0;
|
|
// Binding 1:
|
|
#ifdef DEF_SKINNED
|
|
VK_LOCATION_BLENDWEIGHTS int4 bw : BLENDWEIGHTS;
|
|
VK_LOCATION_BLENDINDICES int4 bi : BLENDINDICES;
|
|
#endif
|
|
_PER_INSTANCE_DATA
|
|
};
|
|
|
|
struct VSO
|
|
{
|
|
float4 pos : SV_Position;
|
|
float4 color0 : COLOR0;
|
|
float2 tc0 : TEXCOORD0;
|
|
float4 posW_depth : TEXCOORD1;
|
|
#if !defined(DEF_TEXTURE) && !defined(DEF_BAKE_AO)
|
|
float3 nrmW : TEXCOORD2;
|
|
float3 dirToEye : TEXCOORD3;
|
|
#endif
|
|
float clipDistance : SV_ClipDistance;
|
|
};
|
|
|
|
struct FSO
|
|
{
|
|
float4 color : SV_Target0;
|
|
};
|
|
|
|
#ifdef _VS
|
|
VSO mainVS(VSI si)
|
|
{
|
|
VSO so;
|
|
|
|
const float3 eyePos = g_ubSimplePerFrame._eyePos_clipDistanceOffset.xyz;
|
|
const float clipDistanceOffset = g_ubSimplePerFrame._eyePos_clipDistanceOffset.w;
|
|
|
|
// Dequantize:
|
|
const float3 inPos = DequantizeUsingDeq3D(si.pos.xyz, g_ubSimplePerMeshVS._posDeqScale.xyz, g_ubSimplePerMeshVS._posDeqBias.xyz);
|
|
const float2 inTc0 = DequantizeUsingDeq2D(si.tc0, g_ubSimplePerMeshVS._tc0DeqScaleBias.xy, g_ubSimplePerMeshVS._tc0DeqScaleBias.zw);
|
|
const float3 inNrm = si.nrm.xyz;
|
|
|
|
// <TheMatrix>
|
|
#ifdef DEF_INSTANCED
|
|
mataff matW = GetInstMatrix(
|
|
si.matPart0,
|
|
si.matPart1,
|
|
si.matPart2);
|
|
const float4 userColor = si.instData;
|
|
#else
|
|
mataff matW = g_ubSimplePerObject._matW;
|
|
const float4 userColor = g_ubSimplePerObject._userColor;
|
|
#endif
|
|
|
|
const float3 pos = inPos;
|
|
// </TheMatrix>
|
|
|
|
float3 posW;
|
|
float3 nrmW;
|
|
{
|
|
#if defined(DEF_SKINNED)
|
|
const float4 weights = si.bw * (1.0 / 255.0);
|
|
const int4 indices = si.bi;
|
|
|
|
float3 posSkinned = 0.0;
|
|
float3 nrmSkinned = 0.0;
|
|
|
|
for (int i = 0; i < 4; ++i)
|
|
{
|
|
const mataff matBone = g_ubSimpleSkeletonVS._vMatBones[indices[i]];
|
|
posSkinned += mul(float4(pos, 1), matBone).xyz * weights[i];
|
|
nrmSkinned += mul(inNrm, (float3x3)matBone) * weights[i];
|
|
}
|
|
|
|
posW = mul(float4(posSkinned, 1), matW).xyz;
|
|
nrmW = mul(nrmSkinned, (float3x3)matW);
|
|
#elif defined(DEF_ROBOTIC)
|
|
const int index = si.pos.w;
|
|
|
|
const mataff matBone = g_ubSimpleSkeletonVS._vMatBones[index];
|
|
|
|
const float3 posSkinned = mul(float4(pos, 1), matBone).xyz;
|
|
nrmW = mul(inNrm, (float3x3)matBone);
|
|
|
|
posW = mul(float4(posSkinned, 1), matW).xyz;
|
|
nrmW = mul(nrmW, (float3x3)matW);
|
|
#else
|
|
posW = mul(float4(pos, 1), matW).xyz;
|
|
nrmW = mul(inNrm, (float3x3)matW);
|
|
#endif
|
|
}
|
|
|
|
so.pos = mul(float4(posW, 1), g_ubSimplePerFrame._matVP);
|
|
so.posW_depth = float4(posW, so.pos.w);
|
|
so.color0 = userColor;
|
|
so.tc0 = inTc0;
|
|
#if !defined(DEF_TEXTURE) && !defined(DEF_BAKE_AO)
|
|
so.nrmW = nrmW;
|
|
so.dirToEye = eyePos - posW;
|
|
#endif
|
|
so.clipDistance = posW.y + clipDistanceOffset;
|
|
|
|
return so;
|
|
}
|
|
#endif
|
|
|
|
#ifdef _FS
|
|
FSO mainFS(VSO si)
|
|
{
|
|
FSO so;
|
|
|
|
#if defined(DEF_TEXTURE)
|
|
const float4 albedo = g_texA.Sample(g_samA, si.tc0);
|
|
so.color.rgb = albedo.rgb * si.color0.rgb;
|
|
so.color.rgb = SaturateHDR(so.color.rgb);
|
|
so.color.a = 1.0;
|
|
#elif defined(DEF_BAKE_AO)
|
|
// <Material>
|
|
const float4 mm_tc0ScaleBias = g_ubSimplePerMaterialFS._tc0ScaleBias;
|
|
// </Material>
|
|
|
|
const float2 tc0 = si.tc0 * mm_tc0ScaleBias.xy + mm_tc0ScaleBias.zw;
|
|
|
|
// <Albedo>
|
|
const float4 albedo = g_texA.Sample(g_samA, tc0);
|
|
// </Albedo>
|
|
|
|
so.color.rgb = albedo.rgb * si.color0.rgb;
|
|
|
|
const float fog = saturate(si.posW_depth.w * g_ubSimplePerFrame._fogColor.a);
|
|
so.color.rgb = lerp(so.color.rgb, g_ubSimplePerFrame._fogColor.rgb, fog);
|
|
|
|
so.color.rgb = SaturateHDR(so.color.rgb);
|
|
so.color.a = 1.0;
|
|
|
|
clip(albedo.a - 0.5);
|
|
#else
|
|
// <Material>
|
|
const float mm_emission = g_ubSimplePerMaterialFS._anisoSpecDir_detail_emission.w;
|
|
const float4 mm_solidA = g_ubSimplePerMaterialFS._solidA;
|
|
const float4 mm_solidX = g_ubSimplePerMaterialFS._solidX;
|
|
const float4 mm_tc0ScaleBias = g_ubSimplePerMaterialFS._tc0ScaleBias;
|
|
const float4 mm_userPick = g_ubSimplePerMaterialFS._userPick;
|
|
const float2 mm_xMetallicScaleBias = g_ubSimplePerMaterialFS._xAnisoSpecScaleBias_xMetallicScaleBias.zw;
|
|
const float2 mm_xRoughnessScaleBias = g_ubSimplePerMaterialFS._xRoughnessScaleBias_xWrapDiffuseScaleBias.xy;
|
|
// </Material>
|
|
|
|
const float2 tc0 = si.tc0 * mm_tc0ScaleBias.xy + mm_tc0ScaleBias.zw;
|
|
|
|
// <Albedo>
|
|
float4 albedo;
|
|
{
|
|
const float texEnabled = 1.0 - floor(mm_solidA.a);
|
|
float4 albedoSam = g_texA.Sample(g_samA, tc0 * texEnabled);
|
|
albedoSam.rgb = lerp(albedoSam.rgb, mm_solidA.rgb, mm_solidA.a);
|
|
|
|
albedo = albedoSam;
|
|
}
|
|
const float gray = Grayscale(albedo.rgb);
|
|
// </Albedo>
|
|
|
|
// <Pick>
|
|
const float userMask = PickAlpha(albedo.rgb, mm_userPick, 16.0);
|
|
// </Pick>
|
|
|
|
albedo.rgb = lerp(albedo.rgb, Overlay(gray, si.color0.rgb), userMask * si.color0.a);
|
|
|
|
// <X>
|
|
float occlusion;
|
|
float roughness;
|
|
float metallic;
|
|
float emission;
|
|
{
|
|
const float texEnabled = 1.0 - floor(mm_solidX.a);
|
|
float4 xSam = g_texX.Sample(g_samX, tc0 * texEnabled);
|
|
xSam.rgb = lerp(xSam.rgb, mm_solidX.rgb, mm_solidX.a);
|
|
|
|
occlusion = xSam.r;
|
|
roughness = xSam.g;
|
|
const float2 metallic_wrapDiffuse = CleanMutexChannels(SeparateMutexChannels(xSam.b));
|
|
const float2 emission_anisoSpec = CleanMutexChannels(SeparateMutexChannels(xSam.a));
|
|
metallic = metallic_wrapDiffuse.r;
|
|
emission = emission_anisoSpec.r;
|
|
|
|
// Scale & bias:
|
|
roughness = roughness * mm_xRoughnessScaleBias.x + mm_xRoughnessScaleBias.y;
|
|
metallic = metallic * mm_xMetallicScaleBias.x + mm_xMetallicScaleBias.y;
|
|
emission *= mm_emission;
|
|
}
|
|
// </X>
|
|
|
|
const float3 normal = normalize(si.nrmW);
|
|
const float3 dirToLight = g_ubSimplePerFrame._dirToSun.xyz;
|
|
const float3 dirToEye = normalize(si.dirToEye.xyz);
|
|
const float depth = si.posW_depth.w;
|
|
|
|
// <Shadow>
|
|
float shadowMask;
|
|
{
|
|
const float3 posForShadow = AdjustPosForShadow(si.posW_depth.xyz, normal, dirToLight, depth);
|
|
shadowMask = SimpleShadowMapCSM(
|
|
g_texShadowCmp,
|
|
g_samShadowCmp,
|
|
si.posW_depth.xyz,
|
|
posForShadow,
|
|
g_ubSimplePerFrame._matShadow,
|
|
g_ubSimplePerFrame._matShadowCSM1,
|
|
g_ubSimplePerFrame._matShadowCSM2,
|
|
g_ubSimplePerFrame._matShadowCSM3,
|
|
g_ubSimplePerFrame._matScreenCSM,
|
|
g_ubSimplePerFrame._csmSplitRanges,
|
|
g_ubSimplePerFrame._shadowConfig);
|
|
}
|
|
// </Shadow>
|
|
|
|
float3 punctualDiff, punctualSpec;
|
|
VerusSimpleLit(normal, dirToLight, dirToEye,
|
|
albedo.rgb,
|
|
roughness, metallic,
|
|
punctualDiff, punctualSpec);
|
|
|
|
punctualDiff *= g_ubSimplePerFrame._sunColor.rgb * shadowMask;
|
|
punctualSpec *= g_ubSimplePerFrame._sunColor.rgb * shadowMask;
|
|
|
|
so.color.rgb = albedo.rgb * (g_ubSimplePerFrame._ambientColor.rgb * occlusion + punctualDiff + emission) + punctualSpec;
|
|
so.color.a = 1.0;
|
|
|
|
const float fog = ComputeFog(depth, g_ubSimplePerFrame._fogColor.a, si.posW_depth.y);
|
|
so.color.rgb = lerp(so.color.rgb, g_ubSimplePerFrame._fogColor.rgb, fog);
|
|
|
|
so.color.rgb = SaturateHDR(so.color.rgb);
|
|
|
|
clip(albedo.a - 0.5);
|
|
#endif
|
|
|
|
return so;
|
|
}
|
|
#endif
|
|
|
|
//@main:#
|
|
//@main:#Instanced INSTANCED
|
|
//@main:#Robotic ROBOTIC
|
|
//@main:#Skinned SKINNED
|
|
|
|
//@main:#Texture TEXTURE
|
|
//@main:#TextureInstanced TEXTURE INSTANCED
|
|
//@main:#TextureRobotic TEXTURE ROBOTIC
|
|
//@main:#TextureSkinned TEXTURE SKINNED
|
|
|
|
//@main:#BakeAO BAKE_AO
|
|
//@main:#BakeAOInstanced BAKE_AO INSTANCED
|
|
//@main:#BakeAORobotic BAKE_AO ROBOTIC
|
|
//@main:#BakeAOSkinned BAKE_AO SKINNED
|