栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 游戏开发 > 其他

【unity笔记】L4Unity中的基础光照

其他 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【unity笔记】L4Unity中的基础光照

本章导图

一、基础光照概述 1.包含物件
  • 光源 —— 衡量标准:辐射度(垂直与表面法线上余弦值乘以斜线上的辐射度)
  • 吸收和散射 —— 光线经过散射后,一个会散射到物体内部,一个是反射到物体外部

  • 着色 —— 利用材质属性和光源信息进行物体表面光照模型的计算过程,称为着色。
  • BRDF光照模型 —— 计算光线和物体表面交互的渲染方程。
2.标准光照模型
  • 环境光 —— 表述物体表面的间接光照:光线在进入摄像机前,经过了不止一次的物体反射。
  • 自发光 —— 光线直接由光源发射进入摄像机
  • 漫反射 —— 针对于光线从物体表面随机散射到各个方向的辐射度进行建模。这个时候入射方向反而不重要,因为都会散射到各个方向。而散射的光线强度和光源方向之间夹角的余弦值成正比
  • 高光 —— 计算高光由两种模型,一种是Blinn模型,还有一种是Phong模型
3.逐像素还是逐顶点
  • 对于计算光照模型的位置:在片元着色器中计算称为逐像素光照,在顶点着色器中计算称为逐顶点光照。
  • Phong着色:以每个像素为基础,计算法线,再根据面片之间对顶点法线进行插值
  • 高洛德着色:再每个顶点上计算光照,然后在渲染图元内部进行线性插值,最后输出成像素颜色
4.Blinn-Phong模型
  • 定义:使用了漫反射和高光反射来对反射光线进行建模,提出的基于经验的计算高光反射的方法。
  • 优点:简化了计算,更快
  • 局限性:由于是一个经验模型,对于一些复杂的现象,例如菲涅耳反射表现不出来,另外各项同性的特点导致旋转物体时,反射表面不会由任何变化。对于毛发等不适用。
5.环境光和自发光
  • 环境光:在添加热河照明之前该空间中已经可用的光
  • 自发光:在片元着色器输出最后颜色之前,把材质的自发光颜色添加到输出颜色上即可
二、在Unity Shader上实现漫反射光照模型
  • 公式:要计算漫反射需要知道4个参数,入射光线的颜色和强度c,材质的漫反射系数m,表面法线n以及光源方向I。为了防止点积结果为负值,需要max操作。
  • 逐像素实现漫反射
    shader代码如下:
Shader "Unity Shaders Book/Chapter 6/Diffuse Vertex-Level" {
	Properties{
		_Diffuse("Diffuse", Color) = (1, 1, 1, 1)
	}
		SubShader{
			Pass {
				Tags { "LightMode" = "ForwardBase" }

				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;
					// Transform the vertex from object space to projection space
					o.pos = mul(UNITY_MATRIX_MVP, v.vertex);

					o.worldNormal = mul(v.normal, (float3x3)_World2Object);

					 Get ambient term
					//fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;

					 Transform the normal from object space to world space
					//fixed3 worldNormal = normalize(mul(v.normal, (float3x3)unity_WorldToObject));
					 Get the light direction in world space
					//fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz);
					 Compute diffuse term
					//fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal, worldLight));

					//o.color = ambient + diffuse;

					return o;
				}

				fixed4 frag(v2f i) : SV_Target{
					fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;

				fixed3 worldNormal = normalize(i.worldNormal);

				fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal, worldLightDir));

				fixed3 color = ambient + diffuse;

				return fixed4(i.color, 1.0);
				}

				ENDCG
			}
	}
		FallBack "Diffuse"
}

  • 效果如图:

三、在Unity Shader上实现高光反射光照模型

  • 公式

  • 逐像素实现高光(逐顶点使得高光呈现非线性的特征)
    shader代码如下:

// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Unity Shaders Book/Chapter 6/Specular Pixel-Level" {
	Properties {
		_Diffuse ("Diffuse", Color) = (1, 1, 1, 1)
		_Specular ("Specular", Color) = (1, 1, 1, 1)
		_Gloss ("Gloss", Range(8.0, 256)) = 20
	}
	SubShader {
		Pass { 
			Tags { "LightMode"="ForwardBase" }
		
			CGPROGRAM
			
			#pragma vertex vert
			#pragma fragment frag

			#include "Lighting.cginc"
			
			fixed4 _Diffuse;
			fixed4 _Specular;
			float _Gloss;
			
			struct a2v {
				float4 vertex : POSITION;
				float3 normal : NORMAL;
			};
			
			struct v2f {
				float4 pos : SV_POSITION;
				float3 worldNormal : TEXCOORD0;
				float3 worldPos : TEXCOORD1;
			};
			
			v2f vert(a2v v) {
				v2f o;
				// Transform the vertex from object space to projection space
				o.pos = UnityObjectToClipPos(v.vertex);
				
				// Transform the normal from object space to world space
				o.worldNormal = mul(v.normal, (float3x3)unity_WorldToObject);
				// Transform the vertex from object spacet to world space
				o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
				
				return o;
			}
			
			fixed4 frag(v2f i) : SV_Target {
				// Get ambient term
				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
				
				fixed3 worldNormal = normalize(i.worldNormal);
				fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
				
				// Compute diffuse term
				fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal, worldLightDir));
				
				// Get the reflect direction in world space
				fixed3 reflectDir = normalize(reflect(-worldLightDir, worldNormal));
				// Get the view direction in world space
				fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);
				// Compute specular term
				fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(reflectDir, viewDir)), _Gloss);
				
				return fixed4(ambient + diffuse + specular, 1.0);
			}
			
			ENDCG
		}
	} 
	FallBack "Specular"
}

  • 逻辑图如下:
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/905507.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号