第18章 像素着色器入门

版权声明:转载请注明出处 https://blog.csdn.net/weixin_39918693/article/details/88738825

pixel shader是在对每个像素进行光栅化处理期间运行在显卡上的一段定制程序(其不会用软件运算方式来模拟)

PS实质上是取代了固定功能渲染管线中的多重纹理(multitexturing)环节,而且赋予了我们直接操纵单个像素以及访问每个像素的纹理坐标的能力个人觉得PS取代了光栅化阶段中的某一个子部分

像素着色器版本检查
if(caps.PixelShaderVersion < D3DPS_VERSION(2, 0)){

}
  • 1、对多重纹理的理解
  • 2、PS的使用步骤
  • 3、使用PS实现多重纹理

1、多重纹理概述

多重纹理可能是PS实现的最简单的技术

由于PS取代了固定功能渲染管线中的多重纹理环节,所以我们应该对多重纹理环节及其功能有基本的理解

多重纹理包含的思想与融合有些关联。我们同时启用若干层纹理,并定义这些纹理的融合方式,以获得某种特殊效果

多重纹理的一种典型应用就是进行光照运算

光照效果的两种实现方式

  • 1、在顶点运算阶段使用实时光照模型
  • 2、使用光照纹理图(light maps)

光照纹理图规定了某一表面是如何被照亮的

在固定功能的多重纹理环节,我们通过纹理绘制状态对多重纹理的融合方式进行控制;而在PS中,我们可以在代码中以可编程方式来定义多重纹理的具体融合方式(更灵活)

扫描二维码关注公众号,回复: 5639639 查看本文章

通过多重纹理实现的光照运算之于实时光照模型的优点:

  • 1、光照已预先计算好了,节省运算时间。只对静止物体和固定光源才可以预先进行光照计算
  • 2、可以使用更精确、更复杂的光照模型

多重纹理环节一般用于为静态物体实现一个完整的光照计算引擎

当给定场景和光源时,可以用专门的程序来生成光照纹理图

1.1、启用多重纹理

纹理用IDirect3DDevice9::SetTexture来启用;采样状态(sampler state)可用IDirect3DDevice9::SetSamplerState来设置

一个特定的采样器级数索引i第i层纹理是关联的,即第i个采样级为第i层纹理指定了采样器状态

纹理层索引标识了我们想要将纹理设置成的纹理层采样级索引标识了我们想要将采样器设置成的采样级这样,我们就可以激活多个纹理,并通过不同的层索引来为这些纹理设置相应的采样状态

采样状态过滤模式

每一层纹理都有其对应的采样状态(包括其对应的多级渐进纹理采样状态)

应用程序源代码
d3ddev->SetTexture(i, Texi);
d3ddev->SetSamplerState(i, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
d3ddev->SetSamplerState(i, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
d3ddev->SetSamplerState(i, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); 多级纹理过滤器的设置

1.2、多重纹理坐标

在使用多重纹理时,对于定义3D三角形图元的三个顶点,我们需要在启用的每个纹理中定义相应的三角形。为此,我们可为每个顶点额外增加若干纹理坐标对——每对纹理坐标对对应于某一层被启用的纹理

该顶点结构少了顶点法线,因为多重纹理和光照可同时具有
struct MultiTexVertex{
	MultiTexVertex(float x, float y, float z,
					float u0, float v0,
					float u1, float v1,
					float u2, float v2)
	{
		_x = x; _y = y; _z = z;
		_u0 = u0; _v0 = v0;
		_u1 = u1; _v1 = v1;
		_u2 = u2; _v2 = v2;				
	}

	float _x, _y, _z;
	float _u0, _v0;		texture stage 0
	float _u1, _v1;		texture stage 1
	float _u2, _v2;		texture stage 2
	static const DWORD FVF;
};
const DWORD MultiTexVertex::FVF = D3DFVF_XYZ | D3DFVF_TEX3;

固定功能渲染管线至多支持8层纹理。如果要使用的纹理层数超过8,则必须使用顶点声明和VS


2、像素着色器的输入和输出

PS的输入包括每个像素的颜色和纹理坐标

每个像素的纹理坐标其实是指定的纹理中将被映射到当前像素的纹理元的坐标

在进入PS之前,D3D先根据VS输出结构中的顶点颜色和顶点纹理坐标计算出每个像素的颜色和纹理坐标(已经是2D了),然后将计算所得每个像素的颜色和纹理坐标输入PS

输入PS的颜色纹理坐标对的个数由VS输出的颜色纹理坐标对的个数决定。数量关系不变,但是具体的值由D3D计算得出(应该是差值运算)

我们需要借助语义语法来将输入的颜色和纹理坐标映射为PS程序中的变量。说的不太明白,需要通过例子说明

PS将输出计算所得的每个像素的单个颜色值

struct PS_OUTPUT
{
	vector finalPixelColor : COLOR0;
};

VS和PS之间起到计算作用的是光栅化(rasterizatioin)


3、使用像素着色器的步骤

与使用VS的步骤相同,只是有些参数不同


4、HLSL采样器对象

在PS中对纹理进行采样,可使用专门与纹理相关的HLSL内置函数

采样是指根据像素的纹理坐标采样状态来检索某一像素所对应的纹理元

纹理坐标来自于PS的输入;采样状态和想要检索的特定纹理在PS中是用一个特别的HLSL对象——采样器(sampler)来标识的

在PS的HLSL代码中定义sampler对象,然后在应用程序代码中通过常量表获取该对象,然后对该对象进行纹理和采样状态的设置

除了可以使用sampler类型外,还可以使用更具体、类型检查更严格的相关类型

猜你喜欢

转载自blog.csdn.net/weixin_39918693/article/details/88738825