Shader Color

  • RGB颜色
  • HSV颜色简介
  • RGB与HSV的转换
    • RGB TO HSV
    • HSV TO RGB
  • HDR
    • HDRColor面板的疑惑
    • HDRColor、Color、BloomColor、Intensity的转换代码
  • 后效Bloom和HDR的关系

RGB颜色

这个就是祖传手艺了,RGB三原色,不多说。他的应该是这样的,没错一个正方体

HSV颜色简介

作为一个程序员,对于 颜色的理解就是RGBA,但是当我们跟美术大大进行沟通时,他们老是给整什么饱和度,色相之类的外星话。我们给他说你通过调节RGB的值做效果,大眼瞪小眼了。
其实对于美术而言他们更熟悉的HSV(也叫HSB)模型:
H 为 色相(hue):取值范围0-360, 在0~360°的标准色轮上,色相是按位置度量的。在通常的使用中,色相是由颜色名称标识的,比如红、绿或橙色。黑色和白色无色相。
S为饱和度(saturation):取值范围0-1(或者0-100百分制),表示色彩的纯度,为0时为灰色。白、黑和其他灰色色彩都没有饱和度的。在最大饱和度时,每一色相具有最纯的色光。取值范围0~100%。
V 为 亮度(value):取值范围0-1(或者0-100百分制),是色彩的明亮度。为0时即为黑色。最大亮度是色彩最鲜明的状态。取值范围0~100%。
在Unity中他长这个样子:
如果用数学模型去表示HSV的话,他大概是这个样子:

啊?按照上面说的HSV的取值范围不应该是一个圆柱体么?怎么是个倒三角?我只能强行理解一波就是亮度越大我们能识别的颜色范围越大,亮度为0可识别的也就只有黑色。(也不知道这么想对不对。。)

RGB与HSV的转换

这个转换的版本有点多,这里就直接拿Unity的转换了,UnityEngine.Color类

RGB TO HSV

// UnityEngine.Color
public static void RGBToHSV(Color rgbColor, out float H, out float S, out float V)
{if (rgbColor.b > rgbColor.g && rgbColor.b > rgbColor.r){Color.RGBToHSVHelper(4f, rgbColor.b, rgbColor.r, rgbColor.g, out H, out S, out V);}else if (rgbColor.g > rgbColor.r){Color.RGBToHSVHelper(2f, rgbColor.g, rgbColor.b, rgbColor.r, out H, out S, out V);}else{Color.RGBToHSVHelper(0f, rgbColor.r, rgbColor.g, rgbColor.b, out H, out S, out V);}
}
private static void RGBToHSVHelper(float offset, float dominantcolor, float colorone, float colortwo, out float H, out float S, out float V)
{V = dominantcolor;if (V != 0f){float num;if (colorone > colortwo){num = colortwo;}else{num = colorone;}float num2 = V - num;if (num2 != 0f){S = num2 / V;H = offset + (colorone - colortwo) / num2;}else{S = 0f;H = offset + (colorone - colortwo);}H /= 6f;if (H < 0f){H += 1f;}}else{S = 0f;H = 0f;}
}

HSV TO RGB

public static Color HSVToRGB(float H, float S, float V, bool hdr)
{Color white = Color.white;if (S == 0f){white.r = V;white.g = V;white.b = V;}else if (V == 0f){white.r = 0f;white.g = 0f;white.b = 0f;}else{white.r = 0f;white.g = 0f;white.b = 0f;float num = H * 6f;int num2 = (int)Mathf.Floor(num);float num3 = num - (float)num2;float num4 = V * (1f - S);float num5 = V * (1f - S * num3);float num6 = V * (1f - S * (1f - num3));switch (num2 + 1){case 0:white.r = V;white.g = num4;white.b = num5;break;case 1:white.r = V;white.g = num6;white.b = num4;break;case 2:white.r = num5;white.g = V;white.b = num4;break;case 3:white.r = num4;white.g = V;white.b = num6;break;case 4:white.r = num4;white.g = num5;white.b = V;break;case 5:white.r = num6;white.g = num4;white.b = V;break;case 6:white.r = V;white.g = num4;white.b = num5;break;case 7:white.r = V;white.g = num6;white.b = num4;break;}if (!hdr){white.r = Mathf.Clamp(white.r, 0f, 1f);white.g = Mathf.Clamp(white.g, 0f, 1f);white.b = Mathf.Clamp(white.b, 0f, 1f);}}return white;
}

都是代码也没啥可以说的,还以其他的算法

HDR

HDRColor面板的疑惑

随着手机性能越来越强,现在HDR几乎已经成了游戏的标配了。扯到HDR就要有一点点Gamma和Linear的转换,具体什么是Gamma和Linear就不细说了。先来说一个当初一直让我苦恼的问题,先看情况1:
一切看上去是那么的祥和,毫无违和感。不要眨眼,请看情况2:
WTF?关闭再打开Intensity居然变了~当时我是怎么想都想不出是个啥机制,反正纠结挺久的,后来发现还是我想复杂了。其实就是HDR的Intensity和RGB的关系,直接改变Intensity会直接改变颜色值,所以情况2中改变Intensity,RGB直接发生变化,但是Intensity的真实取值并不是有上面的滑块决定,而是有颜色决定,所以当我们关闭再次打开(或者改变RGB的数值),都会用Intensity的数值刷新,显示其真正的数据,不得不说unity的这个设计真的有点而,就不能再加个变量控制啊!接下来我们看看,HDR的Intensity和RGB是怎么变化的,对于HDRColor的颜色值为(10,1,1,1)来说,究竟是个什么颜色?白色?红色?接下来,请欣赏代码:

HDRColor、Color、BloomColor、Intensity的转换代码

//颜色面板中的Indensity,可见对其进行赋值时,直接改变HDR的颜色值
public float exposureValue
{get{return this.m_ExposureValue;}set{if (this.m_ExposureValue != value){this.m_ExposureValue = value;//--这里就是核心了,没错是pow(2,Indensity)Color color = this.color * Mathf.Pow(2f, this.m_ExposureValue);this.m_ColorHdr[0] = color.r;this.m_ColorHdr[1] = color.g;this.m_ColorHdr[2] = color.b;}}
}
//--通过HDRRGB计算Indensity(下面的exposure),以及将HDRColor转换成基础的颜色
//linearColorHdr:为HDR的Color的输入(接下来简称HDRColor)。
// baseLinearColor:为HDR转化为基础的颜色,Bloom的颜色(接下来简称BloomColor)。
//exposure:曝光度即Indensity
internal static void DecomposeHdrColor(Color linearColorHdr, out Color32 baseLinearColor, out float exposure)
{baseLinearColor = linearColorHdr;//-获取HDRColor的RGB中的最大值float maxColorComponent = linearColorHdr.maxColorComponent;//最大值小于1大于0.003921569(最小非0正数)或者等于0,则HDRColor就是Colorif (maxColorComponent == 0f || (maxColorComponent <= 1f && maxColorComponent >= 0.003921569f)){exposure = 0f;baseLinearColor.r = (byte)Mathf.RoundToInt(linearColorHdr.r * 255f);baseLinearColor.g = (byte)Mathf.RoundToInt(linearColorHdr.g * 255f);baseLinearColor.b = (byte)Mathf.RoundToInt(linearColorHdr.b * 255f);}else{//-下面两行就是计算Indensity的方法float num = 191f / maxColorComponent;exposure = Mathf.Log(255f / num) / Mathf.Log(2f);//-下面是HDRColor到BloomColor的转换,所以10,1,1,1应该显示色为白色,Bloom偏红色baseLinearColor.r = Math.Min(191, (byte)Mathf.CeilToInt(num * linearColorHdr.r));baseLinearColor.g = Math.Min(191, (byte)Mathf.CeilToInt(num * linearColorHdr.g));baseLinearColor.b = Math.Min(191, (byte)Mathf.CeilToInt(num * linearColorHdr.b));}
}

后效Bloom和HDR的关系

unity中有个PostProcessing的Package包,里面的Bloom的效果配合HDR可以达到天人合一的效果,总之就是很happy。在Shader中生命HDRColor的需要加上[HDR]的标签,通过上面的分析我们知道了HDR的数据计算原理,那么一个普通的颜色,我们可以把他做成HDR的效果么?
直接上结果了:


哇~~看来是可以啊,那我们就可以将美术的贴图通过其他方式给他做成HDR效果的了,是不是很兴奋。

Unity Shader Color、HSV、HDRColor以及HDRColor面板转换源码分析相关推荐

  1. Unity Fog 原理 源码分析 案例

    Unity Fog 原理 源码分析 案例 效果图 简述 背景知识 clip空间坐标的范围 d3d (near,0), unity remapping to (0,far) 越靠近相机z值越小 open ...

  2. threejs 源码解析_ThreeJS 物理材质shader源码分析(顶点着色器)

    ThreeJS 物理材质shader源码分析(顶点着色器) Threejs将shader代码分为ShaderLib和ShaderChunk两部分,ShaderLib通过组合ShaderChunk的代码 ...

  3. Unity huatuo示例项目源码分析与启发

    上一节我们安装huatuo的开发环境,然后运行示例项目,体验了huatuo做热更新,这节课我们来分析示例项目的源码,掌握huatuo做热更新的主要的步骤,让你自己的项目很好的基于huatuo来组织热更 ...

  4. Unity UGUI Batches合批规则详解(含源码)

    Unity UGUI Batches合批规则详解 在处理UGUI DrawCall问题的时候,我们经常遇到各式各样的问题. 问题1:在处理UGUI合批的时候,发现了一个面板父节点发生旋转,底下的UI合 ...

  5. Unity+SenseAR教程:用手势发射爱心【源码】

    摘要:Unity+SenseAR2.3开发的AR应用,基于手势识别功能,发射你的爱心~ 洪流学堂,让你快人几步.你好,我是你的技术探路者郑洪智,你可以叫我大智. 今天开头就不絮叨了,一句"名 ...

  6. 太空射击unity工程素材文件 飞机大战 飞行射击游戏源码(C#,Unity2019.2.4f1)素材+源码 最新写的,demo简单版本

    飞机大战素材 太空大战unity工程文件 飞行射击游戏源码(C#,Unity2019.2.4f1)素材+源码 最新写的,demo简单版本 希望能对初学者提供帮助,代码根据教材以及out了的代码更新了, ...

  7. 【Unity】2D游戏-愤怒的小鸟教学实战(附源码和实现步骤 超详细)

    需要源码和资源文件请点赞关注收藏后评论区留言私信~~~ 下面我们将在Unity3D中实现愤怒的小鸟的简单版,游戏中最复杂的部分是物理系统,但是借助于Unity3D编辑器,我们就不用担心太多了 一.效果 ...

  8. Unity Shader:Waveform波形(1)-用正弦函数做闪烁效果并分析波形公式中的参数

    (图1:利用三角函数实现的闪烁动画) 由于GPU机制的特殊性,在写Shader做动画效果时,很多时候要用到三角函数. 实现上图中闪烁效果的Shader代码: float brightness=pow( ...

  9. Unity shader 入门之渲染管线三、空间转换

    一个顶点是怎么显示在屏幕上的 开始 妞妞的鼻子是怎么绘制到屏幕上的? 一些重要的空间变换 渲染流水线中顶点的空间变换过程 模型空间 模型空间,有时也被称为对象空间(object space)或局部空间 ...

  10. 【Unity】Unity开发进阶(六)UnityEvent使用与源码解析

    文章目录 UnityEvent 如何使用 何时使用 实现原理 总结 UnityEvent UnityEvent是Unity提供的用于处理事件的类,方便我们自定义事件.为了便于参数传递,Unity默认为 ...

最新文章

  1. 文巾解题 733. 图像渲染
  2. 闲来无事,做了个简单的在线编辑的mock服务
  3. usb转rj45_毕亚兹ZH5网卡转接口评测:3HUB接口+1网口,好用还便宜
  4. linux最小安装桌面,Linux工作环境:CentOS7最小安装+Xfce桌面环境
  5. centos7 mysql
  6. ES6新特性_ES6的数值扩展---JavaScript_ECMAScript_ES6-ES11新特性工作笔记039
  7. L2TP连接尝试失败,因为安全层在初始化与远程计算机的协商时遇到一个处理错误...
  8. LINUX的文件链接,管道和用户组
  9. iterator adapter inserter
  10. 房地产企业的客户细分战略
  11. Android线程创建aop,【android安卓】一个注解搞定线程切换,基于AOP的线程转换框架...
  12. 诺基亚智能手机知识大全
  13. 信息安全工程师真题1
  14. Delphi使用THTTPClient实现异步下载
  15. 工业App能否成为继Android和iOS后下一个App开发者的春天?
  16. linux sort排序及取前几条数据
  17. python练习实例——字母图形
  18. Apollo 2.0 传感器标定方法 使用指南(官方)
  19. 全差分运放阻抗匹配计算(四)
  20. 微信小程序选项卡数组列表单项选择切换效果

热门文章

  1. 微信公众号里的文章图片应该如何原图下载
  2. SubsamplingScaleImageView + Glide显示网络超大图片
  3. stack的常见用法
  4. 九宫格,二十五宫格,甚至八十一宫格 技巧
  5. TextMeshPro的超链接
  6. .prevent 与 .stop,以及解决其他地方长按,文本被选中的问题
  7. 芝诺数解|「七」月是故乡明,月饼表浓情
  8. Java web之五-网站访问统计
  9. 聊下如何设计知识中台?(附代码)
  10. 四、PHP进阶学习之MySQL②