[UPDATE FÜR SOURCE-CODE AUSTAUSCH]
@Moderation : Danke sehr ( = !
Guten Tag liebe Community,
im Folgenden möchte ich Euch die Source für eine Wellen-Animation in Monogame bereitstellen...
Es umfasst zwei Klassen, jeweils der WaterManager und eine individuelle Vertex Deklaration ( die ich WaterMolecule nenne )...
Die WaterManager-Klasse
WaterMolecule-Vertex-Deklaration:
Die HLSL Klasse:
Im Anhang ein Exempel ( =
@Moderation : Danke sehr ( = !
Guten Tag liebe Community,
im Folgenden möchte ich Euch die Source für eine Wellen-Animation in Monogame bereitstellen...
Es umfasst zwei Klassen, jeweils der WaterManager und eine individuelle Vertex Deklaration ( die ich WaterMolecule nenne )...
Die WaterManager-Klasse
C#-Quellcode
- public class WaterManager
- {
- public GraphicsDevice Device { get; private set; }
- public ContentManager Content { get; private set; }
- public DynamicVertexBuffer VertexBuffer { get; private set; }
- public DynamicIndexBuffer IndexBuffer { get; private set; }
- private List<WaterMolecule> mainVertices = new List<WaterMolecule>();
- private Dictionary<Vector3, int> hashTable = new Dictionary<Vector3, int>();
- private List<int> vertexIndices = new List<int>();
- private static Random RAND = new Random();
- private Texture2D waterTexture;
- private Effect waveEffect;
- private float animationTime;
- private WaterMolecule[] vertexPuffer;
- public WaterManager(GraphicsDevice device, ContentManager content)
- {
- Device = device;
- Content = content;
- waterTexture = Content.Load<Texture2D>(@"water");
- waveEffect = Content.Load<Effect>(@"wave");
- }
- public void AddWaterTile(Vector3 position)
- {
- // ADD VERTICES
- var wavefactor = (float)RAND.NextDouble() * 0.35f;
- wavefactor = RAND.NextDouble() >= 0.5 ? -wavefactor : wavefactor;
- if (vertexPuffer != null)
- mainVertices = new List<WaterMolecule>(vertexPuffer);
- else mainVertices = new List<WaterMolecule>();
- // CORNERS
- Vector3 local = position;
- Vector3 forward = new Vector3(position.X, position.Y, position.Z + 1);
- Vector3 left = new Vector3(position.X + 1, position.Y, position.Z);
- Vector3 leftForward = new Vector3(position.X + 1, position.Y, position.Z + 1);
- if (!mainVertices.Exists(p => p.Position.Equals(local)))
- {
- mainVertices.Add(new WaterMolecule(local, Vector3.Zero, new Vector2(position.X, position.Z), new Vector2(wavefactor)));
- hashTable.Add(local, mainVertices.Count - 1);
- }
- if (!mainVertices.Exists(p => p.Position.Equals(forward)))
- {
- mainVertices.Add(new WaterMolecule(forward, Vector3.Zero, new Vector2(forward.X, forward.Z), new Vector2(wavefactor)));
- hashTable.Add(forward, mainVertices.Count - 1);
- }
- if (!mainVertices.Exists(p => p.Position.Equals(left)))
- {
- mainVertices.Add(new WaterMolecule(left, Vector3.Zero, new Vector2(left.X, left.Z), new Vector2(wavefactor)));
- hashTable.Add(left, mainVertices.Count - 1);
- }
- if (!mainVertices.Exists(p => p.Position.Equals(leftForward)))
- {
- mainVertices.Add(new WaterMolecule(leftForward, Vector3.Zero, new Vector2(leftForward.X, leftForward.Z), new Vector2(wavefactor)));
- hashTable.Add(leftForward, mainVertices.Count - 1);
- }
- vertexIndices.Add(hashTable[local]);
- vertexIndices.Add(hashTable[left]);
- vertexIndices.Add(hashTable[leftForward]);
- vertexIndices.Add(hashTable[leftForward]);
- vertexIndices.Add(hashTable[forward]);
- vertexIndices.Add(hashTable[local]);
- ReInitialize();
- }
- private void ReInitialize()
- {
- VertexBuffer = new DynamicVertexBuffer(Device, typeof(WaterMolecule), mainVertices.Count, BufferUsage.None);
- IndexBuffer = new DynamicIndexBuffer(Device, IndexElementSize.ThirtyTwoBits, vertexIndices.Count, BufferUsage.None);
- VertexBuffer.SetData<WaterMolecule>(mainVertices.ToArray());
- IndexBuffer.SetData<int>(vertexIndices.ToArray());
- vertexPuffer = mainVertices.ToArray();
- mainVertices.Clear();
- }
- private void SetUpN()
- {
- Task.Run(() =>
- {
- for (int i = 0; i < vertexPuffer.Length; i++)
- {
- WaterMolecule molecule = vertexPuffer[i];
- float waveFactor = molecule.WaveFactor.X;
- Vector3 suVector = molecule.Position;
- Vector3 aVector = Vector3.Zero;
- Vector3 bVecot = Vector3.Zero;
- int index0 = 0;
- int index1 = 0;
- var a = hashTable.TryGetValue(new Vector3(suVector.X + 1, suVector.Y, suVector.Z), out index0);
- var b = hashTable.TryGetValue(new Vector3(suVector.X, suVector.Y, suVector.Z + 1), out index1);
- if (a)
- aVector = vertexPuffer[index0].Position;
- if (b)
- bVecot = vertexPuffer[index1].Position;
- suVector.Y += 0.35f * (float)(Math.Sin(animationTime * waveFactor));
- Vector3 dir0 = aVector - suVector;
- Vector3 dir1 = bVecot - suVector;
- Vector3 n = Vector3.Cross(dir0, dir1);
- molecule.Normal = n * n;
- vertexPuffer[i] = molecule;
- }
- });
- }
- public void Update(GameTime gTime)
- {
- animationTime += 25.0f * (float)gTime.ElapsedGameTime.TotalSeconds;
- SetUpN();
- waveEffect.Parameters["GlobalTime"].SetValue(animationTime);
- }
- public void Render(Matrix view, Matrix projection, Matrix world)
- {
- if (VertexBuffer == null)
- return;
- Task.Run(() =>
- {
- VertexBuffer.SetData<WaterMolecule>(vertexPuffer);
- });
- Device.SetVertexBuffer(VertexBuffer);
- Device.Indices = IndexBuffer;
- waveEffect.CurrentTechnique = waveEffect.Techniques["main"];
- waveEffect.Parameters["Texture0"].SetValue(waterTexture);
- waveEffect.Parameters["World"].SetValue(world);
- waveEffect.Parameters["View"].SetValue(view);
- waveEffect.Parameters["Projection"].SetValue(projection);
- waveEffect.Parameters["WorldInverseTranspose"].SetValue(Matrix.Transpose(Matrix.Invert(world)));
- waveEffect.CurrentTechnique.Passes[0].Apply();
- Device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, vertexPuffer.Length * 2);
- }
- }
WaterMolecule-Vertex-Deklaration:
C#-Quellcode
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public struct WaterMolecule : IVertexType
- {
- private static VertexDeclaration VertexPositionMolecule = new VertexDeclaration
- (
- new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
- new VertexElement(12, VertexElementFormat.Vector3, VertexElementUsage.Normal, 0),
- new VertexElement(24, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0),
- new VertexElement(32, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 1)
- );
- public VertexDeclaration VertexDeclaration
- {
- get { return VertexPositionMolecule; }
- }
- public Vector3 Position;
- public Vector3 Normal;
- public Vector2 TextureCoordinate;
- public Vector2 WaveFactor;
- public WaterMolecule(Vector3 position, Vector3 normal, Vector2 textureCoordinate, Vector2 wavefac)
- : this()
- {
- Position = position;
- Normal = normal;
- TextureCoordinate = textureCoordinate;
- WaveFactor = wavefac;
- }
- }
Die HLSL Klasse:
C#-Quellcode
- #if OPENGL
- #define VS_SHADERMODEL vs_4_0
- #define PS_SHADERMODEL ps_4_0
- #else
- #define VS_SHADERMODEL vs_4_0_level_9_1
- #define PS_SHADERMODEL ps_4_0_level_9_1
- #endif
- float4x4 World;
- float4x4 View;
- float4x4 Projection;
- Texture Texture0;
- sampler Sampler0 = sampler_state {
- Texture = (Texture0);
- MinFilter = Linear;
- MagFilter = Linear;
- AddressU = Clamp;
- AddressV = Clamp;
- };
- float GlobalTime;
- float4 AmbientColor = float4(1, 1, 1, 1);
- float AmbientIntensity = 0.1;
- float4x4 WorldInverseTranspose;
- float3 DiffuseLightDirection = float3(1, 0, 0);
- float4 DiffuseColor = float4(1, 1, 1, 1);
- float DiffuseIntensity = 5;
- float Shininess = 450;
- float4 SpecularColor = float4(1, 1, 1, 1);
- float SpecularIntensity = .15f;
- float3 ViewVector = float3(1, 0, .1f);
- struct VertexShaderInput
- {
- float4 Position : POSITION0;
- float4 Normal : NORMAL0;
- float2 TextureCoordinates : TEXCOORD0;
- float2 WaveValue: TEXCOORD1;
- };
- struct VertexShaderOutput
- {
- float4 Position : POSITION0;
- float2 TextureCoordinates : TEXCOORD0;
- float3 Normal : TEXCOORD1;
- float4 Color : COLOR0;
- };
- VertexShaderOutput MainVS(VertexShaderInput input)
- {
- VertexShaderOutput output;
- float4 worldPosition = mul(input.Position, World);
- float4 viewPosition = mul(worldPosition, View);
- float4 pos = mul(viewPosition, Projection);
- output.Position = float4(pos.x, pos.y + 0.45f * sin(GlobalTime * input.WaveValue.x), pos.z, pos.w);
- float4 normal = normalize(mul(input.Normal, WorldInverseTranspose));
- float lightIntensity = dot(normal, float4(DiffuseLightDirection.x,DiffuseLightDirection.y,DiffuseLightDirection.z, .3f));
- output.Color = saturate(DiffuseColor * DiffuseIntensity * lightIntensity);
- output.Normal = float3(input.Normal.x, input.Normal.y, input.Normal.z);
- output.TextureCoordinates = input.TextureCoordinates;
- return output;
- }
- float4 MainPS(VertexShaderOutput input) : COLOR
- {
- float3 light = normalize(DiffuseLightDirection);
- float3 normal = normalize(input.Normal);
- float3 r = normalize(2 * dot(light, normal) * normal - light);
- float4 multiplication = mul(normalize(float4(ViewVector.x,ViewVector.y,ViewVector.z,1)), World);
- float3 v = normalize(multiplication.xyz);
- float dotProduct = dot(r, v.xyz);
- float4 specular = SpecularIntensity * SpecularColor * max(pow(abs(dotProduct), Shininess), 0) * length(input.Color);
- float4 textureColor = tex2D(Sampler0, input.TextureCoordinates);
- textureColor.a = .35f;
- return saturate(textureColor * (input.Color) + AmbientColor * AmbientIntensity + specular);
- }
- technique main
- {
- pass P0
- {
- VertexShader = compile VS_SHADERMODEL MainVS();
- PixelShader = compile PS_SHADERMODEL MainPS();
- }
- };
Im Anhang ein Exempel ( =
Und Gott alleine weiß alles am allerbesten und besser.
Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „φConst“ ()