05_面部阴影SDF重构

面部阴影SDF重构

添加空组件进行定位

找到模型骨骼的头部,添加三个空组件用于定位 使用本地坐标进行位置调整 HeadCenter位置 HeadForward位置 HeadRight位置

创建C#脚本

开启编辑模式也可以调用 C#完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[ExecuteInEditMode]
public class NewBehaviourScript : MonoBehaviour
{
    //挂载的空组件容器
    //脚本外部指定
    public Transform HeadBoneTransform;
    public Transform HeadForwardTransform;
    public Transform HeadRightTransform;

    private Renderer[] allRanderers;
	//传出的值在Shader中的命名
    private int headCenterID = Shader.PropertyToID("_HeadCenter");
    private int headForwardID = Shader.PropertyToID("_HeadForward");
    private int headRightID = Shader.PropertyToID("_HeadRight");
    //脚本开启时也更新一次
    #if UNITY_EDITOR
    void OnValidate() 
    {
        Update();    
    }
    #endif

    // Update is called once per frame
    void Update()
    {
	    //获取所有渲染组件
        if(allRanderers == null)
        {
            allRanderers = GetComponentsInChildren<Renderer>(true);
        }
        //遍历各组件
        for(int i = 0; i < allRanderers.Length; i++) 
        {
            Renderer r = allRanderers[i];
            //遍历各组件材质
            foreach (Material mat in r.sharedMaterials)
            {
                if (mat.shader)
                {
                    //这里应该多次设置给不同的子材质,为了省事直接传的父材质
                    if (mat.shader.name == "URP/XingJianYa")
                    {
                        mat.SetVector(headCenterID, HeadBoneTransform.position);
                        mat.SetVector(headForwardID, HeadForwardTransform.position);
                        mat.SetVector(headRightID, HeadRightTransform.position);

                    }  
                }
            }
        }
    }
}

Shader新增参数

采样SDF图

通过脚本传入值计算角度阈值等,点乘判断光线方向进行UV的水平方向翻转 计算阈值是为了混合光照强度,当正脸有光照的话就将混合强度降低,而背光时就需要将面部增亮了 注意这里不是常规的反正切而是actan2函数,对应上图的话就是左右分两半,从-Forward方向为起点也就是0,向下为末端π,左半为正右半为负。所以函数的输出范围就是-π到π,那么转为弧度就-1到1。如果大于0就1-去这个值,小于零就加1,这样就得到当光线在正面时为0,在背面为1

将SDF融入光照模型

当前预览


Enjoy Reading This Article?

Here are some more articles you might like to read next:

  • URP - RendererFeature :ScreenSpaceOutline
  • 平滑法线处理 - 八面体映射
  • Lv.3 Unity主线:一个简单的PBRShader
  • 理论支线:直接光漫反射与GGX高光的混合问题
  • 理论支线:PBR - 基于图像的照明( image based lighting-IBL)
  • # #