在一个基本模型里,一个物体表面的颜色是由放射(emissive)、环境反射(ambient)、漫反射(diffuse)和镜面反射(specular)等光照作用的总和。每种光照作用取决于表面材质的性质(如亮度和材质颜色)和光源的性质(如光的颜色和位置)的共同作用。

从数学上描述基本模型的高级公式如下所示:

surfaceColor = emissive +ambient + diffuse + specular

一、放射项

emissive = Ke

其中:

Ke代表材质的放射光颜色。

二、环境反射项

ambient = Ka * globalAmbient

其中:

Ka是材质的环境反射系数。

globalAmbient是入射环境光的颜色。

三、漫反射项

diffuse = Kd * lightColor * max(dot(N, L), 0)

其中:

Kd是材质的漫反射颜色。

lightColor是入射漫反射光的颜色。

N是规范化的表面法向量。

L是规范化的从顶点到光源的向量。

四、镜面反射项

specular = Ks * lightColor * facing * pow(max(dot(N, H), 0), shininess)

其中:

Ks 是材质的镜面反射颜色。

lightColor是入射镜面反射光的颜色。

N是规范化的表面法向量。

H是规范化的,顶点到光源的向量与顶点到眼睛的向量的中间向量。

facing是,如果dot(N,L)大于0则为1,否则为0。其中L是顶点到光源位置的向量。

shinniess是表面光泽度。

例如,在unity3d shaderLab,在顶点shader中计算光照的代码如下:

 Shader "Custom/Test"
{
Properties
{
_Ke("Ke", Color) = (,,,)
_Ka("Ka", Color) = (,,,)
_GlobalAmbient("Global ambient", Color) = (,,,)
_Kd("Kd", Color) = (,,,)
_Ks("Ks", Color) = (,,,)
_Shininess("", float) =
} SubShader
{
Pass
{
Tags
{
"RenderType" = "Opaque"
} CGPROGRAM
#pragma vertex Vert
#pragma fragment Frag #include "UnityCG.cginc"
#include "Lighting.cginc" uniform float4 _Ke;
uniform float4 _Ka;
uniform float4 _GlobalAmbient;
uniform float4 _Kd;
uniform float4 _Ks;
uniform float _Shininess; struct VertexInput
{
float4 pos : POSITION;
float2 uv : TEXCOORD0;
float3 nor : NORMAL;
float4 col : COLOR;
}; struct FragmentInput
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float4 col : COLOR;
}; FragmentInput Vert(VertexInput vi)
{
FragmentInput fi;
fi.pos = mul(UNITY_MATRIX_MVP, vi.pos);
fi.uv = vi.uv; // compute emissive
float3 emissiveC = _Ke.rgb; // compute ambient
float3 ambientC = _Ka.rgb * _GlobalAmbient.rgb; // compute diffuse
float3 nor = mul(vi.nor, (float3x3)_World2Object);
float3 dir2Light = normalize(WorldSpaceLightDir(vi.pos));
float nl = max(, dot(nor, dir2Light));
float3 diffuseC = _Kd.rgb * _LightColor0.rgb * nl; // compute specular
float3 dir2Cam = normalize(WorldSpaceViewDir(vi.pos));
float nh = max(, dot(nor, dir2Cam + dir2Light));
float specLight = nl > ? pow(nh, _Shininess) : ;
float3 specC = _Ks * _LightColor0.rgb * specLight; fi.col.rgb = emissiveC + ambientC + diffuseC + specC;
fi.col.a = ; return fi;
} float4 Frag(FragmentInput fi) : Color
{
return fi.col;
} ENDCG
}
}
}

shader

效果图如下:

转载请注明出处: http://www.cnblogs.com/jietian331/p/5549889.html

CG之基本光照模型计算公式的更多相关文章

  1. [CG编程] 基本光照模型的实现与拓展以及常见光照模型解析

    0.前言 这篇文章写于去年的暑假.大二的假期时间多,小组便开发一个手机游戏的项目,开发过程中忙里偷闲地了解了Unity的shader编写,而CG又与shaderLab相似,所以又阅读了<CG教程 ...

  2. (转)光照模型及cg实现

    经典光照模型(illumination model) 物体表面光照颜色由入射光.物体材质,以及材质和光的交互规律共同决定. 由于环境光给予物体各个点的光照强度相同,且没有方向之分,所以在只有环境光的情 ...

  3. 【Unity Shader】(三) ------ 光照模型原理及漫反射和高光反射的实现

    [Unity Shader](三) ---------------- 光照模型原理及漫反射和高光反射的实现 [Unity Shader](四) ------ 纹理之法线纹理.单张纹理及遮罩纹理的实现 ...

  4. (转)透明光照模型与环境贴图之基础理论篇(折射率、色散、fresnel定律) .

     摘抄“GPU Programming And Cg Language Primer 1rd Edition” 中文名“GPU编程与CG语言之阳春白雪下里巴人” 材质和光的交互除了反射现象,对于透明物 ...

  5. 解读Unity中的CG编写Shader系列八(镜面反射)

    转自http://www.itnose.net/detail/6117378.html 讨论完漫反射之后,接下来肯定就是镜面反射了 在开始镜面反射shader的coding之前,要扩充一下前面提到的知 ...

  6. Unity3D ShaderLab 自定义光照模型

    接着上一篇BasicMyDiffuse的代码来说,这次要说明的就是自定义的光照模型,Ctrl+D>BasicMyDiffuse. 1.>//#pragma surface surf Lam ...

  7. 【Unity Shaders】使用CgInclude让你的Shader模块化——创建CgInclude文件存储光照模型

    本系列主要參考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同一时候会加上一点个人理解或拓展. 这里是本书全部的插图. 这里是本书所需的代码 ...

  8. Directx11学习笔记【十六】 光照模型的实现

    本文由zhangbaochong原创,转载请注明出处http://www.cnblogs.com/zhangbaochong/p/5579289.html 在之前的场景绘制中我们都是给每个顶点指定了单 ...

  9. 【Unity Shaders】Lighting Models —— 光照模型之Lit Sphere

    本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...

随机推荐

  1. 深入浅出Koa

    深入浅出Koa(1):生成器和Thunk函数 Koa是个小而美的Node.js web框架,它由Express的原班人马打造的, 致力于以一种现代化开发的方式构建web应用. 通过这个系列,你将能够理 ...

  2. Linux系统的信号详解

    一.信号类型 1) SIGHUP       2) SIGINT       3) SIGQUIT     4) SIGILL        5) SIGTRAP 6) SIGABRT      7) ...

  3. linkButton

    <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="ht ...

  4. web项目docker化的两种方法

    标题所讲的两种方法其实就是创建docker镜像的两种方法 第一种:启动镜像后进入容器中操作,将需要的软件或者项目移动到容器中,安装或者部署,然后退出即可 第二种:编写dockerfile,将需要的镜像 ...

  5. oracle恢复一个数据表的方法

    今天提交给客户方一个sql脚本去跟新历史数据,结果客户那边的部署人员犯了一个错误,直接拿系统账号去部署,结果第一段代码没有执行成功,结果第二段代码却执行成功了,并且已经提交了的,....由于事前没有备 ...

  6. C++调用C#之C++DLL调用C# COM控件

    1. 新建项目 这里我们使用ATL,来接受C# COM控件向外发送的事件. 2. 初始化ATL #include "stdafx.h" CComModule _module; BO ...

  7. 什么是dtd文件,为什么需要

    DTD为英文Document Type Definition,中文意思为“文档类定义”.DTD肩负着两重任务:一方面它帮助你编写合法的代码,另一方面它让浏览器正确地显示器代码.也许你会问它们居然有这样 ...

  8. android cts 命令的说明

    Host help showthis message 帮助文档 exit exitcts command line 退出CTS ls 全部用l替代,--plan直接用p替代,也即 l p .其他类似 ...

  9. MySql数据库基本介绍和基本语法

    一.数据库简单介绍 1. 按照数据库的发展时间顺序,主要出现了以下类型数据库系统: Ø 网状型数据库 Ø 层次型数据库 Ø 关系型数据库 Ø 面向对象数据库 上面4中数据库系统中,关系型数据库使用最为 ...

  10. Windows API 之 CreateThread、WaitForSingleObject(未完)

    WaitForSingleObject Waits until the specified object is in the signaled state or the time-out interv ...