use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "camelCase")]
pub enum ShaderNode {
MaterialOutput {
surface: Box<ShaderNode>,
},
PrincipledBsdf {
#[serde(alias = "baseColor")]
base_color: Box<ShaderNode>,
metallic: Box<ShaderNode>,
roughness: Box<ShaderNode>,
#[serde(default, skip_serializing_if = "Option::is_none")]
normal: Option<Box<ShaderNode>>,
emission: Box<ShaderNode>,
#[serde(alias = "emissionStrength")]
emission_strength: Box<ShaderNode>,
#[serde(default, skip_serializing_if = "Option::is_none")]
ao: Option<Box<ShaderNode>>,
alpha: Box<ShaderNode>,
#[serde(default, skip_serializing_if = "Option::is_none")]
subsurface: Option<Box<ShaderNode>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[serde(alias = "subsurfaceColor")]
subsurface_color: Option<Box<ShaderNode>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
clearcoat: Option<Box<ShaderNode>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[serde(alias = "clearcoatRoughness")]
clearcoat_roughness: Option<Box<ShaderNode>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
anisotropic: Option<Box<ShaderNode>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[serde(alias = "anisotropicRotation")]
anisotropic_rotation: Option<Box<ShaderNode>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
sheen: Option<Box<ShaderNode>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[serde(alias = "sheenTint")]
sheen_tint: Option<Box<ShaderNode>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
transmission: Option<Box<ShaderNode>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
ior: Option<Box<ShaderNode>>,
},
ImageTexture {
#[serde(alias = "assetId")]
asset_id: String,
uv: Box<ShaderNode>,
},
NoiseTexture {
scale: Box<ShaderNode>,
detail: Box<ShaderNode>,
roughness: Box<ShaderNode>,
},
VoronoiTexture {
scale: Box<ShaderNode>,
randomness: Box<ShaderNode>,
},
CheckerTexture {
scale: Box<ShaderNode>,
color1: Box<ShaderNode>,
color2: Box<ShaderNode>,
},
GradientTexture {
#[serde(alias = "gradientType")]
gradient_type: GradientType,
},
BrickTexture {
scale: Box<ShaderNode>,
#[serde(alias = "mortarSize")]
mortar_size: Box<ShaderNode>,
color1: Box<ShaderNode>,
color2: Box<ShaderNode>,
#[serde(alias = "mortarColor")]
mortar_color: Box<ShaderNode>,
},
MusgraveTexture {
scale: Box<ShaderNode>,
detail: Box<ShaderNode>,
dimension: Box<ShaderNode>,
},
WaveTexture {
#[serde(alias = "waveType")]
wave_type: WaveType,
scale: Box<ShaderNode>,
distortion: Box<ShaderNode>,
},
WhiteNoiseTexture,
EnvironmentTexture {
#[serde(alias = "assetId")]
asset_id: String,
},
SkyTexture {
#[serde(alias = "sunDirection")]
sun_direction: Box<ShaderNode>,
turbidity: Box<ShaderNode>,
},
TexCoord,
ObjectPosition,
ObjectNormal,
CameraVector,
VertexColor,
Tangent,
Time,
MathOp {
op: MathOpType,
a: Box<ShaderNode>,
#[serde(default, skip_serializing_if = "Option::is_none")]
b: Option<Box<ShaderNode>>,
},
ColorMix {
mode: MixMode,
fac: Box<ShaderNode>,
a: Box<ShaderNode>,
b: Box<ShaderNode>,
},
ColorRamp {
stops: Vec<ColorStop>,
input: Box<ShaderNode>,
},
SeparateXYZ {
input: Box<ShaderNode>,
component: String, },
CombineXYZ {
x: Box<ShaderNode>,
y: Box<ShaderNode>,
z: Box<ShaderNode>,
},
Fresnel {
ior: Box<ShaderNode>,
},
BumpMap {
strength: Box<ShaderNode>,
height: Box<ShaderNode>,
},
NormalMap {
strength: Box<ShaderNode>,
color: Box<ShaderNode>,
},
Mapping {
location: [f32; 3],
rotation: [f32; 3],
scale: [f32; 3],
input: Box<ShaderNode>,
},
Clamp {
input: Box<ShaderNode>,
#[serde(alias = "minVal")]
min_val: f32,
#[serde(alias = "maxVal")]
max_val: f32,
},
MapRange {
input: Box<ShaderNode>,
#[serde(alias = "fromMin")]
from_min: f32,
#[serde(alias = "fromMax")]
from_max: f32,
#[serde(alias = "toMin")]
to_min: f32,
#[serde(alias = "toMax")]
to_max: f32,
},
Displacement {
height: Box<ShaderNode>,
midlevel: Box<ShaderNode>,
scale: Box<ShaderNode>,
},
ConstFloat {
c: f32,
},
ConstVec3 {
c: [f32; 3],
},
ConstVec4 {
c: [f32; 4],
},
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum MathOpType {
Add,
Subtract,
Multiply,
Divide,
Power,
Sqrt,
Abs,
Sin,
Cos,
Tan,
Asin,
Acos,
Atan2,
Min,
Max,
Floor,
Ceil,
Fract,
Modulo,
Smoothstep,
Lerp,
Step,
Sign,
Log,
Exp,
Dot,
Cross,
Normalize,
Length,
Distance,
Reflect,
Negate,
Invert, }
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum MixMode {
Mix,
Add,
Multiply,
Screen,
Overlay,
Darken,
Lighten,
Dodge,
Burn,
SoftLight,
LinearLight,
Difference,
Subtract,
Divide,
Hue,
Saturation,
Color,
Value,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum GradientType {
Linear,
Quadratic,
Easing,
Diagonal,
Spherical,
Radial,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum WaveType {
Bands,
Rings,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ColorStop {
pub position: f32,
pub color: [f32; 4],
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TextureSlot {
pub binding: u32,
pub asset_id: String,
pub label: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VertexAttr {
pub name: String,
pub format: String,
pub offset: u32,
pub shader_location: u32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompiledMaterial {
pub vertex_wgsl: String,
pub fragment_wgsl: String,
pub vertex_stride: u32,
pub vertex_attributes: Vec<VertexAttr>,
pub texture_slots: Vec<TextureSlot>,
pub base_color: [f32; 4],
pub metallic: f32,
pub roughness: f32,
pub emission_color: [f32; 3],
pub emission_strength: f32,
pub ao_strength: f32,
pub pipeline_hash: u64,
}