Vertex Shader - 合成光(包含环境、散射、镜面)

本文详细记录了作者初次成功完成DEMO的喜悦与成就感,通过简单的程序展示对Direct3D(D3D)有了进一步的理解,并深入探讨了镜面光照方程的实现原理,包括环境光、散射光与镜面光的计算过程。代码展示了如何在Shader中实现这些概念,特别关注了镜面反射光的强度计算。通过实例代码解析,读者可以直观地理解光照模型的实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天是个特殊的日子,因为是笔者第一次完成DEMO没有经过漫长的调试(其实并不能说明什么,因为演示程序的确太简单了,如果这样的一个程序还要纠结几天,我可能也要怀疑自己智商问题,不过还是小有成就,毕竟表示我对D3D有了进一步了解,以及明白了光照模型的实现原理(现在是越来越爱Shader了,和Fixed Pipeline Say 拜拜吧)。


关于镜面光照方程,基本上就是按PHONE的那个公式来的。 IS = IL · KS · Cos@^n


IS 为镜面反射光的强度,IL为入射光光强,KS为镜面反射常量,Cos@^n中n值越大,代表反射表面越光滑


下面是代码:

// File name : SpecularLighting.vsh
//
// Author : Dormy.X.C
//
// Description :
//

matrix viewMat;
matrix worldViewProjMat;

vector lightDir;
vector eyePosition;

vector ambientMtrl;
vector diffuseMtrl;
vector specularMtrl;

// 定义环境光及,镜面光照强度
vector ambientLightingIntensity		= {0.5f, 0.5f, 0.5f, 0.0f};
vector diffuseLightingIntensity		= {1.0f, 0.0f, 1.0f, 0.0f};
vector specularLightingIntensity	= {1.0f, 1.0f, 1.0f, 0.0f};

// 输入结构
struct VS_INPUT
{
	vector position : POSITION;
	vector normal	: NORMAL;
};

// 输出结构
struct VS_OUTPUT
{
	vector position : POSITION;
	vector color	: COLOR;
};

// 主函数
VS_OUTPUT Specular(VS_INPUT input)
{
	VS_OUTPUT output = (VS_OUTPUT)0;

	output.position = mul(input.position, worldViewProjMat);

	lightDir.w = 0.0f;
	input.normal.w = 0.0f;
	mul(lightDir, viewMat);
	mul(input.normal, viewMat);

	vector vertexWorldPos	= normalize(mul(input.position, viewMat));

	// 计算观察方向
	vector viewDirection	= normalize(eyePosition - vertexWorldPos);

	// 计算法线与入射光线(即光照方向)的值
	float s = saturate( dot( input.normal, lightDir) );
	
	if( s < 0.0f )
		s = 0.0f;

	// 计算镜面反射向量
	vector reflect = normalize(2 * s * input.normal - lightDir);

	// 表示反射面光滑程度(反射系数)
	vector specularIntensity = pow( saturate(dot(reflect, viewDirection)), 25.0f);

	output.color = (ambientMtrl * ambientLightingIntensity) +							// 环境光
				   ((ambientMtrl * diffuseLightingIntensity) * s) +						// 散射光
				   (specularMtrl * specularIntensity * specularLightingIntensity);		// 镜面光

	return output;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值