Add animation controller system, material assets and skeleton visualization
- .animctrl state machine asset (params/transitions/blend trees, 1D+2D directional blending) with Unity Animator-style editor panel: state list, transitions, params, directional pad preview driving live CrossFade on the selected entity - Split animation evaluation out of SceneRenderer into AnimationSystem/AnimationEvaluator; skin palettes with rest-pose fallback and blend-weight epsilon filtering - MaterialAsset (.material) with reload-safe preview tile pool (DropMaterial clears dirty refs before instance destruction) - EditorGizmoPass skeleton wires + viewport joint overlay; camera projection rework (baked Vulkan Y-flip, ortho support) - Editor/game build split via HELLOVULKAN_EDITOR option
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
#version 450
|
||||
|
||||
// Editor gizmo 图标片元:按 aux.x(形状 id,与 SceneRenderer 收集常量
|
||||
// 一一对应)在 uv ∈ [-1,1] 上做程序化 SDF 造型,预乘 alpha 输出
|
||||
//(pass 侧混合 ONE, ONE_MINUS_SRC_ALPHA)。
|
||||
// 0 方向光(太阳盘 + 8 向光芒)
|
||||
// 1 点光(亮核 + 柔和光晕)
|
||||
// 2 相机(机身挖孔 + 镜头环 + 取景器凸块)
|
||||
// 3 天空盒(等距立方线框)
|
||||
// 4 天空光(环 + 内核点)
|
||||
|
||||
layout(location = 0) in vec4 inColor;
|
||||
layout(location = 1) in vec4 inAux;
|
||||
|
||||
layout(location = 0) out vec4 outColor;
|
||||
|
||||
// 方框 SDF
|
||||
float sdBox(vec2 p, vec2 b) {
|
||||
vec2 d = abs(p) - b;
|
||||
return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0);
|
||||
}
|
||||
|
||||
// 线段 SDF
|
||||
float sdSegment(vec2 p, vec2 a, vec2 b) {
|
||||
vec2 pa = p - a, ba = b - a;
|
||||
float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);
|
||||
return length(pa - ba * h);
|
||||
}
|
||||
|
||||
// 等边六边形 SDF(circumradius r,iq 惯用式)
|
||||
float sdHexagon(vec2 p, float r) {
|
||||
const vec3 k = vec3(-0.866025404, 0.5, 0.577350269);
|
||||
p = abs(p);
|
||||
p -= 2.0 * min(dot(k.xy, p), 0.0) * k.xy;
|
||||
p -= vec2(clamp(p.x, -k.z * r, k.z * r), r);
|
||||
return length(p) * sign(p.y);
|
||||
}
|
||||
|
||||
float ShapeSDF(vec2 p, int id) {
|
||||
if (id == 0) { // 方向光:太阳盘 + 8 向光芒
|
||||
float r = length(p);
|
||||
float disc = r - 0.38;
|
||||
float a = atan(p.y, p.x);
|
||||
float s45 = 0.78539816; // 45° 扇区
|
||||
float fa = abs(mod(a + s45 * 0.5, s45) - s45 * 0.5);
|
||||
float ray = max(r * sin(fa), abs(r - 0.58) - 0.20);
|
||||
return min(disc, ray);
|
||||
}
|
||||
if (id == 1) return length(p) - 0.22; // 点光亮核(光晕在 main)
|
||||
if (id == 2) { // 相机
|
||||
float body = sdBox(p - vec2(0.05, 0.0), vec2(0.50, 0.36));
|
||||
float hole = max(body, -(length(p - vec2(0.05, 0.0)) - 0.20));
|
||||
float ring = abs(length(p - vec2(0.05, 0.0)) - 0.28) - 0.035;
|
||||
float vf = sdBox(p - vec2(0.30, 0.44), vec2(0.14, 0.10));
|
||||
return min(min(hole, ring), vf);
|
||||
}
|
||||
if (id == 3) { // 天空盒:等距立方线框
|
||||
float hex = abs(sdHexagon(p, 0.72)) - 0.045;
|
||||
float e1 = sdSegment(p, vec2(0.0), vec2(0.0, -0.72)) - 0.045;
|
||||
float e2 = sdSegment(p, vec2(0.0), vec2(-0.6235, 0.36)) - 0.045;
|
||||
float e3 = sdSegment(p, vec2(0.0), vec2(0.6235, 0.36)) - 0.045;
|
||||
return min(hex, min(e1, min(e2, e3)));
|
||||
}
|
||||
// 天空光(id == 4):环 + 内核点
|
||||
return min(abs(length(p) - 0.52) - 0.09, length(p) - 0.14);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 uv = inAux.yz;
|
||||
int id = int(inAux.x + 0.5);
|
||||
// uv 空间的像素级边缘宽度(quad 上 uv 随屏幕像素线性变化)
|
||||
float aa = fwidth(uv.x) * 1.5 + 1e-4;
|
||||
|
||||
float alpha = smoothstep(aa, -aa, ShapeSDF(uv, id));
|
||||
|
||||
if (id == 1) { // 点光:核心外叠加径向光晕
|
||||
float r = length(uv);
|
||||
float halo = (1.0 - smoothstep(0.25, 1.0, r)) * 0.35;
|
||||
alpha = max(alpha, halo);
|
||||
}
|
||||
|
||||
// 预乘 alpha:ONE / ONE_MINUS_SRC_ALPHA 混合下的正确形式
|
||||
outColor = vec4(inColor.rgb * alpha, alpha);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#version 450
|
||||
|
||||
// Editor gizmo billboard 顶点:世界空间 billboard quad(CPU 侧已面向相机
|
||||
// 展开),无描述符 set——viewProj 走 push constant(与 debug_line 同约定)。
|
||||
// aux = (shapeId, uv.x, uv.y, 0),uv ∈ [-1,1] 供片元 SDF 造型。
|
||||
|
||||
layout(location = 0) in vec3 inPos;
|
||||
layout(location = 1) in vec4 inColor;
|
||||
layout(location = 2) in vec4 inAux;
|
||||
|
||||
layout(location = 0) out vec4 outColor;
|
||||
layout(location = 1) out vec4 outAux;
|
||||
|
||||
layout(push_constant) uniform PC {
|
||||
mat4 viewProj;
|
||||
} pc;
|
||||
|
||||
void main() {
|
||||
gl_Position = pc.viewProj * vec4(inPos, 1.0);
|
||||
outColor = inColor;
|
||||
outAux = inAux;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#version 450
|
||||
|
||||
// Editor gizmo 拾取片元:实体 id 原样写 R32Uint(与 hitproxy.frag 同
|
||||
// 语义)。flat = 无插值,像素值即命中图元的实体位模式。
|
||||
|
||||
layout(location = 0) flat in uint inEntityId;
|
||||
|
||||
layout(location = 0) out uvec4 outColor;
|
||||
|
||||
void main() {
|
||||
outColor = uvec4(inEntityId, 0u, 0u, 0u);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#version 450
|
||||
|
||||
// Editor gizmo 拾取顶点:与 billboard 共享同一 ring VB(pos/color/aux
|
||||
// + entityId 四属性流),画进 HitProxy 的 R32Uint 目标。只有 entityId
|
||||
// 参与变换输出,color/aux 声明占位(属性流绑定时全开)。
|
||||
|
||||
layout(location = 0) in vec3 inPos;
|
||||
layout(location = 1) in vec4 inColor; // 占位(拾取不用)
|
||||
layout(location = 2) in vec4 inAux; // 占位
|
||||
layout(location = 3) in uint inEntityId;
|
||||
|
||||
layout(location = 0) flat out uint outEntityId;
|
||||
|
||||
layout(push_constant) uniform PC {
|
||||
mat4 viewProj;
|
||||
} pc;
|
||||
|
||||
void main() {
|
||||
gl_Position = pc.viewProj * vec4(inPos, 1.0);
|
||||
outEntityId = inEntityId;
|
||||
}
|
||||
@@ -44,8 +44,21 @@ layout(set = 1, binding = 5) uniform sampler2D roughnessMap; // 独立粗糙度
|
||||
layout(set = 1, binding = 6) uniform MaterialParams {
|
||||
vec4 factors; // x = metallic 因子,y = roughness 因子,z = 独立粗糙度图开关,w = MASK 镂空开关
|
||||
vec4 baseColor; // glTF baseColorFactor:rgb 调色 albedo,a = BLEND 透明度
|
||||
vec4 surface; // x = ior(F0 换算),y = transmission(不透明段恒 0 语义),z = 自发光强度,w = 体积厚度
|
||||
vec4 misc; // x = unlit(KHR_materials_unlit,1 = 早退直出 albedo)
|
||||
vec4 uvA[6]; // 每槽 UV 线性变换(KHR_texture_transform,v-up 空间)(a11,a12,a21,a22),槽序 = binding
|
||||
vec4 uvT[6]; // 每槽 UV 平移 (tx, ty, 0, 0)
|
||||
} matParams;
|
||||
|
||||
// 每槽 UV 变换:uv' = A·uv + t(identity 时退化为直通)。slot 必须
|
||||
// 字面量调用点(编译期展开索引);6 = Material::kSlotCount
|
||||
vec2 ApplyUv(int slot, vec2 uv) {
|
||||
vec4 a = matParams.uvA[slot];
|
||||
vec4 t = matParams.uvT[slot];
|
||||
return vec2(a.x * uv.x + a.y * uv.y + t.x,
|
||||
a.z * uv.x + a.w * uv.y + t.y);
|
||||
}
|
||||
|
||||
// CSM 阴影(sampler2DShadow:单次采样 = 硬件 2×2 深度比较 PCF)
|
||||
layout(set = 2, binding = 0) uniform sampler2DShadow shadowMap0; // CSM 级联 0(最近)
|
||||
layout(set = 2, binding = 1) uniform sampler2DShadow shadowMap1; // 级联 1
|
||||
@@ -136,23 +149,40 @@ vec3 FresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness) {
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 albedoTex = texture(albedoMap, fragUV);
|
||||
vec4 albedoTex = texture(albedoMap, ApplyUv(0, fragUV));
|
||||
// alphaMode=MASK 镂空(表针/栅栏等硬边贴图):低于阈值的纹素直接丢弃
|
||||
if (matParams.factors.w > 0.5 && albedoTex.a < 0.5) discard;
|
||||
vec3 albedo = albedoTex.rgb * matParams.baseColor.rgb;
|
||||
vec4 mr = texture(metallicRoughnessMap, fragUV);
|
||||
// KHR_materials_unlit:无光照语义(文字标签/示意图),albedo 直出
|
||||
if (matParams.misc.x > 0.5) {
|
||||
outColor = vec4(albedo, albedoTex.a * matParams.baseColor.a);
|
||||
outVelocity = fragVelocity;
|
||||
return;
|
||||
}
|
||||
vec4 mr = texture(metallicRoughnessMap, ApplyUv(2, fragUV));
|
||||
// 粗糙度源按 factors.z 切换:glTF 合图工作流读 MR.g;
|
||||
// FBX/OBJ specular 工作流(z=1)换用独立粗糙度图 R 通道
|
||||
float roughness = clamp(mix(mr.g, texture(roughnessMap, fragUV).r,
|
||||
float roughness = clamp(mix(mr.g, texture(roughnessMap, ApplyUv(5, fragUV)).r,
|
||||
matParams.factors.z) * matParams.factors.y,
|
||||
0.045, 1.0);
|
||||
float metallic = clamp(mr.b * matParams.factors.x, 0.0, 1.0);
|
||||
vec3 emissive = texture(emissiveMap, fragUV).rgb;
|
||||
// 自发光强度(KHR_materials_emissive_strength,缺省 1)
|
||||
vec3 emissive = texture(emissiveMap, ApplyUv(3, fragUV)).rgb * matParams.surface.z;
|
||||
|
||||
vec3 N = MappedNormal(normalize(fragNormal), fragTangent, fragUV);
|
||||
vec3 N = MappedNormal(normalize(fragNormal), fragTangent, ApplyUv(1, fragUV));
|
||||
vec3 V = normalize(ubo.cameraPos.xyz - fragWorldPos);
|
||||
// 双面法线:cull 关闭 + glTF doubleSided=true,背面片元(表壳后盖/
|
||||
// 内壁等从背面看到的表面)几何法线背向相机,NdotL≤0 → 直接光全灭、
|
||||
// IBL 采错半球 = 纯黑壳(three.js DoubleSide 对背面自动翻法线,
|
||||
// 这里对齐该语义;与 translucent shader 的翻转同款)
|
||||
if (dot(N, V) < 0.0) N = -N;
|
||||
float NdotV = max(dot(N, V), 1e-4);
|
||||
vec3 F0 = mix(vec3(0.04), albedo, metallic); // 电介质基准反射率 4%
|
||||
// F0 按折射率换算(KHR_materials_ior):((ior-1)/(ior+1))²;
|
||||
// glTF 缺省 ior=1.5 → 0.04,与旧固定值一致
|
||||
float ior = max(matParams.surface.x, 1.0);
|
||||
vec3 F0 = mix(vec3((ior - 1.0) / (ior + 1.0)
|
||||
* (ior - 1.0) / (ior + 1.0)),
|
||||
albedo, metallic); // 电介质 F0 / 金属 albedo
|
||||
|
||||
vec3 Lo = vec3(0.0);
|
||||
float shade0 = 1.0f; // 第 0 盏光的阴影因子(环境光同步衰减用)
|
||||
@@ -213,7 +243,7 @@ void main() {
|
||||
vec3 kD_amb = (1.0 - F_amb) * (1.0 - metallic);
|
||||
|
||||
vec3 irradiance = texture(irradianceMap, N).rgb;
|
||||
float ao = texture(aoMap, fragUV).r;
|
||||
float ao = texture(aoMap, ApplyUv(4, fragUV)).r;
|
||||
vec3 diffuse = kD_amb * irradiance * albedo * ao;
|
||||
|
||||
vec3 R = reflect(-V, N);
|
||||
@@ -229,5 +259,7 @@ void main() {
|
||||
// alpha = albedo 贴图覆盖率 × baseColorFactor.a(glTF alphaMode=BLEND
|
||||
// 混合源);不透明资产两者恒 1 行为不变。预乘在 tonemap 段完成。
|
||||
outColor = vec4(ambient + Lo + emissive, albedoTex.a * matParams.baseColor.a);
|
||||
// ==== DEBUG B1: 纯 albedo 直出(验证贴图绑定/UV 采样)====
|
||||
// outColor = vec4(albedo, 1.0);
|
||||
outVelocity = fragVelocity;
|
||||
}
|
||||
|
||||
@@ -44,8 +44,20 @@ layout(set = 1, binding = 5) uniform sampler2D roughnessMap; // 独立粗糙度
|
||||
layout(set = 1, binding = 6) uniform MaterialParams {
|
||||
vec4 factors; // x = metallic 因子,y = roughness 因子,z = 独立粗糙度图开关,w = MASK 镂空开关
|
||||
vec4 baseColor; // glTF baseColorFactor:rgb 调色 albedo,a = BLEND 透明度
|
||||
vec4 surface; // x = ior,y = transmission(KHR_materials_transmission),z = 自发光强度,w = 体积厚度
|
||||
vec4 misc; // x = unlit(透射材质不会是 unlit,仅为与 simple_shader 布局一致)
|
||||
vec4 uvA[6]; // 每槽 UV 线性变换(KHR_texture_transform,v-up 空间)(a11,a12,a21,a22)
|
||||
vec4 uvT[6]; // 每槽 UV 平移 (tx, ty, 0, 0)
|
||||
} matParams;
|
||||
|
||||
// 每槽 UV 变换:uv' = A·uv + t(与 simple_shader.frag 同款,6 = kSlotCount)
|
||||
vec2 ApplyUv(int slot, vec2 uv) {
|
||||
vec4 a = matParams.uvA[slot];
|
||||
vec4 t = matParams.uvT[slot];
|
||||
return vec2(a.x * uv.x + a.y * uv.y + t.x,
|
||||
a.z * uv.x + a.w * uv.y + t.y);
|
||||
}
|
||||
|
||||
// CSM 阴影(sampler2DShadow:单次采样 = 硬件 2×2 深度比较 PCF)
|
||||
layout(set = 2, binding = 0) uniform sampler2DShadow shadowMap0; // CSM 级联 0(最近)
|
||||
layout(set = 2, binding = 1) uniform sampler2DShadow shadowMap1; // 级联 1
|
||||
@@ -53,6 +65,7 @@ layout(set = 2, binding = 2) uniform sampler2DShadow shadowMap2; // 级联 2
|
||||
layout(set = 2, binding = 3) uniform samplerCube irradianceMap; // 漫反射环境光(IBL 阶段②)
|
||||
layout(set = 2, binding = 4) uniform samplerCube prefilteredMap; // 镜面环境(mip 分 roughness,阶段③)
|
||||
layout(set = 2, binding = 5) uniform sampler2D brdfLut; // BRDF 积分表 (NdotV, roughness) → (scale, bias)
|
||||
layout(set = 2, binding = 6) uniform sampler2D sceneColor; // 不透明段快照(透射折射采样源)
|
||||
|
||||
// 第 0 盏方向光(KeyLight)的 CSM 阴影因子。
|
||||
// 级联按视图深度选择;3×3 纹素偏移采样(每 tap 硬件 2×2 PCF,
|
||||
@@ -136,21 +149,35 @@ vec3 FresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness) {
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 albedoTex = texture(albedoMap, fragUV);
|
||||
vec4 albedoTex = texture(albedoMap, ApplyUv(0, fragUV));
|
||||
vec3 albedo = albedoTex.rgb * matParams.baseColor.rgb;
|
||||
vec4 mr = texture(metallicRoughnessMap, fragUV);
|
||||
vec4 mr = texture(metallicRoughnessMap, ApplyUv(2, fragUV));
|
||||
// 粗糙度源按 factors.z 切换:glTF 合图工作流读 MR.g;
|
||||
// FBX/OBJ specular 工作流(z=1)换用独立粗糙度图 R 通道
|
||||
float roughness = clamp(mix(mr.g, texture(roughnessMap, fragUV).r,
|
||||
float roughness = clamp(mix(mr.g, texture(roughnessMap, ApplyUv(5, fragUV)).r,
|
||||
matParams.factors.z) * matParams.factors.y,
|
||||
0.045, 1.0);
|
||||
float metallic = clamp(mr.b * matParams.factors.x, 0.0, 1.0);
|
||||
vec3 emissive = texture(emissiveMap, fragUV).rgb;
|
||||
// 自发光强度(KHR_materials_emissive_strength,缺省 1)
|
||||
vec3 emissive = texture(emissiveMap, ApplyUv(3, fragUV)).rgb * matParams.surface.z;
|
||||
|
||||
vec3 N = MappedNormal(normalize(fragNormal), fragTangent, fragUV);
|
||||
// glTF 表面扩展:透射率(KHR_materials_transmission)/
|
||||
// 折射率(ior,缺省 1.5)/ 体积厚度(KHR_materials_volume)
|
||||
const float transmission = clamp(matParams.surface.y, 0.0, 1.0);
|
||||
const float ior = max(matParams.surface.x, 1.0);
|
||||
const float thickness = max(matParams.surface.w, 0.0);
|
||||
|
||||
vec3 N = MappedNormal(normalize(fragNormal), fragTangent, ApplyUv(1, fragUV));
|
||||
vec3 V = normalize(ubo.cameraPos.xyz - fragWorldPos);
|
||||
// 双面法线:cull 关闭,背面片元(玻璃壳内壁)几何法线背向相机,
|
||||
// 光照/折射方向全反——按外表面等价翻转到视侧
|
||||
if (dot(N, V) < 0.0) N = -N;
|
||||
float NdotV = max(dot(N, V), 1e-4);
|
||||
vec3 F0 = mix(vec3(0.04), albedo, metallic); // 电介质基准反射率 4%
|
||||
// F0 按折射率换算(KHR_materials_ior):((ior-1)/(ior+1))²;
|
||||
// glTF 缺省 ior=1.5 → 0.04,与旧固定值一致
|
||||
vec3 F0 = mix(vec3((ior - 1.0) / (ior + 1.0)
|
||||
* (ior - 1.0) / (ior + 1.0)),
|
||||
albedo, metallic); // 电介质 F0 / 金属 albedo
|
||||
|
||||
vec3 Lo = vec3(0.0);
|
||||
float shade0 = 1.0f; // 第 0 盏光的阴影因子(环境光同步衰减用)
|
||||
@@ -185,7 +212,10 @@ void main() {
|
||||
vec3 F = FresnelSchlick(NdotH2, F0);
|
||||
|
||||
vec3 kS = F;
|
||||
vec3 kD = (1.0 - kS) * (1.0 - metallic); // 金属不参与漫反射
|
||||
// 漫反射能量让位给透射:真玻璃无漫反射(入射光 = 反射 F +
|
||||
// 透射 1-F),transmission=1 时 kD→0 = 纯镜面电介质;透射光
|
||||
// 由场景色副本折射采样补回(见下方 transmitted)
|
||||
vec3 kD = (1.0 - kS) * (1.0 - metallic) * (1.0 - transmission);
|
||||
vec3 specular = (D * G * F) /
|
||||
max(4.0 * NdotV * NdotL, 1e-4);
|
||||
|
||||
@@ -207,8 +237,9 @@ void main() {
|
||||
// 镜面:R 采样 pre-filtered cube(mip = roughness 分级)
|
||||
// × BRDF LUT 查表得 F 缩放/偏置
|
||||
// ambientColor = 用户可调强度/色调乘子
|
||||
// 漫反射侧同步乘 (1-transmission)(同直接光能量重分配)
|
||||
vec3 F_amb = FresnelSchlickRoughness(NdotV, F0, roughness);
|
||||
vec3 kD_amb = (1.0 - F_amb) * (1.0 - metallic);
|
||||
vec3 kD_amb = (1.0 - F_amb) * (1.0 - metallic) * (1.0 - transmission);
|
||||
|
||||
vec3 irradiance = texture(irradianceMap, N).rgb;
|
||||
float ao = texture(aoMap, fragUV).r;
|
||||
@@ -224,10 +255,34 @@ void main() {
|
||||
vec3 ambient = (diffuse + specular) * ubo.ambientColor.rgb
|
||||
* mix(0.4, 1.0, shade0); // 阴影区环境同步衰减(简化遮蔽)
|
||||
|
||||
// alpha = albedo 贴图覆盖率 × baseColorFactor.a(glTF alphaMode=BLEND
|
||||
// 混合源;玻璃类无 baseColor 贴图材质的透明度全靠 factor.a)。
|
||||
// ---- 透射(KHR_materials_transmission):屏幕空间折射 ----
|
||||
// 采样源 = 不透明段快照(天空盒 + 不透明几何,Forward 后
|
||||
// ForwardTrans 前拷贝)。玻璃互相不可见(副本不含透明队列),
|
||||
// 与 UE 屏幕空间透射同一限制。
|
||||
vec3 transmitted = vec3(0.0);
|
||||
if (transmission > 0.0) {
|
||||
// 进入介质 eta = 1/ior;全内反射(TIR)退化为反射方向
|
||||
vec3 refrDir = refract(-V, N, 1.0 / ior);
|
||||
if (dot(refrDir, refrDir) < 1e-6) refrDir = reflect(-V, N);
|
||||
// 世界空间步进 thickness 投回屏幕取折射像素(thickness=0 =
|
||||
// 直透同位采样,无弯曲);projNoJitter 保证折射样本位置
|
||||
// 无 TAA 抖动(时域稳定收敛)
|
||||
vec4 clip = ubo.projNoJitter * ubo.view *
|
||||
vec4(fragWorldPos + refrDir * thickness, 1.0);
|
||||
vec2 refrUV = (clip.xy / clip.w) * 0.5 + 0.5;
|
||||
refrUV = clamp(refrUV, vec2(0.0), vec2(1.0));
|
||||
vec3 scene = texture(sceneColor, refrUV).rgb;
|
||||
// albedo 染色 = 有色玻璃近似(Beer-Lambert 体积吸收后续演进)
|
||||
transmitted = scene * albedo * transmission;
|
||||
}
|
||||
|
||||
// alpha = max(覆盖率, transmission):transmission 已烘进 rgb(透射
|
||||
// 背景是颜色的一部分),t≈1 的玻璃对混合方程是完全替换像素
|
||||
//(src*1 + dst*0)——不再有"白 albedo×a 混合"的奶白罩。
|
||||
// 非 transmission 的 BLEND 材质(软粒子/光效)行为不变。
|
||||
// 预乘在 tonemap 段完成。
|
||||
outColor = vec4(ambient + Lo + emissive, albedoTex.a * matParams.baseColor.a);
|
||||
outColor = vec4(ambient + Lo + transmitted + emissive,
|
||||
max(albedoTex.a * matParams.baseColor.a, transmission));
|
||||
outVelocity = fragVelocity;
|
||||
|
||||
// 深度语义:真实深度测试 + 真实写入(depthWrite 状态保持 TRUE——
|
||||
|
||||
Reference in New Issue
Block a user