请问在Unity的像素Shader里返回的颜色的计算模式是啥样的?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了请问在Unity的像素Shader里返回的颜色的计算模式是啥样的?相关的知识,希望对你有一定的参考价值。
我知道unity正常情况下,rgba颜色的range应该都是(0,1)。但在fragment shader中,把多个float4类型的值相加后返回,到底会出现什么样的颜色呢?
举例:
float4 temp=float4(1,0,0,0)
此时return temp,呈现的是红色;如果return temp+temp,呈现的是看起来挺亮的橙色;而return temp/2,返回的又是一模一样的红色。
所以我有些迷惑,在fragment shader中返回的float4 data到底会怎样转化为最终的rgba颜色呢,这里的float4 data的值域肯定已经超过(0,1)了啊
A为缓存色,B为当前色,C为输出色
【正常透明度混合】-
描述:正常透明度混合
公式:当前颜色 x 当前透明度 +(1 - 当前透明度)x 缓存颜色
shader:fixed4 C = B x B.a + A x (1 - B.a);
【正片叠底】-
描述:颜色叠加,使像素重合部分的颜色更暗。像素覆盖顺序随意调换不会改变结果
公式:当前颜色 x 缓存颜色
shader:fixed4 C = A * B;
【滤色】-
描述:与正片叠底相反,重合部分的像素更亮
公式:1 - (1-当前颜色)x (1-缓存颜色)
shader代码:fixed4 C = 1 - (1 - A) * (1 - B);
【叠加】 - -
描述:结合滤色与正片叠底,基色的像素重合部分比较亮的会更亮,比较暗的会跟暗
公式:如果当前颜色 <= 0.5 返回1,否则返回 0 该值记做 w;
w x 缓存色 x 当前色 x 2 + (1 - w) x (1 - (1 - 缓存色) x (1 - 当前色) x 2)
shader代码:
if(A > 0.5)
fixed4 C = 1 - 2 * (1 - A) * (1 - B);
else
fixed4 C = 2 A B;
【反色】
描述:取得与缓存色相反的颜色
公式:1 - 缓存颜色
shader代码:fixed4 C = 1 - A;
【变暗】-
描述:缓存颜色 x 缓存颜色与当前颜色中最小的那个
公式:缓存颜色 x min(缓存颜色,当前颜色)
shader代码:fixed4 C =A * min(A,B) ;
【变亮】-
描述:缓存颜色 x 缓存颜色与当前颜色中最大的那个
公式:缓存颜色 x max(缓存颜色,当前颜色)
shader代码:
fixed4 C =A * max(A, B) ;
【减色】
描述:缓存颜色减掉当前颜色的值
公式:缓存颜色 - 当前颜色
shader代码:fixed4 C = A - B;
【划分】
描述:缓存颜色除当前颜色的值
公式:缓存颜色 / 当前颜色
shader代码: fixed4 C = A / B ;
【颜色加深】
描述:
公式:缓存颜色 - ((1 - 缓存颜色) x (1 - 当前颜色)) / 缓存颜色
shader代码:fixed4 C = A - ((1-A) * (1-B)) / B;
【颜色减淡】
描述:
公式:缓存颜色 + ((缓存颜色 x 当前颜色) / (1 - 当前颜色))
shader代码:fixed4 C = A + (A * B) / (1 - B);
【线性加深】
描述:
公式:当前颜色 + 缓存颜色 - 1
shader代码:fixed4 C = B + A -1;
【线性减淡】
描述:
公式:缓存颜色 + 当前颜色
shader代码:fixed4 C = A + B;
【强光】
描述:
公式:如果当前色 <= 0.5 返回1,否则返回0,记作w;
w x 缓存色 x 当前色 x 2 + (1 - w) x (1 - (1 - 缓存色) x (1 - 当前色) x 2);
shader代码:
fixed4 ifFlag= step(B, fixed4(0.5, 0.5, 0.5, 0.5));
fixed4 C = ifFlag * A * B * 2 + (1 - ifFlag) * (1 - (1 - A) * (1 - B) * 2);
【柔光】
描述:
公式:如果当前色 <= 0.5 返回1,否则返回0,记作w;
w x 缓存色 x 当前色 x 2 + (1 - w) x (1 - (1 - 缓存色) x (1 - 当前色) x 2);
shader代码:
fixed4 ifFlag = step(B, fixed4(0.5, 0.5, 0.5, 0.5));
fixed4 C = ifFlag * (A * B * 2 + A * A * (1 - B * 2)) + (1 - ifFlag) * (A * (1 - B) * 2 + sqrt(A) * (2 * B - 1));
【亮光】
描述:
公式:如果当前色 <= 0.5 返回1,否则返回0,记作w;
w x (缓存色 - (1 - 缓存色) x (1 - 2 x 当前色) / (2 x 当前色)) + (1 - w) x (缓存色 + 缓存色 x (2 x 当前色 - 1) / (2 x (1 - 当前色)));
shader代码:
fixed4 ifFlag = step(B, fixed4(0.5, 0.5, 0.5, 0.5));
fixed4 C = ifFlag * (A - (1 - A) * (1 - 2 * B) / (2 * B)) + (1 - ifFlag) * (A + A * (2 * B - 1) / (2 * (1 - B)));
【点光】
描述:
公式:如果当前色 <= 0.5 返回1,否则返回0,记作w;
w x (min(缓存色, 2 x 当前色)) + (1 - w) x (max(缓存色, ( 当前色 x 2 - 1)));
shader代码:
fixed4 ifFlag = step(B, fixed4(0.5, 0.5, 0.5, 0.5));
fixed4 C = ifFlag * (min(A, 2 * B)) + (1 - ifFlag) * (max(A, ( B * 2 - 1)));
【线性光】
描述:
公式:缓存色,+ 2 x 当前色 - 1;
shader代码: fixed4 C=A+2*B-1;
【实色混合】
描述:
公式:如果当前色 + 缓存色 <= 1 返回1,否则返回0,记作w;
w x (0) + (1 - w) x (1);
shader代码:
fixed4 ifFlag = step(A + B, fixed4(1, 1, 1, 1));
fixed4 C = ifFlag * (fixed4(0, 0, 0, 0)) + (1 - ifFlag) * (fixed4(1, 1, 1, 1));
【深色】
描述:
公式:如果当前色的rgb分量 + 缓存色 <= 1 返回1,否则返回0,记作w;
w x (0) + (1 - w) x (1);
shader代码:
fixed4 ifFlag = step(B.r + B.g + B.b, A.r + A.g + A.b);
fixed4 C = ifFlag * (B) + (1-ifFlag)*(A);
颜色制式
RGBA :红、绿、蓝、透明度
HSL: hue(色相)、saturation(饱和度)、lightness(亮度)
HSV: hue(色相)、saturation(饱和度)、value(色调)
HSB: hue(色相)、saturation(饱和度)、brightness(明度) 参考技术A Shader就是在GPU上运行的程序叫做着色器程序(一般的程序在CPU上执行指令)。
Unity Shader使用的是NVIDIA公司的Cg标准语言,可以处理顶点着色、像素着色任务。Unity中的游戏对象只要是可视的,就一定会调用shader渲染,最简单的shader就是diffuse类型,就是你给对象涂个什么颜色,这个对象在白光下就是什么颜色。
一般来讲游戏中的 材质=shader+贴图和其它数据,要想表现特殊的材质,比如镜面反射、水面、塑料等,就需要编程shader(Unity中有一些默认的shader)。 参考技术B 已知颜色A与颜色B,颜色B覆盖在颜色A上,最终输出的结果为颜色C。
A为缓存色,B为当前色,C为输出色。 参考技术C shader是一个框架,它里面带有材质和颜色等等内容
修改颜色可以用renderer.material.color
Unity shader saturate
当你想将颜色值规范到0~1之间时,你可能会想到使用saturate函数(saturate(x)的作用是如果x取值小于0,则返回值为0。如果x取值大于1,则返回值为1。若x在0到1之间,则直接返回x的值.),当然saturate也可以使用变量的swizzled版本,比如saturate(somecolor.rgb);
以上是关于请问在Unity的像素Shader里返回的颜色的计算模式是啥样的?的主要内容,如果未能解决你的问题,请参考以下文章