材质表面参数接通:新增 emissiveFactor(无 emissive 贴图时的发光入口,glTF 语义)入 UBO/YAML/缓存键/两 shader;Transmission/Thickness 未勾 Transparent 时禁用编辑(不透明段 shader 不读)

This commit is contained in:
2026-10-09 00:04:55 +08:00
parent 235482733c
commit 6447b5c0fa
6 changed files with 42 additions and 8 deletions
+21 -3
View File
@@ -174,12 +174,23 @@ void MaterialEditorPanel::DrawAssetMode(const EditorContext& ctx)
ImGui::DragFloat("Roughness", &p.factors.y, 0.01f, 0.0f, 1.0f)); ImGui::DragFloat("Roughness", &p.factors.y, 0.01f, 0.0f, 1.0f));
EditParam(ImGui::ColorEdit4("Base Color", &p.baseColor.x)); EditParam(ImGui::ColorEdit4("Base Color", &p.baseColor.x));
EditParam(ImGui::DragFloat("IOR", &p.surface.x, 0.01f, 1.0f, 3.0f)); EditParam(ImGui::DragFloat("IOR", &p.surface.x, 0.01f, 1.0f, 3.0f));
EditParam(ImGui::DragFloat("Transmission", &p.surface.y, 0.01f, 0.0f, // 发光 = emissiveFactor × emissive 贴图 × Strength(Emissive 槽
1.0f)); // 兜底贴图恒黑,无贴图时颜色因子是唯一入口)
EditParam(ImGui::ColorEdit3("Emissive Color", &p.emissiveFactor.x));
EditParam(ImGui::DragFloat("Emissive Strength", &p.surface.z, 0.05f, EditParam(ImGui::DragFloat("Emissive Strength", &p.surface.z, 0.05f,
0.0f, 100.0f)); 0.0f, 100.0f));
// transmission/thickness 只有不透明段不读——透明 shader 专属
//(未勾 Transparent 时禁用编辑,防"拖了没反应"的困惑)
ImGui::BeginDisabled(!trans);
EditParam(ImGui::DragFloat("Transmission", &p.surface.y, 0.01f, 0.0f,
1.0f));
EditParam(ImGui::DragFloat("Thickness", &p.surface.w, 0.01f, 0.0f, EditParam(ImGui::DragFloat("Thickness", &p.surface.w, 0.01f, 0.0f,
10.0f)); 10.0f));
ImGui::EndDisabled();
if (!trans)
{
ImGui::TextDisabled("Transmission/Thickness need Transparent");
}
// ---- 纹理槽(变化 → 落盘 + waitIdle 重建)---- // ---- 纹理槽(变化 → 落盘 + waitIdle 重建)----
ImGui::SeparatorText("Textures"); ImGui::SeparatorText("Textures");
@@ -303,9 +314,16 @@ void MaterialEditorPanel::DrawBuiltinMode(const EditorContext& ctx)
ImGui::DragFloat("Roughness", &p.factors.y, 0.01f, 0.0f, 1.0f); ImGui::DragFloat("Roughness", &p.factors.y, 0.01f, 0.0f, 1.0f);
ImGui::ColorEdit4("Base Color", &p.baseColor.x); ImGui::ColorEdit4("Base Color", &p.baseColor.x);
ImGui::DragFloat("IOR", &p.surface.x, 0.01f, 1.0f, 3.0f); ImGui::DragFloat("IOR", &p.surface.x, 0.01f, 1.0f, 3.0f);
ImGui::DragFloat("Transmission", &p.surface.y, 0.01f, 0.0f, 1.0f); ImGui::ColorEdit3("Emissive Color", &p.emissiveFactor.x);
ImGui::DragFloat("Emissive Strength", &p.surface.z, 0.05f, 0.0f, 100.0f); ImGui::DragFloat("Emissive Strength", &p.surface.z, 0.05f, 0.0f, 100.0f);
ImGui::BeginDisabled(!trans);
ImGui::DragFloat("Transmission", &p.surface.y, 0.01f, 0.0f, 1.0f);
ImGui::DragFloat("Thickness", &p.surface.w, 0.01f, 0.0f, 10.0f); ImGui::DragFloat("Thickness", &p.surface.w, 0.01f, 0.0f, 10.0f);
ImGui::EndDisabled();
if (!trans)
{
ImGui::TextDisabled("Transmission/Thickness need Transparent");
}
ImGui::SeparatorText("Textures"); ImGui::SeparatorText("Textures");
static constexpr const char* kSlotNames[Engine::Material::kSlotCount] = { static constexpr const char* kSlotNames[Engine::Material::kSlotCount] = {
"Albedo", "Normal", "MetallicRoughness", "Albedo", "Normal", "MetallicRoughness",
@@ -57,6 +57,10 @@ namespace Engine {
glm::vec4 surface{1.5f, 0.0f, 1.0f, 0.0f}; glm::vec4 surface{1.5f, 0.0f, 1.0f, 0.0f};
// 杂项语义:x = unlit(KHR_materials_unlit,shader 早退直出 albedo) // 杂项语义:x = unlit(KHR_materials_unlit,shader 早退直出 albedo)
glm::vec4 misc{0.0f, 0.0f, 0.0f, 0.0f}; glm::vec4 misc{0.0f, 0.0f, 0.0f, 0.0f};
// glTF emissiveFactor:自发光颜色(rgb;黑 = 不发光)。emissive
// 槽默认兜底纹理是纯黑,无贴图时 Emissive Strength 乘出来恒黑
// ——无贴图想要发光就调这里(rgb × 贴图 × surface.z)
glm::vec4 emissiveFactor{0.0f, 0.0f, 0.0f, 0.0f};
// 每槽 KHR_texture_transform(glTF2 每个 textureInfo 独立声明 // 每槽 KHR_texture_transform(glTF2 每个 textureInfo 独立声明
// offset/scale/rotation——烘焙单份顶点 UV 无法表达"一材质多槽 // offset/scale/rotation——烘焙单份顶点 UV 无法表达"一材质多槽
// 各异变换",收敛为 shader 侧线性式 uv' = A·uv + t,作用在本引擎 // 各异变换",收敛为 shader 侧线性式 uv' = A·uv + t,作用在本引擎
+4 -1
View File
@@ -84,7 +84,10 @@ namespace Engine
",s:" + std::to_string(params.surface.x) + ",s:" + std::to_string(params.surface.x) +
"," + std::to_string(params.surface.y) + "," + std::to_string(params.surface.y) +
"," + std::to_string(params.surface.z) + "," + std::to_string(params.surface.z) +
"," + std::to_string(params.surface.w); "," + std::to_string(params.surface.w) +
",e:" + std::to_string(params.emissiveFactor.x) +
"," + std::to_string(params.emissiveFactor.y) +
"," + std::to_string(params.emissiveFactor.z);
// per-slot UV 变换 + unlit 入键:同一张贴图配不同变换是不同材质 // per-slot UV 变换 + unlit 入键:同一张贴图配不同变换是不同材质
//(KHR_texture_transform 测试模型:一张棋盘格被 82 个材质以不同 //(KHR_texture_transform 测试模型:一张棋盘格被 82 个材质以不同
// 变换共享,键漏了会串成同一份) // 变换共享,键漏了会串成同一份)
+4
View File
@@ -84,6 +84,8 @@ namespace Engine
EmitVec4(out, data.params.baseColor); EmitVec4(out, data.params.baseColor);
out << YAML::Key << "Surface" << YAML::Value; out << YAML::Key << "Surface" << YAML::Value;
EmitVec4(out, data.params.surface); EmitVec4(out, data.params.surface);
out << YAML::Key << "EmissiveFactor" << YAML::Value;
EmitVec4(out, data.params.emissiveFactor);
out << YAML::Key << "Misc" << YAML::Value; out << YAML::Key << "Misc" << YAML::Value;
EmitVec4(out, data.params.misc); EmitVec4(out, data.params.misc);
// per-slot UV 变换(KHR_texture_transform):6 槽各 A(4 分量) + T // per-slot UV 变换(KHR_texture_transform):6 槽各 A(4 分量) + T
@@ -145,6 +147,8 @@ namespace Engine
m["BaseColor"], MaterialParams{}.baseColor); m["BaseColor"], MaterialParams{}.baseColor);
out.params.surface = ReadVec4( out.params.surface = ReadVec4(
m["Surface"], MaterialParams{}.surface); m["Surface"], MaterialParams{}.surface);
out.params.emissiveFactor = ReadVec4(
m["EmissiveFactor"], MaterialParams{}.emissiveFactor);
out.params.misc = ReadVec4( out.params.misc = ReadVec4(
m["Misc"], MaterialParams{}.misc); m["Misc"], MaterialParams{}.misc);
for (u32 slot = 0; slot < Material::kSlotCount; ++slot) { for (u32 slot = 0; slot < Material::kSlotCount; ++slot) {
+5 -2
View File
@@ -46,6 +46,7 @@ layout(set = 1, binding = 6) uniform MaterialParams {
vec4 baseColor; // glTF baseColorFactor:rgb 调色 albedo,a = BLEND 透明度 vec4 baseColor; // glTF baseColorFactor:rgb 调色 albedo,a = BLEND 透明度
vec4 surface; // x = ior(F0 换算),y = transmission(不透明段恒 0 语义),z = 自发光强度,w = 体积厚度 vec4 surface; // x = ior(F0 换算),y = transmission(不透明段恒 0 语义),z = 自发光强度,w = 体积厚度
vec4 misc; // x = unlit(KHR_materials_unlit,1 = 早退直出 albedo) vec4 misc; // x = unlit(KHR_materials_unlit,1 = 早退直出 albedo)
vec4 emissiveFactor; // 自发光颜色(rgb × emissiveMap × surface.z;黑 = 不发光)
vec4 uvA[6]; // 每槽 UV 线性变换(KHR_texture_transform,v-up 空间)(a11,a12,a21,a22),槽序 = binding vec4 uvA[6]; // 每槽 UV 线性变换(KHR_texture_transform,v-up 空间)(a11,a12,a21,a22),槽序 = binding
vec4 uvT[6]; // 每槽 UV 平移 (tx, ty, 0, 0) vec4 uvT[6]; // 每槽 UV 平移 (tx, ty, 0, 0)
} matParams; } matParams;
@@ -166,8 +167,10 @@ void main() {
matParams.factors.z) * matParams.factors.y, matParams.factors.z) * matParams.factors.y,
0.045, 1.0); 0.045, 1.0);
float metallic = clamp(mr.b * matParams.factors.x, 0.0, 1.0); float metallic = clamp(mr.b * matParams.factors.x, 0.0, 1.0);
// 自发光强度(KHR_materials_emissive_strength,缺省 1) // 自发光强度(KHR_materials_emissive_strength,缺省 1);
vec3 emissive = texture(emissiveMap, ApplyUv(3, fragUV)).rgb * matParams.surface.z; // emissiveFactor = 颜色因子(无贴图时发光的入口——兜底贴图恒黑)
vec3 emissive = texture(emissiveMap, ApplyUv(3, fragUV)).rgb
* matParams.emissiveFactor.rgb * matParams.surface.z;
vec3 N = MappedNormal(normalize(fragNormal), fragTangent, ApplyUv(1, fragUV)); vec3 N = MappedNormal(normalize(fragNormal), fragTangent, ApplyUv(1, fragUV));
vec3 V = normalize(ubo.cameraPos.xyz - fragWorldPos); vec3 V = normalize(ubo.cameraPos.xyz - fragWorldPos);
+4 -2
View File
@@ -46,7 +46,8 @@ layout(set = 1, binding = 6) uniform MaterialParams {
vec4 baseColor; // glTF baseColorFactor:rgb 调色 albedo,a = BLEND 透明度 vec4 baseColor; // glTF baseColorFactor:rgb 调色 albedo,a = BLEND 透明度
vec4 surface; // x = ior,y = transmission(KHR_materials_transmission),z = 自发光强度,w = 体积厚度 vec4 surface; // x = ior,y = transmission(KHR_materials_transmission),z = 自发光强度,w = 体积厚度
vec4 misc; // x = unlit(透射材质不会是 unlit,仅为与 simple_shader 布局一致) vec4 misc; // x = unlit(透射材质不会是 unlit,仅为与 simple_shader 布局一致)
vec4 uvA[6]; // 每槽 UV 线性变换(KHR_texture_transform,v-up 空间)(a11,a12,a21,a22) vec4 emissiveFactor; // 自发光颜色(rgb × emissiveMap × surface.z;黑 = 不发光)
vec4 uvA[6]; // 每槽 UV 线性变换(KHR_texture_transform,v-up 空间)(a11,a12,a21,a22),槽序 = binding
vec4 uvT[6]; // 每槽 UV 平移 (tx, ty, 0, 0) vec4 uvT[6]; // 每槽 UV 平移 (tx, ty, 0, 0)
} matParams; } matParams;
@@ -159,7 +160,8 @@ void main() {
0.045, 1.0); 0.045, 1.0);
float metallic = clamp(mr.b * matParams.factors.x, 0.0, 1.0); float metallic = clamp(mr.b * matParams.factors.x, 0.0, 1.0);
// 自发光强度(KHR_materials_emissive_strength,缺省 1) // 自发光强度(KHR_materials_emissive_strength,缺省 1)
vec3 emissive = texture(emissiveMap, ApplyUv(3, fragUV)).rgb * matParams.surface.z; vec3 emissive = texture(emissiveMap, ApplyUv(3, fragUV)).rgb
* matParams.emissiveFactor.rgb * matParams.surface.z;
// glTF 表面扩展:透射率(KHR_materials_transmission)/ // glTF 表面扩展:透射率(KHR_materials_transmission)/
// 折射率(ior,缺省 1.5)/ 体积厚度(KHR_materials_volume) // 折射率(ior,缺省 1.5)/ 体积厚度(KHR_materials_volume)