前提,
在阅读这个文章前,你需要
1)前面<从头敲游戏引擎的Engine.exe>跑通(小学生都能跑通)
2)懂得什么是光线,什么是漫反射(初中知识)
3)懂得 Shader 和 HLSL
4)c++编程(c++很多,但只需要知道其中恶心的结构体,包长度)
上面。。。。。。。。 | |
往下移动。。。。。。。 |
官方Diffuse代码
我们先上一段官方的代码
很多大神,老师也提供这段代码:
// 展开,避免动态分支
[flatten]
if (diffuseFactor > 0.0f)
{
float3 v = reflect(-lightVec, normal);
float specFactor = pow(max(dot(v, toEye), 0.0f), mat.Specular.w);
diffuse = diffuseFactor * mat.Diffuse * L.Diffuse;
spec = specFactor * mat.Specular * L.Specular;
}
逻辑都对,大家都在用,关键在于这句
//factor == 光照渐变,通过光的朝向和物体的法线计算(连插值都没用,插值貌似只适合用在vertex,这里是Pixel)
//mat == Material ,实际上mat.diffuse是一个颜色值
//L == light,实际上光的diffuse“没有颜色”非黑即白
diffuse = diffuseFactor * mat.Diffuse * L.Diffuse;
我们不用这么"辣眼睛“的代码
最简单的代码:
C++代码
// 片元着色器的常量缓存
struct FrameConstantBuffer
{
DirectionalLight gDirLight; // 直射光
PointLight gPointLight; // 点光源
SpotLight gSpotLight; // 聚光灯
Material gMaterial; // 物体材质
XMFLOAT4 gEyePosW; // 当前点到相机向量
};
// 常量数据结构
ConstantBuffer mCBuffer;
FrameConstantBuffer mFrameCBuffer;
//light.h
struct DirectionalLight
{
DirectionalLight()
{
ZeroMemory(this, sizeof(this));
}
XMFLOAT4 Ambient;
XMFLOAT4 Diffuse;
XMFLOAT4 Specular;
XMFLOAT3 Direction;
float Pad; // Ìî²¹×îºóһ룬±£Ö¤128bit¶ÔÆë
};
struct Material
{
Material() {
ZeroMemory(this, sizeof(this));
}
XMFLOAT4 Ambient;
XMFLOAT4 Diffuse;
XMFLOAT4 Specular;
XMFLOAT4 Reflect;
};
struct PointLight
{
PointLight()
{
ZeroMemory(this, sizeof(this));
}
XMFLOAT4 Ambient;
XMFLOAT4 Diffuse;
XMFLOAT4 Specular;
XMFLOAT3 Position;
float Range;
XMFLOAT3 Att;
float Pad;
};
struct SpotLight
{
SpotLight()
{
ZeroMemory(this, sizeof(this));
}
XMFLOAT4 Ambient;
XMFLOAT4 Diffuse;
XMFLOAT4 Specular;
XMFLOAT3 Position;
float Range;
XMFLOAT3 Direction;
float Spot;
XMFLOAT3 Att;
float Pad;
};
调用API(官方的用不了,无解)
HLSL,shader部分代码:
void ComputeLight(DirectionalLight L, float3 normal,out float4 diffuse)
{
float3 lightVec = -L.Direction;
float diffuseFactor = (dot(lightVec, normal) + 1) / 2;
if (diffuseFactor > 0)
{
diffuse = diffuseFactor;
}
}
float4 PS(VertexOut outa) : SV_Target
{
float4 l;
DirectionalLight litStruct;
litStruct.Direction = gLiteColor.xyz;
//ComputeLight(gDirLight,outa.normal,l);
ComputeLight(litStruct, outa.normal, l);
return l;
}
参考:
待实现各种基础模型的C++创建
DirectX11 With Windows SDK--07 添加光照与常用几何模型、光栅化状态 - X_Jun - 博客园
Dx11 Demo
DirectX11编程7 光照_暗光之痕的博客-CSDN博客_dx11光照f
获取LightHelper.fx,某韩国仁引擎初级
SeawoodEngine/LightHelper.fx at master · jwvg0425/SeawoodEngine · GitHub