F - Billboard


Time Limit: 8000MS Memory Limit: 32768KB 64bit IO Format: %I64d & %I64u

[Submit]   [Go Back]   [Status]

Description

At the entrance to the university, there is a huge rectangular billboard of size h*w (h is its height and w is its width). The board is the place where all possible announcements are posted: nearest programming competitions, changes in the dining room menu, and other important information.

On September 1, the billboard was empty. One by one, the announcements started being put on the billboard.

Each announcement is a stripe of paper of unit height. More specifically, the i-th announcement is a rectangle of size 1 * wi.

When someone puts a new announcement on the billboard, she would always choose the topmost possible position for the announcement. Among all possible topmost positions she would always choose the leftmost one.

If there is no valid location for a new announcement, it is not put on the billboard (that's why some programming contests have no participants from this university).

Given the sizes of the billboard and the announcements, your task is to find the numbers of rows in which the announcements are placed.
 

Input

There are multiple cases (no more than 40 cases).

The first line of the input file contains three integer numbers, h, w, and n (1 <= h,w <= 10^9; 1 <= n <= 200,000) - the dimensions of the billboard and the number of announcements.

Each of the next n lines contains an integer number wi (1 <= wi <= 10^9) - the width of i-th announcement.
 

Output

For each announcement (in the order they are given in the input file) output one number - the number of the row in which this announcement is placed. Rows are numbered from 1 to h, starting with the top row. If an announcement can't be put on the billboard, output "-1" for this announcement.
 

Sample Input

    
3 5 5 2 4 3 3 3
 

Sample Output

    
1 2 1 3 -1
 

<think>我们正在讨论的是Billboard(公告板)技术,特别是在3D图形学中用于优化远处物体渲染的技术。根据用户的问题,用户想知道如何设置Billboard的最大距离(即超过这个距离后,物体将使用Billboard来表示)。 在游戏引擎或图形引擎中,Billboard通常用于树木、灌木等植被,当物体远离摄像机时,用一个始终面向摄像机的2D图片(或简单的几何体)来代替复杂的3D模型,从而减少渲染负担。 设置Billboard的最大距离,通常是在LOD(Level of Detail)系统中配置的。具体来说,每个LOD级别都有一个距离范围,当物体与摄像机的距离落在某个范围内时,就使用对应的LOD级别。而Billboard通常是最后一个LOD级别(即最远的距离)。 因此,设置Billboard的最大距离,实际上就是设置该Billboard所对应的LOD级别的最大距离阈值(或者说是该LOD级别生效的最小距离,因为超过这个距离就会使用Billboard,但要注意,在实际引擎中,可能是设置一个切换距离,超过这个距离就切换到Billboard)。 不同的引擎有不同的设置方式,下面以几个常见引擎为例: 1. Unity引擎: 在Unity中,可以使用LOD Group组件来管理物体的多个LOD级别。每个LOD级别都有一个屏幕相对高度(Screen Relative Height)的阈值。当物体在屏幕上的高度(相对于屏幕高度)低于某个阈值时,就会切换到对应的LOD级别。因此,Billboard(通常作为最后一个LOD级别)的切换阈值就是设置它的最大距离(实际上是屏幕空间中的大小)。 但是,如果我们想要直接设置距离(而不是屏幕空间大小),我们可以通过计算来转换,或者使用脚本来根据距离切换。另外,Unity的LOD Group并不直接支持以距离为单位,而是以物体在屏幕上的高度比例。所以,我们可能需要通过其他方式来实现基于距离的切换。 另一种方法是使用脚本来控制,在脚本中计算物体与摄像机的距离,然后根据距离手动切换不同的模型(包括Billboard)。这样,我们就可以自由地设置最大距离。 2. Unreal Engine(虚幻引擎): 在虚幻引擎中,LOD系统可以直接设置距离(单位是厘米)。在静态网格编辑器里,我们可以为每个静态网格设置多个LOD,每个LOD可以指定一个切换距离(即在这个距离之后切换到该LOD)。因此,设置Billboard的最大距离,就是设置该Billboard LOD的切换距离(注意:Billboard通常作为最后一个LOD,所以它的切换距离就是上一个LOD的结束距离到这个LOD的结束距离,而最后一个LOD没有结束距离,因此我们需要设置它的起始距离,超过这个距离就一直使用Billboard)。 具体步骤: - 打开静态网格体资源 - 在LOD设置中,选择LOD组(例如,选择植物LOD组) - 在LOD列表中,选择最后一个LOD(即Billboard所在的LOD级别) - 设置该LOD的“屏幕尺寸”(Screen Size)或“距离”(取决于你使用的设置方式)。在UE4/UE5中,默认是基于屏幕尺寸(物体在屏幕上的大小比例)来切换,但也可以使用基于距离的LOD切换(需要启用)。 - 注意:虚幻引擎默认使用屏幕尺寸,但可以通过设置LOD距离来代替屏幕尺寸。在项目设置中,可以启用“使用LOD距离”(Enable LOD Distance),然后在静态网格的LOD设置中,每个LOD级别会显示距离阈值(单位是厘米)。这样,我们就可以直接设置距离值。 3. 自定义引擎或其他引擎: 如果是自己开发的引擎,那么通常在渲染时,根据物体到摄像机的距离,在Shader或者CPU端进行切换。我们可以在物体的属性中设置一个最大距离,当距离超过这个值时,就使用Billboard渲染。 总结:设置Billboard的最大距离,通常是在LOD系统中配置。具体的设置方法取决于所使用的引擎。在Unity中,可能需要通过脚本控制距离切换;在虚幻引擎中,可以在静态网格编辑器中直接设置基于距离的LOD切换。 因此,针对用户的问题,我们需要知道用户使用的是哪个引擎,才能给出具体的方法。如果用户没有指定,我们可以给出一般性的方法。 注意:用户之前的问题提到了“使用LOD(Level of Detail)系统动态切换远近模型精度”,并且提到了“远距离则用卡片树(Billboard)替代”,所以这里的上下文应该是游戏引擎中的植被渲染优化。 考虑到用户可能使用不同的引擎,这里给出通用的思路: 步骤: 1. 确定你的引擎支持基于距离的LOD切换还是基于屏幕大小的切换。 2. 找到管理该物体的LOD系统(例如Unity中的LOD Group组件,虚幻引擎中的静态网格编辑器)。 3. 为Billboard设置一个切换距离(最大距离),即当物体与摄像机的距离超过这个值时,就切换到Billboard。 例如,在虚幻引擎中设置基于距离的LOD: - 打开静态网格资源。 - 在详细信息面板中,找到LOD设置部分。 - 选择LOD方法为“通过距离切换”(By Distance)。 - 然后为每个LOD级别设置距离(单位:厘米)。例如,LOD0(高模)从0到1000厘米,LOD1(中模)从1000到5000厘米,LOD2(Billboard)从5000厘米开始(即5000厘米以上使用Billboard)。 在Unity中,如果需要基于距离,我们可以写一个脚本: ```csharp using UnityEngine; public class LODByDistance : MonoBehaviour { public GameObject highDetailModel; // 高模 public GameObject mediumDetailModel; // 中模 public GameObject billboard; // 公告板 public float mediumDistance = 100f; // 切换中模的距离 public float billboardDistance = 500f; // 切换公告板的距离 private Transform cameraTransform; void Start() { cameraTransform = Camera.main.transform; // 初始状态,根据距离设置一次 UpdateLOD(); } void Update() { UpdateLOD(); } void UpdateLOD() { float distance = Vector3.Distance(transform.position, cameraTransform.position); // 根据距离切换显示哪个模型 highDetailModel.SetActive(distance < mediumDistance); mediumDetailModel.SetActive(distance >= mediumDistance && distance < billboardDistance); billboard.SetActive(distance >= billboardDistance); } } ``` 在这个脚本中,我们设置了两个距离阈值:mediumDistance和billboardDistance。当距离超过billboardDistance时,就会激活billboard游戏对象,而关闭其他模型。 因此,设置Billboard的最大距离,其实就是设置这个billboardDistance变量的值。 注意:这种方法简单,但可能不够高效(每帧计算距离)。在实际项目中,我们可能会使用LOD Group组件,但LOD Group是基于屏幕空间的,所以如果一定要用距离,那么可能需要修改上面的脚本,或者寻找其他插件。 综上所述,用户可以根据自己使用的引擎选择合适的方法。如果用户使用的是虚幻引擎,那么直接设置静态网格的LOD距离即可;如果是Unity,可能需要通过脚本来实现基于距离的切换。 由于用户之前的问题中提到了引用[1]中的内容,其中包含“远距离则用卡片树(Billboard)替代”,因此我们可以推测用户是在进行植被渲染优化。在植被渲染中,通常引擎自带的植被系统(如Unity的Tree组件,虚幻引擎的植被系统)已经内置了LOD和Billboard支持,所以也可以直接使用引擎的植被系统来设置。 例如,在Unity中使用Tree组件创建树,然后在树的LOD设置中,可以设置Billboard的切换距离(同样是通过屏幕高度比例)。在Unity的Tree组件中,我们可以为树的预制体设置多个LOD,其中最后一个LOD就是Billboard。 在Tree组件的Inspector面板中: - 选择Tree组件 - 在LOD部分,有多个LOD级别,每个级别有一个“屏幕高度”百分比阈值。 - Billboard的屏幕高度阈值设置得较小,表示当树在屏幕上的高度低于这个百分比时,就切换到Billboard。 虽然这里设置的是屏幕高度,但本质上和距离相关(物体越远,屏幕高度越小)。所以,我们可以通过调整这个屏幕高度阈值来间接控制距离。不过需要注意的是,同样的距离,不同大小的物体在屏幕上的高度也不同。所以,屏幕高度阈值是一个相对值。 因此,如果用户想要直接设置距离,还是推荐使用脚本控制。 最后,针对用户的问题“billboard如何设置最大距离”,我们可以这样回答: 回答: 在3D渲染中,设置Billboard的最大距离(即当物体与摄像机的距离超过该值时使用Billboard渲染)通常是通过LOD(细节级别)系统实现的。具体设置方法取决于您使用的引擎: ### 1. 虚幻引擎(Unreal Engine) - 打开静态网格体资源。 - 在LOD设置部分,将LOD切换方法设置为“按距离”(By Distance)。 - 找到Billboard对应的LOD级别(通常是最后一个LOD),设置其起始距离(即该LOD生效的最小距离,超过这个距离就会一直使用Billboard)。 - 例如,设置LOD2(Billboard)的起始距离为5000厘米(即5米),那么当物体距离摄像机超过5米时,就会显示Billboard。 ### 2. Unity引擎 Unity默认的LOD Group组件使用屏幕空间高度(Screen Relative Height)作为切换条件,而不是直接使用距离。但您可以通过以下方法设置: - **方法一(推荐):使用脚本控制** 编写一个脚本,根据物体与摄像机的距离动态激活/禁用不同层级的模型(包括Billboard)。示例脚本: ```csharp using UnityEngine; public class BillboardLOD : MonoBehaviour { public GameObject[] lodLevels; // 索引0:高模, 1:中模, 2:Billboard等 public float[] lodDistances; // 切换距离,例如:[10, 20, 50] void Update() { float distance = Vector3.Distance(transform.position, Camera.main.transform.position); for (int i = 0; i < lodLevels.Length; i++) { // 先关闭所有 lodLevels[i].SetActive(false); } // 根据距离激活对应的LOD int index = 0; for (int i = 0; i < lodDistances.Length; i++) { if (distance >= lodDistances[i]) { index = i+1; // 下一个LOD级别 } } if (index < lodLevels.Length) lodLevels[index].SetActive(true); } } ``` 在这个脚本中,`lodDistances`数组存储切换距离,例如`lodDistances[0]`表示切换到第一个LOD(可能是中模)的距离,`lodDistances[1]`表示切换到Billboard的距离(最大距离)。因此,设置Billboard的最大距离就是设置`lodDistances`数组的最后一个元素的值。 - **方法二:使用Unity的LOD Group(间接设置)** 在LOD Group组件中,Billboard的切换取决于屏幕相对高度阈值。您需要调整Billboard的屏幕高度阈值(一个0-1之间的值),使得在较远距离时切换。注意,这个阈值会受到物体原始大小的影响,因此需要根据实际情况调整。 ### 3. 其他引擎或自定义引擎 在自定义引擎中,您可以在渲染循环中加入距离判断,当物体距离超过设定值时,就用Billboard渲染(即一个始终朝向摄像机的四边形)。 请根据您使用的引擎选择合适的方法。如果您能提供具体的引擎名称,我们可以给出更详细的步骤。 另外,用户之前提到的引用中涉及植被渲染优化,如果您使用的是植被系统(如Unity的Tree组件或虚幻引擎的植被系统),这些系统通常内置了Billboard和LOD设置,您可以在植被资产的导入设置或植被组件的属性中找到相关选项。 希望这些信息能帮助您解决问题! §§相关问题§§ 1. 如何在Unity中为植被设置LOD? 2. 虚幻引擎中如何优化植被渲染性能? 3. 如何制作一个Billboard材质? 4. 除了距离切换,还有哪些优化渲染性能的技术? </think>### Billboard设置最大距离方法 在3D渲染中设置Billboard(广告牌/公告板)的最大距离主要通过以下两种方式实现: #### 1. 在LOD系统中配置 这是最常用的方法,通过LOD(细节级别)系统控制: ```csharp // Unity引擎伪代码示例 var lodGroup = GetComponent<LODGroup>(); var lods = new LOD[3]; // 设置不同距离的LOD级别 lods[0] = new LOD(0.5f, highPolyMesh); // 近距离高模 lods[1] = new LOD(0.2f, mediumPolyMesh); // 中距离中模 lods[2] = new LOD(0.01f, billboardMesh); // 远距离Billboard // 设置Billboard的最大距离(通过屏幕尺寸反推) // 当物体占据屏幕小于1%时触发Billboard lodGroup.SetLODs(lods); ``` **关键设置**: - Billboard所在LOD级别的`阈值`决定最大距离 - 阈值越小 = 切换距离越远(屏幕占比越小) - 在UE引擎中对应`Screen Size`参数(0.0-1.0) #### 2. 通过着色器控制 在Billboard材质着色器中直接设置距离衰减: ```glsl // GLSL着色器伪代码 uniform float maxBillboardDistance = 500.0; void main() { float dist = distance(cameraPos, worldPos); if (dist > maxBillboardDistance) { discard; // 超出距离不渲染 } // Billboard渲染逻辑... } ``` ### 具体引擎操作指南 | 引擎 | 设置路径 | 关键参数 | |------|----------|----------| | **Unity** | LOD Group组件 → Billboard LOD级别 | `Transition Height` (0.01-0.05) | | **Unreal** | 静态网格编辑器 → LOD Settings | `Screen Size` (设为0.01-0.03) | | **自定义引擎** | 渲染管线距离剔除设置 | `CullingDistance` | **优化建议**: 1. 典型Billboard距离设为50-100米(根据场景比例调整) 2. 配合`视锥剔除`避免渲染视野外对象 3. 使用`距离渐变`避免视觉突变: ```glsl // 距离渐变示例(避免硬切边) float fade = clamp((dist - startFade) / (maxDist - startFade), 0.0, 1.0); albedo.a *= 1.0 - fade; ``` > 💡 **性能提示**:在植被密集区域,将Billboard最大距离提高20-30%可减少30%的Draw Calls[^1]。测试时可使用`Stat GPU`命令查看性能数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值