Page 1 of 2

[Library] A simple 3D scene renderer

Posted: Sun Aug 09, 2020 6:56 am
by Jon
https://github.com/xiejiangzhi/model_renderer

This library just creates or loads a simple 3D model and draws it.

For a example

Code: Select all

local MR = require 'src'

-- Create model from obj file or basic shape
local ground = MR.model.new_plane(2000, 2000)
local model = MR.model.load('3d.obj')
local box = MR.model.new_box(50)
local sphere = MR.model.new_sphere(30)
local cylinder = MR.model.new_cylinder(30, 100)

local renderer, scene, camera

function love.load()
  -- Initalize render, scene and camera
  renderer = MR.renderer.new()
  renderer.light_pos = { 1000, 2000, 1000 }
  renderer.light_color = { 1, 1, 1 }
  renderer.ambient_color = { 0.6, 0.6, 0.6 }
  scene = MR.scene.new()
  camera = MR.camera.new()
end

function love.draw()
  local w, h = love.graphics.getDimensions()
  local hw, hh = w * 0.5, h * 0.5

  -- Set camera projection and view, and apply camera for renderer
  camera:orthogonal(-hw, hw, hh, -hh, -500, 2000)
  camera:look_at(0, 0, 0, math.rad(60), 0, 0)
  renderer:apply_camera(camera)

  local ts = love.timer.getTime()

  -- Add some model to scene
  -- model, coord, angle, scale, color
  scene:add_model(ground, { -1000, 0, -1000 }, nil, nil, { 0, 1, 0, 1 })
  scene:add_model(model, { 0, 0, 0 }, { 0, math.sin(ts) * math.pi * 2, 0 }, 10, { 0, 1, 0, 1 })
  scene:add_model(model,
    { math.sin(ts) * 100, 0, math.cos(ts) * 100 },
    { 0, math.rad(45), 0 }, 10, { 1, 0, 0, 1 }
  )
  scene:add_model(box, { -300, 0, 0 }, { 0, math.rad(45), 0 })
  scene:add_model(sphere, { -300, 100, 300 })
  scene:add_model(cylinder, { 300, 0, 300 })

  love.graphics.clear(0.5, 0.5, 0.5)
  -- Render and clean scene
  renderer:render(scene:build())
  scene:clean()
end
The attachment Screen Shot 2020-08-09 at 14.49.19.png is no longer available
Of course, it also supports projecting 2D drawing operations to the 3D world

Code: Select all

  local lg = love.graphics
  local transform_mat = Cpml.mat4.identity()
  transform_mat:rotate(transform_mat, math.pi * 0.5, Cpml.vec3.unit_x)
  transform_mat:translate(transform_mat, Cpml.vec3(0, 10, 0))

  camera:attach(transform_mat)
  lg.setColor(1, 0, 0, 0.5)
  lg.circle('fill', 0, 0, 20)
  lg.circle('line', 0, 0, 25)
  lg.setColor(0, 1, 0, 0.5)
  lg.circle('fill', hw / 2, hh / 2, 30)
  lg.circle('line', hw / 2, hh / 2, 35)
  lg.setColor(0, 0, 1, 0.5)
  lg.circle('fill', hw, hh, 40)
  lg.circle('line', hw, hh, 45)
  lg.setColor(1, 1, 1)
  camera:detach()
These codes rotate the Love2D drawing based on the x-axis by 90 degrees and increase the height by 10.
The attachment Screen Shot 2020-08-09 at 14.49.19.png is no longer available
For more, please view in https://github.com/xiejiangzhi/model_renderer

Re: [Library] A simple 3D scene renderer

Posted: Mon Aug 10, 2020 1:04 am
by Jon
Some pictures are missing.
Screen Shot 2020-08-09 at 14.49.19.png
Screen Shot 2020-08-09 at 14.49.19.png (87.29 KiB) Viewed 9969 times

Re: [Library] A simple 3D scene renderer

Posted: Tue Aug 11, 2020 2:40 am
by siberian
Nice!
But why are you recreating the scene in every frame?

Re: [Library] A simple 3D scene renderer

Posted: Tue Aug 11, 2020 3:05 am
by Jon
siberian wrote: Tue Aug 11, 2020 2:40 am Nice!
But why are you recreating the scene in every frame?
Because the current scene only helps users organize the position and angle of various models, and then outputs a scene table for rendering. Therefore, when the number or position of the model changes, it is easier to directly construct a new scene.

The renderer also receives a scene table.

Code: Select all

local m1 = model.new_box(10)
renderer:render({ model = {
  { m1, { { x, y, z, rx, ry, rz, scale_x, scale_y, scale_z, r,g,b, a},  { x2, y2, z2, rx2, ry2, rz2, scale_x, scale_y, scale_z, r,g,b,a } } }
})

Re: [Library] A simple 3D scene renderer

Posted: Tue Aug 11, 2020 3:07 am
by Jon
If all objects in a scene do not change, there is no need to rebuild the scene every time

Re: [Library] A simple 3D scene renderer

Posted: Tue Aug 11, 2020 8:22 am
by zorg
Did you benchmark how much garbage all those lua tables you define per frame generate?

Re: [Library] A simple 3D scene renderer

Posted: Tue Aug 11, 2020 12:59 pm
by pgimeno
Jon wrote: Tue Aug 11, 2020 3:05 amTherefore, when the number or position of the model changes, it is easier to directly construct a new scene.
Easier than to change the model matrix????

Re: [Library] A simple 3D scene renderer

Posted: Tue Aug 11, 2020 11:59 pm
by Jon
pgimeno wrote: Tue Aug 11, 2020 12:59 pm
Jon wrote: Tue Aug 11, 2020 3:05 amTherefore, when the number or position of the model changes, it is easier to directly construct a new scene.
Easier than to change the model matrix????
Aha, these data are used to build the model matrix.

Their logic is like this

Code: Select all

local data_mesh = love.graphics.newMesh({
  'ModelPos', 'float', 3,
  'ModelAgnle', 'float', 3,
  'ModelScale', 'float', 3,
  'ModelColor', 'byte', 4
}, { { x, y, z, rx, ry, rz, sx, sy, sz, r, g, b, a}, { x2, y2, z2, rx2, ry2, rz2, sx2, sy2, sz2, r, g, b, z} })
model_mesh:attach(data_mesh, 'ModelPos')
model_mesh:attach(data_mesh, 'ModelAngle')
model_mesh:attach(data_mesh, 'ModelScale')
model_mesh:attach(data_mesh, 'ModelColor')

love.graphics.drawInstance(model_mesh, 2)
The model matrix is built on the GPU, maybe build it on the CPU is better. However, these basically have nothing to do with the scene.

Re: [Library] A simple 3D scene renderer

Posted: Wed Aug 12, 2020 9:28 am
by pgimeno
Jon wrote: Tue Aug 11, 2020 11:59 pm Aha, these data are used to build the model matrix.
OK, I understand now. Makes sense.

Re: [Library] A simple 3D scene renderer

Posted: Fri Aug 14, 2020 3:40 am
by Jon
The goal of this project is to easily and quickly create and render 3D geometric scenes through code. On this basis, to support complex 3D model rendering.

Now, support PBR and simply build large static instances.

100000 different instances.
Screen Shot 2020-08-14 at 11.36.27.png
Screen Shot 2020-08-14 at 11.36.27.png (3.93 MiB) Viewed 9677 times