第七章 基础纹理
如何理解纹理?纹理和单纯的颜色有什么区别吗?
保存大量颜色的文件,通过给定坐标获取颜色,而不再是前面那种单纯的颜色,组合起来就能得到图片一样的效果。
纹理坐标怎么使用,怎么获取纹理颜色值?顶点着色器里面可以使用吗?
每个定义的纹理,可以定义一个对应的_ST变量,会自动接收纹理坐标
在顶点着色器中计算uv:o.uv = v.texcoord.xy * _MainTex_ST.xy + _Main_ST.zw;
在片元着色器中使用uv
fixed4 texColor = tex2D(_MainTex, o.uv);
如果使用顶点计算颜色,可以在顶点着色器按之前的方式计算颜色值,最后在片元着色器中处理
return fixed4(o.color * texColor, 1.0);
。Unity中纹理的属性设置,WrapMode怎么理解。
决定纹理坐标超过[0,1]范围之后,如何获取纹理。例如Repeat方式,超过1的部分又从头开始计算。
Filter Mode属性,设置插值方式什么是mipmap?如何使用?
多级渐远纹理技术,就是生成多个不同大小的小纹理,在离视线比较远的地方,使用较小的纹理来采样。为什么要搞这个玩意呢?因为当物体比较远的时候,占用的像素数量变少了,uv变化就比较大,那么从源图像采样出来的像素值就非常不连贯了,而提前压缩成小图之后,效果就好很多。另一方面传递给gpu也只需要很小的一个图像了。
什么是高度纹理?法线纹理是什么?怎么使用?效果是什么样的?
这些不同的纹理怎么理解呢?数据还是一样的数据,只是把颜色值当成是别的数据来对待,高度纹理存储的就是高度数据,法线纹理则是法线向量的数据。高度图一般跟法线图一起使用。
由于color数值范围是[0,1],而法线方向的各分量取值却是[-1,1],所以在存储前需要转换: pixel=(normal+1)/2 ,一个简单的映射。
使用的时候再 normal=pixel∗2−1 得到原来的信息。
法线纹理的作用:在顶点数量较少的情况下,提供额外的法线信息,这样在计算光照的时候,就可从纹理中获得法线来计算。
高度纹理可以用来生成法线纹理。切线空间怎么定义的?
切线空间由顶点的法线、切线以及垂直这两个向量的向量构成。其中法线作为z轴,切线作为x轴, y=z×x 。
如果某像素点的法线向量在切线空间下跟顶点一致,那么它的法线为(0,0,1);使用前面的公式转换得到像素为(0.5,0.5,1),是一个淡蓝色,这就是为什么切线空间下的法线贴图整体都是淡蓝色的原因。
切线使用的时候还可以添加一个_BumpScale的参数,来调节凹凸的缩放fixed3 binormal = UnpackNormal(_BumpTex, o.uv); binormal.xy *= _BumpScale; binormal.z = sqrt(1 - dot(binormal.xy, binormal.xy));
渐变纹理怎么使用?有什么应用场景?
用于产生具有插画风格的渲染。相比普通的漫反射,可以在指定的地方产生较大的色变,从而产生一种插画式的风格。而该纹理的uv获取方式是:
half=(n⋅I+1)/2
其实就是把(-1,1)映射到(0,1)来作为坐标,fixed3 diffuseColor = tex2D(_RampTex, fixed2(half, half)).rgb * _Color.rgb;
什么是遮罩纹理?有什么应用场景?
一种灵活数据,遮罩纹理存储的数据可以用来控制如高光的比例。
甚至一个纹理的四个通道可以存储不同的数据。
总结:普通贴图纹理是存储一系列颜色的文件,有了纹理坐标,通过一定的函数就能获取到指定的颜色。本质上跟直接使用颜色没太大区别。然而在使用中,我们可以把部分纹理的数据处理成别的含义,就是高度、法线等不同含义的纹理,纹理可以存储任何表面属性。通过不同的数据综合处理,可以得到很多不一样的效果。
第8章 透明效果
理解什么是透明度测试及透明度混合。
- ”测试”这个名称就决定了是用来判定像素是否绘制的。使用透明度测试的结果是,要么完全透明,要么完全不透明。
- 透明度混合才是一般意义上的透明。当前物体的颜色跟底层颜色按一定方式混合得出一个新的颜色,看起来就像是透明的。
- 透明需要关闭深度写入,为什么呢?原书提到深度写入会导致其他表明被剔除,这里应该只是针对其他透明物体的表明,因为不透明物体总是在透明物体之前渲染,不存在被剔除的问题。而透明物体之间可能涉及排序问题,所以都不能被剔除。
UnityShader的渲染队列是什么?
预定义的一些渲染顺序,当然用户也可以自定义渲染顺序。如:”Queue”=”Geometry + 1”。序号越小,渲染越早。
透明度混合如何开启,参数的意思?
- Blend SrcFactor DstFactor 混合源和目标颜色的混合因子
- Blend SrcFactor DstFactor, SrcFactorA DstFactorA 额外提供Alpha的混合因子。Factor取值一般使用预定义的,如One OnMinusSrcColor等
- BlendOp BlendOperation 不设置的话,默认是Add,还可以选择其他一些操作,详见下面文档
- 参考文档Unity Blend说明
- 使用顶点光照,法线在模型空间下计算,代码更为简洁简单。
v2f vert(a2v v) { v2f o; o.pos = UnityObjectToClipPos(v.modelPos); o.uv = TRANSFORM_TEX(v.coord, _MainTex); fixed3 lightDir = normalize(ObjSpaceLightDir(v.modelPos)); o.diffuse = UNITY_LIGHTMODEL_AMBIENT.rgb + _LightColor0.rgb * _Color.rgb * max(0, dot(v.normal, lightDir)); // 使用顶点计算光照 return o; } fixed4 frag(v2f o) : SV_Target { fixed4 texColor = tex2D(_MainTex, o.uv); return fixed4(o.diffuse * texColor.rgb, texColor.a); // 光照同texColor融合 }
开启深度写入的半透明效果如何实现?优点和缺点?
使用两个Pass来渲染,第一个Pass开启深度写入,但不输出颜色,仅用来更新深度值
Pass { ZWright On ColorMask 0 }
该方法只为了解决“单个”透明物体“自身有相覆盖的情况”。并且结果是层级对了,但不能透过自己看到被自己遮挡的部分。所以看起来没啥用。
双面渲染
Cull Off 关闭剔除 单纯使用这个方式,渲染顺序可能有不正常。为什么背面和正面的渲染顺序会无法保证呢??不能理解。
使用两个Pass,第一个Pass中 Cull Front 第二个Pass Cull Back 其他代码一致。
链接汇总:
Unity Blend说明