shader学习之路——更复杂的光照之Base Pass 和 Additional Pass和光照的衰减
在 Base Pass 中处理了场景中的最重要的平行光。如果场景中包含了多个平行光, Unity 会选择最亮的平行光传递给 Base Pass进行逐 像素处理, 其他平行光会按照逐顶点或在 Additional Pass 中按逐像素的方式处理
Additional Pass 处理的光源类型可能是平行光、点光源或是聚光灯 , 因此在计算光源 的 5 个属性一位置、 方向、颜色、强度以及衰减时,颜色和强度我们仍然可以使用_LightColorO 来得到,但对于位翌、 方向和衰减属性, 我们就需要根据光源类型分别计算
Shader "Custom/ForwardRenderingShader" {Properties {_Color ("Color", Color) = (1,1,1,1)_MainTex ("Albedo (RGB)", 2D) = "white" {}_Gloss ("Gloss", Range(8,255)) = 20_Diffuse("Diffuse Color",Color) = (1,1,1,1)_SpecularColor("Specular Color",Color) = (1,1,1,1)}SubShader {Tags { "RenderType"="Opaque" } Pass{Tags{"LightMode" = "ForwardBase"} //我们希望环境光计算一次即可因此我们放在base里计算CGPROGRAM#pragma vertex vert#pragma fragment frag#pragma multi_compile_fwdbase //编译指令 可以保证我们在Shader中使用光照衰减等光照变量可以被正确赋值#include "Lighting.cginc"sampler2D _MainTex;float4 _MainTex_ST;fixed4 _Color;fixed4 _Diffuse;float _Gloss;fixed4 _SpecularColor;//a2v:应用程序传递到顶点函数。application to vertex//v2f:顶点函数传递到片元函数。vertex to fragmentstruct v2f{float4 vertex:POSITION;float3 normal:NORMAL;float2 texcoord:TEXCOORD0;};struct a2v{float4 pos:SV_POSITION;float3 worldNormal:TEXCOORD0;float3 worldPos:TEXCOORD1;float2 uv:TEXCOORD2;};a2v vert(v2f v){a2v o;o.pos = UnityObjectToClipPos(v.vertex);o.worldNormal = UnityObjectToWorldNormal(v.normal);o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);return o;}fixed4 frag(a2v i):SV_Target{fixed3 worldNormal = normalize(i.worldNormal);fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos)); fixed4 texColor = tex2D(_MainTex,i.uv);fixed3 albedo = texColor.rgb * _Color.rgb;fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb * albedo ;fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * max(0,dot(worldNormal,worldLightDir));fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));fixed3 halfDir = normalize(worldLightDir + viewDir);fixed3 specular = _LightColor0.rgb * _SpecularColor.rgb * pow(max(0,dot(worldNormal,halfDir)),_Gloss);fixed atten =1.0;return fixed4(ambient + (diffuse + specular) * atten,1);}ENDCG }Pass{ //点光源会通过ForwardAdd来渲染Tags {"LightMode" = "ForwardAdd"}Blend One One //开启混合模式 希望计算得到的光照结果可以在帧缓存中与之前的光照结果进行叠加CGPROGRAM #pragma vertex vert#pragma fragment frag#pragma multi_compile_fwdadd#include "Lighting.cginc"#include "Autolight.cginc"sampler2D _MainTex;float4 _MainTex_ST;fixed4 _Color;fixed4 _Diffuse;float _Gloss;fixed4 _SpecularColor;//a2v:应用程序传递到顶点函数。application to vertex//v2f:顶点函数传递到片元函数。vertex to fragmentstruct v2f{float4 vertex:POSITION;float3 normal:NORMAL;float2 texcoord:TEXCOORD0;};struct a2v{float4 pos:SV_POSITION;float3 worldNormal:TEXCOORD0;float3 worldPos:TEXCOORD1;float2 uv:TEXCOORD2;};a2v vert(v2f v){a2v o;o.pos = UnityObjectToClipPos(v.vertex);o.worldNormal = UnityObjectToWorldNormal(v.normal);o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz; return o;}fixed4 frag(a2v i):SV_Target{fixed3 worldNormal = normalize(i.worldNormal);#ifdef USING_DIRECTIONAL_LIGHTfixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos)); #elsefixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz - i.worldPos.xyz);#endiffixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * max(0,dot(worldNormal,worldLightDir));fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));fixed3 halfDir = normalize(worldLightDir + viewDir);fixed3 specular = _LightColor0.rgb * _SpecularColor.rgb * pow(max(0,dot(worldNormal,halfDir)),_Gloss);#ifdef USING_DIRECTIONAL_LIGHT //判断是否是平行光fixed atten =1.0;#else//unity_WorldToLight:把顶点从世界空间变换到光源空间 再用这个坐标的模的平方对衰减纹理采样float3 lightCoord = mul(unity_WorldToLight,float4(i.worldPos,1)).xyz;fixed atten = tex2D(_LightTexture0,dot(lightCoord,lightCoord).rr).UNITY_ATTEN_CHANNEL;#endifreturn fixed4((diffuse + specular) * atten,1);//通过使用#ifdef 指令 判断是否定义了 USING_DIRECTIONAL_LIGHT 来得到的。如果当前前向渲染 Pass //处理的光源 类型是平行光, 那么 Unity 的底层渲染引擎就会定义 USING_DIRECTIONAL_ LIGHT。如果判//断 得知是平行光的话, 光源方向可 以直接由_WorldSpaceLigbtPosO.xyz 得到;如果是点光源或聚光//灯, 那么_WorldSpaceLightPosO.xyz 表示的是世界空间下的光源位置, }ENDCG }}FallBack "Diffuse"
}
使用数学公式计算衰减:
float distance = length(_WorldSpaceLightPos0.xyz - i.worldPosition.xyz);
atten = 1.0/distance; //衰减系数
shader学习之路——更复杂的光照之Base Pass 和 Additional Pass和光照的衰减相关推荐
- 【Shader笔记10】更复杂的光照-Unity的光源类型
目录 光源类型 在前向渲染中处理不同的光源类型 Unity的光照衰减 光源类型 分类:平行光.点光源.聚光灯.面光源 属性:位置.方向.颜色.强度.衰减 面光源仅在烘培时才可发挥作用 PS:需要在Sc ...
- shader学习摘要(八)unity光源类型
目录 光源的分类 代码 按光源类型计算5个属性 效果 Bass Pass和Additional Pass的调用 总结 光源的分类 1.平行光 2.点光源 3.聚光灯 在前向渲染中我们在unity sh ...
- 虚幻引擎学习之路:渲染模块之光照系统
原文链接:https://blog.uwa4d.com/archives/Study_unreal4_Rendering_1.html 写在前面 "UWA什么时候可以支持Unreal引擎?& ...
- Unity Shader 学习笔记(33) 全局光照(GI)、反射探针、线性空间和伽马空间、高动态范围(HDR)
Unity Shader 学习笔记(33) 全局光照(GI).反射探针.线性空间和伽马空间.高动态范围(HDR) 参考书籍:<Unity Shader 入门精要> [<Real-Ti ...
- Android学习之路-----倒计时欢迎界面(更有条理)
2019独角兽企业重金招聘Python工程师标准>>> Android学习之路-----倒计时欢迎界面(更有条理) 转载于:https://my.oschina.net/symahl ...
- 【TA之路知识总结】shader学习笔记——入门篇——纹理篇——使用一张纹理模拟物体的漫反射和对纹理的处理等相关知识
文章目录 前言 一.关键代码 二.全部代码 纹理相关知识点: 1.纹理展开技术(展UV): 2.在Unity shader中声明一个纹理的方式: 3.纹理的属性: 4.Unity中对顶点纹理坐标变换的 ...
- 虚幻引擎学习之路:渲染模块之全局光照明
虚幻引擎学习之路:渲染模块之全局光照明 https://zhuanlan.zhihu.com/p/31791392 原文链接:虚幻引擎学习之路:渲染模块之全局光照明 - UWA Blog 之前UWA为 ...
- Shader学习笔记(三)学习Shader所需的数学基础
感受高数 一.笛卡尔坐标系 1.二维笛卡尔坐标系 2.三维笛卡尔坐标系 二.点和矢量 1.矢量和标量的乘法/除法 2.矢量的加法和减法 3.矢量的模 4.单位矢量 5.矢量的点积 6.矢量的叉积(cr ...
- Unity Shader学习-高光反射
Unity Shader学习-高光反射 高光反射计算公式 高光反射 = 光源的色彩和强度 * 材质的高光反射系数 * pow(max(0,视角方向 · 反射方向),_Gloss) 视角方向 = ref ...
最新文章
- IDEA真牛逼,900行又臭又长的类重构,几分钟搞定
- NLP学习笔记:word2vec
- Java的运行机制分析!
- 文献记录(part32)--Face spoofing detection under super-realistic 3D wax face attacks
- android 存储不被垃圾清理,手机内存足够大,就不需要清理垃圾了?你错了!
- 敲重点,数据需要这么做才能成为资产
- Regional Proposal的输出到底是什么
- 架构师被疯抢,华为出了什么招?
- windows7 配置iis技巧
- laravel 数据库操作之查询构造器
- 微信小程序下载文件,保存文件功能总结
- JUnit执行单元测试用例成功,mvn test却失败的问题和解决方法
- 非线性声学回声消除技术
- Vue项目中使用富文本编辑器
- linux tar命令将压缩包解压到指定位置,用tar命令把目标压缩包解压到指定位置
- CodeForces703D Mishka and Interesting sum(树状数组)
- ECS 入门到入土: 一、什么是 ECS
- MobaXterm连接到Linux虚拟机教程
- 查找一个字符串中的所有子串的位置
- 双基测试题计算机理论基础知识梳理,与时俱进的认识“双基”