初始化内容
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
#version 450
|
||||
|
||||
layout (push_constant) uniform PushConstant
|
||||
{
|
||||
mat4 model;
|
||||
uint samplerIndex;
|
||||
} constant;
|
||||
|
||||
layout(set = 0, binding = 1) uniform sampler samplers[3];
|
||||
layout(set = 1, binding = 0) uniform texture2D tex;
|
||||
|
||||
layout(location = 0) in vec4 fragColor;
|
||||
layout(location = 1) in vec2 fragTexCoord;
|
||||
|
||||
layout(location = 0) out vec4 outColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
outColor = texture(sampler2D(tex, samplers[constant.samplerIndex]), fragTexCoord) * fragColor;
|
||||
if(outColor.a == 0)
|
||||
discard;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#version 450
|
||||
|
||||
layout(set = 0, binding = 0) uniform UniformBufferObject
|
||||
{
|
||||
mat4 viewProj;
|
||||
} ubo;
|
||||
|
||||
layout (push_constant) uniform PushConstant
|
||||
{
|
||||
mat4 model;
|
||||
uint samplerIndex;
|
||||
} constant;
|
||||
|
||||
layout(location = 0) in vec3 inPosition;
|
||||
layout(location = 1) in vec4 inColor;
|
||||
layout(location = 2) in vec2 inTexCoord;
|
||||
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
layout(location = 1) out vec2 fragTexCoord;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = ubo.viewProj * constant.model * vec4(inPosition, 1.0);
|
||||
fragColor = inColor;
|
||||
fragTexCoord = inTexCoord;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#version 450
|
||||
|
||||
layout (push_constant) uniform PushConstant
|
||||
{
|
||||
mat4 model;
|
||||
uint samplerIndex;
|
||||
} constant;
|
||||
|
||||
layout(set = 0, binding = 1) uniform sampler samplers[3];
|
||||
layout(set = 1, binding = 0) uniform texture2D tex;
|
||||
|
||||
layout(location = 0) in vec4 fragColor;
|
||||
layout(location = 1) in vec2 fragTexCoord;
|
||||
|
||||
layout(location = 0) out vec4 outColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
outColor = texture(sampler2D(tex, samplers[constant.samplerIndex]), fragTexCoord) * fragColor;
|
||||
if(outColor.a == 0)
|
||||
discard;
|
||||
float gray = dot(outColor.rgb, vec3(0.299, 0.587, 0.114));
|
||||
outColor = vec4(gray, gray, gray, outColor.a);
|
||||
}
|
||||
+541
@@ -0,0 +1,541 @@
|
||||
#version 450
|
||||
#extension GL_GOOGLE_cpp_style_line_directive : enable
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
#include "include/light.glsl"
|
||||
|
||||
const float M_PI = 3.141592653589793;
|
||||
const float c_MinRoughness = 0.04;
|
||||
|
||||
#define ONLY_SH false
|
||||
|
||||
layout (constant_id = 0) const int SHADOW_MAP_CASCADE_COUNT = 4;
|
||||
layout (constant_id = 1) const int enablePCF = 1;
|
||||
|
||||
layout (set = 0, binding = 0) uniform UniformBufferObject
|
||||
{
|
||||
mat4 proj;
|
||||
mat4 view;
|
||||
vec3 camPos;
|
||||
float pad;
|
||||
} ubo;
|
||||
|
||||
layout(set = 0, binding = 1) uniform UniformBufferMaterial
|
||||
{
|
||||
vec4 baseColorFactor; // 基础颜色系数
|
||||
vec4 emissiveFactor; // 自发光系数
|
||||
// -1.无贴图 0.使用UV0 1.使用UV1
|
||||
int baseColorTextureSet;
|
||||
int physicalDescriptorTextureSet;
|
||||
int normalTextureSet;
|
||||
int occlusionTextureSet;
|
||||
int emissiveTextureSet;
|
||||
|
||||
float metallicFactor; // 金属度
|
||||
float roughnessFactor; // 粗糙度
|
||||
float alphaMask; // 透明度裁剪
|
||||
float alphaMaskCutoff; // 丢弃阈值
|
||||
float emissiveStrength; // 自发光强度
|
||||
vec2 pad;
|
||||
} material;
|
||||
|
||||
layout(set = 0, binding = 2) uniform UniformBufferPass
|
||||
{
|
||||
float exposure; // 曝光度
|
||||
float gamma; // gamma校正
|
||||
float prefilteredCubeMipLevels; // 预过滤的立方体贴图级数
|
||||
float scaleIBLAmbient; // ibl环境光系数
|
||||
vec4 sh[9]; // 球谐漫反射
|
||||
vec4 cascadeSplits; // 级联分割
|
||||
float debugViewInputs;
|
||||
Light light[NUM_LIGHT];
|
||||
} pass;
|
||||
|
||||
layout (set = 0, binding = 3) uniform UniformBufferCascade
|
||||
{
|
||||
mat4 viewProj[SHADOW_MAP_CASCADE_COUNT];
|
||||
} cascade;
|
||||
|
||||
// 依赖pass
|
||||
#include "include/tonemap.glsl"
|
||||
|
||||
// 预过滤镜面环境贴图(ibl)
|
||||
layout (set = 0, binding = 4) uniform samplerCube prefilteredMap;
|
||||
// BRDF 积分查找表
|
||||
layout (set = 0, binding = 5) uniform sampler2D samplerBRDFLUT;
|
||||
// 阴影贴图
|
||||
layout (set = 0, binding = 6) uniform sampler2DArray shadowMap;
|
||||
|
||||
layout(set = 1, binding = 0) uniform sampler2D diffuseMap; // 漫反射
|
||||
layout(set = 1, binding = 1) uniform sampler2D physicalMap; // 物理
|
||||
layout(set = 1, binding = 2) uniform sampler2D normalMap; // 法线
|
||||
layout(set = 1, binding = 3) uniform sampler2D aoMap; // 环境光遮蔽
|
||||
layout(set = 1, binding = 4) uniform sampler2D emissiveMap; // 自发光
|
||||
|
||||
layout (location = 0) in vec3 inPosition;
|
||||
layout (location = 1) in vec3 inNormal;
|
||||
layout (location = 2) in vec2 inUV0;
|
||||
layout (location = 3) in vec2 inUV1;
|
||||
layout (location = 4) in vec4 inColor;
|
||||
layout (location = 5) in vec3 inViewPos;
|
||||
|
||||
layout(location = 0) out vec4 outColor;
|
||||
|
||||
// 计算中间值
|
||||
struct PbrInfo
|
||||
{
|
||||
float NdotL; // 法线 · 光照方向 夹角余弦
|
||||
float NdotV; // 法线 · 视角方向 夹角余弦
|
||||
float NdotH; // 法线 · 半角向量 夹角余弦
|
||||
float LdotH; // 光照方向 · 半角向量 夹角余弦
|
||||
float VdotH; // 视角方向 · 半角向量 夹角余弦
|
||||
float perceptualRoughness; // 感知粗糙度(美术编辑的原始值)
|
||||
float metalness; // 金属度
|
||||
vec3 reflectance0; // 0度入射角 反射率(垂直入射)
|
||||
vec3 reflectance90; // 90度入射角 反射率(掠射入射)
|
||||
float alphaRoughness; // 物理粗糙度(perceptualRoughness²,用于光照计算)
|
||||
vec3 diffuseColor; // 漫反射颜色
|
||||
vec3 specularColor; // 高光反射颜色
|
||||
};
|
||||
|
||||
// 从顶点或贴图获取法线(世界坐标系)
|
||||
vec3 getNormal()
|
||||
{
|
||||
vec3 tangentNormal = texture(normalMap, material.normalTextureSet == 0 ? inUV0 : inUV1).xyz * 2.0 - 1.0;
|
||||
|
||||
// dFdx的返回值表示当前片元在屏幕空间x方向上的局部偏导数
|
||||
// 即当屏幕坐标x增加1个像素时,输入变量的变化率。
|
||||
// 它通常在GPU的2x2像素块内计算,通过相邻像素的值差来获得。
|
||||
vec3 q1 = dFdx(inPosition);
|
||||
vec3 q2 = dFdy(inPosition);
|
||||
vec2 st1 = dFdx(inUV0);
|
||||
vec2 st2 = dFdy(inUV0);
|
||||
|
||||
// N 向上(模型表面法线)
|
||||
// T 向右(切线 纹理 U 方向)
|
||||
// B 向前(副切线 纹理 V 方向)
|
||||
vec3 N = normalize(inNormal);
|
||||
vec3 T = normalize(q1 * st2.t - q2 * st1.t);
|
||||
vec3 B = normalize(cross(N, T));
|
||||
mat3 TBN = mat3(T, B, N);
|
||||
|
||||
return normalize(TBN * tangentNormal);
|
||||
}
|
||||
|
||||
vec4 SRGBtoLINEAR(vec4 srgbIn)
|
||||
{
|
||||
//#define MANUAL_SRGB 1
|
||||
#ifdef MANUAL_SRGB
|
||||
#ifdef SRGB_FAST_APPROXIMATION
|
||||
vec3 linOut = pow(srgbIn.xyz,vec3(2.2));
|
||||
#else //SRGB_FAST_APPROXIMATION
|
||||
vec3 bLess = step(vec3(0.04045),srgbIn.xyz);
|
||||
vec3 linOut = mix( srgbIn.xyz/vec3(12.92), pow((srgbIn.xyz+vec3(0.055))/vec3(1.055),vec3(2.4)), bLess );
|
||||
#endif //SRGB_FAST_APPROXIMATION
|
||||
return vec4(linOut,srgbIn.w);;
|
||||
#else //MANUAL_SRGB
|
||||
return srgbIn;
|
||||
#endif //MANUAL_SRGB
|
||||
}
|
||||
|
||||
// F 菲涅尔函数
|
||||
vec3 specularReflection(PbrInfo pbrInputs)
|
||||
{
|
||||
// reflectance0:垂直入射反射率
|
||||
// reflectance90:掠射入射反射率
|
||||
// VdotH:视线与半角向量夹角
|
||||
// 公式效果:角度越偏,反射越强
|
||||
return pbrInputs.reflectance0 + (pbrInputs.reflectance90 - pbrInputs.reflectance0) * pow(clamp(1.0 - pbrInputs.VdotH, 0.0, 1.0), 5.0);
|
||||
}
|
||||
|
||||
// G 几何遮蔽函数
|
||||
float geometricOcclusion(PbrInfo pbrInputs)
|
||||
{
|
||||
// 粗糙表面会自己遮挡自己 → 让高光更真实、不刺眼
|
||||
// 越粗糙 → G 值越小 → 高光越暗
|
||||
float NdotL = pbrInputs.NdotL;
|
||||
float NdotV = pbrInputs.NdotV;
|
||||
float r = pbrInputs.alphaRoughness;
|
||||
|
||||
// 计算光方向的遮蔽
|
||||
// 计算视线方向的遮蔽
|
||||
// 相乘得到总遮蔽
|
||||
float attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL)));
|
||||
float attenuationV = 2.0 * NdotV / (NdotV + sqrt(r * r + (1.0 - r * r) * (NdotV * NdotV)));
|
||||
return attenuationL * attenuationV;
|
||||
}
|
||||
|
||||
// D 微表面分布函数
|
||||
float microfacetDistribution(PbrInfo pbrInputs)
|
||||
{
|
||||
// 控制高光的形状与大小
|
||||
// 光滑 → D 值高 → 小而亮的高光
|
||||
// 粗糙 → D 值低 → 大而散的高光
|
||||
float roughnessSq = pbrInputs.alphaRoughness * pbrInputs.alphaRoughness;
|
||||
float f = (pbrInputs.NdotH * roughnessSq - pbrInputs.NdotH) * pbrInputs.NdotH + 1.0;
|
||||
return roughnessSq / (M_PI * f * f);
|
||||
}
|
||||
|
||||
// 漫反射率,能量守恒所以除以PI
|
||||
vec3 diffuse(PbrInfo pbrInputs)
|
||||
{
|
||||
// 漫反射率 = 漫反射颜色 / π
|
||||
return pbrInputs.diffuseColor / M_PI;
|
||||
}
|
||||
|
||||
#include "include/tocubemap.glsl"
|
||||
// 球谐函数
|
||||
vec3 irradianceFromSH(vec3 i_normal)
|
||||
{
|
||||
vec3 normal = tocubemap(i_normal);
|
||||
vec3 result =
|
||||
pass.sh[0].xyz +
|
||||
pass.sh[1].xyz * normal.y +
|
||||
pass.sh[2].xyz * normal.z +
|
||||
pass.sh[3].xyz * normal.x +
|
||||
pass.sh[4].xyz * normal.y * normal.x +
|
||||
pass.sh[5].xyz * normal.y * normal.z +
|
||||
pass.sh[6].xyz * (1.0 - 3.0*normal.z*normal.z) +
|
||||
pass.sh[7].xyz * normal.z * normal.x +
|
||||
pass.sh[8].xyz * (normal.x*normal.x - normal.y*normal.y);
|
||||
return result * 0.282095;
|
||||
}
|
||||
// 计算IBL环境光照
|
||||
vec3 getIBLContribution(PbrInfo pbrInputs, vec3 n, vec3 reflection)
|
||||
{
|
||||
vec3 cubeVec = tocubemap(reflection);
|
||||
|
||||
float lod = (pbrInputs.perceptualRoughness * pass.prefilteredCubeMipLevels);
|
||||
// 从 BRDF LUT 获取缩放和偏移
|
||||
vec3 brdf = (texture(samplerBRDFLUT, vec2(pbrInputs.NdotV, 1.0 - pbrInputs.perceptualRoughness))).rgb;
|
||||
// 球谐函数 计算漫反射环境光
|
||||
vec3 diffuseLight = irradianceFromSH(n);
|
||||
// 镜面反射:采样预过滤贴图
|
||||
vec3 specularLight = tonemap(textureLod(prefilteredMap, cubeVec, lod)).rgb;
|
||||
// 漫反射 + 镜面反射 计算
|
||||
vec3 diffuse = diffuseLight * pbrInputs.diffuseColor;
|
||||
vec3 specular = specularLight * (pbrInputs.specularColor * brdf.x + brdf.y);
|
||||
|
||||
// 环境光强度缩放
|
||||
diffuse *= pass.scaleIBLAmbient;
|
||||
if(ONLY_SH)
|
||||
return diffuse;
|
||||
|
||||
specular *= pass.scaleIBLAmbient;
|
||||
|
||||
return diffuse + specular;
|
||||
}
|
||||
|
||||
#define ambient 0.3
|
||||
|
||||
float textureProj(vec4 shadowCoord, vec2 offset, uint cascadeIndex)
|
||||
{
|
||||
float shadow = 1.0;
|
||||
float bias = 0.005;
|
||||
|
||||
if ( shadowCoord.z > 0 && shadowCoord.z < 1.0 )
|
||||
{
|
||||
float dist = texture(shadowMap, vec3(shadowCoord.st + offset, cascadeIndex)).r;
|
||||
// 从光看 dist
|
||||
// 同一个点,但是主相机看 shadowCoord.z
|
||||
// 如果光看到的更小,则说明被遮挡
|
||||
if (shadowCoord.w > 0 && dist < shadowCoord.z - bias)
|
||||
{
|
||||
shadow = ambient;
|
||||
}
|
||||
}
|
||||
return shadow;
|
||||
}
|
||||
// 百分比渐进过滤
|
||||
float filterPCF(vec4 sc, uint cascadeIndex)
|
||||
{
|
||||
ivec2 texDim = textureSize(shadowMap, 0).xy;
|
||||
float scale = 0.75;
|
||||
float dx = scale * 1.0 / float(texDim.x);
|
||||
float dy = scale * 1.0 / float(texDim.y);
|
||||
|
||||
float shadowFactor = 0.0;
|
||||
int count = 0;
|
||||
int range = 1;
|
||||
|
||||
for (int x = -range; x <= range; x++)
|
||||
{
|
||||
for (int y = -range; y <= range; y++)
|
||||
{
|
||||
shadowFactor += textureProj(sc, vec2(dx*x, dy*y), cascadeIndex);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return shadowFactor / count;
|
||||
}
|
||||
const mat4 biasMat = mat4(
|
||||
0.5, 0.0, 0.0, 0.0,
|
||||
0.0, 0.5, 0.0, 0.0,
|
||||
0.0, 0.0, 1.0, 0.0,
|
||||
0.5, 0.5, 0.0, 1.0
|
||||
);
|
||||
|
||||
void main()
|
||||
{
|
||||
float perceptualRoughness;
|
||||
float metallic;
|
||||
vec3 diffuseColor;
|
||||
vec4 baseColor;
|
||||
// 基础反射值
|
||||
vec3 f0 = vec3(0.04);
|
||||
|
||||
// 透明度裁剪
|
||||
if (material.alphaMask == 1.0f)
|
||||
{
|
||||
if (material.baseColorTextureSet > -1)
|
||||
{
|
||||
baseColor = SRGBtoLINEAR(texture(diffuseMap, material.baseColorTextureSet == 0 ? inUV0 : inUV1)) * material.baseColorFactor;
|
||||
}
|
||||
else
|
||||
{
|
||||
baseColor = material.baseColorFactor;
|
||||
}
|
||||
if (baseColor.a < material.alphaMaskCutoff)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
}
|
||||
|
||||
// 粗糙度(基础值)
|
||||
perceptualRoughness = material.roughnessFactor;
|
||||
// 金属度(基础值)
|
||||
metallic = material.metallicFactor;
|
||||
// 采样 粗糙度和金属度
|
||||
if (material.physicalDescriptorTextureSet > -1)
|
||||
{
|
||||
// R 通道 = 环境光遮蔽 AO (Occlusion)
|
||||
// G 通道 = 粗糙度 (Roughness)
|
||||
// B 通道 = 金属度 (Metallic)
|
||||
vec4 mrSample = texture(physicalMap, material.physicalDescriptorTextureSet == 0 ? inUV0 : inUV1);
|
||||
perceptualRoughness = mrSample.g * perceptualRoughness;
|
||||
metallic = mrSample.b * metallic;
|
||||
}
|
||||
else
|
||||
{
|
||||
perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0);
|
||||
metallic = clamp(metallic, 0.0, 1.0);
|
||||
}
|
||||
|
||||
// 采样 基础颜色
|
||||
if (material.baseColorTextureSet > -1)
|
||||
{
|
||||
baseColor = SRGBtoLINEAR(texture(diffuseMap, material.baseColorTextureSet == 0 ? inUV0 : inUV1)) * material.baseColorFactor;
|
||||
}
|
||||
else
|
||||
{
|
||||
baseColor = material.baseColorFactor;
|
||||
}
|
||||
|
||||
baseColor *= inColor;
|
||||
|
||||
diffuseColor = baseColor.rgb * (vec3(1.0) - f0);
|
||||
diffuseColor *= 1.0 - metallic;
|
||||
|
||||
// 粗糙度的平方(人眼对粗糙的感受不是线性的)
|
||||
float alphaRoughness = perceptualRoughness * perceptualRoughness;
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// 高光颜色
|
||||
// 它决定了:
|
||||
// 物体反光有多亮
|
||||
// 反光是什么颜色
|
||||
// 金属 / 非金属的反光区别
|
||||
vec3 specularColor = mix(f0, baseColor.rgb, metallic);
|
||||
// 计算反射率基准值
|
||||
float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
|
||||
|
||||
// 计算90°掠射时的反射强度(菲涅尔上限)
|
||||
float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
|
||||
|
||||
// 定义菲涅尔的两个关键参数:垂直入射(R0) / 掠射入射(R90)
|
||||
vec3 specularEnvironmentR0 = specularColor.rgb;
|
||||
vec3 specularEnvironmentR90 = vec3(1.0) * reflectance90;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// 1. 获取最终表面法线(纹理法线 / 模型法线)
|
||||
vec3 n = (material.normalTextureSet > -1) ? getNormal() : normalize(inNormal);
|
||||
// 2. 计算PBR核心方向向量
|
||||
vec3 v = normalize(ubo.camPos - inPosition); // 点 -> 相机
|
||||
vec3 l = normalize(-pass.light[0].direction); // 点 -> 光源(平行光需要取反)
|
||||
vec3 h = normalize(l+v); // 半角向量:光线+视角的中间方向
|
||||
|
||||
// 相机 -> 点 转换为 点 -> 光
|
||||
vec3 reflection = normalize(reflect(-v, n)); // 环境反射向量(用于环境贴图采样)
|
||||
|
||||
// 3. 计算PBR必需的点积(全部钳位避免除零/负数)
|
||||
float NdotL = clamp(dot(n, l), 0.001, 1.0); // 法线·光线
|
||||
float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0); // 法线·视角(取绝对值)
|
||||
float NdotH = clamp(dot(n, h), 0.0, 1.0); // 法线·半角向量
|
||||
float LdotH = clamp(dot(l, h), 0.0, 1.0); // 光线·半角向量
|
||||
float VdotH = clamp(dot(v, h), 0.0, 1.0); // 视角·半角向量
|
||||
|
||||
PbrInfo pbrInputs = PbrInfo(
|
||||
NdotL,
|
||||
NdotV,
|
||||
NdotH,
|
||||
LdotH,
|
||||
VdotH,
|
||||
perceptualRoughness,
|
||||
metallic,
|
||||
specularEnvironmentR0,
|
||||
specularEnvironmentR90,
|
||||
alphaRoughness,
|
||||
diffuseColor,
|
||||
specularColor
|
||||
);
|
||||
|
||||
// 计算参数
|
||||
vec3 F = specularReflection(pbrInputs);
|
||||
float G = geometricOcclusion(pbrInputs);
|
||||
float D = microfacetDistribution(pbrInputs);
|
||||
|
||||
const vec3 u_LightColor = pass.light[0].strength;
|
||||
|
||||
// 计算光照结果
|
||||
// 漫反射
|
||||
vec3 diffuseContrib = (1.0 - F) * diffuse(pbrInputs);
|
||||
// 高光部分
|
||||
vec3 specContrib = F * G * D / (4.0 * NdotL * NdotV);
|
||||
// 最终光照 = 漫反射 + 高光,受法线与灯光夹角影响
|
||||
vec3 color = NdotL * u_LightColor * (diffuseContrib + specContrib);
|
||||
|
||||
if(ONLY_SH)
|
||||
color = diffuseContrib;
|
||||
|
||||
//----------------------------------阴影计算
|
||||
// 返回所在级联
|
||||
uint cascadeIndex = 0;
|
||||
for(uint i = 0; i < SHADOW_MAP_CASCADE_COUNT - 1; ++i)
|
||||
{
|
||||
if(inViewPos.z < pass.cascadeSplits[i])
|
||||
{
|
||||
cascadeIndex = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// 所在贴图位置
|
||||
vec4 shadowCoord = (biasMat * cascade.viewProj[cascadeIndex]) * vec4(inPosition, 1.0);
|
||||
// xy 纹理坐标
|
||||
// z 点到光源的距离
|
||||
shadowCoord.xyz /= shadowCoord.w;
|
||||
|
||||
float shadow = 0;
|
||||
if (enablePCF == 1)
|
||||
{
|
||||
shadow = filterPCF(shadowCoord, cascadeIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
shadow = textureProj(shadowCoord, vec2(0.0), cascadeIndex);
|
||||
}
|
||||
// 只影响直射光
|
||||
if(!ONLY_SH)
|
||||
color *= shadow;
|
||||
|
||||
|
||||
// 计算ibl光照
|
||||
color += getIBLContribution(pbrInputs, n, reflection);
|
||||
|
||||
const float u_OcclusionStrength = 1.0f;
|
||||
// 采样 环境光遮蔽
|
||||
if (material.occlusionTextureSet > -1)
|
||||
{
|
||||
float ao = texture(aoMap, (material.occlusionTextureSet == 0 ? inUV0 : inUV1)).r;
|
||||
color = mix(color, color * ao, u_OcclusionStrength);
|
||||
}
|
||||
// 采样 自发光
|
||||
vec3 emissive = material.emissiveFactor.rgb * material.emissiveStrength;
|
||||
if (material.emissiveTextureSet > -1)
|
||||
{
|
||||
emissive *= SRGBtoLINEAR(texture(emissiveMap, material.emissiveTextureSet == 0 ? inUV0 : inUV1)).rgb;
|
||||
};
|
||||
if(!ONLY_SH)
|
||||
color += emissive;
|
||||
|
||||
outColor = vec4(color, baseColor.a);
|
||||
|
||||
// --------------------------------调试绘图-------------------------------
|
||||
if (pass.debugViewInputs > 0.0)
|
||||
{
|
||||
int index = int(pass.debugViewInputs);
|
||||
switch (index)
|
||||
{
|
||||
case 1:
|
||||
outColor.rgba = material.baseColorTextureSet > -1 ? texture(diffuseMap, material.baseColorTextureSet == 0 ? inUV0 : inUV1) : vec4(1.0f);
|
||||
break;
|
||||
case 2:
|
||||
outColor.rgb = (material.normalTextureSet > -1) ? texture(normalMap, material.normalTextureSet == 0 ? inUV0 : inUV1).rgb : inNormal;
|
||||
break;
|
||||
case 3:
|
||||
outColor.rgb = (material.occlusionTextureSet > -1) ? texture(aoMap, material.occlusionTextureSet == 0 ? inUV0 : inUV1).rrr : vec3(0.0f);
|
||||
break;
|
||||
case 4:
|
||||
outColor.rgb = (material.emissiveTextureSet > -1) ? texture(emissiveMap, material.emissiveTextureSet == 0 ? inUV0 : inUV1).rgb : vec3(0.0f);
|
||||
break;
|
||||
case 5: // 金属度
|
||||
outColor.rgb = texture(physicalMap, inUV0).bbb;
|
||||
break;
|
||||
case 6: // 粗糙度
|
||||
outColor.rgb = texture(physicalMap, inUV0).ggg;
|
||||
break;
|
||||
// PBR 光照方程 调试可视化
|
||||
case 10:
|
||||
outColor.rgb = diffuseContrib; // 漫反射
|
||||
break;
|
||||
case 11:
|
||||
outColor.rgb = F; // 菲涅尔
|
||||
break;
|
||||
case 12:
|
||||
outColor.rgb = vec3(G); // 几何遮蔽
|
||||
break;
|
||||
case 13:
|
||||
outColor.rgb = vec3(D); // 微表面分布
|
||||
break;
|
||||
case 14:
|
||||
outColor.rgb = specContrib; // 高光
|
||||
break;
|
||||
case 15:// 点 -> 光
|
||||
outColor.rgb = reflection; // 反射向量
|
||||
break;
|
||||
// 级联阴影
|
||||
case 20:
|
||||
{
|
||||
switch(cascadeIndex)
|
||||
{
|
||||
case 0 :
|
||||
outColor.rgb *= vec3(1.0f, 0.25f, 0.25f);
|
||||
break;
|
||||
case 1 :
|
||||
outColor.rgb *= vec3(0.25f, 1.0f, 0.25f);
|
||||
break;
|
||||
case 2 :
|
||||
outColor.rgb *= vec3(0.25f, 0.25f, 1.0f);
|
||||
break;
|
||||
case 3 :
|
||||
outColor.rgb *= vec3(1.0f, 1.0f, 0.25f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 21:
|
||||
outColor.rgb = shadowCoord.xxx; // 采样坐标
|
||||
break;
|
||||
case 22:
|
||||
outColor.rgb = shadowCoord.zzz; //当前点 到光源的距离(深度)
|
||||
break;
|
||||
case 23:
|
||||
// 把屏幕UV直接当阴影贴图UV,全屏展示阴影贴图
|
||||
vec2 uv = gl_FragCoord.xy / vec2(1280.0, 720.0); // 换成你屏幕分辨率
|
||||
float depth = texture(shadowMap, vec3(uv, cascadeIndex)).r;
|
||||
|
||||
// 直接把阴影贴图的深度值画出来
|
||||
outColor = vec4(vec3(depth), 1.0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
#version 450
|
||||
|
||||
layout (set = 0, binding = 0) uniform UniformBufferObject
|
||||
{
|
||||
mat4 proj;
|
||||
mat4 view;
|
||||
vec3 camPos;
|
||||
float pad;
|
||||
} ubo;
|
||||
|
||||
layout (push_constant) uniform PushConstant
|
||||
{
|
||||
mat4 model;
|
||||
vec4 color;
|
||||
} constant;
|
||||
|
||||
#ifdef BONE
|
||||
layout (set = 2, binding = 0) uniform UniformBufferBone
|
||||
{
|
||||
mat4 trans[256];
|
||||
} bone;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef BONE
|
||||
layout(location = 0) in vec3 inPosition;
|
||||
layout(location = 1) in vec2 inUV0;
|
||||
layout(location = 2) in vec2 inUV1;
|
||||
layout(location = 3) in vec3 inNormal;
|
||||
layout(location = 4) in vec3 inTangent;
|
||||
layout(location = 5) in vec3 boneWeight;
|
||||
layout(location = 6) in uvec4 boneIndex;
|
||||
layout(location = 7) in vec4 inColor;
|
||||
#else
|
||||
layout(location = 0) in vec3 inPosition;
|
||||
layout(location = 1) in vec2 inUV0;
|
||||
layout(location = 2) in vec2 inUV1;
|
||||
layout(location = 3) in vec3 inNormal;
|
||||
layout(location = 4) in vec3 inTangent;
|
||||
layout(location = 5) in vec4 inColor;
|
||||
#endif
|
||||
|
||||
layout (location = 0) out vec3 outPosition;
|
||||
layout (location = 1) out vec3 outNormal;
|
||||
layout (location = 2) out vec2 outUV0;
|
||||
layout (location = 3) out vec2 outUV1;
|
||||
layout (location = 4) out vec4 outColor;
|
||||
layout (location = 5) out vec3 outViewPos;
|
||||
|
||||
void main()
|
||||
{
|
||||
#ifdef BONE
|
||||
vec4 weights;
|
||||
weights.x = boneWeight.x;
|
||||
weights.y = boneWeight.y;
|
||||
weights.z = boneWeight.z;
|
||||
weights.w = 1.0 - weights.x - weights.y - weights.z;
|
||||
|
||||
vec3 posL = vec3(0, 0, 0);
|
||||
vec3 normalL = vec3(0, 0, 0);
|
||||
posL = weights[0] * (bone.trans[boneIndex[0]] * vec4(inPosition,1)).xyz
|
||||
+ weights[1] * (bone.trans[boneIndex[1]] * vec4(inPosition,1)).xyz
|
||||
+ weights[2] * (bone.trans[boneIndex[2]] * vec4(inPosition,1)).xyz
|
||||
+ weights[3] * (bone.trans[boneIndex[3]] * vec4(inPosition,1)).xyz;
|
||||
|
||||
normalL = weights[0] * mat3(bone.trans[boneIndex[0]]) * inNormal
|
||||
+ weights[1] * mat3(bone.trans[boneIndex[1]]) * inNormal
|
||||
+ weights[2] * mat3(bone.trans[boneIndex[2]]) * inNormal
|
||||
+ weights[3] * mat3(bone.trans[boneIndex[3]]) * inNormal;
|
||||
#else
|
||||
vec3 posL = inPosition;
|
||||
vec3 normalL = inNormal;
|
||||
#endif
|
||||
vec4 worldPos = constant.model * vec4(posL, 1.0);
|
||||
mat3 normalMat = transpose(inverse(mat3(constant.model)));
|
||||
vec3 worldNormal = normalize(normalMat * normalL);
|
||||
vec4 viewPos = ubo.view * worldPos; // 相机空间位置
|
||||
|
||||
outPosition = worldPos.xyz;
|
||||
outNormal = worldNormal;
|
||||
outUV0 = inUV0;
|
||||
outUV1 = inUV1;
|
||||
outColor = inColor * constant.color;
|
||||
outViewPos = viewPos.xyz;
|
||||
|
||||
gl_Position = ubo.proj * ubo.view * worldPos;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
::3d普通
|
||||
glslc.exe 3d.vert -o 3d_vert.spv
|
||||
glslc.exe 3d.frag -o 3d_frag.spv
|
||||
copy 3d_vert.spv ..\res\dl\shader\
|
||||
copy 3d_frag.spv ..\res\dl\shader\
|
||||
del 3d_vert.spv
|
||||
del 3d_frag.spv
|
||||
|
||||
::3d骨骼
|
||||
glslc.exe 3d.vert -D=BONE -o 3d_bone_vert.spv
|
||||
glslc.exe 3d.frag -D=BONE -o 3d_bone_frag.spv
|
||||
copy 3d_bone_vert.spv ..\res\dl\shader\
|
||||
copy 3d_bone_frag.spv ..\res\dl\shader\
|
||||
del 3d_bone_vert.spv
|
||||
del 3d_bone_frag.spv
|
||||
|
||||
::天空盒
|
||||
glslc.exe skybox.vert -o skybox_vert.spv
|
||||
glslc.exe skybox.frag -o skybox_frag.spv
|
||||
copy skybox_vert.spv ..\res\dl\shader\
|
||||
copy skybox_frag.spv ..\res\dl\shader\
|
||||
del skybox_vert.spv
|
||||
del skybox_frag.spv
|
||||
|
||||
::阴影贴图
|
||||
glslc.exe csm.vert -o csm_vert.spv
|
||||
glslc.exe csm.frag -o csm_frag.spv
|
||||
copy csm_vert.spv ..\res\dl\shader\
|
||||
copy csm_frag.spv ..\res\dl\shader\
|
||||
del csm_vert.spv
|
||||
del csm_frag.spv
|
||||
|
||||
::阴影贴图 骨骼
|
||||
glslc.exe csm.vert -D=BONE -o csm_bone_vert.spv
|
||||
glslc.exe csm.frag -D=BONE -o csm_bone_frag.spv
|
||||
copy csm_bone_vert.spv ..\res\dl\shader\
|
||||
copy csm_bone_frag.spv ..\res\dl\shader\
|
||||
del csm_bone_vert.spv
|
||||
del csm_bone_frag.spv
|
||||
|
||||
::2d
|
||||
glslc.exe 2d.vert -o 2d_vert.spv
|
||||
glslc.exe 2d.frag -o 2d_frag.spv
|
||||
glslc.exe 2d_gray.frag -o 2d_gray_frag.spv
|
||||
copy 2d_vert.spv ..\res\dl\shader\
|
||||
copy 2d_frag.spv ..\res\dl\shader\
|
||||
copy 2d_gray_frag.spv ..\res\dl\shader\
|
||||
del 2d_vert.spv
|
||||
del 2d_frag.spv
|
||||
del 2d_gray_frag.spv
|
||||
|
||||
::gfx
|
||||
glslc.exe gfx.vert -o gfx_vert.spv
|
||||
glslc.exe gfx.frag -o gfx_frag.spv
|
||||
copy gfx_vert.spv ..\res\dl\shader\
|
||||
copy gfx_frag.spv ..\res\dl\shader\
|
||||
del gfx_vert.spv
|
||||
del gfx_frag.spv
|
||||
|
||||
pause
|
||||
@@ -0,0 +1,14 @@
|
||||
#version 450
|
||||
|
||||
layout (set = 1, binding = 0) uniform sampler2D colorMap;
|
||||
|
||||
layout (location = 0) in vec2 inUV;
|
||||
|
||||
void main()
|
||||
{
|
||||
float alpha = texture(colorMap, inUV).a;
|
||||
if (alpha < 0.5)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
#version 450
|
||||
|
||||
// 级联级数,创建管线时可覆盖
|
||||
layout(constant_id = 0) const int SHADOW_MAP_CASCADE_COUNT = 4;
|
||||
|
||||
#ifdef BONE
|
||||
layout(location = 0) in vec3 inPosition;
|
||||
layout(location = 1) in vec2 inUV0;
|
||||
layout(location = 2) in vec2 inUV1;
|
||||
layout(location = 3) in vec3 inNormal;
|
||||
layout(location = 4) in vec3 inTangent;
|
||||
layout(location = 5) in vec3 boneWeight;
|
||||
layout(location = 6) in uvec4 boneIndex;
|
||||
layout(location = 7) in vec4 inColor;
|
||||
#else
|
||||
layout(location = 0) in vec3 inPosition;
|
||||
layout(location = 1) in vec2 inUV0;
|
||||
layout(location = 2) in vec2 inUV1;
|
||||
layout(location = 3) in vec3 inNormal;
|
||||
layout(location = 4) in vec3 inTangent;
|
||||
layout(location = 5) in vec4 inColor;
|
||||
#endif
|
||||
|
||||
|
||||
layout (push_constant) uniform PushConstant
|
||||
{
|
||||
mat4 model;
|
||||
uint cascadeIndex;
|
||||
} constant;
|
||||
|
||||
#ifdef BONE
|
||||
layout (set = 2, binding = 0) uniform UniformBufferBone
|
||||
{
|
||||
mat4 trans[256];
|
||||
} bone;
|
||||
#endif
|
||||
|
||||
// 注意与标准的位置不一样
|
||||
layout (set = 0, binding = 0) uniform UniformBufferCascade
|
||||
{
|
||||
mat4 viewProj[SHADOW_MAP_CASCADE_COUNT];
|
||||
} cascade;
|
||||
|
||||
layout (location = 0) out vec2 outUV;
|
||||
|
||||
void main()
|
||||
{
|
||||
#ifdef BONE
|
||||
vec4 weights;
|
||||
weights.x = boneWeight.x;
|
||||
weights.y = boneWeight.y;
|
||||
weights.z = boneWeight.z;
|
||||
weights.w = 1.0 - weights.x - weights.y - weights.z;
|
||||
|
||||
vec3 posL = vec3(0, 0, 0);
|
||||
posL = weights[0] * (bone.trans[boneIndex[0]] * vec4(inPosition,1)).xyz
|
||||
+ weights[1] * (bone.trans[boneIndex[1]] * vec4(inPosition,1)).xyz
|
||||
+ weights[2] * (bone.trans[boneIndex[2]] * vec4(inPosition,1)).xyz
|
||||
+ weights[3] * (bone.trans[boneIndex[3]] * vec4(inPosition,1)).xyz;
|
||||
#else
|
||||
vec3 posL = inPosition;
|
||||
#endif
|
||||
|
||||
outUV = inUV0;
|
||||
|
||||
vec4 pos = constant.model * vec4(posL, 1.0);
|
||||
gl_Position = cascade.viewProj[constant.cascadeIndex] * pos;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#version 450
|
||||
|
||||
layout(location = 0) in vec4 fragColor;
|
||||
|
||||
layout(location = 0) out vec4 outColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
outColor = fragColor;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#version 450
|
||||
|
||||
layout(binding = 0) uniform UniformBufferObject
|
||||
{
|
||||
mat4 viewProj;
|
||||
} ubo;
|
||||
|
||||
|
||||
layout(location = 0) in vec3 inPosition;
|
||||
layout(location = 1) in vec4 inColor;
|
||||
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_PointSize = 1.0;
|
||||
gl_Position = ubo.viewProj * vec4(inPosition, 1.0);
|
||||
fragColor = inColor;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#define NUM_LIGHT_DIR 3
|
||||
#define NUM_LIGHT_DOT 10
|
||||
#define NUM_LIGHT_SPOT 3
|
||||
#define NUM_LIGHT 16
|
||||
|
||||
//灯光
|
||||
struct Light
|
||||
{
|
||||
vec3 strength; //强度
|
||||
float falloffStart; //衰减起始 仅点光源、聚光灯
|
||||
vec3 direction; //方向 仅平行光、聚光灯
|
||||
float falloffEnd; //衰减结束 仅点光源、聚光灯
|
||||
vec3 position; //位置 仅点光源、聚光灯
|
||||
float spotPower; //聚光灯强度 仅聚光灯
|
||||
};
|
||||
@@ -0,0 +1,11 @@
|
||||
vec3 tocubemap(vec3 vec)
|
||||
{
|
||||
// 世界坐标系 → 转换成标准 Cubemap Y-Up 坐标
|
||||
// +X 右 (Right)
|
||||
// -X 左 (Left)
|
||||
// +Y 上 (Up)
|
||||
// -Y 下 (Down)
|
||||
// +Z 前 (Forward)
|
||||
// -Z 后 (Backward)
|
||||
return vec3(-vec.y, vec.z, vec.x);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/* Copyright (c) 2018-2024, Sascha Willems
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
// From http://filmicworlds.com/blog/filmic-tonemapping-operators/
|
||||
vec3 Uncharted2Tonemap(vec3 color)
|
||||
{
|
||||
float A = 0.15;
|
||||
float B = 0.50;
|
||||
float C = 0.10;
|
||||
float D = 0.20;
|
||||
float E = 0.02;
|
||||
float F = 0.30;
|
||||
float W = 11.2;
|
||||
return ((color*(A*color+C*B)+D*E)/(color*(A*color+B)+D*F))-E/F;
|
||||
}
|
||||
|
||||
// HDR颜色 + 曝光、gamma -> 屏幕颜色
|
||||
vec4 tonemap(vec4 color)
|
||||
{
|
||||
vec3 outcol = Uncharted2Tonemap(color.rgb * pass.exposure);
|
||||
outcol = outcol * (1.0f / Uncharted2Tonemap(vec3(11.2f)));
|
||||
return vec4(pow(outcol, vec3(1.0f / pass.gamma)), color.a);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#version 450
|
||||
#extension GL_GOOGLE_include_directive : require
|
||||
|
||||
|
||||
layout (location = 0) in vec3 inUVW;
|
||||
|
||||
layout (location = 0) out vec4 outColor;
|
||||
|
||||
layout (set = 0, binding = 1) uniform UniformBufferPass
|
||||
{
|
||||
float exposure;
|
||||
float gamma;
|
||||
} pass;
|
||||
|
||||
layout (set = 0, binding = 2) uniform samplerCube samplerEnv;
|
||||
|
||||
#include "include/tonemap.glsl"
|
||||
void main()
|
||||
{
|
||||
vec3 color = tonemap(textureLod(samplerEnv, inUVW, 1.5)).rgb;
|
||||
outColor = vec4(color * 1.0, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#version 450
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
||||
layout (set = 0, binding = 0) uniform UniformBufferObject
|
||||
{
|
||||
mat4 proj;
|
||||
mat4 view;
|
||||
} ubo;
|
||||
|
||||
|
||||
layout(location = 0) in vec3 inPosition;
|
||||
|
||||
layout (location = 0) out vec3 outUVW;
|
||||
|
||||
#include "include/tocubemap.glsl"
|
||||
void main()
|
||||
{
|
||||
outUVW = tocubemap(inPosition);
|
||||
|
||||
mat4 viewNoTranslation = mat4(mat3(ubo.view));
|
||||
|
||||
vec4 pos = ubo.proj * viewNoTranslation * vec4(inPosition.xyz, 1.0);
|
||||
gl_Position = pos.xyww;
|
||||
}
|
||||
Reference in New Issue
Block a user