GithubHelp home page GithubHelp logo

meshgradient's Introduction

MeshGradient

Metal-based implementation of beautiful mesh gradient. Image worth thousands of words, so just let me show you.

Mesh gradient gif

How to generate mesh

Small notes before I show you the code. This mesh is generated from the constants you provide. To create mesh you have to provide grid with ControlPoint matrix that describe your gradient (just like with other gradients, huh?):

  • You need to provide colors for gradient - that is obvious, right?
  • You need to provide locations of control points. Locations are in metal coordinate space - that one is a bit scarier. Relax, it is just values in -1...1
  • You need to provide how turbulent your mesh is. This is uTangent and vTangent exists for.

Again, don't be scared. You have all the randomizers out of the box and they are pretty easy to use.

Now, to the code:

typealias MeshColor = SIMD3<Float>

// You can provide custom `locationRandomizer` and `turbulencyRandomizer` for advanced usage
var meshRandomizer = MeshRandomizer(colorRandomizer: MeshRandomizer.arrayBasedColorRandomizer(availableColors: meshColors))

private var meshColors: [simd_float3] {
 return [
  MeshRandomizer.randomColor(),
  MeshRandomizer.randomColor(),
  MeshRandomizer.randomColor(),
 ]
}

// This methods prepares the grid model that will be sent to metal for rendering
func generatePlainGrid(size: Int = 6) -> Grid<ControlPoint> {
  let preparationGrid = Grid<MeshColor>(repeating: .zero, width: size, height: size)
  
  // At first we create grid without randomisation. This is smooth mesh gradient without 
  // any turbulency and overlaps
  var result = MeshGenerator.generate(colorDistribution: preparationGrid)

  // And here we shuffle the grid using randomizer that we created
  for x in stride(from: 0, to: result.width, by: 1) {
   for y in stride(from: 0, to: result.height, by: 1) {
    meshRandomizer.locationRandomizer(&result[x, y].location, x, y, result.width, result.height)
    meshRandomizer.turbulencyRandomizer(&result[x, y].uTangent, x, y, result.width, result.height)
    meshRandomizer.turbulencyRandomizer(&result[x, y].vTangent, x, y, result.width, result.height)

    meshRandomizer.colorRandomizer(&result[x, y].color, result[x, y].color, x, y, result.width, result.height)
   }
  }

  return result
}

SwiftUI

// If you want just show static grid without any animations
struct MyStaticGrid: View {
 var body: some View {
  MeshGradient(grid: generatePlainGrid())
 }
}

struct MyAnimatedGrid: View {

 // MeshRandomizer is a plain struct with just the functions. So you can dynamically change it!
 @State var meshRandomizer = MeshRandomizer(colorRandomizer: MeshRandomizer.arrayBasedColorRandomizer(availableColors: meshColors))

 var body: some View {
  MeshGradient(initialGrid: generatePlainGrid(), 
    		   animatorConfiguration: .init(animationSpeedRange: 2 ... 4, meshRandomizer: meshRandomizer)))
 }
}

UIKit

Use MTKView and MetalMeshRenderer. I hope you have minimal knowledge in metal rendering. Good luck ;) Check source code of SwiftUI MeshGradient implementation that just wraps MTKView.

meshgradient's People

Contributors

juliensagot avatar patskovn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

meshgradient's Issues

new

typealias MeshColor = SIMD3

// You can provide custom locationRandomizer and turbulencyRandomizer for advanced usage
var meshRandomizer = MeshRandomizer(colorRandomizer: MeshRandomizer.arrayBasedColorRandomizer(availableColors: meshColors))

private var meshColors: [simd_float3] {
return [
MeshRandomizer.randomColor(),
MeshRandomizer.randomColor(),
MeshRandomizer.randomColor(),
]
}

// This methods prepares the grid model that will be sent to metal for rendering
func generatePlainGrid(size: Int = 6) -> Grid {
let preparationGrid = Grid(repeating: .zero, width: size, height: size)

// At first we create grid without randomisation. This is smooth mesh gradient without
// any turbulency and overlaps
var result = MeshGenerator.generate(colorDistribution: preparationGrid)

// And here we shuffle the grid using randomizer that we created
for x in stride(from: 0, to: result.width, by: 1) {
for y in stride(from: 0, to: result.height, by: 1) {
meshRandomizer.locationRandomizer(&result[x, y].location, x, y, result.width, result.height)
meshRandomizer.turbulencyRandomizer(&result[x, y].uTangent, x, y, result.width, result.height)
meshRandomizer.turbulencyRandomizer(&result[x, y].vTangent, x, y, result.width, result.height)

meshRandomizer.colorRandomizer(&result[x, y].color, result[x, y].color, x, y, result.width, result.height)

}
}

return result
}

Crash when keyboard is shown

Hello!

First of all, thanks a lot for creating this wonderful library.

I am planning to use it in one of my apps, but I stumbled across a crash when the iOS keyboard is shown.

I am able to reproduce this 100% of times, happy to provide more data if you need.

This is the crash:

-[MTLTextureDescriptorInternal validateWithDevice:], line 1357: error 'Texture Descriptor Validation
MTLTextureDescriptor has height of zero.
'

this is the LOC that is causing the problem in MTLComputeNoiseFunction.swift:

guard let noiseTexture = device.**makeTexture**(descriptor: textureDescriptor),
              let encoder = commandBuffer.makeComputeCommandEncoder()

Let me know if you need any more information!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.