庄懂的TA笔记(五)<漫反射 && 镜面反射>

1、漫反射:

黑话:

常用向量:(全要记)

nDir:法线方向,点乘操作,简称,n;

lDir:光照方向,点乘操作,简称,l;

vDir:观察方向,点乘操作,简称,v;

rDir:光反射方向,点乘操作,简称,r;

hDir:半角方向(Halfway),lDir和vDir的中间角方向,点乘操作,简称h;

所在空间:

OS:ObjectSpace 物体空间,本地空间。

WS:WorldSpace 世界空间。

VS:ViewSpace 观察空间。

CS:HomogenousClipSpace 齐次裁剪空间??

TS:TangentSpace 切线空间。??

TXS:TextureSpace 纹理空间。??

2、镜面反射phong:

phong:光反射方向和视角方向越重合,反射越强。

Blling实现思路01:

1、光的方向=实际上是=光方向的反方向。这里获取到正值,所以  乘   -1,获取正常光方向

2、反射沿 法线  反射,=得到=  光的反射方向(rDir)。

3、观察方向(vDir)  点乘   光的反射方向(rDir)  == 镜面反射 Blling

4、点乘过后有 负值  ,这里负值截断,(Max=0)>>(小于0的数值,都压到  0).

5、添加Slider,控制Power(叠加),收紧高光 次数,得到最终Blling(反射效果)。

Blling实现思路02:

1、视角反射  *   光方向    ==  反射(Blling)。

Blinn-phong:法线方向和半角方向越重合,反射越强。

实现思路: 

1、half Dir 半角反射,点乘  法线方向  =得到= 半反射(Bliinn-Phong)。

Bliinn-Phong  与  Phong的区别:

Bliinn-Phong 相比  Phong性能消耗减少一半,无力效果不及Phong。

3、代码>>漫反射&&镜面反射:

代码段 实现OldShool光照模型 (油腻  巧克力反射  效果)   思路:

准备阶段:

1、使用 shaderForge 最简模板 备用。

2、改命名路径,改命名路径,改命名路径。

3、书写 基础 Lambert 漫反射  光照模型。

关于声明几个不同公开类型的格式:

                Properties段定义参数的格式:

                ·格式:_名称("面板标签",类型(参数,可无))=默认值

关于不同类型的公开声明示例:

顶点(身份证)输入声明    要和    屏幕转换一致(匹配身份信息)

前缀修饰字符知识:

修饰字:

        uniform:共享于 Vert(顶点)  , 和   Frag(像素)。

        attibute:仅限于 Vert(顶点)。

        Varying:用于 Vert 和  Frag 传数据

转像素声明类型的知识:

        顶点转像素阶段,没有Color之类的类型声明只有

        1、Float

        2、Float2

        3、Float3

        4、Float4

        5、Half

代码实现思路:

像素获取阶段:

原料:

1、posCS:拿到屏幕空间顶点位置       转像素         o.posSC=UnityObjectToClipPos(v.vertex)

2、posWS:拿到世界空间顶点位置      转像素    o.posWS=mul(unity_ObjectToWorld,v.vertex)

3、 nDirWS世界空间法线方向        转像素    o.nDirWS=UnityObjectToWorldNormal(v.normal)

像素shader阶段:

        目标:

        1、得到一个 Lambert(漫反)  +   Bliiing(反射)的效果。

        阶段:

        1、准备向量

                获取法线(nDir):                

                        float3 nDir = i.nDirWS;

                获取光向量(lDir):

                         float3 lDir = _WorldSpaceLightPos0.xyz;

                获取观察方向(vDir),并归一化:

                        观察方向=  摄像机位置    -     世界顶点像素位置(posWS)

                        normallize(float3 vDir = _WorldSpaceCameraPoss.xyz  -   i . posWS);

                获取半角光向量(hDir):==   视角方向和光方向的中间角

                       光方向半角    =    归一化后的  ( 视角方向     +    光方向)。

                        float3 hDir = normalize( vDir  +   lDir)

        2、准备点积结果

                获取 n&l 点乘结果(法线  &  灯光)

                        float ndotl = dot(nDir , lDir);

                获取 n&h点乘结果(法线 & 半角反射)

                        float ndoth = dot(nDir , hDir);

        3、光照模型

                赋值截断  基础光照模型

                float lambert = max(0.0 , ndotl );

                赋值截断,反射光照模型,并叠加_SpecularPow  次。

                float blinnphong = pow(max(0.0 , ndoth) , _SpecularPow);

                最终结果:

                float3 finalRGB = _MainCol  *  lambert + blinnPhong;

                (好习惯:这里建议拿三维的乘一维的东西,因为结果是三维的)。

        4、返回结果

                return  float4(finalRGB ,1.0);

                

 

预想阶段:

1、基础兰伯特Lambert着色代码段,

2、color色彩Public 可控制修改。

3、高光,叠加(Powor)次数   可控制修改。
       

4、作业:

代码段案例。

重点公式精华:

1、Lambert(基础光照)

Lambert=(法线 点积 灯光)

Lambert = dot(nDir , lDir);

2、blinnphong(反射)

blinnphong=(法线 点积 半角反射)

blinnphong = dot(nDir,hDir);

3、Phong (高光反射)

float3 rdir = reflect(-ldir,ndir);         //反射  是由  光照方向 反射出法线 的。

Phong = dot(vdir,rdir);                   // 反射摄像机 反应,就是 高光反射.

Shader "Unlit/Sc05_SL_OldSchool04"
{
    Properties
    {
        _MainCol("MainColor",Color)=(1,1,1,1)
        _SpecularPow("SpecularPow",Range(0,90))=30
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

         Pass {
            Name "FORWARD"
            Tags {
                "LightMode"="ForwardBase"
            }
            
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_instancing
            #include "UnityCG.cginc"
            #pragma multi_compile_fwdbase_fullshadows
            #pragma target 3.0
            UNITY_INSTANCING_BUFFER_START( Props )
               // UNITY_DEFINE_INSTANCED_PROP( float4, _Color)
            UNITY_INSTANCING_BUFFER_END( Props )

            //同步通知全局 声明了他们。
            uniform float3 _MainCol;
            uniform float _SpecularPow;

            //输入结构
            struct VertexInput
            {
                float4 vertex : POSITION;
                float4 normal : NORMAL;
            };


            //顶点输出结构   准备工作 法线(法线是依存于光的,所以如下命名), UV ,顶点啊 ,等等 声明变量
            struct VertexOutput 
            {
                float4 posCS : SV_POSITION;
                float4 posWS : TEXCOORD0;
                float3 nDirWS : TEXCOORD1;
            };

            //输出结构>>>顶点shader>>>输出结构
            VertexOutput vert (VertexInput v) 
            {
               VertexOutput o = (VertexOutput)0;

               o.posCS = UnityObjectToClipPos(v.vertex);

               //获取输出世界空间位置像素;
               o.posWS = mul(unity_ObjectToWorld,v.vertex);

               o.nDirWS = UnityObjectToWorldNormal(v.normal);

               return o ;
            }

            //色彩输出结构
            float4 frag(VertexOutput i) : COLOR 
            {
                //1、向量准备
                float3 nDir = i.nDirWS;
                float3 lDir = _WorldSpaceLightPos0.xyz;
                                            //摄像机向量 = 相机位置 - 对象位置(世界空间)
                float3 vDir = normalize(_WorldSpaceCameraPos.xyz - i.posWS);
                                            //半角反射向量 = 相机位置 + 灯光位置
                float3 hDir = normalize(vDir + lDir);
                float3 rdir = reflect(-ldir,ndir);// 反射 = (光向量,法线向量)
               //2、点积结果准备 lambert=(法线 点积 灯光)  blinnphong=(法线 点积 半角反射)
                float ndotl = dot(nDir,lDir);//Lambert
                float ndoth = dot(nDir,hDir);//blinPhong
                float rdotv = dot(rdir,vdir);//Phong
                //3、光照模型公式:
                float lambert = max(0,ndotl);
                float Phong = pow(max(0,rdotv),_SpecularPow);
                float blinnPhong = pow(max(0,ndoth),_SpecularPow);
                float3 finalRGB = _MainCol * lambert + blinnPhong;
                //float3 finalRGB = _MainCol * lambert + Phong;
                //4、返回输出
                return float4 (finalRGB,1);
            }
            ENDCG
        }
    }
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Allen7474

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值