Sharedwww / talks / 2006-05-09-sage-digipen / tutorial / modeling-cellshading-1.pyOpen in CoCalc
Author: William A. Stein
1
# Soya 3D tutorial
2
# Copyright (C) 2001-2004 Jean-Baptiste LAMY
3
#
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
18
19
# modeling-cellshading-1: Modeling : using cell-shading !
20
21
# Cell-shading gives a cartoon-like look to your 3D objects by :
22
# - adding an outline around this object
23
# - shading the object in a non-linear way, according to a 'shader'
24
#
25
# The shader is a 1-dimensional gray texture that maps light intensity to the shade level ;
26
# usually the shader have only a few color levels. See tutorial/data.images/shader.png for
27
# an example.
28
#
29
# In Soya, cell-shading can be activated during world-to-shape compilation.
30
# In this tuto, we'll draw 2 rotating swords, one normal and one with cell-shading.
31
32
# To add cell-shading to an animated character, see also tutorial lesson
33
# character-animation-shadow-cellshading-1.
34
35
36
# Imports and inits Soya (see lesson basic-1.py).
37
38
import sys, os, os.path, soya
39
40
soya.init()
41
soya.path.append(os.path.join(os.path.dirname(sys.argv[0]), "data"))
42
43
# Creates the scene.
44
45
scene = soya.World()
46
47
# Set up an atmosphere, so as the background is white (in order to see the black outline
48
# of the cell-shading).
49
50
scene.atmosphere = soya.Atmosphere()
51
scene.atmosphere.bg_color = (1.0, 1.0, 1.0, 1.0)
52
53
54
# Loads the sword model
55
56
sword = soya.World.get("sword")
57
58
# Modify the material, for a better effect
59
60
material = sword.children[0].material
61
material.texture = soya.Image.get("epee_turyle-cs.png")
62
#material.separate_specular = 1
63
#material.shininess = 15.0
64
#material.specular = (1.0, 1.0, 1.0, 1.0)
65
66
# Compiles the sword model to a normal shape
67
68
sword_shape = sword.shapify()
69
70
# Creates the shader. The shader is a normal material with a texture.
71
72
shader = soya.Material()
73
shader.texture = soya.Image.get("shader.png")
74
75
# Creates a cell-shading shapifier object. A shapifier is an object that says how a world
76
# is compiled into a shape. When no shapifier is specified, Soya uses the default shapifier
77
# (an instance of SimpleShapifier, that does not include cell-shading effect).
78
79
cellshading = soya.CellShadingShapifier()
80
81
# Sets the shapifier properties. These properties can also be passed to the constructor,
82
# see docstrings for more info.
83
# The shader property is (obviously) the shader :-)
84
# outline_color specifies the color of the outline (default : black)
85
# outline_width specifies the width of the outline (default 4.0) ; set to 0.0 for no outline
86
# outline_attenuation specifies how the distance affects the outline_width (default 0.3).
87
88
cellshading.shader = shader
89
cellshading.outline_color = (0.0, 0.0, 0.0, 1.0)
90
cellshading.outline_width = 7.0
91
cellshading.outline_attenuation = 1.0
92
93
# Assigns the shapifier to the sword.
94
95
sword.shapifier = cellshading
96
97
# Compiles the sword model to a cell-shaded shape. Notice that is you save the sword now,
98
# the shapifier would be saved with it too, and thus you can use 'soya.Shape.get("sword")'
99
# with cell-shading.
100
101
sword_cellshaded_shape = sword.shapify()
102
103
# Create a rotating volume class, and 2 rotating volumes. The left one is normal, the right
104
# one is cell-shaded.
105
106
class RotatingVolume(soya.Volume):
107
def __init__(self, parent = None, shape = None, sens = 1.0):
108
soya.Volume.__init__(self, parent, shape)
109
self.sens = sens
110
111
def advance_time(self, proportion):
112
soya.Volume.advance_time(self, proportion)
113
self.rotate_lateral(proportion * 2.0 * self.sens)
114
115
volume1 = RotatingVolume(scene, sword_shape)
116
volume1.set_xyz(-1.0, 0.0, 0.0)
117
volume1.rotate_vertical(90.0)
118
119
volume2 = RotatingVolume(scene, sword_cellshaded_shape, -1)
120
volume2.set_xyz( 1.0, 0.0, 0.0)
121
volume2.rotate_vertical(90.0)
122
123
# Creates a light.
124
125
light = soya.Light(scene)
126
light.set_xyz(0.0, 1.0, 1.0)
127
128
# Creates a camera.
129
130
camera = soya.Camera(scene)
131
camera.set_xyz(0.0, 0.8, 2.5)
132
soya.set_root_widget(camera)
133
134
soya.Idler(scene).idle()
135
136