Skip to content

06 - Terrain and Optical Properties

This chapter introduces LESS's various optical property models and how to set appropriate properties for different scene elements.

Overview of optical properties

LESS provides a variety of optical property models suitable for different surface types:

Property type Applicable objects Features
Lambertian Soil, artificial surface Uniform reflection in all directions, the simplest
Prospect Green leaves Spectrum calculated from leaf biochemical parameters
RPV Any non-Lambertian surface Parametric BRDF model
SpectrumDB / SpectrumLibrary Various surfaces Load measured spectra from built-in database

Lambertian - Lambertian

The Lambertian body is the simplest optical model: incident light is reflected uniformly in all directions.

Scalar reflectance

import less

# Constant reflectivity (same for all wavelengths)
soil = less.Lambertian(reflectance=0.15)

Spectral reflectance

import numpy as np

# Specify wavelength and corresponding reflectance
wavelengths = [400, 500, 600, 700, 800, 900, 1000]
reflectance = [0.03, 0.05, 0.08, 0.10, 0.25, 0.30, 0.32]

soil = less.Lambertian(
    reflectance=reflectance,
    wavelengths=wavelengths,
)

When the simulated band is not in the given wavelength list, LESS automatically performs linear interpolation.

Transmission properties

For translucent materials such as blades, Lambertian also supports transmittance:

# Simple green leaves (not recommended, Prospect is more accurate)
simple_leaf = less.Lambertian(
    reflectance=0.1,
    transmittance=0.05,
)

Prospect —— Blade optical model

Prospect is the most widely used blade optical model in remote sensing. It calculates the complete reflectance and transmittance spectrum in the range 400-2500 nm based on the biochemical parameters of the leaves (chlorophyll, moisture, etc.).

Parameter description

Parameters Meaning Typical range Units
cab Chlorophyll a+b content 10-80 μg/cm²
car Carotenoid content 5-20 μg/cm²
canth Anthocyanin content 0-40 μg/cm²
cbrown Brown pigment 0-1 Dimensionless
cw Equivalent water thickness 0.005-0.03 cm
cm Dry matter content 0.003-0.015 g/cm²
N Blade structural parameters 1.0-3.0 Dimensionless

Different blade states

# healthy green leaves
green_leaf = less.Prospect(
    cab=45, car=10, canth=0, cbrown=0,
    cw=0.012, cm=0.008, N=1.5,
)

# Senescent yellow leaves
yellow_leaf = less.Prospect(
    cab=5, car=15, canth=0, cbrown=0.3,
    cw=0.008, cm=0.010, N=2.0,
)

# Autumn red leaves (high anthocyanins)
red_leaf = less.Prospect(
    cab=3, car=5, canth=30, cbrown=0.15,
    cw=0.010, cm=0.009, N=1.8,
)

Physical meaning

The core idea of ​​the Prospect model is to treat the blade as a multi-layer parallel plate structure:

  • Chlorophyll (cab): absorbs red and blue light, reflects green light → determines the "green" degree of the leaves
  • Carotenoids (car): absorb blue light → protect chlorophyll
  • Anthocyanin (canth): Absorbs green light → produces red-purple color
  • Moisture (cw): Affects the absorption from near infrared to shortwave infrared
  • Structural parameters (N): The number of air cavities inside the blade → affects near-infrared scattering

RPV - BRDF model

The RPV (Rahman-Pinty-Verstraete) model describes the directional reflection properties of non-Lambertian surfaces:

# Typical forest canopy BRDF
forest_brdf = less.RPV(rho0=0.05, k=0.7, theta=-0.1)
Parameters Meaning
rho0 Total reflectance magnitude
k Bowl/bell parameters (<1 bowl, >1 bell)
theta Forward/Backscatter (<0 Backscatter enhancement, hot spot effect)

The RPV model is described in more detail in Chapter 10 .

SpectrumLibrary - built-in spectral library

LESS has built-in a variety of measured spectral data, covering common natural and artificial surfaces:

lib = less.SpectrumLibrary()

# List all available spectra
names = lib.list_spectra()
for name in names[:10]:
    print(name)

# View data for a spectrum
data = lib.get("birch_leaf_green")
print(f"Wavelength: {data['wavelength'][:5]} ... nm")
print(f"Reflectivity: {data['reflectance'][:5]} ...")

# Convert directly to Property object
birch_leaf = lib.as_property("birch_leaf_green")

Set properties for objects

Single component object

If the OBJ file has only one component (or you want all components to use the same properties), you can leave the component name unspecified:

maize = less.Object("maize", mesh=less.examples.asset_path("maize.obj"))
maize.set_property(less.Prospect(cab=40, car=8, cw=0.012, cm=0.006, N=1.5))

Multi-component objects

FREX.obj (European Ash) has two components: leaves and stem_branch. Different properties can be set for them respectively:

tree = less.Object("ash", mesh=less.examples.asset_path("FREX.obj"))

# View component list
print(tree.components)  # ['leaves', 'stem_branch']

# Blade: Prospect model
tree.set_property("leaves", less.Prospect(cab=40, car=10, cw=0.012, cm=0.008, N=1.5))

# Trunk/Branches: Low Reflectivity Lambertian
tree.set_property("stem_branch", less.Lambertian(reflectance=0.08))

Complete Example: Corn + Soil Scenario

import less
import numpy as np

scene = less.Scene()
scene.size = 10.0

# Soil: Dark Lambertian
scene.terrain = less.Terrain(
    property=less.Lambertian(reflectance=0.12)
)

# illumination
scene.illumination = less.Illumination(source=less.Sun(zenith=30, azimuth=150), atmosphere=less.NoAtmosphere())

# corn
maize = less.Object("maize", mesh=less.examples.asset_path("maize.obj"))
maize.set_property(less.Prospect(cab=45, car=10, cw=0.012, cm=0.006, N=1.55))

# Place 9 corn plants in the scene (3×3 grid)
xs = np.linspace(2, 8, 3)
ys = np.linspace(2, 8, 3)
gx, gy = np.meshgrid(xs, ys)
positions = np.column_stack([gx.ravel(), gy.ravel(), np.zeros(9)])

scene.add(maize, positions=positions)
sensor = less.OpticalImager(
    less.Orthographic(image_size=512),
    bands=[650, 550, 450, 842],   # R, G, B, NIR
    quality=128,
)
image = scene.simulate(sensor)
image.save("06_maize_grid.png")

# Access NIR band data
data = image.data
nir = data[:, :, 3]    # Band 4 = 842 nm (NIR)
red = data[:, :, 0]    # Band 1 = 650 nm (Red)

# Calculate NDVI
ndvi = (nir - red) / (nir + red + 1e-10)
print(f"NDVI range: {ndvi.min():.2f} ~ {ndvi.max():.2f}")

Supporting script: scripts/06_terrain_properties.py

The effect of Prospect parameters on spectrum

Understanding how each Prospect parameter affects the spectrum will help you set simulation parameters correctly:

Band range Main influencing factors
400-500 nm (blue light) cab, car (strong absorption)
500-600 nm (green light) cab (absorption weakened, "green peak")
600-700 nm (red light) cab (red edge absorption), canth (anthocyanin absorption)
700-750 nm (red edge) cab, N (red edge position and slope)
750-1300 nm (near infrared) N (mesophyll scattering), cab No effect
1300-2500 nm (short wave infrared) cw (moisture absorption band), cm (dry matter)

Chlorophyll cab affects almost exclusively the 400-750 nm range. In the near-infrared band, the high reflectivity of leaves is mainly determined by the mesophyll structure (N).

Next step

  • less.Lambertianless.Prospectless.RPV
  • less.SpectrumLibrary
  • less.Sceneless.Terrainless.Object
  • less.Orthographicless.OpticalImager