【DX11地形篇】16-位图云

参考教程

Tutorial 11: Bitmap Clouds

学习记录

  这篇文章种我们介绍云的实现,本篇代码基于上一篇,新增 SkyPlaneClassSkyPlaneShaderClass

  我们实现云效果的原理则是一个弧面模型,然后使用云的贴图即可,在 SkyPlaneClass 种我们负责弧面模型的创建等,其声明如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
////////////////////////////////////////////////////////////////////////////////
// Filename: skyplaneclass.h
////////////////////////////////////////////////////////////////////////////////
#ifndef _SKYPLANECLASS_H_
#define _SKYPLANECLASS_H_


//////////////
// INCLUDES //
//////////////
#include <d3d11.h>
#include <d3dx10math.h>


///////////////////////
// MY CLASS INCLUDES //
///////////////////////
#include "textureclass.h"
#include <DirectXMath.h>


////////////////////////////////////////////////////////////////////////////////
// Class name: SkyPlaneClass
////////////////////////////////////////////////////////////////////////////////
class SkyPlaneClass
{
private:
struct SkyPlaneType
{
float x, y, z;
float tu, tv;
};
struct VertexType
{
DirectX::XMFLOAT3 position;
DirectX::XMFLOAT2 texture;
};

public:
SkyPlaneClass();
SkyPlaneClass(const SkyPlaneClass&);
~SkyPlaneClass();

bool Initialize(ID3D11Device* , ID3D11DeviceContext*, CHAR*, CHAR*);
void Shutdown();
void Render(ID3D11DeviceContext*);
void Frame();

int GetIndexCount();
ID3D11ShaderResourceView* GetCloudTexture1();
ID3D11ShaderResourceView* GetCloudTexture2();

float GetBrightness();
float GetTranslation(int);

private:
bool InitializeSkyPlane(int, float, float, float, int);
void ShutdownSkyPlane();

bool InitializeBuffers(ID3D11Device*, int);
void ShutdownBuffers();
void RenderBuffers(ID3D11DeviceContext*);

bool LoadTextures(ID3D11Device*,ID3D11DeviceContext*, CHAR*, CHAR*);
void ReleaseTextures();

private:
SkyPlaneType* m_skyPlane;
int m_vertexCount, m_indexCount;
ID3D11Buffer *m_vertexBuffer, *m_indexBuffer;
TextureClass *m_CloudTexture1, *m_CloudTexture2;
float m_brightness;
float m_translationSpeed[4];
float m_textureTranslation[4];
};

#endif

  比起其他模型类其实差不多,我们使用 m_translationSpeed 等数据控制云的移动,在 skyplane.ps 中实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
////////////////////////////////////////////////////////////////////////////////
// Filename: skyplane.ps
////////////////////////////////////////////////////////////////////////////////


/////////////
// GLOBALS //
/////////////
Texture2D cloudTexture1 : register(t0);
Texture2D cloudTexture2 : register(t1);
SamplerState SampleType;
cbuffer SkyBuffer
{
float firstTranslationX;
float firstTranslationZ;
float secondTranslationX;
float secondTranslationZ;
float brightness;
float3 padding;
};


//////////////
// TYPEDEFS //
//////////////
struct PixelInputType
{
float4 position : SV_POSITION;
float2 tex : TEXCOORD0;
};
////////////////////////////////////////////////////////////////////////////////
// Pixel Shader
////////////////////////////////////////////////////////////////////////////////
float4 SkyPlanePixelShader(PixelInputType input) : SV_TARGET
{
float2 sampleLocation;
float4 textureColor1;
float4 textureColor2;
float4 finalColor;


// Translate the position where we sample the pixel from using the first texture translation values.
sampleLocation.x = input.tex.x + firstTranslationX;
sampleLocation.y = input.tex.y + firstTranslationZ;

// Sample the pixel color from the first cloud texture using the sampler at this texture coordinate location.
textureColor1 = cloudTexture1.Sample(SampleType, sampleLocation);

// Translate the position where we sample the pixel from using the second texture translation values.
sampleLocation.x = input.tex.x + secondTranslationX;
sampleLocation.y = input.tex.y + secondTranslationZ;

// Sample the pixel color from the second cloud texture using the sampler at this texture coordinate location.
textureColor2 = cloudTexture2.Sample(SampleType, sampleLocation);

// Combine the two cloud textures evenly.
finalColor = lerp(textureColor1, textureColor2, 0.5f);

// Reduce brightness of the combined cloud textures by the input brightness value.
finalColor = finalColor * brightness;

return finalColor;
}

  而 SkyPlaneShaderClass 则是和其他 shader 类相同负责 skyplane 着色器的编译等,其声明如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
////////////////////////////////////////////////////////////////////////////////
// Filename: skyplaneshaderclass.h
////////////////////////////////////////////////////////////////////////////////
#ifndef _SKYPLANESHADERCLASS_H_
#define _SKYPLANESHADERCLASS_H_


//////////////
// INCLUDES //
//////////////
#include <d3d11.h>
#include <DirectXMath.h>
#include <d3dx11async.h>
#include <fstream>
using namespace std;
using namespace DirectX;


////////////////////////////////////////////////////////////////////////////////
// Class name: SkyPlaneShaderClass
////////////////////////////////////////////////////////////////////////////////
class SkyPlaneShaderClass
{
private:
struct MatrixBufferType
{
XMMATRIX world;
XMMATRIX view;
XMMATRIX projection;
};
struct SkyBufferType
{
float firstTranslationX;
float firstTranslationZ;
float secondTranslationX;
float secondTranslationZ;
float brightness;
XMFLOAT3 padding;
};

public:
SkyPlaneShaderClass();
SkyPlaneShaderClass(const SkyPlaneShaderClass&);
~SkyPlaneShaderClass();

bool Initialize(ID3D11Device*, HWND);
void Shutdown();
bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, ID3D11ShaderResourceView*, float, float, float,
float, float);

private:
bool InitializeShader(ID3D11Device*, HWND, CHAR*, CHAR*);
void ShutdownShader();
void OutputShaderErrorMessage(ID3D10Blob*, HWND, CHAR*);

bool SetShaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, ID3D11ShaderResourceView*, float, float,
float, float, float);
void RenderShader(ID3D11DeviceContext*, int);

private:
ID3D11VertexShader* m_vertexShader;
ID3D11PixelShader* m_pixelShader;
ID3D11InputLayout* m_layout;
ID3D11SamplerState* m_sampleState;
ID3D11Buffer* m_matrixBuffer;
ID3D11Buffer* m_skyBuffer;
};

#endif

  最后我们在 ShaderManagerClass 中创建 SkyPlaneShaderClass 的对象以及添加对应的渲染方法,在 Zone 中负责 SkyPlane 对象的初始化等等,最后在 Render 里渲染。需要开启透明和关闭背面剔除,因为我们在弧面的内侧。
  最终效果如下:

1

  源代码:DX11TerrainTutorial-BitmapClouds

0%