gpt4 book ai didi

unity3d - 在单个网格上渲染多种 Material

转载 作者:行者123 更新时间:2023-12-04 10:43:17 27 4
gpt4 key购买 nike

在 Unity3D 中,我尝试渲染一个生物并在它被选中时显示一个轮廓。

单独的生物被渲染得很好:

Image of creature

我下载了一个 Outline Shader on Github并将其作为第二种 Material 应用于我的网格:

Image of Renderer Settings

扩展 Material 如下所示:

Image of Expanded Materials

然而,结果完全不像预期的那样:

Wrong Combination of Materials

在对 Material 和着色器了解不多的情况下,我试着摆弄了一下,发现如果我将标准 Material 的渲染模式更改为透明,结果看起来不错:

Right Rendering Result

但是现在这个生物独自以一种奇怪的方式呈现四肢重叠在 body 上:

Wrong rendering of creature

实现我想要做的事情的正确方法是什么?你有资源可以让我阅读更多吗?

最佳答案

您设置的问题是渲染队列。透明对象在不透明对象之后渲染,因此您的轮廓只是绘制在生物的顶部。如果您想更改渲染顺序,您必须将带有轮廓的对象视为“特殊”不透明对象(例如,绘制普通对象、绘制轮廓、绘制生物)。

这里有几个替代方案:

  • 使用 Cull Front - 这个着色器基本上是在原始对象的顶部绘制一个更大的对象副本,就像一个 shell 。 Cull Front 使得它绘制对象后面的 shell 的背面,而不是正面。
  • 使用模板缓冲区标记绘制原始对象的区域,并在绘制轮廓时跳过它。

  • 下面是着色器的修改版本(删除了第二个颜色 channel 和表面着色器 channel ,因为你不使用它们)。这是模板缓冲区选项。如果您想尝试另一个,请删除第一遍,第二遍中的模板块并替换 Cull BackCull Front .
    Shader "Outlined/UltimateOutline"
    {
    Properties
    {
    _Color("Main Color", Color) = (0.5,0.5,0.5,1)

    _FirstOutlineColor("Outline color", Color) = (1,0,0,0.5)
    _FirstOutlineWidth("Outlines width", Range(0.0, 2.0)) = 0.15

    _Angle("Switch shader on angle", Range(0.0, 180.0)) = 89
    }
    CGINCLUDE
    #include "UnityCG.cginc"

    struct appdata {
    float4 vertex : POSITION;
    float4 normal : NORMAL;
    };

    uniform float4 _FirstOutlineColor;
    uniform float _FirstOutlineWidth;

    uniform float4 _Color;
    uniform float _Angle;

    ENDCG

    SubShader{
    Pass {
    Tags{ "Queue" = "Transparent-1" "IgnoreProjector" = "True" }
    ZWrite Off
    Stencil {
    Ref 1
    Comp always
    Pass replace
    }
    ColorMask 0
    }

    //First outline
    Pass{
    Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" }
    Stencil {
    Ref 1
    Comp NotEqual
    }

    Blend SrcAlpha OneMinusSrcAlpha
    ZWrite Off
    Cull Back //Replace this with Cull Front for option 1
    CGPROGRAM

    struct v2f {
    float4 pos : SV_POSITION;
    };

    #pragma vertex vert
    #pragma fragment frag

    v2f vert(appdata v) {
    appdata original = v;

    float3 scaleDir = normalize(v.vertex.xyz - float4(0,0,0,1));
    //This shader consists of 2 ways of generating outline that are dynamically switched based on demiliter angle
    //If vertex normal is pointed away from object origin then custom outline generation is used (based on scaling along the origin-vertex vector)
    //Otherwise the old-school normal vector scaling is used
    //This way prevents weird artifacts from being created when using either of the methods
    if (degrees(acos(dot(scaleDir.xyz, v.normal.xyz))) > _Angle) {
    v.vertex.xyz += normalize(v.normal.xyz) * _FirstOutlineWidth;
    }
    else {
    v.vertex.xyz += scaleDir * _FirstOutlineWidth;
    }

    v2f o;
    o.pos = UnityObjectToClipPos(v.vertex);
    return o;
    }

    half4 frag(v2f i) : COLOR{
    return _FirstOutlineColor;
    }
    ENDCG
    }
    }
    Fallback "Diffuse"
    }

    关于unity3d - 在单个网格上渲染多种 Material ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59832295/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com