您当前的位置: 首页 >  ar

Jave.Lin

暂无认证

  • 3浏览

    0关注

    704博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

LearnGL - 17 - Geometry Shader - 几何着色器

Jave.Lin 发布时间:2020-09-01 16:18:47 ,浏览量:3

文章目录
  • 示例1
    • Vertex Shader
    • Geometry Shader
    • Fragment Shader
    • 运行效果
  • 几何着色器在管线的位置
  • Geometry Shader 中主要部分
    • 接受的输入图元类型
    • 接受的输出图元类型
  • 示例2
    • Vertex Shader
    • Geomestry Shader
    • Fragment Shader
    • 运行效果
  • 示例3 - 显示顶点法线
    • 实现思路
    • 应用层代码
    • Vertex Shader
    • Geometry Shader
    • Fragment Shader
    • 运行效果
  • Fur Shading
  • References

LearnGL - 学习笔记目录

由于时间关系,没能详细的编写几何着色器相关的内容

几何着色器的学习也是早在差不多一个月前完整了,现在才有空补上

示例1

加载网格部分,顶点数据有:位置、颜色信息

			GLfloat temp_vertices[4 * 3] = {
				-0.5f, +0.5f, 0.0f,
				+0.5f, +0.5f, 0.0f,
				+0.5f, -0.5f, 0.0f,
				-0.5f, -0.5f, 0.0f,
			};

			GLfloat temp_colors[4 * 4] = {
				1.0f, 0.0f, 0.0f, 1.0f,
				0.0f, 1.0f, 0.0f, 1.0f,
				0.0f, 0.0f, 1.0f, 1.0f,
				1.0f, 1.0f, 0.0f, 1.0f,
			};

			GLuint temp_indices[4] = {
				0, 1, 2, 3
			};

			mesh->pos_copy_from(temp_vertices, sizeof(temp_vertices) / sizeof(temp_vertices[0]));
			mesh->color_copy_from(temp_colors, sizeof(temp_colors) / sizeof(temp_colors[0]));
			mesh->indices_copy_from(temp_indices, sizeof(temp_indices) / sizeof(temp_indices[0]));

			ReferMgr::setObj(mesh_ref_name.c_str(), mesh);
			memcpy(mesh->name, mesh_ref_name.c_str(), mesh_ref_name.size() + 1);

			mesh->primiveType = DrawState_PrimitiveType::POINTS;

加载着色器

		// material - shader
		std::string shader_ref_name = "TestingGeometryShader\\testing_geometry_shader";
		shader = ReferMgr::getObj(shader_ref_name.c_str());
		if (shader == NULL) {
			shader = new ShaderProgram(shader_ref_name.c_str());
			char vs_path[MAX_PATH], fs_path[MAX_PATH], gs_path[MAX_PATH];
			g_GetShaderPathCallback(vs_path, "TestingGeometryShader\\testing_geometry_shader.vert");
			g_GetShaderPathCallback(fs_path, "TestingGeometryShader\\testing_geometry_shader.frag");
			g_GetShaderPathCallback(gs_path, "TestingGeometryShader\\testing_geometry_shader.geom");
			if (!shader->initByPath(vs_path, fs_path, "", "", gs_path)) {
				std::cout initByPath(vs_path, fs_path)) {
					std::cout ref_name = ref_name;
				setting->set_texture_obj(main_tex);
				setting->name = "main_tex";
			}

			pass->enabledDepthWrite = false;
			pass->enabledBlend = true;
			pass->blendSrcFactor = DrawState_BlendFactorType::SRC_ALPHA;
			pass->blendDstFactor = DrawState_BlendFactorType::ONE_MINUS_SRC_ALPHA;
			pass->SrcRefractionK = 1.00f;
			pass->DstRefractionK = 1.52f;
			pass->UseTexAlpha = false;
			pass->Alpha = 0.80f;
			pass->ReflectionK = 1.0f;
			pass->RefractionK = 0.5f;
			pass->glossy = 100.0f;
		}

		// pass1
		{
			// material - shader1
			std::string shader_ref_name = "TestingGeometryShaderDisplayNormals\\testing_geometry_shader_display_normals";
			shader1 = ReferMgr::getObj(shader_ref_name.c_str());
			if (shader1 == NULL) {
				shader1 = new ShaderProgram(shader_ref_name.c_str());
				char vs_path[MAX_PATH], fs_path[MAX_PATH], gs_path[MAX_PATH];
				g_GetShaderPathCallback(vs_path, "TestingGeometryShaderDisplayNormals\\testing_geometry_shader_display_normals.vert");
				g_GetShaderPathCallback(fs_path, "TestingGeometryShaderDisplayNormals\\testing_geometry_shader_display_normals.frag");
				g_GetShaderPathCallback(gs_path, "TestingGeometryShaderDisplayNormals\\testing_geometry_shader_display_normals.geom");
				if (!shader1->initByPath(vs_path, fs_path, "", "", gs_path)) {
					std::cout getTrans()->local_position = vec3(1.2f, 0, i);
		temp_go->getTrans()->local_position = vec3(0.0f, 0.0f, 0.0f);
		temp_go->getTrans()->local_scale = vec3(1, 1, 1);
		MyGeometryShader_Testing_Display_Normals* temp_comp = new MyGeometryShader_Testing_Display_Normals();
		temp_comp->mesh_name = "Testing_Cube.m";
		temp_go->addComp(temp_comp);
		SceneMgr::inst()->getRoot()->add(temp_go);
	}
	{
		// Sphere
		GameObject* temp_go = new GameObject();
		sprintf_s(name, "%s##%d", "GeemetryShaderTestingDisplayNormals", temp_go->id());
		temp_go->set_name_copy_from(name);
		//temp_go->getTrans()->local_position = vec3(1.2f, 0, i);
		temp_go->getTrans()->local_position = vec3(1.0f, 0.0f, 0.0f);
		temp_go->getTrans()->local_scale = vec3(1, 1, 1);
		MyGeometryShader_Testing_Display_Normals* temp_comp = new MyGeometryShader_Testing_Display_Normals();
		temp_comp->mesh_name = "Sphere_637003627289014299.m";
		temp_go->addComp(temp_comp);
		SceneMgr::inst()->getRoot()->add(temp_go);
	}
	{
		// cube
		GameObject* temp_go = new GameObject();
		sprintf_s(name, "%s##%d", "GeemetryShaderTestingDisplayNormals", temp_go->id());
		temp_go->set_name_copy_from(name);
		//temp_go->getTrans()->local_position = vec3(1.2f, 0, i);
		temp_go->getTrans()->local_position = vec3(2.0f, 0.0f, 0.0f);
		temp_go->getTrans()->local_scale = vec3(1, 1, 1);
		MyGeometryShader_Testing_Display_Normals* temp_comp = new MyGeometryShader_Testing_Display_Normals();
		temp_comp->mesh_name = "BalloonStupidCat_637003750150312129.m";
		temp_go->addComp(temp_comp);
		SceneMgr::inst()->getRoot()->add(temp_go);
	}
Vertex Shader
// jave.lin - testing_geometry_shader.vert
#version 450 compatibility
#extension GL_ARB_shading_language_include : require
#include "/Include/my_global.glsl"

in vec3 vPos;
in vec3 vNormal;

out VS_OUT {
    vec3 normal;
};

void main() {
    normal = ObjectToWorldNormal(vNormal);	// 将模型空间的法线 转换到 世界坐标顶点法线
    gl_Position = mMat * vec4(vPos, 1.0);   // 世界坐标
}
Geometry Shader
// jave.lin - testing_geometry_shader.geos
#version 450 compatibility
#extension GL_ARB_shading_language_include : require
#include "/Include/my_global.glsl"

layout (triangles) in;
layout (line_strip, max_vertices = 2 * 3) out;

// 下面 in/out 是用 interface block 接口块来传输数据
in VS_OUT {         // Vertex Shader 的输出
    vec3 normal;
} gs_in[];

out GS_OUT {        // Geometry Shader 的输出
    vec4 col;
};

// 外部可控的 uniform
uniform float normal_line_len = 1;  // 法线的长度
uniform int normal_type = 1;        // 法线类型,0:三角面中心显示,1:面个顶点都显示

void center_point_normal_line() {
    vec3 vec_1 = (gl_in[1].gl_Position - gl_in[0].gl_Position).xyz;
    vec3 vec_2 = (gl_in[2].gl_Position - gl_in[0].gl_Position).xyz;
    vec3 normal_vec = normalize(cross(vec_1, vec_2));

    vec4 centerPos = (
        gl_in[0].gl_Position +
        gl_in[1].gl_Position +
        gl_in[2].gl_Position) / 3.0;
    
    gl_Position = pMat * vMat * centerPos;
    EmitVertex();
    
    gl_Position = pMat * vMat * vec4(centerPos.xyz + (normal_vec * normal_line_len), centerPos.w);
    EmitVertex();

    EndPrimitive();
}

void point_normal_line(int idx) {
    gl_Position = pMat * vMat * gl_in[idx].gl_Position;
    col = vec4(0, 0.5, 1, 1);   // 法线头部颜色,浅蓝色
    EmitVertex();
    gl_Position = pMat * vMat * vec4(gl_in[idx].gl_Position.xyz + (gs_in[idx].normal * normal_line_len), 1);
    col = vec4(1);              // 法线尾部颜色,白色,便于查看法线是否正确
    EmitVertex();
    EndPrimitive();
}

void per_point_normal_line() {
    point_normal_line(0);
    point_normal_line(1);
    point_normal_line(2);
}

void main() {
    if (normal_type == 0) {
        // 三角面中心
        center_point_normal_line();
    } else {
        // 每个顶点
        per_point_normal_line();
    }
}
Fragment Shader
// jave.lin - testing_geometry_shader.frag
#version 450 compatibility

in GS_OUT {
    vec4 col;
};

void main() {
    gl_FragColor = col;
}
运行效果

在这里插入图片描述

Fur Shading

在 OpenGL 第9版本的红宝书 中,还有使用 Geometry Shader 来使用 fur shading(毛发着色)

后面如果有空,我也会去尝试一下

References
  • OpenGL 编程指南 - 红宝书 - 第9版 - 第10章 - 393 页
  • 几何着色器
关注
打赏
1664331872
查看更多评论
立即登录/注册

微信扫码登录

0.0665s