Code is cheap. Show me the idea.
过去软件行业有一句很有名的话: Text1Talk is cheap. Show me the code. 这句话代表了前 AI 时代非常典型的工程文化。空谈没有意义。能跑的代码才是真东西。不要只讲想法,把实现拿出来。 但站在 2026 年的角度看,这句话背后的价值结构正在发生反转。现在越来越像是:Code is cheap. Show me the idea. 在过去很长一段时间里,“Talk is cheap. Show me the code.” 是成立的。因为从想法到可运行代码之间,存在巨大的实现成本。很多人可以描述一个系统,但真正能把它稳定实现、接入工程、处理边界条件、修完 Bug,最终交付的人要少得多。 编程正在从脑力 + 体力劳动,变成近乎纯粹的脑力劳动 如果把程序开发粗略分成两部分: Text1设计 + 实现 那么在前 AI 时代,一个功能的大多数工时往往都消耗在实现上。 越是复杂的功能,工程实现越像一种体力活。你要写代码、改接口、接系统、补边界、调试、测试、修 Bug,再调试,再测试。即使最初的想法并不复杂,真正把它落地到生产环境里,也常常要付出大量时间。 ...
聊聊UI分辨率分离与线性空间下的GammaUI
整理了下近期以及过去做过的这方面的一些功能, 挑出点有意思的东西或思路谈谈. 这篇没有什么代码之类的东西, 就纯是碎碎念. UI 分辨率分离 这年头在移动端做 3D 游戏, 分辨率基本是没可能拉满的, 最高基本也就八九百这样子, 低配下甚至六百多都有可能. 虽然场景怎么低分辨率怎么糊都好说, 但 UI 是万万不能糊的, 一糊这游戏也别玩了. 所以场景&UI 分辨率分离就成了一个项目必需的 feature. 最简单也是最直接的方案就是给 UI 单独来一张 RT, 我们叫他 UITarget. 场景在低分辨率的 CameraAttachment 上渲完后 Blit 到高分辨率的 UITarget 上, 再交给 UI 相机绘制 UI. 听着很美好, 但实际并不能用. 因为这个方案对于带宽本就不富裕的移动端打击是致命的, 多一张 1080p 的 RT 简直是要了手机的老命. 于是就有了优化方案, 借用系统提供的 Backbuffer 作为 UITarget. Backbuffer 默认为手机硬件的原生分辨率, 无论任何情况下渲染管线的最终目标都会是它, 在 URP 正常的流程...
从插件开始的UE渲染开发0x00: Shader路径重定向
UE 渲染开发一直以来都是个很蛋疼的话题, 拜屎山一般的渲染系统所赐, 想要加点什么东西基本就只有改源码一条路可走, 以至于网上搜十个改源码的文章可能九个都是教你怎么加 ShadingModel 或 MeshPass. 我自己也曾在这类重复且枯燥的工作上花费大量的时间, 深切感受到这玩意到底有多恶心. 而且源码修改一时爽, 后续维护火葬场, 将来如果要升级引擎版本, 面对茫茫多的 diff 那才叫一个痛不欲生. 所以这个系列从 UE 的插件系统(Plugin)入手, 尝试探索在不改动源码的情况下, 如何最大限度的自定义渲染. 虽说不改 C++ 源码, 但 Shader 该改还是要改. 不过直接去引擎路径下改 Shader 就很恶心, 可能我只想为当前项目改动某部分 Shader, 但引擎路径下 Shader 的改动却会影响到本地的所有项目. 如果能像 Unity 那样每个项目自己有一份 Shader 就好了——正确的, 我们就先来把这个功能做了. 在动工之前, 需要先理解 UE Shader 的路径引用原理. UE shader 代码中 include 的文件路径并非真实的路径...
一个C++20下的string split实现
众所周知,C一直没有一个官方提供的string split用于分割字符串,在过去(C20之前)我们可能需要使用std::regex、std::string::find系列方法、甚至是继承自C的strtok函数来自行封装一个split,非常繁琐与不便。 然而,这一切都在C20中发生了变化。C20引入了范围库ranges,其中提供的两个范围适配器std::split、std::lazy_split可以使我们以一种更为优雅的形式实现split。 12345678910111213141516171819202122232425262728293031#include <concept>#include <ranges>#include <algorithm>#include <format>#include <iostream>#define stdr std::ranges#define stdrv std::ranges::viewstemplate<template<typename> typena...
UE5.1移动端延迟管线基于Light Channels模拟Unity Rendering Layers
待搬运, 内容详见原文链接. 原文链接: https://zhuanlan.zhihu.com/p/577239276
UE5.1移动端延迟渲染管线测试与剖析
待搬运, 内容详见原文链接. 原文链接: https://zhuanlan.zhihu.com/p/575618981
浅谈UE5的C++程序化生成Shader
待搬运, 内容详见原文链接. 原文链接: https://zhuanlan.zhihu.com/p/574551808
URP延迟渲染+Native Renderpass踩坑记录
过去两周多折腾URP Deferred + Native Renderpass, 踩了无数的坑, 翻遍国内国外的社区也找不到太多可供参考的资料. 于是在这里简述一下一些不可回避的问题以及其解决方案, 也算是为社区做点贡献. 在开始之前, 我想延迟渲染这种烂大街的玩意就没什么讲的必要了, 而Native Renderpass可能不少人没听过, 这东西底层调用的其实就是vulkan的renderpass/subpass API(metal也有类似的一套), 简单来说就是利用移动端TB(D)R的硬件架构, 相比于传统延迟管线在basepass结束后将gbuffer store回system memory, 之后再在lightpass中load回来这种带宽压力极大的方案, Native Renderpass可以在每个tile的basepass结束后将gbuffer保存在On-Chip Memory上, 以供接下来的lightpass直接使用, 直接优化掉了两个pass之间的store/load操作, 极大减缓了带宽压力, 这种形式的rt也被称之为memoryless. 简单科普到此为止...
从零开始的UE5卡通渲染0x01:自定义着色模型
待搬运, 内容详见原文链接. 原文链接: https://zhuanlan.zhihu.com/p/551343308
从零开始的UE5卡通渲染0x00:理论基础
最近在研究基于UE5的卡通渲染,颇有收获。正巧前段时间与同事吃饭,聊到知乎,深感自己知乎各种不正经的东西实在太多了,而我又是个懒得腾出时间写正经东西的懒狗,遂决定趁编译Shader的空闲,写点学习笔记、心得与分享。 虽然卡渲本身的知识不算很多,但放到UE5上就是不得不改动源码的大工程了,不由得让人怀念起自由的Unity,令人感叹……扯远了,总之UE5卡渲这块我准备分成多篇文章,多水一水。 目前的大(feng)致(kuang)计(hua)划(bing)如下: 卡通渲染理论基础 修改源码的卡渲光照模型实现 基于卷积矩阵的卡渲描边实现、添加子Mesh的Backface卡渲描边实现 修改源码自定义Pass的Backface卡渲描边实现 …… 次世代卡渲/独立的Hair、Skin卡渲光照模型/UE5复刻原神ShadingModel……(或许会有?) 废话不多说了,进入正题。 提到卡通渲染,很多了解不多的朋友可能就会将其与NPR(Non-Photorealistic Rendering)混为一谈,可实际上这两者并不能划等号。事实上NPR是个非常广泛的概念,不止是卡渲,油画、水墨风等等...
