Unity Shader实现素描效果

本文实例为大家分享了Unity Shader实现素描效果的具体代码,供大家参考,具体内容如下

这是乐乐大佬书里的非真实渲染,其中的算法还是挺有意思的,感兴趣的小伙伴可以试一试。

素描效果基本原理:先将物体进行描边画出轮廓,计算物体的漫反射部分,漫反射越暗表明颜色越暗,然后根据漫反射的值来设置采样贴图的权重。

采样贴图:

shader部分:

Shader "Unlit/Sketch"
{
 Properties
 {
 _Color("Color",Color) = (1,1,1,1)
 //贴图平铺系数
   _TileFactor("TileFactor", Range(0, 10)) = 1
 _Hatch0("Hatch0",2D)="white"{}
   _Hatch1("Hatch1",2D) = "white"{}
   _Hatch2("Hatch2",2D) = "white"{}
   _Hatch3("Hatch3",2D) = "white"{}
   _Hatch4("Hatch4",2D) = "white"{}
   _Hatch5("Hatch5",2D) = "white"{}
 //描边系数
 _OutlineFactor("OutlineFactor",Range(0.0,0.1))=0.01
 }
 SubShader
 {
 Tags{ "Queue" = "Transparent" }
 //描边使用两个Pass,第一个pass沿法线挤出一点,只输出描边的颜色
 Pass
 {
  //剔除正面,只渲染背面
  Cull Front
  //关闭深度写入
  ZWrite Off
  //控制深度偏移,描边pass远离相机一些,防止与正常pass穿插
  Offset 1,1

  CGPROGRAM
      #include "UnityCG.cginc"
      #pragma vertex vert
      #pragma fragment frag
   float _OutlineFactor;

   struct v2f
   {
    float4 pos : SV_POSITION;
   };

   v2f vert(appdata_full v)
   {
    v2f o;
    o.pos = UnityObjectToClipPos(v.vertex);
    //将法线方向转换到视空间
    float3 vnormal = mul((float3x3)UNITY_MATRIX_IT_MV, v.normal);
    //将视空间法线xy坐标转化到投影空间
    float2 offset = TransformViewToProjection(vnormal.xy);
    //在最终投影阶段输出进行偏移操作
    o.pos.xy += offset * _OutlineFactor;
    return o;
   }

   fixed4 frag(v2f i) : SV_Target
   {
    return float4(0,0,0,1);
   }
  ENDCG
 }

 Pass
 {
  CGPROGRAM
      #include "UnityCG.cginc"
      #include "Lighting.cginc"
  //使用阴影需添加
      #include "AutoLight.cginc"
  #pragma vertex vert
  #pragma fragment frag
  //使主要平行光产生阴影
      #pragma multi_compile_fwdbase

  float4 _Color;
     float _TileFactor;
  sampler2D _Hatch0;
  sampler2D _Hatch1;
  sampler2D _Hatch2;
  sampler2D _Hatch3;
  sampler2D _Hatch4;
  sampler2D _Hatch5;

  struct v2f
  {
  float2 uv : TEXCOORD0;
  float4 vertex : SV_POSITION;
  //6张依次加深的贴图
  float3 hatchWeights0:TEXCOORD1;
  float3 hatchWeights1:TEXCOORD2;
  //声明阴影
  SHADOW_COORDS(4)
  float3 worldPos:TEXCOORD3;
  };

  v2f vert (appdata_full v)
  {
  v2f o;
  o.vertex = UnityObjectToClipPos(v.vertex);
  //平铺系数越大,显示的贴图越密集
  o.uv = v.texcoord* _TileFactor;
  float3 worldLightDir = normalize(WorldSpaceLightDir(v.vertex));
  float3 worldNormal = UnityObjectToWorldNormal(v.normal);
  //漫反射
  float diffuse = max(0, dot(worldLightDir, worldNormal));
  o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz ;
  //六张图片的权重
  o.hatchWeights0 = float3(0, 0, 0);
  o.hatchWeights1 = float3(0, 0, 0);
  //根据漫反射值计算权重,漫反射越暗,线条越密集
  float hatchFactor = diffuse * 7.0;
  if (hatchFactor > 6.0) {
  }
  else if (hatchFactor > 5.0) {
   o.hatchWeights0.x = hatchFactor - 5.0;
  }
  else if (hatchFactor > 4.0) {
   o.hatchWeights0.x = hatchFactor - 4.0;
   o.hatchWeights0.y = 1.0 - o.hatchWeights0.x;
  }
  else if (hatchFactor > 3.0) {
   o.hatchWeights0.y = hatchFactor - 3.0;
   o.hatchWeights0.z = 1.0 - o.hatchWeights0.y;
  }
  else if (hatchFactor > 2.0) {
   o.hatchWeights0.z = hatchFactor - 2.0;
   o.hatchWeights1.x = 1.0 - o.hatchWeights0.z;
  }
  else if (hatchFactor > 1.0) {
   o.hatchWeights1.x = hatchFactor - 1.0;
   o.hatchWeights1.y = 1.0 - o.hatchWeights1.x;
  }
  else {
   o.hatchWeights1.y = hatchFactor;
   o.hatchWeights1.z = 1.0 - o.hatchWeights1.y;
  }
  //把计算的阴影传到fragment中
  TRANSFER_SHADOW(o);
  return o;
  }

  fixed4 frag (v2f i) : SV_Target
  {
  float4 hatchTex0 = tex2D(_Hatch0, i.uv) * i.hatchWeights0.x;
  float4 hatchTex1 = tex2D(_Hatch1, i.uv) * i.hatchWeights0.y;
  float4 hatchTex2 = tex2D(_Hatch2, i.uv) * i.hatchWeights0.z;
  float4 hatchTex3 = tex2D(_Hatch3, i.uv) * i.hatchWeights1.x;
  float4 hatchTex4 = tex2D(_Hatch4, i.uv) * i.hatchWeights1.y;
  float4 hatchTex5 = tex2D(_Hatch5, i.uv) * i.hatchWeights1.z;
  //漫反射暗色部分权重越大,白色越少
  float4 whiteColor = float4(1, 1, 1, 1)*(1 - i.hatchWeights0.x - i.hatchWeights0.y - i.hatchWeights0.z - i.hatchWeights1.x - i.hatchWeights1.y - i.hatchWeights1.z);
  float4 hatchColor = hatchTex0 + hatchTex1 + hatchTex2 + hatchTex3 + hatchTex4 + hatchTex5+ whiteColor;
  //使物体接受阴影
  UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);
  return float4(hatchColor.rgb*_Color.rgb*atten, 1.0);
  }
  ENDCG
 }
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Unity Shader实现素描风格的渲染

    本文实例为大家分享了Unity Shader实现素描风格的具体代码,供大家参考,具体内容如下 原理 使用6张素描纹理进行渲染,在渲染阶段,在顶点着色阶段计算逐顶点的光照,根据光照结果决定6张纹理的混合权重,并传递给片元着色器.在片元着色器中根据这些权重来混合6张纹理的采样结果 Shader实现 Shader "Hatching" { Properties { _Color ("Color Tint", Color) = (1, 1, 1, 1)//颜色 _TileF

  • Unity Shader实现素描效果

    本文实例为大家分享了Unity Shader实现素描效果的具体代码,供大家参考,具体内容如下 这是乐乐大佬书里的非真实渲染,其中的算法还是挺有意思的,感兴趣的小伙伴可以试一试. 素描效果基本原理:先将物体进行描边画出轮廓,计算物体的漫反射部分,漫反射越暗表明颜色越暗,然后根据漫反射的值来设置采样贴图的权重. 采样贴图: shader部分: Shader "Unlit/Sketch" { Properties { _Color("Color",Color) = (1,

  • Unity shader实现遮罩效果

    本文实例为大家分享了Unity shader实现遮罩效果的具体代码,供大家参考,具体内容如下 效果: shader代码: Shader "Custom/Mask" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {}//目标图片,即需要被遮罩的图片 _MaskLayer("Culling Mask",2D) = "white"{}//混合的图片,设置

  • Unity shader实现消融效果

    本文实例为大家分享了Unity shader实现消融效果的具体代码,供大家参考,具体内容如下 效果图: shader代码: // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' Shader "Custom/EdgeColo" { Properties { _MainTex ("Texture", 2D) = "white" {} _N

  • Unity Shader实现序列帧动画效果

    本文实例为大家分享了Unity Shader序列帧动画效果的具体代码,供大家参考,具体内容如下   实现原理 主要的思想是设置显示UV纹理的大小,并逐帧修改图片的UV坐标.(可分为以下四步) 1.我们首先把 _Time.y 和速度属性_Speed 相乘来得到模拟的时间,并使用CG 的floor 函数对结果值取整来得到整数时间time 2.然后,我们使用time 除以_HorizontalAmount 的结果值的商来作为当前对应的行索引,除法结果的余数则是列索引. 3.接下来,我们需要使用行列索引

  • Unity shader实现高斯模糊效果

    本文实例为大家分享了Unity shader实现高斯模糊效果的具体代码,供大家参考,具体内容如下 正常图: 高斯模糊效果图: shader代码: Shader "Custom/GaoSiMoHu" { Properties { _MainTex ("Texture", 2D) = "white" {} _BlurSize("Blur size",Float)=1.0 } SubShader { ZTest Always cul

  • Unity shader实现自由放大缩小效果

    本文实例为大家分享了Unity shader实现自由放大缩小效果的具体代码,供大家参考,具体内容如下 代码: 以下实现的shader代码: Shader "Hidden/Wave" { Properties { _MainTex ("Texture", 2D) = "white" {} _WaveWidth("Wave Width",float) = 0.5 _CenterX("CenterX",float

  • unity shader实现较完整光照效果

    本文实例为大家分享了unity shader实现光照效果的具体代码,供大家参考,具体内容如下 效果图: shader被附给了球. 灯光需要在属性面板开启阴影. // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' Shader "Unlit/lightFull" { Properties { _MainTex ("Texture", 2D) = "

  • Unity Shader实现翻书效果

    今天实现一个简单的翻书的效果,话不多说,先上一张效果图: 这里就随便用的一张纹理了,我们还是称为"翻木板"吧,哈哈. 实现过程: 其实这个效果实现起来还是挺简单的,大概思路其实就是 让所有顶点都绕Z轴旋转,并且通过正余弦使之带有一点弧度. 下面开始让我们一步一步的实现该效果. 首先打开Unity新建一个工程,场景,并且创建一个名为openBookEffect的Shader文件,删掉原本多余的代码. 第一步,我们先让它绕z轴旋转起来 这里就要用到一个旋转矩阵了,让顶点左乘该矩阵,就能得到

  • Unity shader实现百叶窗特效

    本文实例为大家分享了Unity shader百叶窗展示的具体代码,供大家参考,具体内容如下 1.将图片划分为水平N栏,代码如下: Shader "Unlit/BYCShader" { Properties { [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {} _Color ("Tint", Color) = (1,1,1,1) _StencilComp

  • Unity Shader实现描边OutLine效果

    本文实例为大家分享了Unity Shader实现描边OutLine效果的具体代码,供大家参考,具体内容如下 Shader实现描边流程大致为:对模型进行2遍(2个pass)绘制,第一遍(描边pass)在vertex shader中对模型沿顶点法线方向放大,fragment shader设置输出颜色为描边颜色:第二遍正常绘制模型,除被放大的部分外,其余被覆盖,这样就有了描边的效果. 实现代码如下: Shader "Custom/OutlineShader" { Properties { _

随机推荐