private void BindShader([MaybeNull] WorldCamera camera, RenderingDevice device, IList <Light3d> lights, MdfRenderOverrides overrides) { // Fill out the globals for the shader var globals = new MdfGlobalConstants(); Matrix4x4 viewProj; if (overrides != null && overrides.uiProjection) { viewProj = device.UiProjection; } else { viewProj = camera?.GetViewProj() ?? device.UiProjection; } // Should we use a separate world matrix? if (overrides != null && overrides.useWorldMatrix) { // Build a world * view * proj matrix var worldViewProj = overrides.worldMatrix * viewProj; globals.viewProj = worldViewProj; } else { globals.viewProj = viewProj; } // Set material diffuse color for shader Vector4 color; // TODO: This is a bug, it should check overrideDiffuse if (overrides != null && overrides.overrideColor != default) { color = overrides.overrideColor.ToRGBA(); } else { color = new PackedLinearColorA(mSpec.diffuse).ToRGBA(); } globals.matDiffuse = color; if (overrides != null && overrides.alpha != 1.0f) { globals.matDiffuse.W *= overrides.alpha; } // Set time for UV animation in minutes as a floating point number var timeInSec = (float)(device.GetLastFrameStart() - device.GetDeviceCreated()).Seconds; globals.uvAnimTime.X = timeInSec / 60.0f; // Clamp to [0, 1] if (globals.uvAnimTime.X > 1) { globals.uvAnimTime.X -= MathF.Floor(globals.uvAnimTime.X); } // Swirl is more complicated due to cos/sin involvement // This means speedU is in "full rotations every 60 seconds" . RPM var uvRotations = globals.UvRotations; for (var i = 0; i < mSpec.samplers.Count; ++i) { var sampler = mSpec.samplers[i]; if (sampler.uvType != MdfUvType.Swirl) { continue; } ref var uvRot = ref uvRotations[i]; uvRot.X = MathF.Cos(sampler.speedU * globals.uvAnimTime.X * MathF.PI * 2) * 0.1f; uvRot.Y = MathF.Sin(sampler.speedV * globals.uvAnimTime.X * MathF.PI * 2) * 0.1f; }