Casino online









Mercato forex






B20. Muovere l'acqua


L'effetto fresnel è completo, le increspature ci sono. Manca solo un po' di movimento. Il codice che segue è preso dal solito sito a cui faccio riferimento: per questa volta non l'ho scritto io, anche perchè il principio su cui si basa è lo stesso e alcuni passaggi rimangono un po' oscuri. In sostanza, presi in input il tempo passato dall'inizio del gioco, la direzione del vento e la sua forza, muove l'acqua di conseguenza. Ecco il codice modificato del file shader:
float Time;
float WindForce;
float3 WindDirection;

//...

WaterVertexToPixel WaterVertexShader(float4 inPos : POSITIO, 
    float2 inTex: TEXCOORD)
{    
    WaterVertexToPixel Output = (WaterVertexToPixel)0;

    float4x4 ViewProjection = mul(View, Projection);
    float4x4 WorldViewProjection = mul(World, ViewProjection);
    
    float4x4 ReflectionViewProjection = mul(ReflectionView, Projection);
    float4x4 WorldReflectionViewProjection = mul(World, ReflectionViewProjection);
    
    Output.Position = mul(inPos, WorldViewProjection);
    Output.ReflectionPos = mul(inPos, WorldReflectionViewProjection);
    Output.RefractionPos = mul(inPos, WorldViewProjection);
    
    //Normalizza la direzione
    float3 windDir = normalize(WindDirection); 
    //Calcola la perpendicolare alla direzione del vento    
    float3 perpDir = cross(WindDirection, float3(0,1,0));
    //Ottiene le componenti x e y del vettore risultante
    float ydot = dot(inTex, WindDirection.xz);
    float xdot = dot(inTex, perpDir.xz);
    float2 moveVector = float2(xdot, ydot);  
    //Aumenta la componente y di un fattore pari a Time * WindForce.
    //Questo è il passaggio più importante e, volendo,
    //si potrebbe usare solo questo tralasciando ciò che
    //viene prima. Più WindForce è grande, maggiore
    //sarà lo spostamento compiuto dall'acqua in un
    //secondo.
    moveVector.y += Time * WindForce;
    //Imposta le coordinate della bump map
    Output.BumpPos = (moveVector) / WaveLength;
    
    Output.PointPosition = mul(inPos, World);

    return Output;
} 
E ora si modifica anche il codice xna:
   '...

    Private Sub DrawWater(ByVal Time As Single)
        Shader.CurrentTechnique = Shader.Techniques("Water")

        Shader.Parameters("View").SetValue(ViewMatrix)
        Shader.Parameters("Projection").SetValue(ProjectionMatrix)
        Shader.Parameters("World").SetValue(Matrix.Identity)
        Shader.Parameters("ReflectionView").SetValue(ReflectionViewMatrix)
        Shader.Parameters("RefractionMap").SetValue(RefractionMap)
        Shader.Parameters("ReflectionMap").SetValue(ReflectionMap)
        Shader.Parameters("BumpMap").SetValue(BumpMap)
        Shader.Parameters("WaveLength").SetValue(0.01F)
        Shader.Parameters("WaveHeight").SetValue(0.3F)
        Shader.Parameters("CameraPosition").SetValue(CameraPosition)
        'Imposta i nuovi parametri
        Shader.Parameters("Time").SetValue(Time)
        Shader.Parameters("WindDirection").SetValue(New Vector3(0, 0, 1))
        Shader.Parameters("WindForce").SetValue(0.0002F)

        Dim Prev As CullMode = Me.GraphicsDevice.RenderState.CullMode
        Me.GraphicsDevice.RenderState.CullMode = CullMode.None

        Me.GraphicsDevice.Vertices(0).SetSource( _
            WaterVBuffer, 0, VertexPositionTexture.SizeInBytes)

        Shader.Begin()
        For Each Pass As EffectPass In Shader.CurrentTechnique.Passes
            Pass.Begin()
            With Me.GraphicsDevice
                .VertexDeclaration = WDeclaration
                Me.GraphicsDevice.DrawPrimitives( _ 
                    PrimitiveType.TriangleList, 0, WaterVertices.Length / 3)
            End With
            Pass.End()
        Next
        Shader.End()

        Me.GraphicsDevice.RenderState.CullMode = Prev
    End Sub
    
    '... 
Non dimenticate di passare al metodo DrawWater il parametro corretto:
    Protected Overrides Sub Draw(ByVal gameTime As GameTime)
        Me.Graphics.GraphicsDevice.Clear(Color.CornflowerBlue)

        DrawRefractionMap()
        DrawReflectionMap()

        DrawSky(ViewMatrix)
        DrawTerrain(ViewMatrix)
        DrawWater(gameTime.TotalGameTime.TotalMilliseconds / 100.0F)

        MyBase.Draw(gameTime)
    End Sub 
gameTime.TotalGameTime.TotalMilliseconds restituisce il numero totale di millisecondi passati dall'inizio del gioco. Il risultato che si dovrebbe ottenere è questo.








 

The Totem's Lair - Copyright (C) 2009
È vietata la riproduzione sia totale che parziale del sito.