| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- /*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
- #include <Atom/Features/SrgSemantics.azsli>
- #include <Atom/RPI/Math.azsli>
- ShaderResourceGroup PassSrg : SRG_PerPass
- {
- StructuredBuffer<float3> m_sourceVertexData;
- RWStructuredBuffer<float3> m_targetVertexData;
- StructuredBuffer<float3> m_instanceOffsetData;
- float m_frameTime;
- uint m_vertexCountPerInstance;
- uint m_targetVertexStridePerInstance;
- }
- class ContinuousSineRng
- {
- uint m_seed;
- float m_timeshift;
- void Initialize(float3 position, uint instanceIndex, float timeshift)
- {
- m_seed = 0;
- m_seed ^= asuint(position.x);
- Xorshift(m_seed);
- m_seed ^= asuint(position.y);
- Xorshift(m_seed);
- m_seed ^= asuint(position.z);
- Xorshift(m_seed);
- m_seed ^= instanceIndex;
- Xorshift(m_seed);
- m_timeshift = timeshift;
- }
- float GetRandomNormalizedFloat()
- {
- // Duration in seconds after which the animation repeats
- float animationDuration = (Xorshift(m_seed) % 60 + 120) / 60.f;
- // The float values passed to the sin-function should not be too large, otherwise the result is not continuous
- uint seedSmall = m_seed % 1024;
- float timeshiftSmall = (m_timeshift % animationDuration) / animationDuration * TWO_PI;
- return sin(seedSmall + timeshiftSmall) * 0.5f + 0.5f;
- }
- float3 GetRandomUnitSphereDirection()
- {
- float z = GetRandomNormalizedFloat() * 2.f - 1.f;
- float phi = GetRandomNormalizedFloat() * TWO_PI;
- float rxy = sqrt(1.f - z * z);
- float x = rxy * cos(phi);
- float y = rxy * sin(phi);
- return normalize(float3(x, y, z));
- }
- };
- [numthreads(64, 1, 1)]
- void AnimateVertices(uint3 dispatchId : SV_DispatchThreadID)
- {
- uint instanceIndex = dispatchId.x / PassSrg::m_vertexCountPerInstance;
- uint inputIndex = dispatchId.x % PassSrg::m_vertexCountPerInstance;
- uint outputIndex = instanceIndex * PassSrg::m_targetVertexStridePerInstance + inputIndex;
- ContinuousSineRng rng;
- rng.Initialize(PassSrg::m_sourceVertexData[inputIndex], instanceIndex, PassSrg::m_frameTime);
- // Animated the vertices by displacing each vertex in a random direction by a random amount
- float3 animationMoveDirection = rng.GetRandomUnitSphereDirection();
- float animationMoveAmount = rng.GetRandomNormalizedFloat() * 0.02f;
- // Need to move vertices per instance in the compute shader since CLAS does not have a separate transform
- float3 vertexBaseLocation = PassSrg::m_instanceOffsetData[instanceIndex] + PassSrg::m_sourceVertexData[inputIndex];
- PassSrg::m_targetVertexData[outputIndex] = vertexBaseLocation + animationMoveDirection * animationMoveAmount;
- }
|