65.9K
CodeProject 正在变化。 阅读更多。
Home

VR 100 天挑战第 64 天:如何在游戏对象上添加轮廓效果

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2018 年 5 月 27 日

CPOL

4分钟阅读

viewsIcon

2876

如何为游戏对象添加轮廓效果

引言

我知道我们在之前的文章中,当我们研究 Daydream 时,已经接触过 Google Daydream Elements 中的投掷手臂模型,如果需要,我们可以参考那里的代码。 但是,在使用 VR 中的控制器时,我们应该知道的最重要的事情之一是如何拾取和与世界中的游戏对象交互。

以下是我们将要研究的几个方面

  1. 当我们选择对象时突出显示它(今天)
  2. 拾取对象(稍后)
  3. 抛掷我们拾取的对象(稍后)

今天我们将从第一部分开始。 如何突出显示一个 game 对象。

在游戏对象上创建高亮效果

我们的目标是能够拾取和投掷物品。 我们之前看到的一个很酷的效果是,当我们突出显示一个 game 对象时,对象本身会被突出显示。

就像这样(忽略我们正在使用一个立方体)

让我们看看我们如何创建一个游戏对象的边框高亮效果? 我们将点击链接,我们将得到答案! 我们必须创建一个着色器来使用!

着色器是“……包含数学计算和算法的小脚本,用于根据光照输入和材质配置来计算渲染的每个像素的 Color。”

幸运的是,我们不必弄清楚如何创建自己的着色器。 这是我们以后可能会尝试学习的东西,但今天,我们将只使用上面链接中提供的现有着色器,轮廓线扩散着色器

要创建一个新的着色器

  1. 在 Unity 的“项目”窗格中,创建一个名为Shaders 的新文件夹
  2. Shaders 文件夹中,选择,右键单击并选择 创建 > 着色器 > 标准表面着色器,将其命名为 Border
  3. 打开 Border,让我们添加上面的着色器脚本。 具体来说,我们只需要轮廓效果,因此我们在 Border 着色器中复制和粘贴的代码是
Shader "Outlined/Silhouette Only" {
    Properties {
        _OutlineColor ("Outline Color", Color) = (0,0,0,1)
        _Outline ("Outline width", Range (0.0, 0.03)) = .005
    }
 
CGINCLUDE
#include "UnityCG.cginc"
 
struct app data {
    float4 vertex : POSITION;
    float3 normal : NORMAL;
};
 
struct v2f {
    float4 pos : POSITION;
    float4 color : COLOR;
};
 
uniform float _Outline;
uniform float4 _OutlineColor;
 
v2f vert(appdata v) {
    // just make a copy of incoming vertex data but scaled according to normal direction
    v2f o;
    o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
 
    float3 norm   = mul ((float3x3)UNITY_MATRIX_IT_MV, v.normal);
    float2 offset = TransformViewToProjection(norm.xy);
 
    o.pos.xy += offset * o.pos.z * _Outline;
    o.color = _OutlineColor;
    return o;
}
ENDCG
 
    SubShader {
        Tags { "Queue" = "Transparent" }
 
        Pass {
            Name "BASE"
            Cull Back
            Blend Zero One
 
            // uncomment this to hide inner details:
            //Offset -8, -8
 
            SetTexture [_OutlineColor] {
                ConstantColor (0,0,0,0)
                Combine constant
            }
        }
 
        // note that a vertex shader is specified here but it's using the one above
        Pass {
            Name "OUTLINE"
            Tags { "LightMode" = "Always" }
            Cull Front
 
            // you can choose what kind of blending mode you want for the outline
            //Blend SrcAlpha OneMinusSrcAlpha // Normal
            //Blend One One                   // Additive
            Blend One OneMinusDstColor        // Soft Additive
            //Blend DstColor Zero             // Multiplicative
            //Blend DstColor SrcColor         // 2x Multiplicative
 
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
 
half4 frag(v2f i) :COLOR {
    return i.color;
}
ENDCG
        }
    }
 
    Fallback "Diffuse"
}

别问我代码做了什么,我也不知道,但我可以向你保证它有效!

现在我们有了着色器,接下来我们需要做的是将它应用到材质上,这样我们就可以在我们的 game 对象上使用它来获得我们的高亮效果。

  1. 在我们的项目目录中创建一个名为Materials 的新文件夹
  2. 右键单击项目面板并选择 创建 > 材质,让我们也把新的材质叫做 Outline
  3. 选择新的轮廓,然后将着色器设置为我们刚刚制作的轮廓。 具体来说,我可以在 Outlined/Silhouette Only 找到它。

这就是它的样子

我们可以控制两个变量,它们是

  • 轮廓颜色 – 我们将在 game 对象上创建的轮廓的颜色。
  • 轮廓宽度 – 轮廓在我们 game 对象上显示的宽度。

现在我们有了轮廓材质,是时候将它们附加到我们想要与之交互的 game 对象了。 让我们创建它。

  1. game 对象中创建一个新的球体。 我们就叫它
  2. 将其移动到 position (0, 1.2, 2.5) 以便在玩家正前方。
  3. BallMesh Renderer 组件中,选择 Materials 并将它的大小更改为 2
  4. 对于第 2 个材质槽,添加我们刚刚创建的 Outline material。 现在你应该在 Ball 上看到一个白色的轮廓。
  5. 为了使轮廓更明显,让我们将球体的默认材质更改为不同的颜色。 在 Element 0 中,更改材质。 让我们选择 Google VR SDK 提供的 Cube Red 来使用。 因为我们只选择创建一个轮廓,所以我们可以在我们的游戏对象上拥有多个材质,并且仍然拥有我们的网格轮廓!

这就是我们应该拥有的

左边是我们的场景,我们几乎看不到白色的轮廓。

然而,在右侧的游戏窗格中,这是玩家看到的。 我们可以更清楚地看到轮廓。

结论

有了这个,我们就完成了我们的原始目标,创建一个适用于我们任何 game 对象的轮廓材质,并且我们更多地了解了如何创建着色器(或者至少复制一个)以及如何在我们的材质中使用它们。

在下一篇文章中,我们将继续我们的下一步,并研究当我们悬停并选择一个对象时,我们如何能够突出显示它。

© . All rights reserved.