Пример #1
0
	void RenderableLineBox::Init()
	{
		RenderFactory& rf = Context::Instance().RenderFactoryInstance();

		RenderEffectPtr effect = SyncLoadRenderEffect("RenderableHelper.fxml");
		technique_ = simple_forward_tech_ = effect->TechniqueByName("LineTec");
		v0_ep_ = effect->ParameterByName("v0");
		v1_ep_ = effect->ParameterByName("v1");
		v2_ep_ = effect->ParameterByName("v2");
		v3_ep_ = effect->ParameterByName("v3");
		v4_ep_ = effect->ParameterByName("v4");
		v5_ep_ = effect->ParameterByName("v5");
		v6_ep_ = effect->ParameterByName("v6");
		v7_ep_ = effect->ParameterByName("v7");
		color_ep_ = effect->ParameterByName("color");
		mvp_param_ = effect->ParameterByName("mvp");

		float vertices[] =
		{
			0, 1, 2, 3, 4, 5, 6, 7
		};

		uint16_t indices[] =
		{
			0, 1, 1, 3, 3, 2, 2, 0,
			4, 5, 5, 7, 7, 6, 6, 4,
			0, 4, 1, 5, 2, 6, 3, 7
		};

		rl_ = rf.MakeRenderLayout();
		rl_->TopologyType(RenderLayout::TT_LineList);

		ElementInitData init_data;
		init_data.row_pitch = sizeof(vertices);
		init_data.slice_pitch = 0;
		init_data.data = vertices;

		GraphicsBufferPtr vb = rf.MakeVertexBuffer(BU_Static, EAH_GPU_Read | EAH_Immutable, &init_data);
		rl_->BindVertexStream(vb, make_tuple(vertex_element(VEU_Position, 0, EF_R32F)));

		init_data.row_pitch = sizeof(indices);
		init_data.slice_pitch = 0;
		init_data.data = indices;

		GraphicsBufferPtr ib = rf.MakeIndexBuffer(BU_Static, EAH_GPU_Read | EAH_Immutable, &init_data);
		rl_->BindIndexStream(ib, EF_R16UI);

		tc_aabb_ = AABBox(float3(0, 0, 0), float3(0, 0, 0));

		*(effect->ParameterByName("pos_center")) = float3(0, 0, 0);
		*(effect->ParameterByName("pos_extent")) = float3(1, 1, 1);

		effect_attrs_ |= EA_SimpleForward;
	}
Пример #2
0
void OCTree::DivideNode(size_t index, uint32_t curr_depth)
{
    if (octree_[index].obj_ptrs.size() > 1)
    {
        size_t const this_size = octree_.size();
        AABBox const parent_bb = octree_[index].bb;
        float3 const parent_center = parent_bb.Center();
        octree_[index].first_child_index = static_cast<int>(this_size);
        octree_[index].visible = BO_No;

        octree_.resize(this_size + 8);
        for (SceneObjsType::const_reference so : octree_[index].obj_ptrs)
        {
            AABBox const & aabb = *so->PosBoundWS();
            int mark[6];
            mark[0] = aabb.Min().x() >= parent_center.x() ? 1 : 0;
            mark[1] = aabb.Min().y() >= parent_center.y() ? 2 : 0;
            mark[2] = aabb.Min().z() >= parent_center.z() ? 4 : 0;
            mark[3] = aabb.Max().x() >= parent_center.x() ? 1 : 0;
            mark[4] = aabb.Max().y() >= parent_center.y() ? 2 : 0;
            mark[5] = aabb.Max().z() >= parent_center.z() ? 4 : 0;
            for (int j = 0; j < 8; ++ j)
            {
                if (j == ((j & 1) ? mark[3] : mark[0])
                        + ((j & 2) ? mark[4] : mark[1])
                        + ((j & 4) ? mark[5] : mark[2]))
                {
                    octree_[this_size + j].obj_ptrs.push_back(so);
                }
            }
        }

        for (size_t j = 0; j < 8; ++ j)
        {
            octree_node_t& new_node = octree_[this_size + j];
            new_node.first_child_index = -1;
            new_node.bb = AABBox(float3((j & 1) ? parent_center.x() : parent_bb.Min().x(),
                                        (j & 2) ? parent_center.y() : parent_bb.Min().y(),
                                        (j & 4) ? parent_center.z() : parent_bb.Min().z()),
                                 float3((j & 1) ? parent_bb.Max().x() : parent_center.x(),
                                        (j & 2) ? parent_bb.Max().y() : parent_center.y(),
                                        (j & 4) ? parent_bb.Max().z() : parent_center.z()));

            if (curr_depth < max_tree_depth_)
            {
                this->DivideNode(this_size + j, curr_depth + 1);
            }
        }

        SceneObjsType empty;
        octree_[index].obj_ptrs.swap(empty);
    }
}
Пример #3
0
	RenderableSkyBox::RenderableSkyBox()
		: RenderableHelper(L"SkyBox")
	{
		RenderFactory& rf = Context::Instance().RenderFactoryInstance();

		RenderEffectPtr effect = SyncLoadRenderEffect("SkyBox.fxml");
		if (deferred_effect_)
		{
			this->BindDeferredEffect(effect);
			depth_tech_ = effect->TechniqueByName("DepthSkyBoxTech");
			gbuffer_rt0_tech_ = effect->TechniqueByName("GBufferSkyBoxRT0Tech");
			gbuffer_rt1_tech_ = effect->TechniqueByName("GBufferSkyBoxRT1Tech");
			gbuffer_mrt_tech_ = effect->TechniqueByName("GBufferSkyBoxMRTTech");
			special_shading_tech_ = effect->TechniqueByName("SkyBoxTech");
			this->Technique(gbuffer_rt0_tech_);

			effect_attrs_ |= EA_SpecialShading;
		}
		else
		{
			this->Technique(effect->TechniqueByName("SkyBoxTech"));
		}

		float3 xyzs[] =
		{
			float3(1.0f, 1.0f, 1.0f),
			float3(1.0f, -1.0f, 1.0f),
			float3(-1.0f, 1.0f, 1.0f),
			float3(-1.0f, -1.0f, 1.0f),
		};

		ElementInitData init_data;
		init_data.row_pitch = sizeof(xyzs);
		init_data.slice_pitch = 0;
		init_data.data = xyzs;

		rl_ = rf.MakeRenderLayout();
		rl_->TopologyType(RenderLayout::TT_TriangleStrip);

		GraphicsBufferPtr vb = rf.MakeVertexBuffer(BU_Static, EAH_GPU_Read | EAH_Immutable, &init_data);
		rl_->BindVertexStream(vb, make_tuple(vertex_element(VEU_Position, 0, EF_BGR32F)));

		pos_aabb_ = MathLib::compute_aabbox(&xyzs[0], &xyzs[4]);
		tc_aabb_ = AABBox(float3(0, 0, 0), float3(0, 0, 0));
	}
Пример #4
0
	void PSSMCascadedShadowLayer::UpdateCascades(Camera const & camera, float4x4 const & light_view_proj,
			float3 const & light_space_border)
	{
		float const range = camera.FarPlane() - camera.NearPlane();
		float const ratio = camera.FarPlane() / camera.NearPlane();

		std::vector<float> distances(intervals_.size() + 1);
		for (size_t i = 0; i < intervals_.size(); ++ i)
		{
			float p = i / static_cast<float>(intervals_.size());
			float log = camera.NearPlane() * std::pow(ratio, p);
			float uniform = camera.NearPlane() + range * p;
			distances[i] = lambda_ * (log - uniform) + uniform;
		}
		distances[intervals_.size()] = camera.FarPlane();

		for (size_t i = 0; i < intervals_.size(); ++ i)
		{
			AABBox aabb = CalcFrustumExtents(camera, distances[i], distances[i + 1],
								  light_view_proj);

			aabb &= AABBox(float3(-1, -1, -1), float3(+1, +1, +1));

			aabb.Min() -= light_space_border;
			aabb.Max() += light_space_border;

			aabb.Min().x() = +aabb.Min().x() * 0.5f + 0.5f;
			aabb.Min().y() = -aabb.Min().y() * 0.5f + 0.5f;
			aabb.Max().x() = +aabb.Max().x() * 0.5f + 0.5f;
			aabb.Max().y() = -aabb.Max().y() * 0.5f + 0.5f;

			std::swap(aabb.Min().y(), aabb.Max().y());

			float3 const scale = float3(1.0f, 1.0f, 1.0f) / (aabb.Max() - aabb.Min());
			float3 const bias = -aabb.Min() * scale;

			intervals_[i] = float2(distances[i], distances[i + 1]);
			scales_[i] = scale;
			biases_[i] = bias;
		}

		this->UpdateCropMats();
	}
Пример #5
0
Sphere::Sphere(const double radius)
	: Geometry(AABBox(Point(-radius,-radius,-radius), Point(radius,radius,radius))), m_radius(radius)
{
	m_radiusSqFixed = (m_radius-Ray::default_tmin)*(m_radius-Ray::default_tmin);
}
Пример #6
0
	void SDSMCascadedShadowLayer::UpdateCascades(Camera const & camera, float4x4 const & light_view_proj,
			float3 const & light_space_border)
	{
		RenderFactory& rf = Context::Instance().RenderFactoryInstance();
		RenderEngine& re = rf.RenderEngineInstance();

		uint32_t const num_cascades = static_cast<uint32_t>(intervals_.size());
		uint32_t const copy_index = frame_index_ & 1;
		uint32_t const read_back_index = (0 == frame_index_) ? copy_index : !copy_index;

		if (cs_support_)
		{
			re.BindFrameBuffer(FrameBufferPtr());

			float max_blur_light_space = 8.0f / 1024;
			float3 max_cascade_scale(max_blur_light_space / light_space_border.x(),
				max_blur_light_space / light_space_border.y(),
				std::numeric_limits<float>::max());

			int const TILE_DIM = 128;

			int dispatch_x = (depth_tex_->Width(0) + TILE_DIM - 1) / TILE_DIM;
			int dispatch_y = (depth_tex_->Height(0) + TILE_DIM - 1) / TILE_DIM;

			*interval_buff_param_ = interval_buff_;
			*interval_buff_uint_param_ = interval_buff_;
			*interval_buff_read_param_ = interval_buff_;
			*cascade_min_buff_uint_param_ = cascade_min_buff_;
			*cascade_max_buff_uint_param_ = cascade_max_buff_;
			*cascade_min_buff_read_param_ = cascade_min_buff_;
			*cascade_max_buff_read_param_ = cascade_max_buff_;
			*scale_buff_param_ = scale_buff_;
			*bias_buff_param_ = bias_buff_;
			*depth_tex_param_ = depth_tex_;
			*num_cascades_param_ = static_cast<int32_t>(num_cascades);
			*inv_depth_width_height_param_ = float2(1.0f / depth_tex_->Width(0), 1.0f / depth_tex_->Height(0));
			*near_far_param_ = float2(camera.NearPlane(), camera.FarPlane());
			float4x4 const & inv_proj = camera.InverseProjMatrix();
			float3 upper_left = MathLib::transform_coord(float3(-1, +1, 1), inv_proj);
			float3 upper_right = MathLib::transform_coord(float3(+1, +1, 1), inv_proj);
			float3 lower_left = MathLib::transform_coord(float3(-1, -1, 1), inv_proj);
			*upper_left_param_ = upper_left;
			*xy_dir_param_ = float2(upper_right.x() - upper_left.x(), lower_left.y() - upper_left.y());
			*view_to_light_view_proj_param_ = camera.InverseViewMatrix() * light_view_proj;
			*light_space_border_param_ = light_space_border;
			*max_cascade_scale_param_ = max_cascade_scale;

			re.Dispatch(*clear_z_bounds_tech_, 1, 1, 1);
			re.Dispatch(*reduce_z_bounds_from_depth_tech_, dispatch_x, dispatch_y, 1);
			re.Dispatch(*compute_log_cascades_from_z_bounds_tech_, 1, 1, 1);
			re.Dispatch(*clear_cascade_bounds_tech_, 1, 1, 1);
			re.Dispatch(*reduce_bounds_from_depth_tech_, dispatch_x, dispatch_y, 1);
			re.Dispatch(*compute_custom_cascades_tech_, 1, 1, 1);

			interval_buff_->CopyToBuffer(*interval_cpu_buffs_[copy_index]);
			scale_buff_->CopyToBuffer(*scale_cpu_buffs_[copy_index]);
			bias_buff_->CopyToBuffer(*bias_cpu_buffs_[copy_index]);

			GraphicsBuffer::Mapper interval_mapper(*interval_cpu_buffs_[read_back_index], BA_Read_Only);
			GraphicsBuffer::Mapper scale_mapper(*scale_cpu_buffs_[read_back_index], BA_Read_Only);
			GraphicsBuffer::Mapper bias_mapper(*bias_cpu_buffs_[read_back_index], BA_Read_Only);
			float2* interval_ptr = interval_mapper.Pointer<float2>();
			float3* scale_ptr = scale_mapper.Pointer<float3>();
			float3* bias_ptr = bias_mapper.Pointer<float3>();

			for (size_t i = 0; i < intervals_.size(); ++ i)
			{
				float3 const & scale = scale_ptr[i];
				float3 const & bias = bias_ptr[i];

				intervals_[i] = interval_ptr[i];
				scales_[i] = scale;
				biases_[i] = bias;
			}
		}
		else
		{
			float2 const near_far(camera.NearPlane(), camera.FarPlane());

			reduce_z_bounds_from_depth_pp_->SetParam(1, near_far);
			reduce_z_bounds_from_depth_pp_->Apply();

			for (uint32_t i = 1; i < depth_deriative_tex_->NumMipMaps(); ++ i)
			{
				int width = depth_deriative_tex_->Width(i - 1);
				int height = depth_deriative_tex_->Height(i - 1);

				float delta_x = 1.0f / width;
				float delta_y = 1.0f / height;
				float4 delta_offset(delta_x, delta_y, -delta_x / 2, -delta_y / 2);			
				reduce_z_bounds_from_depth_mip_map_pp_->SetParam(0, delta_offset);

				reduce_z_bounds_from_depth_mip_map_pp_->OutputPin(0, depth_deriative_small_tex_, i - 1);
				reduce_z_bounds_from_depth_mip_map_pp_->Apply();

				int sw = depth_deriative_tex_->Width(i);
				int sh = depth_deriative_tex_->Height(i);

				depth_deriative_small_tex_->CopyToSubTexture2D(*depth_deriative_tex_, 0, i, 0, 0, sw, sh,
					0, i - 1, 0, 0, sw, sh);
			}

			compute_log_cascades_from_z_bounds_pp_->SetParam(1, static_cast<int32_t>(num_cascades));
			compute_log_cascades_from_z_bounds_pp_->SetParam(2, near_far);
			compute_log_cascades_from_z_bounds_pp_->Apply();

			interval_tex_->CopyToSubTexture2D(*interval_cpu_texs_[copy_index], 0, 0, 0, 0, num_cascades, 1,
				0, 0, 0, 0, num_cascades, 1);

			Texture::Mapper interval_mapper(*interval_cpu_texs_[read_back_index], 0, 0,
				TMA_Read_Only, 0, 0, num_cascades, 1);
			Vector_T<half, 2>* interval_ptr = interval_mapper.Pointer<Vector_T<half, 2> >();

			for (size_t i = 0; i < intervals_.size(); ++ i)
			{
				float2 const interval(static_cast<float>(interval_ptr[i].x()),
					static_cast<float>(interval_ptr[i].y()));

				AABBox aabb = CalcFrustumExtents(camera, interval.x(), interval.y(), light_view_proj);

				aabb &= AABBox(float3(-1, -1, -1), float3(+1, +1, +1));

				aabb.Min() -= light_space_border;
				aabb.Max() += light_space_border;

				aabb.Min().x() = +aabb.Min().x() * 0.5f + 0.5f;
				aabb.Min().y() = -aabb.Min().y() * 0.5f + 0.5f;
				aabb.Max().x() = +aabb.Max().x() * 0.5f + 0.5f;
				aabb.Max().y() = -aabb.Max().y() * 0.5f + 0.5f;

				std::swap(aabb.Min().y(), aabb.Max().y());

				float3 const scale = float3(1.0f, 1.0f, 1.0f) / (aabb.Max() - aabb.Min());
				float3 const bias = -aabb.Min() * scale;

				intervals_[i] = interval;
				scales_[i] = scale;
				biases_[i] = bias;
			}
		}

		this->UpdateCropMats();

		++ frame_index_;
	}
Пример #7
0
	RenderDecal::RenderDecal(TexturePtr const & normal_tex, TexturePtr const & diffuse_tex, float3 const & diffuse_clr,
			TexturePtr const & specular_tex, float3 const & specular_level, float shininess)
		: RenderableHelper(L"Decal")
	{
		this->BindDeferredEffect(SyncLoadRenderEffect("Decal.fxml"));

		gbuffer_alpha_test_rt0_tech_ = deferred_effect_->TechniqueByName("DecalGBufferAlphaTestRT0Tech");
		gbuffer_alpha_test_rt1_tech_ = deferred_effect_->TechniqueByName("DecalGBufferAlphaTestRT1Tech");
		gbuffer_alpha_test_mrt_tech_ = deferred_effect_->TechniqueByName("DecalGBufferAlphaTestMRTTech");
		technique_ = gbuffer_alpha_test_rt0_tech_;

		pos_aabb_ = AABBox(float3(-1, -1, -1), float3(1, 1, 1));
		tc_aabb_ = AABBox(float3(0, 0, 0), float3(1, 1, 0));

		float3 xyzs[] =
		{
			pos_aabb_.Corner(0), pos_aabb_.Corner(1), pos_aabb_.Corner(2), pos_aabb_.Corner(3),
			pos_aabb_.Corner(4), pos_aabb_.Corner(5), pos_aabb_.Corner(6), pos_aabb_.Corner(7)
		};

		uint16_t indices[] =
		{
			0, 2, 3, 3, 1, 0,
			5, 7, 6, 6, 4, 5,
			4, 0, 1, 1, 5, 4,
			4, 6, 2, 2, 0, 4,
			2, 6, 7, 7, 3, 2,
			1, 3, 7, 7, 5, 1
		};

		RenderFactory& rf = Context::Instance().RenderFactoryInstance();
		rl_ = rf.MakeRenderLayout();
		rl_->TopologyType(RenderLayout::TT_TriangleList);

		ElementInitData init_data;
		init_data.row_pitch = sizeof(xyzs);
		init_data.slice_pitch = 0;
		init_data.data = xyzs;

		GraphicsBufferPtr vb = rf.MakeVertexBuffer(BU_Static, EAH_GPU_Read | EAH_Immutable, &init_data);
		rl_->BindVertexStream(vb, make_tuple(vertex_element(VEU_Position, 0, EF_BGR32F)));

		init_data.row_pitch = sizeof(indices);
		init_data.slice_pitch = 0;
		init_data.data = indices;

		GraphicsBufferPtr ib = rf.MakeIndexBuffer(BU_Static, EAH_GPU_Read | EAH_Immutable, &init_data);
		rl_->BindIndexStream(ib, EF_R16UI);

		model_mat_ = float4x4::Identity();
		effect_attrs_ |= EA_AlphaTest;

		inv_mv_ep_ = technique_->Effect().ParameterByName("inv_mv");
		g_buffer_rt0_tex_param_ = deferred_effect_->ParameterByName("g_buffer_rt0_tex");

		normal_tex_ = normal_tex;
		diffuse_tex_ = diffuse_tex;
		diffuse_clr_ = diffuse_clr;
		specular_tex_ = specular_tex;
		specular_level_ = specular_level.x();
		shininess_ = shininess;
	}
Пример #8
0
	RenderablePlane::RenderablePlane(float length, float width,
				int length_segs, int width_segs, bool has_tex_coord, bool has_tangent)
			: RenderableHelper(L"RenderablePlane")
	{
		RenderFactory& rf = Context::Instance().RenderFactoryInstance();

		rl_ = rf.MakeRenderLayout();
		rl_->TopologyType(RenderLayout::TT_TriangleList);

		std::vector<int16_t> positions;
		for (int y = 0; y < width_segs + 1; ++ y)
		{
			for (int x = 0; x < length_segs + 1; ++ x)
			{
				float3 pos(static_cast<float>(x) / length_segs, 1 - (static_cast<float>(y) / width_segs), 0.5f);
				int16_t s_pos[4] = 
				{
					static_cast<int16_t>(MathLib::clamp<int32_t>(static_cast<int32_t>(pos.x() * 65535 - 32768), -32768, 32767)),
					static_cast<int16_t>(MathLib::clamp<int32_t>(static_cast<int32_t>(pos.y() * 65535 - 32768), -32768, 32767)),
					static_cast<int16_t>(MathLib::clamp<int32_t>(static_cast<int32_t>(pos.z() * 65535 - 32768), -32768, 32767)),
					32767
				};

				positions.push_back(s_pos[0]);
				positions.push_back(s_pos[1]);
				positions.push_back(s_pos[2]);
				positions.push_back(s_pos[3]);
			}
		}

		ElementInitData init_data;
		init_data.row_pitch = static_cast<uint32_t>(positions.size() * sizeof(positions[0]));
		init_data.slice_pitch = 0;
		init_data.data = &positions[0];

		GraphicsBufferPtr pos_vb = rf.MakeVertexBuffer(BU_Static, EAH_GPU_Read | EAH_Immutable, &init_data);
		rl_->BindVertexStream(pos_vb, make_tuple(vertex_element(VEU_Position, 0, EF_SIGNED_ABGR16)));

		if (has_tex_coord)
		{
			std::vector<int16_t> tex_coords;
			for (int y = 0; y < width_segs + 1; ++ y)
			{
				for (int x = 0; x < length_segs + 1; ++ x)
				{
					float3 tex_coord(static_cast<float>(x) / length_segs * 0.5f + 0.5f,
						static_cast<float>(y) / width_segs * 0.5f + 0.5f, 0.5f);
					int16_t s_tc[2] = 
					{
						static_cast<int16_t>(MathLib::clamp<int32_t>(static_cast<int32_t>(tex_coord.x() * 65535 - 32768), -32768, 32767)),
						static_cast<int16_t>(MathLib::clamp<int32_t>(static_cast<int32_t>(tex_coord.y() * 65535 - 32768), -32768, 32767)),
					};

					tex_coords.push_back(s_tc[0]);
					tex_coords.push_back(s_tc[1]);
				}
			}

			init_data.row_pitch = static_cast<uint32_t>(tex_coords.size() * sizeof(tex_coords[0]));
			init_data.slice_pitch = 0;
			init_data.data = &tex_coords[0];

			GraphicsBufferPtr tex_vb = rf.MakeVertexBuffer(BU_Static, EAH_GPU_Read | EAH_Immutable, &init_data);
			rl_->BindVertexStream(tex_vb, make_tuple(vertex_element(VEU_TextureCoord, 0, EF_SIGNED_GR16)));
		}

		if (has_tangent)
		{
			std::vector<uint32_t> tangent(positions.size() / 4);
			ElementFormat fmt;
			if (rf.RenderEngineInstance().DeviceCaps().vertex_format_support(EF_ABGR8))
			{
				fmt = EF_ABGR8;
				tangent.assign(tangent.size(), 0x807F7FFE);
			}
			else
			{
				BOOST_ASSERT(rf.RenderEngineInstance().DeviceCaps().vertex_format_support(EF_ARGB8));

				fmt = EF_ARGB8;
				tangent.assign(tangent.size(), 0x80FE7F7F);
			}

			init_data.row_pitch = static_cast<uint32_t>(tangent.size() * sizeof(tangent[0]));
			init_data.slice_pitch = 0;
			init_data.data = &tangent[0];

			GraphicsBufferPtr tex_vb = rf.MakeVertexBuffer(BU_Static, EAH_GPU_Read | EAH_Immutable, &init_data);
			rl_->BindVertexStream(tex_vb, make_tuple(vertex_element(VEU_Tangent, 0, fmt)));
		}

		std::vector<uint16_t> index;
		for (int y = 0; y < width_segs; ++ y)
		{
			for (int x = 0; x < length_segs; ++ x)
			{
				index.push_back(static_cast<uint16_t>((y + 0) * (length_segs + 1) + (x + 0)));
				index.push_back(static_cast<uint16_t>((y + 0) * (length_segs + 1) + (x + 1)));
				index.push_back(static_cast<uint16_t>((y + 1) * (length_segs + 1) + (x + 1)));

				index.push_back(static_cast<uint16_t>((y + 1) * (length_segs + 1) + (x + 1)));
				index.push_back(static_cast<uint16_t>((y + 1) * (length_segs + 1) + (x + 0)));
				index.push_back(static_cast<uint16_t>((y + 0) * (length_segs + 1) + (x + 0)));
			}
		}

		init_data.row_pitch = static_cast<uint32_t>(index.size() * sizeof(index[0]));
		init_data.slice_pitch = 0;
		init_data.data = &index[0];

		GraphicsBufferPtr ib = rf.MakeIndexBuffer(BU_Static, EAH_GPU_Read | EAH_Immutable, &init_data);
		rl_->BindIndexStream(ib, EF_R16UI);

		pos_aabb_ = AABBox(float3(-length / 2, -width / 2, 0), float3(+length / 2, +width / 2, 0));
		tc_aabb_ = AABBox(float3(0, 0, 0), float3(1, 1, 0));
	}
Пример #9
0
inline bool YZRect::computeAABBox(float, float, AABBox& bbox) const
{
    bbox = AABBox(glm::vec3(_k-0.0001, _y_dim.x, _z_dim.x), glm::vec3(_k+0.0001, _y_dim.y, _z_dim.y));
    return true;
}
Пример #10
0
void ShadowMapRenderer::setupVirtualLightCamera(Camera* camera, DirectionalLightNode* lightNode, int cascadeIndex)
{
	const float BOUND_EXPAND_FACTOR = 0.8f;

	_Assert(camera != NULL);
	_Assert(cascadeIndex >= 0 && cascadeIndex < CASCADE_COUNTS);

	DirectionalLight* dirLight = lightNode->GetDirLight();
	Vector3 lightDir = dirLight->GetDirection();
	lightDir.Normalize();

	Vector3 frustumPos[5];
	{
		float farZ = 0;
		float aspect = 0;
		float fov = 0;

		camera->GetCameraParams(NULL, &farZ, &fov, &aspect);
		farZ *= calcCascadeDist(cascadeIndex);


		float fy = farZ * tanf(fov / 2.0f);
		float fx = aspect * fy;

		frustumPos[0] = Vector3::Zero;
		frustumPos[1] = Vector3(-fx,  fy, farZ);
		frustumPos[2] = Vector3( fx,  fy, farZ);
		frustumPos[3] = Vector3(-fx, -fy, farZ);
		frustumPos[4] = Vector3( fx, -fy, farZ);
	}

	D3DXMATRIX matCameraViewInv;
	D3DXMatrixInverse(&matCameraViewInv, 0, &camera->ViewMatrix());

	D3DXMATRIX matLightView;
	{
		Vector3 lightPos = lightNode->GetWorldPosition();

		D3DXMATRIX matRotTranspose, matTransInverse;
		D3DXMatrixTranspose(&matRotTranspose, &(lightNode->GetWorldOrient().Matrix()));
		D3DXMatrixTranslation(&matTransInverse, -lightPos.x, -lightPos.y, -lightPos.z);
		matLightView = matTransInverse * matRotTranspose; 
	}

	AABBox lightSpaceBound;
	for(int i = 0; i < 5; ++i)
	{
		Vector3 posW = PosVecTransform(frustumPos[i], matCameraViewInv);
		Vector3	posL = PosVecTransform(posW, matLightView);	

		lightSpaceBound = AABBox::CombinePoint(lightSpaceBound, posL);
	}

	float nearZ = 0.1f;
	float farZ = 0;
	float width = 0;
	float height = 0;
	{
		Vector3 lookDir = camera->GetWorldForward();
		lookDir.Normalize();

		float adjustFactor = lookDir.Dot(lightDir);		// lookDir与lightDir贴近时, 向后扩展virtualCamera范围
		float expandDist = adjustFactor * BOUND_EXPAND_FACTOR * fabsf(lightSpaceBound.mMax.z - lightSpaceBound.mMin.z);

		Vector3 centerL = lightSpaceBound.GetCenter();
		D3DXMATRIX matLightViewInv;
		D3DXMatrixInverse(&matLightViewInv, 0, &matLightView);

		Vector3 centerW = PosVecTransform(centerL, matLightViewInv);
		float lightDist = fabsf(lightSpaceBound.mMax.z - lightSpaceBound.mMin.z) / 2.0f;
		width = fabsf(lightSpaceBound.mMax.x - lightSpaceBound.mMin.x);
		height = fabsf(lightSpaceBound.mMax.y - lightSpaceBound.mMin.y);

		farZ = 2.0f * lightDist + expandDist;
		mVirtualCamera[cascadeIndex].pos = centerW - (lightDist + expandDist) * lightDir;
	}

	D3DXMATRIX matLightProj;
	D3DXMatrixOrthoLH(&matLightProj, width, height, nearZ, farZ);

	D3DXMATRIX matVirtualCameraView;
	{
		Vector3 virtualCameraPos = mVirtualCamera[cascadeIndex].pos;

		D3DXMATRIX matRotTranspose, matTransInverse;
		D3DXMatrixTranspose(&matRotTranspose, &(lightNode->GetWorldOrient().Matrix()));
		D3DXMatrixTranslation(&matTransInverse, -virtualCameraPos.x, -virtualCameraPos.y, -virtualCameraPos.z);
		matVirtualCameraView = matTransInverse * matRotTranspose; 

		mVirtualCamera[cascadeIndex].bound = AABBox::MatTransform(AABBox(Vector3(0, 0, farZ/2.0f), width, height, farZ), 
			InversedMatrix(matVirtualCameraView));
	}

	mVirtualCamera[cascadeIndex].matVP = matVirtualCameraView * matLightProj;
}
Пример #11
0
// Build KD tree for tris
void KDNode::build(std::vector<Triangle*> &tris, int depth){
    leaf = false;
    triangles = std::vector<Triangle*>();
    left = NULL;
    right = NULL;
    box = AABBox();

    if (tris.size() == 0) return;

    if (depth > 25 || tris.size() <= 6) {
        triangles = tris;
        leaf = true;
        box = tris[0]->get_bounding_box();

        for (long i=1; i<tris.size(); i++) {
            box.expand(tris[i]->get_bounding_box());
        }

        left = new KDNode();
        right = new KDNode();
        left->triangles = std::vector<Triangle*>();
        right->triangles = std::vector<Triangle*>();

        return;
    }

    box = tris[0]->get_bounding_box();
    Vec midpt = Vec();
    double tris_recp = 1.0/tris.size();

    for (long i=1; i<tris.size(); i++) {
        box.expand(tris[i]->get_bounding_box());
        midpt = midpt + (tris[i]->get_midpoint() * tris_recp);
    }

    std::vector<Triangle*> left_tris;
    std::vector<Triangle*> right_tris;
    int axis = box.get_longest_axis();

    for (long i=0; i<tris.size(); i++) {
        switch (axis) {
            case 0:
                midpt.x >= tris[i]->get_midpoint().x ? right_tris.push_back(tris[i]) : left_tris.push_back(tris[i]);
                break;
            case 1:
                midpt.y >= tris[i]->get_midpoint().y ? right_tris.push_back(tris[i]) : left_tris.push_back(tris[i]);
                break;
            case 2:
                midpt.z >= tris[i]->get_midpoint().z ? right_tris.push_back(tris[i]) : left_tris.push_back(tris[i]);
                break;
        }
    }

    if (tris.size() == left_tris.size() || tris.size() == right_tris.size()) {
        triangles = tris;
        leaf = true;
        box = tris[0]->get_bounding_box();

        for (long i=1; i<tris.size(); i++) {
            box.expand(tris[i]->get_bounding_box());
        }

        left = new KDNode();
        right = new KDNode();
        left->triangles = std::vector<Triangle*>();
        right->triangles = std::vector<Triangle*>();

        return;
    }

    left = new KDNode();
    right = new KDNode();
    left->build(left_tris, depth+1);
    right->build(right_tris, depth+1);
    return;
}
Пример #12
0
void OCTree::ClipScene()
{
    if (rebuild_tree_)
    {
        octree_.resize(1);
        AABBox bb_root(float3(0, 0, 0), float3(0, 0, 0));
        octree_[0].first_child_index = -1;
        octree_[0].visible = BO_No;
        for (SceneObjsType::const_reference obj : scene_objs_)
        {
            uint32_t const attr = obj->Attrib();
            if ((attr & SceneObject::SOA_Cullable)
                    && !(attr & SceneObject::SOA_Moveable))
            {
                bb_root |= *obj->PosBoundWS();
                octree_[0].obj_ptrs.push_back(obj);
            }
        }
        float3 const & center = bb_root.Center();
        float3 const & extent = bb_root.HalfSize();
        float longest_dim = std::max(std::max(extent.x(), extent.y()), extent.z());
        float3 new_extent(longest_dim, longest_dim, longest_dim);
        octree_[0].bb = AABBox(center - new_extent, center + new_extent);

        this->DivideNode(0, 1);

        rebuild_tree_ = false;
    }

#ifdef KLAYGE_DRAW_NODES
    if (!node_renderable_)
    {
        node_renderable_ = MakeSharedPtr<NodeRenderable>();
    }
    checked_pointer_cast<NodeRenderable>(node_renderable_)->ClearInstances();
#endif

    if (!octree_.empty())
    {
        this->NodeVisible(0);
    }

    App3DFramework& app = Context::Instance().AppInstance();
    Camera& camera = app.ActiveCamera();

    float4x4 view_proj = camera.ViewProjMatrix();
    DeferredRenderingLayerPtr const & drl = Context::Instance().DeferredRenderingLayerInstance();
    if (drl)
    {
        int32_t cas_index = drl->CurrCascadeIndex();
        if (cas_index >= 0)
        {
            view_proj *= drl->GetCascadedShadowLayer()->CascadeCropMatrix(cas_index);
        }
    }

    if (camera.OmniDirectionalMode())
    {
        for (SceneObjsType::const_reference obj : scene_objs_)
        {
            if (obj->Visible())
            {
                uint32_t const attr = obj->Attrib();
                if (attr & SceneObject::SOA_Moveable)
                {
                    obj->UpdateAbsModelMatrix();
                }

                if (attr & SceneObject::SOA_Cullable)
                {
                    AABBoxPtr aabb_ws = obj->PosBoundWS();
                    obj->VisibleMark((MathLib::perspective_area(camera.EyePos(), view_proj,
                                      *aabb_ws) > small_obj_threshold_) ? BO_Yes : BO_No);
                }
            }
            else
            {
                obj->VisibleMark(BO_No);
            }
        }
    }
    else
    {
        if (!octree_.empty())
        {
            this->MarkNodeObjs(0, false);
        }

        for (SceneObjsType::const_reference obj : scene_objs_)
        {
            if (obj->Visible())
            {
                BoundOverlap visible = this->VisibleTestFromParent(obj, camera.EyePos(), view_proj);
                if (BO_Partial == visible)
                {
                    uint32_t const attr = obj->Attrib();
                    if (attr & SceneObject::SOA_Moveable)
                    {
                        obj->UpdateAbsModelMatrix();
                    }

                    if (attr & SceneObject::SOA_Cullable)
                    {
                        if (attr & SceneObject::SOA_Moveable)
                        {
                            obj->VisibleMark(this->AABBVisible(*obj->PosBoundWS()));
                        }
                        else
                        {
                            obj->VisibleMark(visible);
                        }
                    }
                    else
                    {
                        obj->VisibleMark(BO_Yes);
                    }
                }
                else
                {
                    obj->VisibleMark(visible);
                }
            }
        }
    }

#ifdef KLAYGE_DRAW_NODES
    node_renderable_->Render();
#endif
}