概述

在之前的教程中,世界看起来很无聊,因为所有对象都以相同的方式点亮。 本教程将介绍简单照明的概念及其应用方法。 使用的技术将是朗伯照明。

本教程的结果将修改前面的示例以包含光源。 该光源将附在轨道上的立方体上。 可以在中心立方体上看到光的影响。

资源目录

(SDK root)\Samples\C++\Direct3D11\Tutorials\Tutorial06

Github

灯光

在本教程中,将介绍最基本的照明类型:朗伯照明。 无论距离光线的距离如何,朗伯照明都具有均匀的强度。 当光照射到表面时,通过光在表面上的入射角计算反射的光量。 当光直接照射在表面上时,它显示出以最大强度反射所有光。 然而,随着光的角度增加,光的强度将逐渐消失。

为了计算光在表面上的强度,必须计算光方向与表面法线之间的角度。 表面的法线定义为垂直于表面的矢量。 角度的计算可以通过简单的点积来完成,该点积将光方向矢量的投影返回到法线上。 角度越宽,投影越小。 因此,这为我们提供了调制漫射光的正确功能。

本教程中使用的光源是定向照明的近似值。 描述光源的矢量确定光的方向。 由于它是近似值,无论物体在哪里,光线照射到它的方向都是相同的。 这种光源的一个例子是太阳。 对于场景中的所有物体,总是看到太阳朝同一方向发光。 另外,不考虑单个物体上的光强度。

其他类型的光包括从中心辐射均匀光的点光源和在所有物体上方向但不均匀的聚光灯。

初始化灯光

在本教程中,将有两个光源。 一个将静态地放置在立方体的上方和后方,另一个将围绕中心立方体进行轨道运行。 请注意,上一个教程中的轨道立方体已替换为此光源。

由于光照是由着色器计算的,因此必须声明变量,然后将其绑定到技术中的变量。 在此示例中,我们只需要光源的方向以及颜色值。 第一盏灯是灰色而不移动,而第二盏是轨道红灯。

// Setup our lighting parameters
XMFLOAT4 vLightDirs[2] =
{
XMFLOAT4( -0.577f, 0.577f, -0.577f, 1.0f ),
XMFLOAT4( 0.0f, 0.0f, -1.0f, 1.0f ),
};
XMFLOAT4 vLightColors[2] =
{
XMFLOAT4( 0.5f, 0.5f, 0.5f, 1.0f ),
XMFLOAT4( 0.5f, 0.0f, 0.0f, 1.0f )
};

  

在上一个教程中,轨道光的旋转方式与立方体一样。 应用的旋转矩阵将改变光的方向,以显示它始终朝向中心发光的效果。 注意,函数XMVector3Transform用于将矩阵与向量相乘。 在上一个教程中,我们将转换矩阵乘以世界矩阵,然后传递到着色器进行转换。 但是,为简单起见,在这种情况下,我们实际上正在对CPU中的光进行世界变换。

// Rotate the second light around the origin
XMMATRIX mRotate = XMMatrixRotationY( -2.0f * t );
XMVECTOR vLightDir = XMLoadFloat4( &vLightDirs[1] );
vLightDir = XMVector3Transform( vLightDir, mRotate );
XMStoreFloat4( &vLightDirs[1], vLightDir );

  

灯光的方向和颜色都像矩阵一样传递到着色器。 调用关联变量进行设置,并传入参数。

    //
// Update matrix variables and lighting variables
//
ConstantBuffer cb1;
cb1.mWorld = XMMatrixTranspose( g_World );
cb1.mView = XMMatrixTranspose( g_View );
cb1.mProjection = XMMatrixTranspose( g_Projection );
cb1.vLightDir[0] = vLightDirs[0];
cb1.vLightDir[1] = vLightDirs[1];
cb1.vLightColor[0] = vLightColors[0];
cb1.vLightColor[1] = vLightColors[1];
cb1.vOutputColor = XMFLOAT4(0, 0, 0, 0);
g_pImmediateContext->UpdateSubresource( g_pConstantBuffer, 0, NULL, &cb1, 0, 0 );

  

渲染像素着色器中的灯光

一旦我们设置了所有数据并且着色器正确地提供了数据,我们就可以计算来自光源的每个像素的朗伯照明术语。 我们将使用之前讨论过的点积规则。

一旦我们将光线与正常光线的点积相乘,就可以将其与光线的颜色相乘,以计算光线的效果。 该值通过饱和函数传递,该函数将范围转换为[0,1]。 最后,将两个单独的灯的结果相加在一起以创建最终的像素颜色。

考虑到表面本身的材料没有考虑到这个光计算中。 表面的最终颜色是灯光颜色的结果。

    //
// Pixel Shader
//
float4 PS( PS_INPUT input) : SV_Target
{
float4 finalColor = 0; //do NdotL lighting for 2 lights
for(int i=0; i<2; i++)
{
finalColor += saturate( dot( (float3)vLightDir[i],input.Norm) * vLightColor[i] );
}
return finalColor;
}

  

一旦通过像素着色器,像素将被光调制,您可以看到每个光在立方体表面上的效果。 请注意,在这种情况下,光看起来很平,因为同一表面上的像素将具有相同的法线。 漫反射是一种非常简单易用的计算照明模型。 您可以使用更复杂的照明模型来获得更丰富,更真实的材料。

最终效果

Direct3D 11 Tutorial 6:Lighting_Direct3D 11 教程6:灯光的更多相关文章

  1. Direct3D 11 Tutorial 1: Basics_Direct3D 11 教程1:基础

    Github-LearnDirectX-DX3D11 tutorial01 概述 在这第一篇教程中,我们将通过介绍创建最小Direct3D应用程序所必需的元素.每一个Direct3D应用程序必需拥有这 ...

  2. Java 11 Tutorial

    Java 11 Tutorial 参考 https://blog.csdn.net/sihai12345/article/details/82889827 原文 https://winterbe.co ...

  3. 【转】正则表达式简介及在C++11中的简单使用教程

    正则表达式Regex(regular expression)是一种强大的描述字符序列的工具.在许多语言中都存在着正则表达式,C++11中也将正则表达式纳入了新标准的一部分,不仅如此,它还支持了6种不同 ...

  4. Gitlab 11.9.1 高可用教程

    Gitlab 11.9.1 高可用教程 一. PostgreSQL数据迁移 由于默认Gitlab的安装会内置Postgres数据库,并且没有对外,所以我们需要通过设置对应的Gitlab的配置将其中的数 ...

  5. MapServer Tutorial——MapServer7.2.1教程学习——第一节用例实践:Example1.7 Adding a wms layer

    MapServer Tutorial——MapServer7.2.1教程学习——第一节用例实践:Example1.7 Adding a wms layer 前言 Add OGC WMS Layers( ...

  6. MapServer Tutorial——MapServer7.2.1教程学习——第一节用例实践:Example1.6 Defining Projections and Extents

    MapServer Tutorial——MapServer7.2.1教程学习——第一节用例实践:Example1.6 Defining Projections and Extents 一.前言 当在m ...

  7. MapServer Tutorial——MapServer7.2.1教程学习——第一节用例实践:Example1.3 Displaying Classes in a Layer

    MapServer Tutorial——MapServer7.2.1教程学习——第一节用例实践:Example1.3 Displaying Classes in a Layer 一.前言 关于第一节的 ...

  8. PSU 离11.2.0.3.0 -&gt; 11.2.0.3.11 如果解决冲突的整个

    Oracle rdbms 扑灭psu离11.2.0.3.0升级到11.2.0.3.11 参考patch :18522512 停止应用,停止听音乐并DB,将db的oracle_home在下面OPatch ...

  9. Oracle DataGuard 升级 [11.2.0.1 -> 11.2.0.4]

    Oracle DataGuard 升级 [11.2.0.1 -> 11.2.0.4] Primary: 11.2.0.1 单机,Site A. Standby: 11.2.0.1 单机,Site ...

随机推荐

  1. ajax 浏览网页等待页面

  2. 读《31天学会CRM项目开发》记录2 - 企业信息管理系统

    在信息技术的快速推动下,企业如果依然利用传统的管理方式,以人为主,那效率便会大打折扣.在此背景下,企业信息化系统得 到了高速发展.如我们常见的ERP系统.MES系统,都是提高公司运行效率,降低运营以及 ...

  3. Linux下安装配置virtualenv与virtualenvwrapper

    一.Linux下安装.配置virtualenv 配置源 #指定清华源下载pip的包 [root@localhost opt]# pip3 install -i https://pypi.tuna.ts ...

  4. 3ds max学习笔记(九)-- 实例操作(路径阵列)

    栅栏 路径阵列也叫间隔工具,将选择的物体沿指定的路径进行复制.实现物体在路径上的饿均匀分布. 选择需要分布的物体对象,在视图中绘制二维图形做为路径线条. 1.选择线条,制作路径 2.选择需要分布的物体 ...

  5. “百度杯”CTF比赛 九月场---123

    右键查看源代码 然后构造user.php,显示空白,源码也是空白,既然上边说用户名,密码了,参考大佬的博客,放文件user.php.bak这是备份文件,一打开上边全是用户名,有戏,爆破 添加字典,也就 ...

  6. iOS 开发中常见的崩溃错误

    1.duplicate symbols for architecture armv7   1.首先排查是否有名字重复的文件:   2.检查是否在#import头文件的时候,不小心把.h写成了.m. 2 ...

  7. Hibernate(6)关联关系_单向n对1

    1.单向 n-1 关联只需从 n 的一端可以访问 1 的一端 2.实体类 n端:Order.java public class Order { private Integer orderId; pri ...

  8. 12、mysql补充

    本篇导航: 视图 触发器 事务 存储过程 函数 流程控制 一.视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,可 ...

  9. .net 多态

    https://espider.github.io/CLR/inheritance-polymorphism/

  10. [Nuget]使用Nuget管理工具包

    摘要 这里演示如何使用Nuget对类库进行打包,并将类库上传到nuget上面. 步骤 1.在nuget官网注册账号,并登陆. https://www.nuget.org 2.下载Nuget.exe,并 ...