示例#1
1
frag_color phong_tangent_space_shader::fragment(
        const vec3& bary,
        const mat3& verts,
        const mat3x2& tex_coords,
        const mat3& vert_norms) const
{
    auto uv = bary_lerp(tex_coords[0], tex_coords[1], tex_coords[2], bary);
    auto objspace_norm = bary_lerp(vert_norms[0], vert_norms[1], vert_norms[2], bary);
    auto ts_normval = normalmap.get_from_ratio(uv[0], uv[1]);
    auto tanspace_norm = normalize(vec3(ts_normval.r - 127.5,
                                        ts_normval.g - 127.5,
                                        ts_normval.b - 127.5));

    // objspace and texture space verts
    auto o1 = verts[1] - verts[0];
    auto o2 = verts[2] - verts[0];
    auto t1 = tex_coords[1] - tex_coords[0];
    auto t2 = tex_coords[2] - tex_coords[0];

    auto tanspace_mat = mat2(t1.x, t2.x,
                             t1.y, t2.y);
    auto objspace_mat = mat3x2(o1.x, o2.x,
                               o1.y, o2.y,
                               o1.z, o2.z);

    // S * t1.x + T * t1.y = o1
    // S * t2.x + T * t2.y = o2
    //
    // [t1.x    t1.y]  *  [tan      =  [o1.x    o1.y   o1.z]
    //  t2.x    t2.y]      bitan]       o2.x    o2.y   o2.z]
    //
    //  tanspace_mat * tan_bitan_mat = objspace_mat
    //  inverse(tanspace_mat) * tanspace_mat * tan_bitan_mat = inverse(tanspace_mat) * objspace_mat
    //  I * tan_bitan_mat = inverse(tansapce_mat) * objspace_mat
    //  tan_bitan_mat = inverse(tanspace_mat) * objspace_mat
    auto tan_bitan_mat = transpose(inverse(tanspace_mat) * objspace_mat);
    auto tan_to_objspace = mat3(normalize(tan_bitan_mat[0]),
                                normalize(tan_bitan_mat[1]),
                                normalize(objspace_norm));
    auto norm = normalize(tan_to_objspace * tanspace_norm);

    // ambient color
    TGAColor ambient(5, 5, 5, 255);

    // specular color
    auto spec_val = specular.get_from_ratio(uv[0], uv[1]).raw[0];
    auto r = normalize(reflect(light_dir(), norm));
    auto spec_intensity = pow(max(0.0f, dot(r, to_cam)), spec_val);

    // diffuse color
    float diff_intensity = max(0.0f, dot(to_light(), norm));
    auto diff_color = diffuse.get_from_ratio(uv[0], uv[1]);

    diff_color.scale(diff_intensity + spec_intensity * .6);

    return frag_color {ambient + diff_color, true};
}
void GuiMeshRender::ProcessEntities(const EntityMap &entities) {

	if (entities.empty()) {
		//printf("Warning: GuiMeshRender: Entity list is empty\n");
		return;
	}

	EntityMap::const_iterator it, ite;

	GuiMeshPtr mesh;
	TransformPtr transform;

	mat4 model, view, projection, model_view, mvp;
	mat3 normal;

	// warning: make sure the values here are all floats
	projection = glm::ortho(0.0f, 800.0f, 600.0f, 0.0f, -1.0f, 1.0f);

	for (it = entities.begin(), ite = entities.end(); it != ite; ++it) {
		mesh = gui_mesh_mapper_(it->second);
		transform = transform_mapper_(it->second);

		model = transform->world();
		model_view = model;				// camera does not need to effect this
		mvp = projection * model_view;
		normal = inverse(transpose(mat3(model_view)));

		shared_ptr<BasicMaterial> material = boost::dynamic_pointer_cast<BasicMaterial>(mesh->material);

		vec4 light_pos = material->light_position_;

		// hack to have light move with world
		// todo: implement light as entity
		material->light_position_ = model_view * light_pos;

		// do things like setup colors and lights
		// and attach shader program
		mesh->material->PreRender();

		material->light_position_ = light_pos;

		// push matrices up
		mesh->material->PushMatrices(model_view, projection, mvp, normal);

		// call draw
		mesh->geometry->Draw();

		// let go of shader program
		mesh->material->PostRender();
	}
}