or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-execution.mdfem.mdframework-integration.mdindex.mdkernel-programming.mdoptimization.mdrendering.mdtypes-arrays.mdutilities.md

rendering.mddocs/

0

# Rendering

1

2

Warp provides rendering capabilities for visualizing simulation results and creating graphics output. The rendering module supports both OpenGL-based real-time rendering and USD-based offline rendering for production workflows.

3

4

## Capabilities

5

6

### OpenGL Renderer

7

8

Real-time OpenGL-based renderer for interactive visualization and debugging.

9

10

```python { .api }

11

class OpenGLRenderer:

12

"""OpenGL-based real-time renderer."""

13

14

def __init__(self, width: int, height: int, headless: bool = False):

15

"""

16

Create OpenGL renderer with specified resolution.

17

18

Args:

19

width: Render target width in pixels

20

height: Render target height in pixels

21

headless: Enable headless rendering (no window)

22

"""

23

24

def render(self, mesh: Mesh, camera_pos: vec3, camera_target: vec3) -> None:

25

"""

26

Render mesh with specified camera parameters.

27

28

Args:

29

mesh: Triangle mesh to render

30

camera_pos: Camera position in world space

31

camera_target: Camera look-at target

32

"""

33

34

def render_points(self,

35

positions: array,

36

colors: array = None,

37

point_size: float = 1.0) -> None:

38

"""

39

Render point cloud.

40

41

Args:

42

positions: Array of 3D point positions

43

colors: Array of point colors (optional)

44

point_size: Size of rendered points

45

"""

46

47

def render_lines(self,

48

positions: array,

49

indices: array,

50

colors: array = None,

51

line_width: float = 1.0) -> None:

52

"""

53

Render line segments.

54

55

Args:

56

positions: Array of vertex positions

57

indices: Array of line segment indices

58

colors: Array of line colors (optional)

59

line_width: Width of rendered lines

60

"""

61

62

def set_camera(self,

63

pos: vec3,

64

target: vec3,

65

up: vec3 = vec3(0, 1, 0)) -> None:

66

"""Set camera position and orientation."""

67

68

def set_projection(self,

69

fov: float = 45.0,

70

near: float = 0.1,

71

far: float = 1000.0) -> None:

72

"""Set camera projection parameters."""

73

74

def clear(self, color: vec4 = vec4(0, 0, 0, 1)) -> None:

75

"""Clear render target with specified color."""

76

77

def present(self) -> None:

78

"""Present rendered frame to display."""

79

80

def save_image(self, filename: str) -> None:

81

"""Save rendered frame to image file."""

82

83

def get_pixels(self) -> array:

84

"""Get rendered pixels as array."""

85

86

def close(self) -> None:

87

"""Clean up renderer resources."""

88

```

89

90

### USD Renderer

91

92

Universal Scene Description (USD) renderer for production-quality output and film workflows.

93

94

```python { .api }

95

class UsdRenderer:

96

"""USD-based renderer for production workflows."""

97

98

def __init__(self, stage_path: str):

99

"""

100

Create USD renderer with specified stage.

101

102

Args:

103

stage_path: Path to USD stage file

104

"""

105

106

def add_mesh(self,

107

mesh: Mesh,

108

transform: mat44 = None,

109

material_path: str = None) -> str:

110

"""

111

Add mesh to USD stage.

112

113

Args:

114

mesh: Triangle mesh to add

115

transform: World transformation matrix

116

material_path: Path to material definition

117

118

Returns:

119

USD prim path for added mesh

120

"""

121

122

def add_points(self,

123

positions: array,

124

radii: array = None,

125

colors: array = None) -> str:

126

"""

127

Add point instances to USD stage.

128

129

Args:

130

positions: Array of point positions

131

radii: Array of point radii (optional)

132

colors: Array of point colors (optional)

133

134

Returns:

135

USD prim path for point instances

136

"""

137

138

def add_camera(self,

139

pos: vec3,

140

target: vec3,

141

up: vec3 = vec3(0, 1, 0),

142

fov: float = 45.0) -> str:

143

"""

144

Add camera to USD stage.

145

146

Returns:

147

USD prim path for camera

148

"""

149

150

def add_light(self,

151

light_type: str,

152

intensity: float = 1.0,

153

color: vec3 = vec3(1, 1, 1),

154

transform: mat44 = None) -> str:

155

"""

156

Add light to USD stage.

157

158

Args:

159

light_type: Type of light ('distant', 'sphere', 'rect')

160

intensity: Light intensity

161

color: Light color

162

transform: Light transformation

163

164

Returns:

165

USD prim path for light

166

"""

167

168

def set_time_sample(self, frame: int, time: float) -> None:

169

"""Set time sample for animation."""

170

171

def save(self, output_path: str = None) -> None:

172

"""

173

Save USD stage to file.

174

175

Args:

176

output_path: Output file path (uses stage_path if None)

177

"""

178

179

def render_frame(self,

180

camera_path: str,

181

output_image: str,

182

width: int = 1920,

183

height: int = 1080) -> None:

184

"""

185

Render single frame to image file.

186

187

Args:

188

camera_path: USD path to camera

189

output_image: Output image file path

190

width: Image width in pixels

191

height: Image height in pixels

192

"""

193

```

194

195

### Rendering Utilities

196

197

Utility functions for color mapping and visualization helpers.

198

199

```python { .api }

200

def bourke_color_map(value: float, min_val: float, max_val: float) -> vec3:

201

"""

202

Map scalar value to Bourke color scheme.

203

204

Args:

205

value: Scalar value to map

206

min_val: Minimum value in range

207

max_val: Maximum value in range

208

209

Returns:

210

RGB color as vec3

211

"""

212

```

213

214

## Usage Examples

215

216

### Basic OpenGL Rendering

217

```python

218

import warp as wp

219

import warp.render as render

220

import numpy as np

221

222

# Create renderer

223

renderer = render.OpenGLRenderer(width=800, height=600)

224

225

# Create simple mesh (triangle)

226

vertices = wp.array([

227

[0.0, 1.0, 0.0], # Top vertex

228

[-1.0, -1.0, 0.0], # Bottom left

229

[1.0, -1.0, 0.0] # Bottom right

230

], dtype=wp.vec3, device='cuda')

231

232

indices = wp.array([

233

[0, 1, 2] # Single triangle

234

], dtype=wp.int32, device='cuda')

235

236

mesh = wp.Mesh(vertices, indices)

237

238

# Set up camera

239

camera_pos = wp.vec3(0, 0, 5)

240

camera_target = wp.vec3(0, 0, 0)

241

renderer.set_camera(camera_pos, camera_target)

242

243

# Render loop

244

for frame in range(100):

245

renderer.clear()

246

renderer.render(mesh, camera_pos, camera_target)

247

renderer.present()

248

249

# Rotate camera

250

angle = frame * 0.1

251

camera_pos = wp.vec3(5 * np.sin(angle), 0, 5 * np.cos(angle))

252

253

# Save final frame

254

renderer.save_image("output.png")

255

renderer.close()

256

```

257

258

### Point Cloud Visualization

259

```python

260

import warp as wp

261

import warp.render as render

262

263

# Generate random point cloud

264

num_points = 10000

265

positions = wp.array(np.random.randn(num_points, 3).astype(np.float32),

266

device='cuda')

267

268

# Color points based on height

269

@wp.kernel

270

def color_by_height(positions: wp.array(dtype=wp.vec3),

271

colors: wp.array(dtype=wp.vec3)):

272

i = wp.tid()

273

pos = positions[i]

274

275

# Map Y coordinate to color

276

height = pos[1]

277

color = render.bourke_color_map(height, -3.0, 3.0)

278

colors[i] = color

279

280

colors = wp.zeros(num_points, dtype=wp.vec3, device='cuda')

281

wp.launch(color_by_height, dim=num_points, inputs=[positions, colors])

282

283

# Render point cloud

284

renderer = render.OpenGLRenderer(1024, 768)

285

renderer.set_camera(wp.vec3(5, 5, 5), wp.vec3(0, 0, 0))

286

287

renderer.clear()

288

renderer.render_points(positions, colors, point_size=2.0)

289

renderer.save_image("point_cloud.png")

290

```

291

292

### Animation with USD

293

```python

294

import warp as wp

295

import warp.render as render

296

297

# Create USD renderer

298

usd_renderer = render.UsdRenderer("animation.usda")

299

300

# Add camera

301

camera_path = usd_renderer.add_camera(

302

pos=wp.vec3(10, 10, 10),

303

target=wp.vec3(0, 0, 0)

304

)

305

306

# Add light

307

usd_renderer.add_light(

308

light_type='distant',

309

intensity=2.0,

310

color=wp.vec3(1, 0.9, 0.8)

311

)

312

313

# Simulate and render animation

314

num_frames = 120

315

dt = 1.0 / 60.0

316

317

# Initialize particle system

318

positions = wp.zeros(1000, dtype=wp.vec3, device='cuda')

319

velocities = wp.zeros(1000, dtype=wp.vec3, device='cuda')

320

321

@wp.kernel

322

def update_particles(positions: wp.array(dtype=wp.vec3),

323

velocities: wp.array(dtype=wp.vec3),

324

dt: float):

325

i = wp.tid()

326

327

# Simple gravity simulation

328

gravity = wp.vec3(0, -9.81, 0)

329

velocities[i] = velocities[i] + gravity * dt

330

positions[i] = positions[i] + velocities[i] * dt

331

332

# Bounce off ground

333

if positions[i][1] < 0.0:

334

positions[i] = wp.vec3(positions[i][0], 0.0, positions[i][2])

335

velocities[i] = wp.vec3(velocities[i][0], -0.8 * velocities[i][1], velocities[i][2])

336

337

# Animation loop

338

for frame in range(num_frames):

339

# Update simulation

340

wp.launch(update_particles, dim=1000, inputs=[positions, velocities, dt])

341

342

# Set time sample

343

time = frame * dt

344

usd_renderer.set_time_sample(frame, time)

345

346

# Add particles for this frame

347

point_path = usd_renderer.add_points(

348

positions,

349

radii=wp.full(1000, 0.05, device='cuda')

350

)

351

352

# Save USD file

353

usd_renderer.save("particle_animation.usda")

354

355

# Render frames

356

for frame in range(0, num_frames, 5): # Every 5th frame

357

usd_renderer.render_frame(

358

camera_path,

359

f"frame_{frame:04d}.png",

360

width=1920,

361

height=1080

362

)

363

```

364

365

### Mesh Visualization with Materials

366

```python

367

import warp as wp

368

import warp.render as render

369

370

# Create complex mesh (sphere)

371

def create_sphere_mesh(radius: float, resolution: int):

372

# Generate sphere vertices and indices

373

vertices = []

374

indices = []

375

376

for i in range(resolution + 1):

377

for j in range(resolution + 1):

378

theta = np.pi * i / resolution

379

phi = 2 * np.pi * j / resolution

380

381

x = radius * np.sin(theta) * np.cos(phi)

382

y = radius * np.cos(theta)

383

z = radius * np.sin(theta) * np.sin(phi)

384

385

vertices.append([x, y, z])

386

387

# Generate triangle indices

388

for i in range(resolution):

389

for j in range(resolution):

390

v0 = i * (resolution + 1) + j

391

v1 = v0 + 1

392

v2 = (i + 1) * (resolution + 1) + j

393

v3 = v2 + 1

394

395

indices.append([v0, v2, v1])

396

indices.append([v1, v2, v3])

397

398

return wp.array(vertices, dtype=wp.vec3), wp.array(indices, dtype=wp.int32)

399

400

# Create sphere mesh

401

vertices, indices = create_sphere_mesh(radius=2.0, resolution=32)

402

sphere_mesh = wp.Mesh(vertices, indices)

403

404

# OpenGL rendering with lighting

405

renderer = render.OpenGLRenderer(1200, 800)

406

renderer.set_camera(wp.vec3(0, 0, 8), wp.vec3(0, 0, 0))

407

renderer.set_projection(fov=60.0)

408

409

# Render with rotation

410

for frame in range(360):

411

renderer.clear(wp.vec4(0.1, 0.1, 0.2, 1.0))

412

413

# Rotate mesh

414

angle = frame * np.pi / 180

415

transform = wp.mat44(

416

np.cos(angle), 0, np.sin(angle), 0,

417

0, 1, 0, 0,

418

-np.sin(angle), 0, np.cos(angle), 0,

419

0, 0, 0, 1

420

)

421

422

renderer.render(sphere_mesh, renderer.camera_pos, renderer.camera_target)

423

424

if frame % 30 == 0: # Save every 30 frames

425

renderer.save_image(f"sphere_{frame:03d}.png")

426

427

renderer.close()

428

```

429

430

### Real-time Simulation Visualization

431

```python

432

import warp as wp

433

import warp.render as render

434

435

# Set up simulation

436

@wp.kernel

437

def cloth_simulation(positions: wp.array(dtype=wp.vec3),

438

velocities: wp.array(dtype=wp.vec3),

439

forces: wp.array(dtype=wp.vec3),

440

dt: float):

441

i = wp.tid()

442

443

# Apply forces and integrate

444

vel = velocities[i] + forces[i] * dt

445

pos = positions[i] + vel * dt

446

447

# Simple constraints

448

if pos[1] < 0.0: # Ground constraint

449

pos = wp.vec3(pos[0], 0.0, pos[2])

450

vel = wp.vec3(vel[0], 0.0, vel[2])

451

452

positions[i] = pos

453

velocities[i] = vel

454

455

# Initialize cloth mesh

456

cloth_res = 32

457

cloth_positions = wp.zeros(cloth_res * cloth_res, dtype=wp.vec3, device='cuda')

458

cloth_velocities = wp.zeros_like(cloth_positions)

459

cloth_forces = wp.zeros_like(cloth_positions)

460

461

# Create renderer

462

renderer = render.OpenGLRenderer(1024, 768)

463

renderer.set_camera(wp.vec3(5, 5, 5), wp.vec3(0, 0, 0))

464

465

# Real-time simulation loop

466

dt = 1.0 / 60.0

467

running = True

468

469

while running:

470

# Update simulation

471

wp.launch(cloth_simulation,

472

dim=cloth_res * cloth_res,

473

inputs=[cloth_positions, cloth_velocities, cloth_forces, dt])

474

475

# Render frame

476

renderer.clear()

477

renderer.render_points(cloth_positions, point_size=3.0)

478

renderer.present()

479

480

# Check for exit condition

481

# running = check_user_input() # Implementation dependent

482

```

483

484

## Types

485

486

```python { .api }

487

# Renderer types

488

class Renderer:

489

"""Base renderer interface."""

490

491

def render(self, *args, **kwargs) -> None:

492

"""Render scene objects."""

493

494

def save(self, filename: str) -> None:

495

"""Save rendered output."""

496

497

# Mesh type for rendering

498

class RenderMesh:

499

"""Mesh optimized for rendering."""

500

501

vertices: array # Vertex positions

502

indices: array # Triangle indices

503

normals: array # Vertex normals (optional)

504

uvs: array # Texture coordinates (optional)

505

colors: array # Vertex colors (optional)

506

507

# Camera parameters

508

class Camera:

509

"""Camera configuration."""

510

511

position: vec3 # Camera position

512

target: vec3 # Look-at target

513

up: vec3 # Up vector

514

fov: float # Field of view (degrees)

515

near: float # Near clipping plane

516

far: float # Far clipping plane

517

518

# Light configuration

519

class Light:

520

"""Light source configuration."""

521

522

type: str # Light type ('distant', 'point', 'spot')

523

position: vec3 # Light position

524

direction: vec3 # Light direction

525

intensity: float # Light intensity

526

color: vec3 # Light color

527

528

# Material properties

529

class Material:

530

"""Rendering material properties."""

531

532

diffuse_color: vec3 # Base color

533

metallic: float # Metallic factor

534

roughness: float # Surface roughness

535

emission: vec3 # Emissive color

536

```