翻译 Cg Program in Unity - 2.4 Silhouetten Enhancement
来源:互联网 发布:linux 自启动文件 编辑:程序博客网 时间:2024/05/29 07:46
本章内容将讲解表面法向量变换(Transformation of surface normal vector)。在学习这章之前,你需要先确保理解了前面章节的内容。
我们想做出的就是右边这张图所展现的效果:一个半透明物体的边缘比其余部分的透明度更低。这样可以增加三维感,即使在没有灯光的情况。这里的法线变化对于获得这种效果是非常重要的。
Silhouetees of Smooth Surface(光滑轮廓表面)
在表面是光滑的情况时,轮廓表面的法向量平行于视平面也垂直于观测者方向。在左图中,位于左图最上部分的蓝色法线平行于视平面,其他的法向量点则对观测者(相机)有个多的方向。通过计算观察者方向和法向量,我们可以得到它们是否(几乎)垂直于彼此,由此可以得到这个点是否是轮廓上的点。
更具体的说,如果V是一个观测者方向上的单位向量(长度是1),而N是一个单位化的表面的法向量,如果这两者相互垂直,那么他们的点积(dot)的结果就是0:V * N = 0。但是,这种直接得到0的情况是非常少见的,通常只要值接近了0,我们都认为这个点属于轮廓上的点。
Increasing the Opacity at Silhouette (增加轮廓上的不透明度)
对于我们想要的效果,我们需要在V*N的结果接近0的点上增加不透明度α。视方向和法向量点积接近于0的点,我们有许多办法去增加不透明度。这里讲其中一个方法(实际上这背后有一个实际的物理模型,我们将在5.1章讲它。),从一个常规的不透明度α增加不透明度到α‘的公式:
像这样的方程去检测极端情况总是有意义的(?)。考虑一个点接近于轮廓的情况: V*N≈0。在这种情况下,正常的α会去除以一个很小的正数值(注意GPU通常都能很优雅的去处理除以0的情况;因此,我们不用担心这个问题)。因此,不管α的值是什么,α和一个很小数的比例都会很大。而Min这个函数的作用就是保证得到的结果不永远不会超过1。
另一方面,如果一个点原理轮廓,我们的V*N≈1.这样,α’≈min(1,α);也就是说它的透明度不会变化多少。这也就是我们想要的效果。所以我们这里这样做是很有道理的。
Implementing an Equation in a Shader
为了在着色器的中实现一个α方程,第一个问题是:我们也该在顶点着色器中还是片段着色器中 ?在一些情况下,回答是很清楚的,因为执行过程中我们需要用到纹理映射(texture mapping),而它通常在片段着色器中获得。在许多情况下,不管怎么样,并没有一个完全的答案。在顶点着色器中可以获得更快的速度(因为在这里需要处理的量比片段着色器里面少),但是得到的图像质量也更低(在不同顶点之间法向量和顶点的其他属性会突兀地变化)。因此,如果你更关心性能,在顶点着色器中执行是一个更好的选择。另外一方面,如果你更关系图像质量,在片段中执行更好。这个问题在逐片段光源(也就高洛德着色(Gouraud shading)和逐顶点光源(补色着色)上也有相同的问题。
下个问题是:我们执行的时候应该使用哪个坐标系?同样的,这也没有统一答案。不管怎样,在Unity中使用世界坐标通常是一个不错的选择,因为许多的uniform变量是使用的世界坐标系的。(在其他环境中很多使用视口坐标。)
最后一个问题:我们从哪儿获得上面等式中的参数?通常α这个值是Unity着色器中的一个属性(一个RGBA颜色)。而法向量gl_Normal是一个标准的顶点输入参数。 而视方向可以通过从世界坐标系中的顶点的坐标到相机位置(_WorldSpaceCameraPos)的向量获得,他们都由Unity提供。
因此,我们仅仅在执行之前需要去变换顶点和法向量到世界坐标系。转换矩阵_Object2World是从对象坐标空间到世界坐标的转换,而它的逆矩阵_World2Objec,他们t由Unity提供,之前我们讨论过。对点和向量使用矩阵我们在专门的章节“Applying Matrix Transformation"讲解。通常情况,点和向量的转换时我们使用点或者向量乘模型矩阵来做计算:
另外方面,法向量转换时要乘以逆转置转换矩阵。因为提供给我们使用逆转换矩阵(它除去右下角的_World2Object * unity_scale.w) ,所以另外一个更好的选择是法向量左乘逆矩阵,这种方法等同于右乘逆转转置矩阵。
注意,如果矩阵的右下角不正确也没关系,因为它会去乘以0。还要提一个问题,去乘以unity_Scale.w不是必须的,因为缩放不会影响单位法向量。
现在我们已经知道着色器所有的 部分,我们可以写出以下着色器程序:
Shader "Cg silhouette enhancement" {Properties {_Color ("Color", Color) = (1, 1, 1, 0.5)// user-specified RGBA color including opacity}SubShader {Tags { "Queue" = "Transparent" }// draw after all opaque geometry has been drawnPass {ZWrite Off // don't occlude other objectsBlend SrcAlpha OneMinusSrcAlpha // standard alpha blendingCGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"uniform float4 _Color; // define shader property for shadersstruct vertexInput {float4 vertex : POSITION;float3 normal : NORMAL;};struct vertexOutput {float4 pos : SV_POSITION;float3 normal : TEXCOORD;float3 viewDir : TEXCOORD1;};vertexOutput vert(vertexInput input){vertexOutput output;float4x4 modelMatrix = _Object2World;float4x4 modelMatrixInverse = _World2Object;// multiplication with unity_Scale.w is unnecessary// because we normalize transformed vectorsoutput.normal = normalize(float3(mul(float4(input.normal, 0.0), modelMatrixInverse)));output.viewDir = normalize(_WorldSpaceCameraPos- float3(mul(modelMatrix, input.vertex)));output.pos = mul(UNITY_MATRIX_MVP, input.vertex);return output;}float4 frag(vertexOutput input) : COLOR{float3 normalDirection = normalize(input.normal);float3 viewDirection = normalize(input.viewDir);float newOpacity = min(1.0, _Color.a/ abs(dot(viewDirection, normalDirection)));return float4(float3(_Color), newOpacity);}ENDCG}}}
More Artistic Control(更多艺术的控制)
当我们用一个物理模型去描述轮廓增加的时候,我们实际缺少了艺术的控制;例如,一个CG艺术家不能轻易地通过物理模型那样地淡化或强化一个轮廓。为了允许更多的艺术性的控制,你可以引进一个(正)浮点数属性,然后取|V*N|和那个数字的指数幂的点积。
0 0
- 翻译 Cg Program in Unity - 2.4 Silhouetten Enhancement
- 翻译 Cg Program in Unity - 2.1 Cutaways
- 翻译 Cg Program in Unity - 1.2 RGB Cube
- 翻译 Cg Program in Unity - 1.3 Debug (一)
- 翻译 Cg Program in Unity - 1.3 Debug (二)
- 翻译 Cg Program in Unity - 2.2 Transparency (1)
- 翻译 Cg Program in Unity - 2.2 Transparency (2)
- 翻译 Cg Program in Unity - 2.3 Order-Independent Transparency
- 翻译 Cg Program in Unity - 1.4 Shading in World Space (一)
- 翻译 Cg Program in Unity - 1.4 Shading in World Space (二)
- 翻译 Cg Program in Unity - A.2 Vertex Transformations (1)
- Cg Programming/Unity/Silhouette Enhancement轮廓增强
- Cg silhouette enhancement
- Program Exit (CMOD enhancement)
- 《CG Programming in Unity》笔记1-基础知识
- Cg Programming in Unity - 3.2 Specular Highlights
- Enhancement in SAP
- Enhancement set in CRM
- 20160312工作小计
- IOS Xcode7.1新建纯代码工程
- 编程技巧笔记
- 大学毕业4年-回顾和总结(3)-投资理财观-图穷而真相现
- 【leetcode】Array——Jump Game(55)
- 翻译 Cg Program in Unity - 2.4 Silhouetten Enhancement
- tslib 1.4 在ARM板上移植(转)
- code forces 548C:Mike and frog
- leetcode 做题记录3
- JavaScript练习(三)
- awakeFromNib
- 杭电2802
- 我在jms工作室的第一堂课
- 数值的整数次方