《Unity Shader入门精要》笔记(三) 基础纹理及透明效果

第七章 基础纹理

  1. 如何理解纹理?纹理和单纯的颜色有什么区别吗?

    保存大量颜色的文件,通过给定坐标获取颜色,而不再是前面那种单纯的颜色,组合起来就能得到图片一样的效果。

  2. 纹理坐标怎么使用,怎么获取纹理颜色值?顶点着色器里面可以使用吗?

    每个定义的纹理,可以定义一个对应的_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);

  3. Unity中纹理的属性设置,WrapMode怎么理解。

    决定纹理坐标超过[0,1]范围之后,如何获取纹理。例如Repeat方式,超过1的部分又从头开始计算。
    Filter Mode属性,设置插值方式

  4. 什么是mipmap?如何使用?

    多级渐远纹理技术,就是生成多个不同大小的小纹理,在离视线比较远的地方,使用较小的纹理来采样。为什么要搞这个玩意呢?因为当物体比较远的时候,占用的像素数量变少了,uv变化就比较大,那么从源图像采样出来的像素值就非常不连贯了,而提前压缩成小图之后,效果就好很多。另一方面传递给gpu也只需要很小的一个图像了。

  5. 什么是高度纹理?法线纹理是什么?怎么使用?效果是什么样的?

    这些不同的纹理怎么理解呢?数据还是一样的数据,只是把颜色值当成是别的数据来对待,高度纹理存储的就是高度数据,法线纹理则是法线向量的数据。高度图一般跟法线图一起使用。
    由于color数值范围是[0,1],而法线方向的各分量取值却是[-1,1],所以在存储前需要转换: pixel=(normal+1)/2 ,一个简单的映射。
    使用的时候再 normal=pixel21 得到原来的信息。
    法线纹理的作用:在顶点数量较少的情况下,提供额外的法线信息,这样在计算光照的时候,就可从纹理中获得法线来计算。
    高度纹理可以用来生成法线纹理。

  6. 切线空间怎么定义的?

    切线空间由顶点的法线、切线以及垂直这两个向量的向量构成。其中法线作为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));
  7. 渐变纹理怎么使用?有什么应用场景?

    用于产生具有插画风格的渲染。相比普通的漫反射,可以在指定的地方产生较大的色变,从而产生一种插画式的风格。而该纹理的uv获取方式是:

    half=(nI+1)/2

    其实就是把(-1,1)映射到(0,1)来作为坐标, fixed3 diffuseColor = tex2D(_RampTex, fixed2(half, half)).rgb * _Color.rgb;

  8. 什么是遮罩纹理?有什么应用场景?

    一种灵活数据,遮罩纹理存储的数据可以用来控制如高光的比例。
    甚至一个纹理的四个通道可以存储不同的数据。

总结:普通贴图纹理是存储一系列颜色的文件,有了纹理坐标,通过一定的函数就能获取到指定的颜色。本质上跟直接使用颜色没太大区别。然而在使用中,我们可以把部分纹理的数据处理成别的含义,就是高度、法线等不同含义的纹理,纹理可以存储任何表面属性。通过不同的数据综合处理,可以得到很多不一样的效果。

第8章 透明效果

  1. 理解什么是透明度测试及透明度混合。

    • ”测试”这个名称就决定了是用来判定像素是否绘制的。使用透明度测试的结果是,要么完全透明,要么完全不透明。
    • 透明度混合才是一般意义上的透明。当前物体的颜色跟底层颜色按一定方式混合得出一个新的颜色,看起来就像是透明的。
    • 透明需要关闭深度写入,为什么呢?原书提到深度写入会导致其他表明被剔除,这里应该只是针对其他透明物体的表明,因为不透明物体总是在透明物体之前渲染,不存在被剔除的问题。而透明物体之间可能涉及排序问题,所以都不能被剔除。
  2. UnityShader的渲染队列是什么?

    预定义的一些渲染顺序,当然用户也可以自定义渲染顺序。如:”Queue”=”Geometry + 1”。序号越小,渲染越早。

  3. 透明度混合如何开启,参数的意思?

    • 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融合
      }
  4. 开启深度写入的半透明效果如何实现?优点和缺点?

    使用两个Pass来渲染,第一个Pass开启深度写入,但不输出颜色,仅用来更新深度值

    Pass { ZWright On ColorMask 0 }

    该方法只为了解决“单个”透明物体“自身有相覆盖的情况”。并且结果是层级对了,但不能透过自己看到被自己遮挡的部分。所以看起来没啥用。

  5. 双面渲染

    Cull Off 关闭剔除 单纯使用这个方式,渲染顺序可能有不正常。为什么背面和正面的渲染顺序会无法保证呢??不能理解。
    使用两个Pass,第一个Pass中 Cull Front 第二个Pass Cull Back 其他代码一致。

链接汇总:
Unity Blend说明

你可能感兴趣的:(3D,Unity)