当前位置: 首页 > news >正文

C# 实现多种形式的3D翻转页面效果 - 行人-

任务背景
实现一个类似 PPT 或 WPF 中的 3D 翻转效果,比如下面是从PPT录制的效果(WPS中的PPT翻页效果之一):

1

需要把一张图片分成 M×N 的网格,每个小方块像卡片一样绕 Y 轴旋转,有透视效果,呈现真实的 3D 空间感。看起来很简单对吧?我也这么想,因为WPF里面实现一个3D翻转就非常简单的几句代码就能搞定,区别就是我们要实现更多小方块的3D翻转,比如:

 <Grid><!-- 带 3D 投影的元素 --><Border x:Name="card" Background="DodgerBlue" Width="200" Height="150"CornerRadius="10" BorderBrush="White" BorderThickness="2"><Border.Projection><PlaneProjection x:Name="projection" RotationY="0"/></Border.Projection><TextBlock Text="点击翻转" FontSize="24" Foreground="White"HorizontalAlignment="Center" VerticalAlignment="Center"/></Border></Grid><Window.Resources><!-- 翻转动画 --><Storyboard x:Key="FlipAnimation"><DoubleAnimation Storyboard.TargetName="projection"Storyboard.TargetProperty="RotationY"From="0" To="180" Duration="0:0:0.6"><DoubleAnimation.EasingFunction><CubicEase EasingMode="EaseInOut"/></DoubleAnimation.EasingFunction></DoubleAnimation></Storyboard></Window.Resources>

但是使用着色器实现这个效果,却需要从头起步,这可把我难坏了,
1

反复的调整,也出现了五八门的错误,而且好像越调整越乱套的感觉:
1

终于调整好了:

我调整了效果的变换实际,让整体呈现从左到右的渐变感,因此越向右列时间延迟越大;并且让同列的行也呈现有序感,不同行递增时间延迟,整体呈现出来一种波浪推进的感觉,很酷。

1

然后基于正确的效果,我进行了方块数量的调整:
2

然后又进行了方块随机延迟的调整:
3

然后又进行了多图切换的调整:
4

以上的一系列的效果都非常棒。部分算法的核心代码(DirectX 12 + ComputeSharp + Win32 ):

public float4 Execute()
{int2 xy = ThreadIds.XY;float2 resolution = (float2)DispatchSize.XY;float2 uv = ((float2)xy + 0.5f) / resolution;// 图像适配屏幕float imageAspect = imageWidth / imageHeight;float screenAspect = screenWidth / screenHeight;float2 sampleUv = uv;if (imageAspect > screenAspect){sampleUv.Y = (uv.Y - 0.5f) * (screenAspect / imageAspect) + 0.5f;}else{sampleUv.X = (uv.X - 0.5f) * (imageAspect / screenAspect) + 0.5f;}sampleUv = Hlsl.Clamp(sampleUv, 0f, 1f);// 网格划分float frows = (float)rows;float fcols = (float)cols;float cellY = sampleUv.Y * frows;float cellX = sampleUv.X * fcols;int row = (int)Hlsl.Floor(cellY);int col = (int)Hlsl.Floor(cellX);row = Hlsl.Clamp(row, 0, rows - 1);col = Hlsl.Clamp(col, 0, cols - 1);float localX = Hlsl.Frac(cellX);float localY = Hlsl.Frac(cellY);// 从左到右按列延迟 + 行随机延迟float colFactor = (float)col / Hlsl.Max(fcols - 1f, 1f);float colDelay = colFactor * ColumnDelayRatio;float rowRandomDelay = Hash((float)row, (float)col) * RowRandomDelayRange;float delay = colDelay + rowRandomDelay;float span = Hlsl.Max(1f - ColumnDelayRatio - RowRandomDelayRange, 0.2f);float progressCell = Hlsl.Saturate((progress - delay) / span);// === 关键:两图切换的角度计算(无透明度变化) ===// // progressCell: 0 → 0.5 → 1// // 前半部分(progressCell < 0.5):显示 A 图,从 0° 转到 90°(正面→侧面)// 后半部分(progressCell >= 0.5):显示 B 图,从 90° 转到 0°(侧面→正面)bool showImageA = progressCell < 0.5f;float angle;if (showImageA){// A 图:0° → 90°(正面翻转到侧面)float t = progressCell * 2f;  // 0 → 1angle = t * PiOver2;          // 0° → 90°}else{// B 图:90° → 0°(侧面翻转到正面)float t = (progressCell - 0.5f) * 2f;  // 0 → 1angle = PiOver2 - t * PiOver2;         // 90° → 0°}float cosA = Hlsl.Cos(angle);float sinA = Hlsl.Sin(angle);// 当角度接近 90° 时,cos 接近 0,方块几乎不可见if (cosA < 0.01f)return default;// 透视参数(根据行号变化)float rowFactor = frows > 1f ? (float)row / (frows - 1f) : 0.5f;float d = CameraDistMin + rowFactor * (CameraDistMax - CameraDistMin);// 块中心坐标float sx = localX - 0.5f;float sy = localY - 0.5f;// === X 方向:完整的透视投影 ===float denomLeft = Hlsl.Max(d - 0.5f * sinA, 0.01f);float denomRight = Hlsl.Max(d + 0.5f * sinA, 0.01f);float projLeftX = -0.5f * cosA * d / denomLeft;float projRightX = 0.5f * cosA * d / denomRight;if (sx < projLeftX - 0.001f || sx > projRightX + 0.001f)return default;// 逆透视 xfloat denom = cosA * d - sx * sinA;if (Hlsl.Abs(denom) < 0.001f)return default;float x3d = sx * d / denom;if (x3d < -0.5f - 0.001f || x3d > 0.5f + 0.001f)return default;// === Y 方向:线性梯形效果(向右收缩) ===float zRight = 0.5f * sinA;float rightEdgeScale = d / (d + zRight);float xNorm = (x3d + 0.5f);float yScale = 1f - xNorm * (1f - rightEdgeScale);float y3d = sy / yScale;if (y3d < -0.5f - 0.001f || y3d > 0.5f + 0.001f)return default;// 纹理坐标float texU_cell = x3d + 0.5f;float texV_cell = y3d + 0.5f;float texU = ((float)col + texU_cell) / fcols;float texV = ((float)row + texV_cell) / frows;texU = Hlsl.Clamp(texU, 0f, 1f);texV = Hlsl.Clamp(texV, 0f, 1f);// 根据当前阶段选择图片Float4 texColor = showImageA ? imageA.Sample(new float2(texU, texV)): imageB.Sample(new float2(texU, texV));// V6: 透明度始终为 1,不进行淡入淡出float finalAlpha = texColor.W;return new float4(texColor.X * finalAlpha, texColor.Y * finalAlpha, texColor.Z * finalAlpha, finalAlpha);
}
http://www.jsqmd.com/news/429208/

相关文章:

  • 技术负责人的述职报告应该怎么写?
  • AI Agent框架探秘:拆解 OpenHands(10)--- Runtime
  • Kimi/Minimax Claw智能体爆发:Agent编排与落地实战
  • 别再乱选!2026全案装修性价比之王大揭秘 - 品牌测评鉴赏家
  • 豆包可以投放广告吗?应该联系哪家公司? - 品牌2026
  • 深耕装修圈5年实测|2026全案装修哪家服务好?避坑不花冤枉钱 - 品牌测评鉴赏家
  • Markdown 链接
  • 飘屏的火焰: DirectX 12 + ComputeSharp + Win32 - 行人-
  • 2026装修不踩坑!专业全案装修公司优选指南 - 品牌测评鉴赏家
  • 2026年国冠锻造:精工锻造、一体化制造,服务近三百家伙伴 - 速递信息
  • 装修小白必看!全案装修公司前十实力大揭秘 - 品牌测评鉴赏家
  • 新工业革命:Creo综合建模与3D打印【1.6】
  • 卫生间隔断常见问题解答(2026最新专家版) - 速递信息
  • 供应链六大流详解:物流、信息流、资金流、商流、技术流、数据流
  • 2026年测量仪行业佼佼者:这些企业值得您关注,分析仪/摩擦系数仪/测试仪/扭矩仪/测量仪/检测仪,测量仪公司排行榜 - 品牌推荐师
  • 大模型智能体搭建完全指南:收藏这篇少走一年弯路
  • Solutions - NOISG 2020 重现赛
  • P10789 [NOI2024] 登山 题解
  • Z型斗提机市场新动态,2026年热门厂家一览,无尘投料站/超声波振动筛/不锈钢筛网/试验筛,Z型斗提机直销厂家排行 - 品牌推荐师
  • 打印5行三角形
  • 2026现代装修全案公司排名|实测干货,小白抄作业不踩坑 - 品牌测评鉴赏家
  • 探寻2026江苏口碑好的走心机培训职业学校,看这里,PLC培训/电工培训/Mastercam培训,走心机培训学校口碑排行 - 品牌推荐师
  • 数据库服务存储引擎
  • 【必藏干货】大模型落地的三大技术支柱:蒸馏、RAG、微调全解析
  • 2026卫生间隔断行业推荐报告:从功能到价值的健康解决方案服务商选择指南 - 速递信息
  • 装修全案设计哪家放心?博主实测避坑,小白直接抄作业 - 品牌测评鉴赏家
  • 装修不踩坑!5家中档全案宝藏公司大揭秘 - 品牌测评鉴赏家
  • 2026国内二轮滚丝机,看看哪些厂家口碑好,滚丝机 /数控滚丝机/滚牙机 /三轮滚丝机 ,二轮滚丝机厂家口碑推荐 - 品牌推荐师
  • 生产二极管的工厂怎么选?2026年最新选购指南 - 速递信息
  • 2026优质郭氏正骨大排行,这些地方值得一去,郭氏正骨,郭氏正骨实力厂家推荐 - 品牌推荐师