博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Unity Shader 逐顶点/像素漫反射光照
阅读量:4987 次
发布时间:2019-06-12

本文共 3103 字,大约阅读时间需要 10 分钟。

漫反射光照符合兰伯特定律 : 反射光线的强度 与 表面法线 和 光源方向 之间的夹角的余弦值成正比 .

逐顶点光照的计算量往往要小于逐像素光照 .

逐顶点光照依赖于线性插值来得到像素光照 , 当光照模型中有非线性的计算的时候 , 逐顶点光照就会出问题 , 例如计算高光反射 .

逐顶点光照会在渲染图元内部对顶点进行插值 , 渲染图元内部的颜色总是暗于顶点处的最高颜色 , 在某些情况下会产生明显的棱角现象 .

Shader "Custom/DiffuseVertexLevel" {    Properties {        _Diffuse("Diffuse", Color) = (1, 1, 1, 1)    }    SubShader {        Pass {            Tags { "LightMode"="ForwardBase" }  //设置正确的LightMode标签才能得到光照信息            CGPROGRAM            #pragma vertex vert            #pragma fragment frag            #include "Lighting.cginc"            fixed4 _Diffuse;            struct a2v {                float4 vertex : POSITION;                float3 normal : NORMAL;            };            struct v2f {                float4 pos : SV_POSITION;                fixed3 color : COLOR;            };            // 逐顶点的漫反射光照            v2f vert(a2v v) {                v2f o;                o.pos = mul(UNITY_MATRIX_MVP, v.vertex);                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz; //得到环境光                fixed3 worldNormal = normalize(mul(v.normal, (float3x3)unity_WorldToObject));  //得到世界空间的法线 下面dot需要在同一空间下才有意义                fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz);      //_WorldSpaceLightPos0得到光源方向                fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal, worldLight));   //saturate控制值在0-1, dot向量点积|a|*|b|cos                o.color = ambient + diffuse; // 环境光 + 漫射光                return o;            }            fixed4 frag(v2f f) : SV_Target {                return fixed4(f.color, 1.0);            }            ENDCG        }    }    FallBack "Diffuse"}

  逐像素光照可以得到更加平滑的光照效果 , 但是有一个问题存在 : 当光照无法到达的区域 , 模型的外观通常是全黑的 , 没有任何的额明暗变化 , 失去了模型细节表现 , 因此有一种改善技术提出 , 即 , 半兰布特光照模型(没有任何物理依据 , 只是一个视觉加强技术) .

Shader "Custom/DiffusePixelLevel" {    Properties {        _Diffuse("Diffuse", Color) = (1,1,1,1)    }    SubShader {        Pass {            CGPROGRAM            #pragma vertex vert            #pragma fragment frag            #include "Lighting.cginc"            fixed4 _Diffuse;            struct a2v {                float4 vertex : POSITION;                float3 normal : NORMAL;            };            struct v2f {                float4 pos : SV_POSITION;                float3 worldNormal : TEXCOORD0;            };            v2f vert(a2v v) {                v2f o;                o.pos = mul(UNITY_MATRIX_MVP, v.vertex);                o.worldNormal = mul(v.normal, (float3x3)_World2Object);                return o;            }            // 逐像素漫反射光照            fixed4 frag(v2f f) : SV_Target {                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;                fixed3 worldNormal = normalize(f.worldNormal);                fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);                fixed3 diffuse = _LightColor0 * _Diffuse.rgb * (dot(worldNormal, worldLightDir) * 0.5 + 0.5); // 半兰伯特光照模型                fixed3 color = ambient + diffuse;                return fixed4(color, 1.0);            }            ENDCG        }    }    FallBack "Diffuse"}

  

转载于:https://www.cnblogs.com/xhg986/p/7509022.html

你可能感兴趣的文章
Vim 加 Gmail 变身 Vmail
查看>>
(5) Orchard 开发之 Localization and NullLocalizer
查看>>
分类算法(1)--KNN
查看>>
妙用python之编码转换
查看>>
hdu 4451 Dressing 衣服裤子鞋 简单容斥
查看>>
linux一些基本常识(四)
查看>>
Docker架构
查看>>
C#设计模式(3)——工厂方法模式
查看>>
过目不忘JS正则表达式
查看>>
Colidity-- StoneWall
查看>>
Leetcode 904. Fruit Into Baskets
查看>>
怎样连接REDIS服务端
查看>>
No.026:Remove Duplicates from Sorted Array
查看>>
SpringBoot项目的几种创建方式,启动、和访问
查看>>
解决"disabled". Expected Boolean, got Number with value 0
查看>>
OC--init,initialize,initWithCoder:,initWithFrame:各方法的区别和加载顺序
查看>>
Exponentiation
查看>>
本地jar上传到本地仓库
查看>>
四则运算C++带Qt界面版本,吾王镇楼。。。。。
查看>>
安卓7.0手机拍照闪退问题解决
查看>>