概述

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

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

资源目录

(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. 生成树的计数 Matrix-Tree(矩阵树)定理

    信息学竞赛中,有关生成树的最优化问题如最小生成树等是我们经常遇到的,而对生成树的计数及其相关问题则少有涉及.事实上,生成树的计数是十分有意义的,在许多方面都有着广泛的应用.本文从一道信息学竞赛中出现的 ...

  2. error :expected initializer before

    很可能头文件或者前面的某个定义少了个:

  3. Sunscreen [POJ3614] [贪心]

    描述 C (1 ≤ C ≤ 2500) 头奶牛在海滩边晒太阳,要避免在日光浴时产生难看的灼伤,每头奶牛必须用防晒霜覆盖它的皮肤.第 i 头奶牛有一个最小和最大 SPF 值 (1 ≤ minSPFi ≤ ...

  4. mysql error

    一.could not find driver  我们这里以 PDO 为例, 问题: PDO 连接数据库找不到驱动程序. 解决方法:在 php.ini 里面讲 php_pdo_mysql 和 php_ ...

  5. Alpha冲刺(1/10)——2019.4.24

    所属课程 软件工程1916|W(福州大学) 作业要求 Alpha冲刺(1/10)--2019.4.24 团队名称 待就业六人组 1.团队信息 团队名称:待就业六人组 团队描述:同舟共济扬帆起,乘风破浪 ...

  6. Hibernate非主键关联

    一. 非主键关联,我们进行外键关联时,通常使用的是主键,但有时候需要使用到其他列时可以通过以下方法设置: 注解中:@JoinColumn(name="city", referenc ...

  7. hihocoder1323 回文字符串(区间dp)

    https://hihocoder.com/problemset/problem/1323 刚开始真没看出来这是一道dp题.. dp[i][j]表示i~j段修改成回文串所需的最少操作次数.然后根据s[ ...

  8. pygame-KidsCanCode系列jumpy-part4-弹跳

    终于要到弹跳环节了,向上弹跳其实很简单,按下空格触发时,只要把y轴速度给一个向上的速度即可. Player类,新加一个jump()方法: def jump(self): self.vel.y = -2 ...

  9. RealTek WiFi 模块 RTL8710AF RTL8711AF RTL8711AM RTL8195AM

    瑞昱 8710 是一个完整且自成体系的 WiFi 网络解决方案, 能够独立运行,也可以作为从机搭载于其他主机 MCU 运行. 瑞昱 8710 在搭载应用并作为设备中唯⼀的应⽤处理器时,能够直接从外接闪 ...

  10. 遭遇ASP.NET的Request is not available in this context

    如果ASP.NET程序以IIS集成模式运行,在Global.asax的Application_Start()中,只要访问Context.Request,比如下面的代码 var request = Co ...