I suppose that you want to make outlines for 3d models.
Add the outline
tag to your models material. You’ll use it for a render predicate to be able to render models which should be outlined.
Make a copy of the material plus its vertex/fragment shaders and name it as outline.material
(the name and tags of that material is not important). Put the material into your custom .render
file with the my_outline_material
id.
Then, in the init function of your render script, add a custom predicate like self.outline_pred = render.predicate({"outline"})
. To render outlines of the models, enable the custom material, draw models, disable the material:
render.enable_material(hash("my_outline_material"))
render.draw(self.outline_pred)
render.disable_material()
To scale the object up, write a custom vertex shader in the outline material.
attribute highp vec3 position;
attribute mediump vec3 normal;
uniform highp mat4 mtx_world;
uniform highp mat4 mtx_worldviewproj;
void main()
{
float outline_width = 0.05;
// We should find the scale of the model to scale the outline width accordingly
float scale_x = length(mtx_world * vec4(1.0, 0.0, 0.0, 0.0));
float scale_y = length(mtx_world * vec4(0.0, 1.0, 0.0, 0.0));
float scale_z = length(mtx_world * vec4(0.0, 0.0, 1.0, 0.0));
vec3 scaled_outline_width = outline_width / vec3(scale_x, scale_y, scale_z);
// Scale vertices up, and there are two ways:
// - by positions, but it works well only for cubes
vec3 outline_offset = position.xyz * scaled_outline_width;
// - by normals, but they should be smoothed
// vec3 outline_offset = normal.xyz * scaled_outline_width;
// Homework: use camera distance to keep outlines consistent!
vec3 new_position = position + outline_offset;
gl_Position = mtx_worldviewproj * vec4(new_position.xyz, 1.0);
}