此篇是根据简单光照模型的理论为基础进行的实现,实现了平行光点,光源,锥形光的效果也算是光照的最基础的入门篇:
1.cbuffer:这里需要强调的是在构造Cbuffer的数据结构的时候,一定要注意字段的顺序,很容易出错。
重要:HLSL的结构体struct其实并不管你是一个变量还是几个变量,它就是按照一次放满一个float4的内存长度,多少变量都往一个float4里面塞,塞满了再接着塞下一个float4。测试结果显示:cbuffer的长度必须是float4的整数倍才行,不知道float+float3的这种组合是否可以正常获取数据,也不清楚float+float+float3+float3这种组合能不能正常分配到数据,关键取决于GPU的内存分配规则。
// 光源
struct LightBuffer
{
float mType; // 光源类型 4种
Vector3 mPosition; // 位置
float mAngleInnerCone; // 内角弧度
Vector3 mAttenuation; // 衰减因子,衰减=1/(x+ y* D+ z* D* D),D是距离
float mAngleOuterCone; // 外角弧度
Vector3 mDirection; // 方向 点光源无用
// 把光的基础颜色分成三种比较有针对性
Color4 mColorAmbient; // 环境光的颜色
Color4 mColorDiffuse; // 漫反射光的颜色
Color4 mColorSpecular; // 镜面光的颜色
};
// 材质
struct MaterialBuffer
{
Vector3 cameraPosition; //摄像机的位置
float shininess; //高光指数
Quaternion Ke; //材质的自发光
Quaternion Ka; //材质的环境光系数
Quaternion Kd; //材质的漫反射系数
Quaternion Ks; //材质的高光系数
};
2.ps:此实现是在ps里面实现的光照,vs里面基本无实现内容
////////////////////////////////////////////////////////////////////////////////
// Pixel Shader
////////////////////////////////////////////////////////////////////////////////
float4 PortPixelShader(PixelInputType input) : SV_TARGET
{
float4 resultColor = float4(0,0,0,1.0);
float4 colorDiffuse = mColorDiffuse; // 漫反射
float4 colorSpecular = mColorSpecular; // 镜面反射
float3 N = input.worldNormal; // 法向量
float3 L = float3(0,0,0); //光线向量
float3 V = cameraPosition - input.worldPosition.xyz; // 世界坐标指向相机(注意方向)
//1.自发光
resultColor = resultColor + Ke;
//2.环境光
resultColor = resultColor + Ka * mColorAmbient; // 对位相乘 (x1*y1,x2*y2,x3*y3,x4*y4)
int type = mType;
float atte = 1.0; // 衰减系数
float d = distance(mPosition, input.worldPosition.xyz); // 光源与点的距离
switch(type)
{
case 1: // 平行光源
L = mDirection;
break;
case 2: // 点光源
L = mPosition - input.worldPosition.xyz; // 方向为空间点-->光源
atte = 1 / (mAttenuation.x + mAttenuation.y * d + mAttenuation.z * d * d);
//atte = 1 / (1 + 0.01 * d + 0.0001 * d * d);
break;
case 3: // 锥形光源
L = mPosition - input.worldPosition.xyz; // 与点光源一致
atte = 1 / (mAttenuation.x + mAttenuation.y * d + mAttenuation.z * d * d);
//θ<α<φ 利用cos值进行比较,并且锥形外角小于PI
L = normalize(L);
float3 direction = normalize(mDirection); // 光源的方向,归一化
float cosa = dot(L, direction);
float coso = cos(mAngleOuterCone);
if(cosa<cos(mAngleInnerCone) && cosa>coso) // 半影区
{
atte = atte*(cosa - coso); // 利用余弦值来
}else if(cosa<coso)
{
atte = 0;
}
break;
default:
break;
}
// 对向量进行归一化
N = normalize(N);
L = normalize(L);
V = normalize(V);
//3.漫反射
float diff = max(dot(L, N),0); // L.N 点积,因为镜面反射会用到,这里提取出来。
resultColor = resultColor + Kd * colorDiffuse * diff * atte; // 漫反射公式:Dintensity*Dcolor *N.L,saturate保障值为[0,1]闭区间
//4.镜面反射
float3 R = normalize(2 * diff * N - L); // 这里求的是反射向量
resultColor = resultColor + Ks * colorSpecular * atte * pow(saturate(dot(R, V)), shininess); // R.V^n 高光指数在这里用上了
return resultColor;
}
基本思路,先算衰减值,然后再计算光照。
分享到:
相关推荐
phong模型(简单光照模型) 对球体光照模型
计算机图形学上机实验:基本光照、材质和纹理的应用与实现 1、实验目的: 掌握OpenGL光照、材质和纹理的应用和程序实现; 熟悉使用MFC及OPENGL。...要求四:理解材质与光源的RGB的关系,掌握简单光照模型的程序实现。
此为计算机图形学球的光照模型的课程设计,内有完整代码可直接运行,运行环境为VC6.0,本次课程设计通过构建MFC工程实现了操作界面的可视化,绘制了一个球体,并可通过菜单选项控制显示效果,进行光照模型、材质、...
实现了Bezier曲面,控制其旋转,并配有阴影生成及光照
这是我的计算机图形学实验,程序使用了NeHe的框架,通过读取一个PLY文件中的数据生成了一个兔子,有完整的鼠标和键盘交互,包括旋转、平移、光照等,不足之处是立体感不足,光照范围有限,开头的数组定义方法也很...
Bezier曲面的创建并实现简单的纹理和光照模型
内含场景移动操作,基础光照光源,材质和shader的实现,可直接运行。
交叉,怀旧,光照,漏光。做的不好,仅供参考。 主要是用来实现图像的各种特殊效果。它在Photoshop中具有非常神奇的作用。所有的滤镜在Photoshop中都按分类放置在菜单中,使用时只需要从该菜单中执行这命令即可。...
计算机图形学-球的光照模型,有代码完美运行,有课程设计书
STM32温湿度光照采集程序IIC,实现了STM32通过IIC采集温湿度,光照的功能,例程清晰简单,实用。
opengl中的简单图形 通过鼠标控制旋转 另有glui菜单可缩放 添加光照等,有exe文件和cpp文件
利用visual studio 2005 opengl 实现光照模型。简单的实现光照模型。
Simulink绘制光伏在不同温度、不同光照强度下UI和PU特性曲线 简单易上手,可以根据自己的需要调整参数,并且代码注释很多
使用C++实现Phong光照模型
在FXCOMPOSER2.5上实现的延迟光照模型,可直接使用
现在这个,里面有一个简单的基于face的数据结构,用于保存读入的数据。 并且对读入的数据进行openGL显示,可以旋转,缩放,平移。 旋转:按下鼠标左键 拖动 缩放:鼠标滚轮上下滚动 平移:鼠标左键按下平移鼠标 以及...
可以通过简单的函数快速实现点光源的光照 并且可以调整点光源的大小,范围,位置,以及最小像素和最小强度 当你需要一个点光源的光照时,可以使用。 详情可以看里面的注释 需要说明的是,此光照采用实时渲染,所以...
基于stm32f103zet6的光照强度传感器例程,在IIC的例程上进行修改,并最终实现了对光照强度的读取和显示。简单易懂,便于移植
这是我学习shadowmap用的事例,它是基于directx sdk里的方法实现的,比较简单,会有锯齿效果,需要另外用PCF处理。