OpenGL学习笔记(十)Material类(材质)

在真实世界里,每个物体会对光产生不同的反应。钢看起来比陶瓷花瓶更闪闪发光,一个木头箱子不会像钢箱子一样对光产生很强的反射。每个物体对镜面高光也有不同的反应。有些物体不会散射(Scatter)很多光却会反射(Reflect)很多光,结果看起来就有一个较小的高光点(Highlight),有些物体散射了很多,它们就会产生一个半径更大的高光。如果我们想要在OpenGL中模拟多种类型的物体,我们必须为每个物体分别定义材质(Material)属性。
所以我们来写一个Material类来控制Material吧!
先是fragmentSource.txt

#version 330 core			
out vec4 FragColor;		
in vec3 FragPos;
in vec3 Normal;
//设置一个材质结构体
struct Material{
vec3 ambient;//环境
vec3 diffuse;//漫反射
vec3 specular;//镜面反射
float shininess;//镜面反射光泽
};
uniform Material material;//声明一个材质球
uniform vec3 objColor;
uniform vec3 ambientColor;
uniform vec3 lightPos;
uniform vec3 lightColor;
uniform vec3 CameraPos;
void main()				
{
vec3 norm=normalize(Normal);

vec3 lightDir=normalize(lightPos-FragPos);
vec3 diffuse =max(dot(norm,lightDir), 0.0f) * lightColor*material.diffuse;//通过diffuse控制漫反射强度

vec3 reflectVec=reflect(-lightDir,norm);
vec3 CameraVec=normalize(CameraPos-FragPos);
vec3 specular=pow(max(dot(reflectVec,CameraVec),0.0f),material.shininess)*lightColor*material.specular;//通过shininess和specular控制镜面反射强度
vec3 ambient=ambientColor*material.ambient;//通过ambient控制环境光强度
vec3 result=(ambient+diffuse+specular)*objColor;//计算更改过后的整体光照

FragColor = vec4(result,1.0f);
}	

Material.h

#pragma once
#include "Shader.h"
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
class Material
{
public:
	Shader* shader;//材质球需要确定对哪个shader进行操作
	glm::vec3 ambient;//环境光控制
	glm::vec3 diffuse; //漫反射控制
	glm::vec3 specular; //镜面反射控制
	float shininess;镜面反射光泽
	Material(Shader* _shader, glm::vec3 _ambient, glm::vec3 _diffuse, glm::vec3 _specular, float _shininess);
};

Material.cpp

#include "Material.h"

Material::Material(Shader* _shader, glm::vec3 _ambient, glm::vec3 _diffuse, glm::vec3 _specular, float _shininess)
	:shader(_shader),ambient(_ambient),diffuse(_diffuse),specular(_specular),shininess(_shininess)//构造函数
{
}

还需要改一下Shader类
Shader.h增加

public:
	void SetUniform3f(const char* paramNameString, glm::vec3 param);
	void SetUniform1f(const char* paramNameString, float param);

Shader.cpp

void Shader::SetUniform3f(const char* paramNameString, glm::vec3 param)//通过直接给予一个vec3传入uniform参数
{ 
	glUniform3f(glGetUniformLocation(ID, paramNameString), param.x, param.y, param.z);
}
void Shader::SetUniform1f(const char* paramNameString, float param)//只是为了队形统一
{
	glUniform1f(glGetUniformLocation(ID, paramNameString), param);

然后是主函数
main.cpp
循环外面:

Material* myMaterial = new Material(myShader,
		glm::vec3(1.0f,1.0f,1.0f),
		glm::vec3(0.0f, 0.0f, 1.0f),
		glm::vec3(0.0f, 1.0f, 0.0f),
		32.0f
		);//声明一个Material

循环里面:

	         glm::vec3 lightColor;//控制灯光的向量
			lightColor.x = sin(glfwGetTime()* 2.0f);//通过时间改变灯光的红色
			lightColor.y = sin(glfwGetTime() * 0.7f);//通过时间改变灯光的绿色
			lightColor.z = sin(glfwGetTime() * 1.3f);//通过时间改变灯光的蓝色
			glm::vec3 diffuseColor = lightColor * glm::vec3(0.5f);//通过改变后的灯光颜色同时改变漫反射颜色
			glm::vec3 specularColor = diffuseColor * glm::vec3(1.0f);//同时改变镜面反射颜色
            //控制材质球的变量
			glUniform3f(glGetUniformLocation(myShader->ID, "lightColor"), lightColor.x, lightColor.y, lightColor.z);
			myMaterial->shader->SetUniform3f("material.ambient", myMaterial->ambient);
			myMaterial->shader->SetUniform3f("material.diffuse", diffuseColor);
			myMaterial->shader->SetUniform3f("material.specular", specularColor);
			myMaterial->shader->SetUniform1f("material.shininess", myMaterial->shininess);

最终效果图,不会放视频,只能截图啦:



 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值