2017-09-11 3 views
0

Ich arbeite an Unity3D für ein Fisch-Shooter. Ich implementiere den Unterwasser-Ätzeffekt für Fische. Ich verwende „BlobLightProjector“ in StandardAsset der Einheit mit einem daran befestigten Skript, um die Textur von jedem Rahmen zu ändern:Wie kann der Projektor nur bestimmte Teile des Objekts beeinflussen?

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

Meine Liste ätzenden Texturen wie folgt aussehen:

List caustic texture

Hier ist, was Ich habe erreicht: My achieve

Jetzt ist das Problem, ich will den Projektor nur die oberen Teile des Fisches beeinflussen (auch wenn ich meinen Fisch in irgendeine Richtung drehen), das ist etwas Hing Aussehen wie folgt: My wish

Könnten Sie mir einige Ratschläge geben, wie es zu tun ist, oder andere Lösung nicht verwenden Projektor ist gut so.

Antwort

0

Es scheint mir, dass Sie einen benutzerdefinierten Shader verwenden müssen. Ich werde ehrlich sein, ich bin kein Experte für sie, aber es gab eine Unite 2016 auf Shadern, die ein ähnliches Beispiel hatten.

Es tut mir leid ich keinen Code für Sie, aber ich hoffe, dass dies zumindest ein kleiner Schritt in die richtige Richtung

0

Sie müssen sein Assets \ Standard-Assets \ Effects \ Projektoren ändern \ Shaders \ ProjectorLight.shader die folgende Art und Weise:

  1. Sie eine neue Variable erstellen müssen, die vom Vertex-Shader zum Pixel-Shader in der v2f Struktur übergeben werden wird: half fade : TEXCOORD3;
  2. dann müssen Sie in der Lage sein zu verwenden die Normale im Vertex-Shader. Eine einfache Wahl besteht darin, appdata_base zu verwenden, anstatt nur die Scheitelpunktposition v2f vert (appdata_base v) zu übergeben und den Aufruf der Position zu ändern, indem Sie v. an vertex überall anfügen.
  3. berechnen Sie dann den Fade-Faktor auf der Grundlage der normalen: Ich entschied mich, nur die vertikale Achse der Welt senkrecht zu klemmen (da es von -1 bis 1 reicht) o.fade = saturate(mul(unity_ObjectToWorld, v.normal).y);. saturate() Klemmen auf 0-1, die Matrix mul() konvertiert in den Weltbereich.
  4. gelten schließlich die Fade auf das Ergebnis in dem Pixel-Shader-texS.rgb *= _Color.rgb * 8.0 * i.fade; (I den Bereich von 8 erhöhen, da sonst Werte nie als 1 heller sein, aber das ist bis zu einer Vielzahl von Design)

     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 
    
Verwandte Themen