HLSL像素着色器

原文: HLSL像素着色器


昨日不可追, 今日尤可为.勤奋,炽诚,不忘初心

手机淘宝二维码 扫描      

或者打开连接:程序设计开发 ,掌声鼓励,欢迎光临.


 

 

像素着色器替代了固定渲染管线的 多纹理化 阶段(书上说的)

这是片面的,不完善的,  其实像素着色器,只要渲染到屏幕上,那就有像素这个东西,就要有像素着色器.

实现步骤:

1.编写和编译像素着色器文件

2.创建像素着色器

3.设置像素着色器

//文本文件代码

//--------------------------begim ps.txt---------------------------------------
//全局变量
//存储颜色混合的比例值s,其中
//Scalar.x = s
//Scalar.y = 1-s

vector Scalar;	//纹理混合比例(权重)

//纹理0; 纹理1
texture Tex0;
texture Tex1;

//纹理采样器0
sampler Samp0 = sampler_state
{
	Texture = <Tex0>;
	MipFilter = LINEAR;
	MinFilter = LINEAR;
	MagFilter = LINEAR;
};

//纹理采样器1
sampler Samp1 = sampler_state
{
	Texture = <Tex1>;
	MipFilter = LINEAR;
	MinFilter = LINEAR;
	MagFilter = LINEAR;
};

//输入两套纹理坐标
struct PS_INPUT
{
	float2 uvCoords0 : TEXCOORD0;
	float2 uvCoords1 : TEXCOORD1;
};

//输出像素颜色
struct PS_OUTPUT
{
	float4 Color : COLOR0;
};

//入口函数
PS_OUTPUT PS_Main(PS_INPUT input)
{
	PS_OUTPUT output = (PS_OUTPUT)0;
	//分别对两个纹理进行采样按照比例混合后输出颜色值
	output.Color = tex2D(Samp0, input.uvCoords0)*Scalar.x + tex2D(Samp1, input.uvCoords1)*Scalar.y;
	return output;
}

//--------------------------end ps.txt---------------------------------------

vs程序中源代码:

	//setup
	void Setup()
	{
		HRESULT hr = 0;
		//创建顶点缓存
		m_d3dDevice->GetD3DDevice()->CreateVertexBuffer(
			4 * sizeof(MultiTexVertex),
			D3DUSAGE_WRITEONLY,
			MultiTexVertex::FVF,
			D3DPOOL_MANAGED,
			&quadVB,
			0);
		//填充顶点缓存
		MultiTexVertex* v = 0;
		quadVB->Lock(0, 0, (void**)&v, 0);
		v[0] = MultiTexVertex(-3.0f, -3.0f, 10.0f, 0.0f, 1.0f, 0.0f, 1.0f);
		v[1] = MultiTexVertex(-3.0f,  3.0f, 10.0f, 0.0f, 0.0f, 0.0f, 0.0f);
		v[2] = MultiTexVertex( 3.0f, -3.0f, 10.0f, 1.0f, 1.0f, 1.0f, 1.0f);
		v[3] = MultiTexVertex( 3.0f,  3.0f, 10.0f, 1.0f, 0.0f, 1.0f, 0.0f);
		quadVB->Unlock();

		//加载纹理:
		D3DXCreateTextureFromFile(D3DDevice, L"D:\\pic1.png", &quadTexture0);
		D3DXCreateTextureFromFile(m_d3dDevice->D3DDevice, L"D:\\pic2.png", &quadTexture1);

		//编译像素着色器:
		//创建像素着色器
		ID3DXBuffer* codeBuffer = 0;
		ID3DXBuffer* errorBuffer = 0;
		hr = D3DXCompileShaderFromFile(
			L"D:\\ps.txt",
			0,
			0,
			"PS_Main", // entry point function name
			"ps_2_0",
			D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY,
			&codeBuffer,
			&errorBuffer,
			&pixelConstTable);
		// 输出错误信息:
		if (errorBuffer)
		{
			string str = (char*)errorBuffer->GetBufferPointer();
			MessageBox(NULL, Common::StringToWString(str).c_str(), L"ERROR", MB_OK);
			//safe_release<ID3DXBuffer*>(error_buffer);
		}
		if (FAILED(hr))
		{
			MessageBox(NULL, L"D3DXCreateEffectFromFile() - FAILED", L"ERROR", MB_OK);
		}


		//创建像素着色器
		hr = D3DDevice->CreatePixelShader((DWORD*)codeBuffer->GetBufferPointer(), &pixelShader);
		if (FAILED(hr))
		{
			MessageBox(NULL, L"CreateVertexShader - FAILED", L"ERROR", MB_OK);
		}
		//释放
		//safe_release<ID3DXBuffer*>(shader_buffer);

		//设置投影矩阵
		D3DXMATRIX p;
		RECT rt;
		GetClientRect(Application::GetInstance()->GetWnd(), &rt);
		D3DXMatrixPerspectiveFovLH(&p, D3DX_PI * 0.25f, (float)rt.right / rt.bottom, 1.0f, 1000.0f);
		D3DDevice->SetTransform(D3DTS_PROJECTION, &p);

		//禁用灯光
		D3DDevice->SetRenderState(D3DRS_LIGHTING, false);

		//得到各常量句柄
		ScalarHandle = pixelConstTable->GetConstantByName(0, "Scalar");
		Samp0Handle = pixelConstTable->GetConstantByName(0, "Samp0");
		Samp1Handle = pixelConstTable->GetConstantByName(0, "Samp1");

		//设置对着色器变量Samp0、Samp1的描述
		UINT count;
		pixelConstTable->GetConstantDesc(Samp0Handle, &Samp0Desc, &count);
		pixelConstTable->GetConstantDesc(Samp1Handle, &Samp1Desc, &count);
		//设定各着色器变量为初始值
		pixelConstTable->SetDefaults(D3DDevice);
	}
	
	//display : 设置像素着色器,取用2张纹理,并在渲染前设置对应采样状态
	void Display(float timeDelta)
	{
		// render now
		D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
		D3DDevice->BeginScene();

		//为着色器全局变量Scalar赋值
		D3DXVECTOR4 scalar(0.5f, 0.5f, 0.0f, 1.0f);//一半一半混合
		pixelConstTable->SetVector(D3DDevice, ScalarHandle, &scalar);
		//设置像素着色器
		D3DDevice->SetPixelShader(pixelShader);

		//设置定点格式、绑定数据流
		D3DDevice->SetFVF(MultiTexVertex::FVF);
		D3DDevice->SetStreamSource(0, quadVB, 0, sizeof(MultiTexVertex));
		//设置第一、二层纹理
		D3DDevice->SetTexture(Samp0Desc.RegisterIndex, quadTexture0);
		D3DDevice->SetTexture(Samp1Desc.RegisterIndex, quadTexture1);

		//绘制图形
		D3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);

		D3DDevice->EndScene();
		D3DDevice->Present(NULL, NULL, NULL, NULL);
	}

代码来自 博客下载:HLSL初级教程.

效果图:纹理1,2:

混合效果:

猜你喜欢

转载自www.cnblogs.com/lonelyxmas/p/10807302.html