Skip to content
Snippets Groups Projects
Commit 1431d88c authored by Jaswant Panchumarti (Kitware)'s avatar Jaswant Panchumarti (Kitware)
Browse files

webgpu: fix lighting for lines and points

- enables lighting only when interpolation type is not flat and shader is rendering tubes or spheres.
- this logic is similar to vtkOpenGLPolyDataMapper
- updated the layout of ShadeOptions struct in vtkWebGPUActor with new InterpolationType
  member which can be one of VTK_FLAT, VTK_GOURAUD, VTK_PHONG or VTK_PBR. The shaders
  only implement VTK_FLAT for now.
parent 2989712d
No related branches found
No related tags found
No related merge requests found
......@@ -5,6 +5,7 @@
#include "vtkActor.h"
#include "vtkProperty.h" // for VTK_FLAT
#include "vtkRenderingWebGPUModule.h" // for export macro
#include "vtk_wgpu.h" // for return
......@@ -98,6 +99,20 @@ protected:
struct ShadeOptions
{
// Material ambient color - applicable when shading type is global.
vtkTypeFloat32 AmbientColor[3] = {};
vtkTypeUInt32 Pad1 = 0;
// Material diffuse color - applicable when shading type is global.
vtkTypeFloat32 DiffuseColor[3] = {};
vtkTypeUInt32 Pad2 = 0;
// Material specular color - applicable when shading type is global.
vtkTypeFloat32 SpecularColor[3] = {};
vtkTypeUInt32 Pad3 = 0;
// Edge color
vtkTypeFloat32 EdgeColor[3] = {};
vtkTypeUInt32 Pad4 = 0;
// Vertex color
vtkTypeFloat32 VertexColor[3] = {};
// Material ambient color intensity.
vtkTypeFloat32 AmbientIntensity = 0;
// Material diffuse color intensity.
......@@ -108,18 +123,8 @@ protected:
vtkTypeFloat32 SpecularPower = 0;
// Opacity level
vtkTypeFloat32 Opacity = 0;
// So that `AmbientColor` starts at 16-byte boundary.
vtkTypeUInt32 Pad[3];
// Material ambient color - applicable when shading type is global.
vtkTypeFloat32 AmbientColor[4] = {};
// Material diffuse color - applicable when shading type is global.
vtkTypeFloat32 DiffuseColor[4] = {};
// Material specular color - applicable when shading type is global.
vtkTypeFloat32 SpecularColor[4] = {};
// Edge color
vtkTypeFloat32 EdgeColor[4] = {};
// Vertex color
vtkTypeFloat32 VertexColor[4] = {};
// Interpolation type
vtkTypeUInt32 InterpolationType = VTK_FLAT;
} ShadeOpts;
};
......
// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
// SPDX-License-Identifier: BSD-3-Clause
const VTK_FLAT: u32 = 0;
const VTK_GOURAUD: u32 = 1;
const VTK_PHONG: u32 = 2;
const VTK_PBR: u32 = 3;
//-------------------------------------------------------------------
struct ActorColorOptions {
// Material ambient color
ambient_color: vec3<f32>,
// Material diffuse color
diffuse_color: vec3<f32>,
// Material specular color
specular_color: vec3<f32>,
// Edge color
edge_color: vec3<f32>,
// Vertex color
vertex_color: vec3<f32>,
// Material ambient color intensity
ambient_intensity: f32,
// Material diffuse color intensity
......@@ -13,20 +28,6 @@ struct ActorColorOptions {
specular_power: f32,
// Opacity level
opacity: f32,
// 0: Global shading - global color for all primitives.
// 1: Smooth shading - point based colors interpolated for in-between fragments.
// 2: Flat shading - cell based colors
shading_type: u32,
// What kind of directional vectors are available to use for lighting?
directional_mask: u32,
// Material ambient color
ambient_color: vec3<f32>,
// Material diffuse color
diffuse_color: vec3<f32>,
// Material specular color
specular_color: vec3<f32>,
// Edge color
edge_color: vec3<f32>,
// Vertex color
vertex_color: vec3<f32>
// One of VTK_FLAT, VTK_GOURAUD, VTK_PHONG and VTK_PBR
interpolation_type: u32,
}
......@@ -56,37 +56,45 @@ fn fragmentMain(fragment: FragmentInput) -> FragmentOutput {
///------------------------///
// Lights
///------------------------///
if scene_lights.count == 0u {
// allow post-processing this pixel.
if (actor.color_options.interpolation_type == VTK_FLAT && !render_lines_as_tubes) {
// when interpolation type is flag, do not use normal vector and light direction to compute color.
output.color = vec4<f32>(
actor.color_options.ambient_intensity * ambient_color + actor.color_options.diffuse_intensity * diffuse_color,
opacity
);
} else if scene_lights.count == 1u {
let light: SceneLight = scene_lights.values[0];
if light.positional == 1u {
// TODO: positional
} else {
if scene_lights.count == 0u {
// allow post-processing this pixel.
output.color = vec4<f32>(
actor.color_options.ambient_intensity * ambient_color + actor.color_options.diffuse_intensity * diffuse_color,
opacity
actor.color_options.ambient_intensity * ambient_color + actor.color_options.diffuse_intensity * diffuse_color,
opacity
);
} else if scene_lights.count == 1u {
let light: SceneLight = scene_lights.values[0];
if light.positional == 1u {
// TODO: positional
output.color = vec4<f32>(
actor.color_options.ambient_intensity * ambient_color + actor.color_options.diffuse_intensity * diffuse_color,
opacity
);
} else {
// headlight
let df: f32 = max(0.000001f, normal_vc.z);
let sf: f32 = pow(df, actor.color_options.specular_power);
diffuse_color = df * diffuse_color * light.color;
specular_color = sf * actor.color_options.specular_intensity * actor.color_options.specular_color * light.color;
output.color = vec4<f32>(
actor.color_options.ambient_intensity * ambient_color + actor.color_options.diffuse_intensity * diffuse_color + specular_color,
opacity
);
}
} else {
// headlight
let df: f32 = max(0.000001f, normal_vc.z);
let sf: f32 = pow(df, actor.color_options.specular_power);
diffuse_color = df * diffuse_color * light.color;
specular_color = sf * actor.color_options.specular_intensity * actor.color_options.specular_color * light.color;
// TODO: light kit
output.color = vec4<f32>(
actor.color_options.ambient_intensity * ambient_color + actor.color_options.diffuse_intensity * diffuse_color + specular_color,
opacity
actor.color_options.ambient_intensity * ambient_color + actor.color_options.diffuse_intensity * diffuse_color,
opacity
);
}
} else {
// TODO: light kit
output.color = vec4<f32>(
actor.color_options.ambient_intensity * ambient_color + actor.color_options.diffuse_intensity * diffuse_color,
opacity
);
}
// pre-multiply colors
output.color = vec4(output.color.rgb * opacity, opacity);
......
......@@ -314,37 +314,45 @@ fn fragmentMain(fragment: FragmentInput) -> FragmentOutput {
///------------------------///
// Lights
///------------------------///
if scene_lights.count == 0u {
// allow post-processing this pixel.
if (actor.color_options.interpolation_type == VTK_FLAT && !render_lines_as_tubes) {
// when interpolation type is flag, do not use normal vector and light direction to compute color.
output.color = vec4<f32>(
actor.color_options.ambient_intensity * ambient_color + actor.color_options.diffuse_intensity * diffuse_color,
opacity
);
} else if scene_lights.count == 1u {
let light: SceneLight = scene_lights.values[0];
if light.positional == 1u {
// TODO: positional
} else {
if scene_lights.count == 0u {
// allow post-processing this pixel.
output.color = vec4<f32>(
actor.color_options.ambient_intensity * ambient_color + actor.color_options.diffuse_intensity * diffuse_color,
opacity
actor.color_options.ambient_intensity * ambient_color + actor.color_options.diffuse_intensity * diffuse_color,
opacity
);
} else if scene_lights.count == 1u {
let light: SceneLight = scene_lights.values[0];
if light.positional == 1u {
// TODO: positional
output.color = vec4<f32>(
actor.color_options.ambient_intensity * ambient_color + actor.color_options.diffuse_intensity * diffuse_color,
opacity
);
} else {
// headlight
let df: f32 = max(0.000001f, normal_vc.z);
let sf: f32 = pow(df, actor.color_options.specular_power);
diffuse_color = df * diffuse_color * light.color;
specular_color = sf * actor.color_options.specular_intensity * actor.color_options.specular_color * light.color;
output.color = vec4<f32>(
actor.color_options.ambient_intensity * ambient_color + actor.color_options.diffuse_intensity * diffuse_color + specular_color,
opacity
);
}
} else {
// headlight
let df: f32 = max(0.000001f, normal_vc.z);
let sf: f32 = pow(df, actor.color_options.specular_power);
diffuse_color = df * diffuse_color * light.color;
specular_color = sf * actor.color_options.specular_intensity * actor.color_options.specular_color * light.color;
// TODO: light kit
output.color = vec4<f32>(
actor.color_options.ambient_intensity * ambient_color + actor.color_options.diffuse_intensity * diffuse_color + specular_color,
opacity
actor.color_options.ambient_intensity * ambient_color + actor.color_options.diffuse_intensity * diffuse_color,
opacity
);
}
} else {
// TODO: light kit
output.color = vec4<f32>(
actor.color_options.ambient_intensity * ambient_color + actor.color_options.diffuse_intensity * diffuse_color,
opacity
);
}
// pre-multiply colors
output.color = vec4(output.color.rgb * opacity, opacity);
......
......@@ -275,37 +275,45 @@ fn fragmentMain(fragment: FragmentInput) -> FragmentOutput {
///------------------------///
// Lights
///------------------------///
if scene_lights.count == 0u {
// allow post-processing this pixel.
if (actor.color_options.interpolation_type == VTK_FLAT && !render_points_as_spheres) {
// when interpolation type is flag, do not use normal vector and light direction to compute color.
output.color = vec4<f32>(
actor.color_options.ambient_intensity * ambient_color + actor.color_options.diffuse_intensity * diffuse_color,
opacity
);
} else if scene_lights.count == 1u {
let light: SceneLight = scene_lights.values[0];
if light.positional == 1u {
// TODO: positional
} else {
if scene_lights.count == 0u {
// allow post-processing this pixel.
output.color = vec4<f32>(
actor.color_options.ambient_intensity * ambient_color + actor.color_options.diffuse_intensity * diffuse_color,
opacity
actor.color_options.ambient_intensity * ambient_color + actor.color_options.diffuse_intensity * diffuse_color,
opacity
);
} else if scene_lights.count == 1u {
let light: SceneLight = scene_lights.values[0];
if light.positional == 1u {
// TODO: positional
output.color = vec4<f32>(
actor.color_options.ambient_intensity * ambient_color + actor.color_options.diffuse_intensity * diffuse_color,
opacity
);
} else {
// headlight
let df: f32 = max(0.000001f, normal_vc.z);
let sf: f32 = pow(df, actor.color_options.specular_power);
diffuse_color = df * diffuse_color * light.color;
specular_color = sf * actor.color_options.specular_intensity * actor.color_options.specular_color * light.color;
output.color = vec4<f32>(
actor.color_options.ambient_intensity * ambient_color + actor.color_options.diffuse_intensity * diffuse_color + specular_color,
opacity
);
}
} else {
// headlight
let df: f32 = max(0.000001f, normal_vc.z);
let sf: f32 = pow(df, actor.color_options.specular_power);
diffuse_color = df * diffuse_color * light.color;
specular_color = sf * actor.color_options.specular_intensity * actor.color_options.specular_color * light.color;
// TODO: light kit
output.color = vec4<f32>(
actor.color_options.ambient_intensity * ambient_color + actor.color_options.diffuse_intensity * diffuse_color + specular_color,
opacity
actor.color_options.ambient_intensity * ambient_color + actor.color_options.diffuse_intensity * diffuse_color,
opacity
);
}
} else {
// TODO: light kit
output.color = vec4<f32>(
actor.color_options.ambient_intensity * ambient_color + actor.color_options.diffuse_intensity * diffuse_color,
opacity
);
}
// pre-multiply colors
output.color = vec4(output.color.rgb * opacity, opacity);
......
......@@ -280,37 +280,45 @@ fn fragmentMain(fragment: FragmentInput) -> FragmentOutput {
///------------------------///
// Lights
///------------------------///
if scene_lights.count == 0u {
// allow post-processing this pixel.
if (actor.color_options.interpolation_type == VTK_FLAT && !render_points_as_spheres) {
// when interpolation type is flag, do not use normal vector and light direction to compute color.
output.color = vec4<f32>(
actor.color_options.ambient_intensity * ambient_color + actor.color_options.diffuse_intensity * diffuse_color,
opacity
);
} else if scene_lights.count == 1u {
let light: SceneLight = scene_lights.values[0];
if light.positional == 1u {
// TODO: positional
} else {
if scene_lights.count == 0u {
// allow post-processing this pixel.
output.color = vec4<f32>(
actor.color_options.ambient_intensity * ambient_color + actor.color_options.diffuse_intensity * diffuse_color,
opacity
actor.color_options.ambient_intensity * ambient_color + actor.color_options.diffuse_intensity * diffuse_color,
opacity
);
} else if scene_lights.count == 1u {
let light: SceneLight = scene_lights.values[0];
if light.positional == 1u {
// TODO: positional
output.color = vec4<f32>(
actor.color_options.ambient_intensity * ambient_color + actor.color_options.diffuse_intensity * diffuse_color,
opacity
);
} else {
// headlight
let df: f32 = max(0.000001f, normal_vc.z);
let sf: f32 = pow(df, actor.color_options.specular_power);
diffuse_color = df * diffuse_color * light.color;
specular_color = sf * actor.color_options.specular_intensity * actor.color_options.specular_color * light.color;
output.color = vec4<f32>(
actor.color_options.ambient_intensity * ambient_color + actor.color_options.diffuse_intensity * diffuse_color + specular_color,
opacity
);
}
} else {
// headlight
let df: f32 = max(0.000001f, normal_vc.z);
let sf: f32 = pow(df, actor.color_options.specular_power);
diffuse_color = df * diffuse_color * light.color;
specular_color = sf * actor.color_options.specular_intensity * actor.color_options.specular_color * light.color;
// TODO: light kit
output.color = vec4<f32>(
actor.color_options.ambient_intensity * ambient_color + actor.color_options.diffuse_intensity * diffuse_color + specular_color,
opacity
actor.color_options.ambient_intensity * ambient_color + actor.color_options.diffuse_intensity * diffuse_color,
opacity
);
}
} else {
// TODO: light kit
output.color = vec4<f32>(
actor.color_options.ambient_intensity * ambient_color + actor.color_options.diffuse_intensity * diffuse_color,
opacity
);
}
// pre-multiply colors
output.color = vec4(output.color.rgb * opacity, opacity);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment