0

我正在为一个鱼射击游戏开发 Unity3D。我正在为鱼实现水下焦散效果。我在 Unity 的 StandardAsset 中使用“BlobLightProjector”和附加的脚本来改变每一帧的纹理:

public Texture2D[] frames;
private int frameIndex;
private Projector projector;
...
// repeat every frame
projector.material.SetTexture("_ShadowTex", frames[frameIndex]);
frameIndex = (frameIndex + 1) % frames.Length;

我的焦散纹理列表如下所示:

列出焦散纹理

这是我取得的成就: 我的成就

现在的问题是我希望投影仪只影响鱼的上部(即使我将鱼旋转到任何方向),看起来像这样: 我的希望

你能给我一些建议吗,或者其他不使用投影仪的解决方案很好。

4

2 回答 2

0

您需要通过以下方式修改Assets\Standard Assets\Effects\Projectors\Shaders\ProjectorLight.shader

  1. 您需要创建一个新变量,该变量将从顶点着色器传递到v2f结构中的像素着色器:half fade : TEXCOORD3;
  2. 那么你需要能够在顶点着色器中使用法线。一个简单的选择是使用appdata_base而不是只传递顶点位置:v2f vert (appdata_base v)并通过附加v.vertex任何地方来修改对位置的调用。
  3. 然后你根据法线计算淡入淡出因子:我选择只夹住世界法线的垂直轴(因为它的范围从 -1 到 1)o.fade = saturate(mul(unity_ObjectToWorld, v.normal).y);saturate()钳制为 0-1,矩阵mul()转换为世界空间。
  4. 最后将淡入淡出应用于像素着色器中的结果texS.rgb *= _Color.rgb * 8.0 * i.fade;(我将范围增加 8,因为否则值永远不会比 1 更亮,但这取决于您的喜好)

            CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
        #pragma multi_compile_fog
        #include "UnityCG.cginc"
    
        struct v2f {
            float4 pos : SV_POSITION;
            float4 uvShadow : TEXCOORD0;
            float4 uvFalloff : TEXCOORD1;
            UNITY_FOG_COORDS(2)
            half fade : TEXCOORD3;
        };
    
        float4x4 unity_Projector;
        float4x4 unity_ProjectorClip;
    
        v2f vert (appdata_base v)
        {
            v2f o;
            o.pos = UnityObjectToClipPos(v.vertex);
            o.uvShadow = mul (unity_Projector, v.vertex);
            o.uvFalloff = mul (unity_ProjectorClip, v.vertex);
            o.fade = saturate(mul(unity_ObjectToWorld, v.normal).y);
            UNITY_TRANSFER_FOG(o, o.pos);
            return o;
        }
    
        fixed4 _Color;
        sampler2D _ShadowTex;
        sampler2D _FalloffTex;
    
        fixed4 frag (v2f i) : SV_Target
        {
            fixed4 texS = tex2Dproj (_ShadowTex, UNITY_PROJ_COORD(i.uvShadow));
            texS.rgb *= _Color.rgb * 8.0 * i.fade;
            texS.a = 1.0-texS.a;
    
            fixed4 texF = tex2Dproj (_FalloffTex, UNITY_PROJ_COORD(i.uvFalloff));
            fixed4 res = texS * texF.a;
    
            UNITY_APPLY_FOG_COLOR(i.fogCoord, res, fixed4(0,0,0,0));
            return res;
        }
        ENDCG
    
于 2017-09-24T23:27:42.657 回答
0

在我看来,您将需要使用自定义着色器。老实说,我不是他们的专家,但有一个关于着色器的 Unite 2016 有一个与此非常相似的示例。

对不起,我没有任何代码给你,但我希望这至少是朝着正确方向迈出的一小步

于 2017-09-11T09:31:00.973 回答