Explorar o código

New camera manual.

Mikael Säker %!s(int64=7) %!d(string=hai) anos
pai
achega
44e516a2cb

+ 35 - 101
docs/en/manuals/camera.md

@@ -5,61 +5,50 @@ brief: This manual describes the functionality of the Defold camera component.
 
 # Cameras
 
-A camera in Defold is a component that changes the viewport into the game world. By default, no camera is needed, but if your game requires scrolling through a level, Defold contains a primitive camera component that you use.
+A camera in Defold is a component that changes the viewport and projection of the game world. Out of the box, Defold ships with a built in render script that renders the game with no need of a camera component but you can easily replace the built in script with one that renders the game to your liking.
 
-Cameras are very simple objects that in essence does the following:
+The camera component defines a bare bones perspective camera that provides a view and projection matrix to the render script. If you need advanced features like chasing, zooming, shake etc you will need to implement it. There are a few library camera solutions that implements common camera features. They are available from the Defold community assets portal:
 
-1. They have a location in space---either 2D or 3D.
-2. They can be moved around in space---by moving the containing game object.
-3. They provide the render script with the data necessary to render with computed view and projection matrices.
-
-Cameras in OpenGL are expressed as coordinate systems with a viewer, or eye, position, a near and a far clipping plane. The near clipping plane equals the viewing plane, or the screen.
-
-![Camera planes](images/cameras/cameras_planes.png)
-
-A 3D camera usually has a viewing volume, a _frustum_, that is shaped like a cut off pyramid. The effect of this is that objects further away from the camera will be rendered smaller--the perspective will be realistic. The wider the _field of view_, the more the camera sees of the scenery, and the more dramatic the difference between near and far objects will be.
-
-![Camera field of view](images/cameras/cameras_fov.png)
+- [Rendercam](https://www.defold.com/community/projects/84064/) by Ross Grams.
+- [Ortographic camera](https://www.defold.com/community/projects/76573/) by Björn Ritzl.
 
 ## Creating a camera
 
-To create a camera, add a _Camera component_ to a game object:
+To create a camera, <kbd>right click</kbd> a game object and select <kbd>Add Component ▸ Camera</kbd>. You can alternatively create a component file in your project hierarchy and add the component file to the game object.
 
-![Create camera component](images/cameras/cameras_create_component.png)
+![create camera component](images/camera/create.png){srcset="images/camera/[email protected] 2x"}
 
-The camera component has a set of properties that defines the camera frustum.
+The camera component has the following properties that defines the camera *frustum*:
 
-![Camera properties](images/cameras/cameras_properties.png)
+![camera settings](images/camera/settings.png){srcset="images/camera/[email protected] 2x"}
 
-::: important
-The current default FOV value is misleading. It is not expressed in degrees but in radians. For a 45 degree FOV, change the value to 0.785 (&#120529; / 4).
-:::
+Id
+: The id of the component
 
-aspect_ratio
-: The ratio between the frustum width and height. 1.0 means that you assume a quadratic view. 1.33 is good for a 4:3 view like 1024x768. 1.78 is good for a 16:9 view.
+Aspect Ratio
+: The ratio between the frustum width and height. 1.0 means that you assume a quadratic view. 1.33 is good for a 4:3 view like 1024x768. 1.78 is good for a 16:9 view. This setting is ignored if *Auto Aspect Ratio* is set.
 
-fov
-: The camera field of view expressed in _radians_.
+Fov
+: The *vertical* camera field of view expressed in _radians_. The wider the field of view, the more the camera will see. Note that the current default value (45) is misleading. For a 45 degree field of view, change the value to 0.785 ($\pi / 4$).
 
-near_z
+Near Z
 : The Z-value of the near clipping plane.
 
-far_z
+Far Z
 : The Z-value of the far clipping plane.
 
-auto_aspect_ratio
-: Set this to 1 to let the camera automatically set the aspect ratio based on the game's screen settings.
+Auto Aspect Ratio
+: Set this to let the camera automatically calculate the aspect ratio.
 
+## Using the camera
 
-## Camera focus
-
-To activate the camera and have it feed its view and projection matrices, you send the component an `acquire_camera_focus` message:
+To activate a camera and have it feed its view and projection matrices to the render script, you send the component an acquire_camera_focus message:
 
 ```lua
 msg.post("#camera", "acquire_camera_focus")
 ```
 
-As soon as the camera component has camera focus, each frame it will send a `set_view_projection` message to the `@render` socket, i.e. to your render script:
+Each frame, the camera component that currently has camera focus will send a `"set_view_projection"` message to the "@render" socket, i.e. it will arrive to your render script:
 
 ```lua
 -- example.render_script
@@ -67,100 +56,45 @@ As soon as the camera component has camera focus, each frame it will send a `set
 function update(self)
     ...
     render.set_view(self.view)
-
     render.set_projection(self.projection)
     ...
 end
 
 function on_message(self, message_id, message)
     if message_id == hash("set_view_projection") then
-    	-- Camera view and projection arrives here. Store them.
-        self.view = message.view
+        self.view = message.view                    -- [1]
         self.projection = message.projection
     end
 end
 ```
+1. The message posted from the camera component includes a view matrix and a projection matrix.
 
-If you use both camera view and projection in your render script you will get a camera view into your game world with 3D perspective, even if your game content is strictly 2D. This is sometimes useful. You can, for instance, move the camera back to reveal more of the level. A simple camera script that measures the current camera move speed and pulls it back relative that speed could look like this:
-
-```lua
--- camera.script
---
-function init(self)
-	msg.post("#camera", "acquire_camera_focus")
-
-    -- Track current position and where someone told us to look at.
-	self.pos = go.get_world_position()
-	self.look_at = self.pos
-end
-
-function update(self, dt)
-	-- Calculate a new position based on current pos interpolated towards current
-	-- target position.
-	self.pos = vmath.lerp(0.03, self.pos, self.look_at)
-	
-	-- Measure speed on the 2D plane (zero Z)
-	local v1 = go.get_world_position()
-	v1.z = 0
-	local v2 = self.pos
-	v2.z = 0
-	local speed = vmath.length(v2 - v1)
-
-	-- Depending on how fast player is moving, pull camera back or push it forward.
-	self.pos.z = 500 + speed * speed * 10
-	go.set_position(self.pos)
-end
-
-function on_message(self, message_id, message, sender)
-    -- This camera reacts to "look_at" messages with a position as where
-    -- to go.
-	if message_id == hash("look_at") then	
-		self.look_at = message.position
-	end
-end
-```
-
-![Camera speed distance](images/cameras/cameras_speed_distance.png)
+## Projections
 
-Of course, we're not limited to moving the camera around. We can also rotate it along its X, Y and Z axis.
-
-```lua
--- 0.314 radians is about 18 degrees.
-go.set_rotation(vmath.quat_rotation_z(0.314) * vmath.quat_rotation_y(0.314))
-```
+The camera component currently supplies the render script with a perspective projection. This is well suited for 3D games. For 2D games, it is often desirable to render the scene with *orthographic projection*. This means that the view of the camera is no longer dictated by a frustum, but by a box. Orthographic projection is unrealistic in that it does not alter the size of objects based on their distance. An object 1000 units away will render at the same size as an object right in front of the camera.
 
-![Rotated camera](images/cameras/cameras_camera_rotated.png)
+![projections](images/camera/projections.png){srcset="images/camera/[email protected] 2x"}
 
-## Orthographic projection
-
-For many 2D games, the business of having a camera that can move back and forth becomes a problem, especially if you have content that you would like to render pixel perfect. Instead of trying to place your camera at the perfect Z distance to get the view you want, you should instead set up a camera with _orthographic projection_. This means that the view of the camera is no longer dictated by a frustum, but by a much simpler box.
-
-![Orthographic projection](images/cameras/cameras_orthographic.png)
-
-Orthographic projection is unrealistic in that it does not alter the size of objects based on their distance. A person standing 10000 meters away will still render at the same size as the person standing right in front of the camera. However, this method of projecting graphics is sometimes useful and 2D games often benefit from using it. To use orthographic projection you just have to modify your render script:
+To use orthographic projection you can ignore the projection matrix sent by the camera component and instead provide one yourself in the render script, just like the default renderscript does:
 
 ```lua
--- example.render_script
+-- example_orthographic.render_script
 --
 function update(self)
     ...
     render.set_view(self.view)
-    -- Set up an orthographic projection based on the width and height of the
-    -- game window.
-	local w = render.get_width()
-	local h = render.get_height()
-	render.set_projection(vmath.matrix4_orthographic(- w / 2, w / 2, -h / 2, h / 2, -1000, 1000))
+    local w = render.get_width() / 2
+    local h = render.get_height() / 2
+    local ortho = vmath.matrix4_orthographic(-w, w, -h, h, -1, 1)
+    render.set_projection(ortho)                    -- [1]
     ...
 end
 
 function on_message(self, message_id, message)
     if message_id == hash("set_view_projection") then
-    	-- Camera view and projection arrives here. We only need the view.
-        self.view = message.view
+        self.view = message.view                    -- [2]
     end
 end
 ```
-
-This is almost what the default render script does, with the difference that the above example centers the screen at the camera position.
-
-(Some of the graphic assets used are made by Kenney: http://kenney.nl/assets)
+1. Set up an orthographic projection based on the width and height of the game window. The center of view is the camera's position. Note that the default render script sets the lower left corner of the view at the camera's position.
+2. Only care about camera view since the projection is done separately.

BIN=BIN
docs/en/manuals/images/camera/create.png


BIN=BIN
docs/en/manuals/images/camera/[email protected]


BIN=BIN
docs/en/manuals/images/camera/projections.png


BIN=BIN
docs/en/manuals/images/camera/[email protected]


BIN=BIN
docs/en/manuals/images/camera/settings.png


BIN=BIN
docs/en/manuals/images/camera/[email protected]


BIN=BIN
docs/en/manuals/images/cameras/cameras_camera_rotated.png


BIN=BIN
docs/en/manuals/images/cameras/cameras_create_component.png


BIN=BIN
docs/en/manuals/images/cameras/cameras_fov.png


BIN=BIN
docs/en/manuals/images/cameras/cameras_orthographic.png


BIN=BIN
docs/en/manuals/images/cameras/cameras_planes.png


BIN=BIN
docs/en/manuals/images/cameras/cameras_properties.png


BIN=BIN
docs/en/manuals/images/cameras/cameras_speed_distance.png


+ 1 - 1
gulpfile.js

@@ -48,7 +48,7 @@ md = new markdown({
         // Callouts hack!
         // replaces "-- [1]", "// [1]" and "-- <1>" and "// <1>" with a span
         // callouts only work if the highlighter kicks in.
-        var exp = /(?:--|\/\/|#) (?:\[|&lt;)([0-9]+)(?:\]|&gt;)/g;
+        var exp = /(?:\-\-|\/\/|#) (?:\[|&lt;)([0-9]+)(?:\]|&gt;)/g;
         return hl.replace(exp, '<span class="callout" data-pseudo-content="$1"></span>');
       } catch (__) {}
     }