7
$\begingroup$

For the start, I thought was orthographic, but when I used the orthographic camera, it didn't match up. Client say they want a so-called "industry schematic", talking about a 135 degree look.

Enter image description here

I found a trick to do this, which is using lattice. I align the lattice with the cube, and move the upper four points a little bit along the axis showing on the following image. But I want to achieve this by just using the camera.

Enter image description here

$\endgroup$
  • $\begingroup$ This might help you: blender.stackexchange.com/questions/1888/… $\endgroup$ – Geri Sep 25 at 8:35
  • $\begingroup$ yeah, I saw, it's done with lattice in that post. But How can I done without deforming the object $\endgroup$ – keydsf Sep 25 at 8:49
  • $\begingroup$ I also found this that doesn't require deforming the object. youtu.be/IFr0NIzDges?t=132 But it involves a lot of post processing. $\endgroup$ – Geri Sep 25 at 9:14
  • $\begingroup$ What is "Clinet"? Do you mean "The client"? $\endgroup$ – Peter Mortensen Sep 25 at 21:22
6
$\begingroup$

Oblique projection Shear matrix to set lattice coordinates

Note: this is adjusting the lattice coordinates based on the shear required, not the camera. IIRC, it has been asked as a feature request to add an Oblique projection to the camera, but AFAIK it isn't available yet.

Enter image description here

Without getting into too much theory, I believe this is pretty much shearing the coordinates of the lattice.

For a front ortho projection, it will shear the XZ plane (side walls) along the x, y vector (1, 1) or some multiple of it.

The test code adds a cube with an encompassing default lattice and shears it based on settings for a front view.

EDIT. Oops, I forgot to scale the lattice object, not the data.

How do you freeze or reset a lattice?

import bpy
from mathutils import Matrix, Vector
from bpy import context

shear_dist = 1 # sqrt(2) for (1, 1)
shear_vec = Vector((-1, 1)).normalized()
lattice_res = 8

Sh = Matrix.Shear(
    'XZ',
    4,
    shear_dist * shear_vec,
    )

T = Matrix.Translation((0, 0.5, 0))
def mm(matrix, space=Matrix()):

    return space.inverted() @ matrix @ space

bpy.ops.mesh.primitive_cube_add(
        location=(0, 0, 0),
        )
cube = context.object
bpy.ops.object.add(
        type='LATTICE',
        location=(0, 0, 0))
latob = context.object

latob.dimensions = cube.dimensions
lat = latob.data
lat.points_u = lattice_res
lat.points_v = lattice_res
lat.points_w = lattice_res

latmod = cube.modifiers.new("Oblique", type='LATTICE')
latmod.object = latob

lat.transform(mm(Sh, T))

Ok, I have it better now. The leading face of the cube stays in place.

The next step is to add shape keys for the projections, for example, TOP, LEFT, ... have FRONT.

| improve this answer | |
$\endgroup$
  • 1
    $\begingroup$ What do you mean by "have FRONT"? $\endgroup$ – Peter Mortensen Sep 25 at 21:27
9
$\begingroup$

With some limitations (or I haven't found the how to, probably), we can tweak the camera matrix when using Gpu module. So that we can have the equivalent of viewport rendering.

enter image description here

The image above is taken with a orthographic camera placed in front of some cubes:

enter image description here

On bottom left the addon (see below) shows a vignette of the tweaked image.

When in camera view you can move the camera or the object and view the corresponding result of the projection:

enter image description here

To take a screenshot, use the D key.

Limitations:

  • The camera targets along Y and it Y position is fixed to -8 units
  • The rendering is limited to the 3D view size
  • Moving objects along Y may push them out of the view
  • Works in rendered viewport shading but for Eevee or Workbench only (not Cycles)

Principles of the script:

The "key" part of the code: as we can give to the GPU module the matrices we want, have added empirical values to make the projection (offset and tweak below).

camera_matrix = scene.camera.matrix_world.copy()
# Static camera position in Y
camera_matrix[1][3] = -8

view_matrix = camera_matrix.inverted()

projection_matrix = scene.camera.calc_matrix_camera(
    context.evaluated_depsgraph_get(), x=width, y=height)

# Empirical offset and perspective tweaks
projection_matrix[0][3] = OFFSET_X
projection_matrix[1][3] = OFFSET_Y

projection_matrix[0][2] = TWEAK_X
projection_matrix[1][2] = TWEAK_Y

# Draw the 3D view    
offscreen.draw_view3d(
    scene,
    context.view_layer,
    context.space_data,
    context.region,
    view_matrix,
    projection_matrix)

Blend file: execute the script then search F3 for "oblique" in the 3D view. Esc to quit. D to take a screenshot. You can zoom in/out by scaling the camera.

The rendering itself is equivalent to "viewport render image" (menu "view"). So you can have the shading you want and disable gizmo and overlays if you want).

| improve this answer | |
$\endgroup$
  • $\begingroup$ Pretty interesting technique, nice answer. Shame this can't be stored in the camera object itself and used for regular render output like through Cycles or EEVEE $\endgroup$ – Duarte Farrajota Ramos Sep 25 at 21:51
  • $\begingroup$ Long live Python ! Wish one day I can write the scripts as well ~ $\endgroup$ – keydsf Sep 26 at 4:24
  • 1
    $\begingroup$ @DuarteFarrajotaRamos, thanks. Well you can use rendered viewport shading but Eevee only. The main constraint is the size limited to the viewport. Have not found a way to get rid of these... $\endgroup$ – lemon Sep 26 at 8:20
  • $\begingroup$ In ur blender file, why even I have run the scripts, but nothing happened. and ther isn't "Oblique" option in F3 search. Btw, when I run the scripts, there isn't some info shows up in the bottom tell me whether the scripts is running or not. blender version 2.90.1 $\endgroup$ – keydsf Sep 26 at 16:15
  • $\begingroup$ @keydsf, I've downloaded the file linked in the question to be sure. All is working for me. So I really don't know. When running the script, it says nothing but just register the operator called "Oblique rendering", so that's normal for that. Now, I do not know why you can't search it from the 3D view. $\endgroup$ – lemon Sep 26 at 16:23
5
$\begingroup$

This is called Oblique projection.
You can't do this in-camera, because Blender doesn't support Oblique camera projection.

enter image description here

You can vote here on Rightclickselect to add Oblique camera projection into Blender.

| improve this answer | |
$\endgroup$
  • $\begingroup$ : ) the coolest answer of the three! $\endgroup$ – lemon Sep 25 at 19:21
  • 1
    $\begingroup$ Hey, thanks :). Doesn't really solve the problem, though. $\endgroup$ – Jachym Michal Sep 25 at 19:26
  • $\begingroup$ Man... I know : ) that's why it is cool! $\endgroup$ – lemon Sep 25 at 19:28
  • $\begingroup$ Comments like that are why I love it around here :) $\endgroup$ – Jachym Michal Sep 25 at 19:40
  • 1
    $\begingroup$ mmm... seem to be addict as I am, so... shame on us!! ; ) $\endgroup$ – lemon Sep 25 at 19:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.