1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="content-type">
<title>Java 3D 1.4 Shaders</title>
</head>
<body>
<h2>Shaders in Java 3D<sup><font size="-2">TM</font></sup> 1.4</h2>
<h4>Introduction and pointer to discussion forum</h4>
<p>Here is the latest rough first draft of what we are thinking in
terms of programmable shader support in Java 3D<sup><font
size="-2">TM</font></sup> for 1.4. We plan to formalize the 1.4 API
specification under the auspices of the Java Community Process
(JCP). However, we very much want to involve the larger community in
API discussions for programmable shaders, so please join in the
discussion.
</p>
<p>We have created a thread on the Java 3D discussion forum for
discussing <a
href="http://www.javadesktop.org/forums/thread.jspa?threadID=5056"
target="_blank">Java 3D Programmable Shaders</a>. Feel free to
post your comments on our ideas, or post some ideas of your own.
</p>
<h4>Class Hierarchy for Shader Objects</h4>
<p>The proposed class hierarchy for programmable shaders
in Java 3D is:</p>
<ul>
<li>Abstract shader base classes:</li>
<ul>
<pre>public abstract class ShaderProgram extends NodeComponent
public abstract class Shader extends NodeComponent
</pre>
</ul>
<li>Concrete GLSL shader classes:</li>
<ul>
<pre>public class GLSLShaderProgram extends ShaderProgram
method: {add/remove/get}Shader(GLSLShader) // set of shader objs
method: {add/remove}ErrorListener(GLSLErrorListener)
method: validate(Canvas3D) ???
public abstract class GLSLShader extends Shader
public class GLSLVertexShader extends GLSLShader
method: set/getShaderSource(String)
method: validate(Canvas3D) ???
public class GLSLFragmentShader extends GLSLShader
method: set/getShaderSource(String)
method: validate(Canvas3D) ???
</pre>
</ul>
<li>Concrete Cg shader classes:</li>
<ul>
<pre>public class CgShaderProgram extends ShaderProgram
method: {set/get}VertexShader(CgVertexShader)
method: {set/get}FragmentShader(CgFramentShader)
method: {add/remove}ErrorListener(CgErrorListener)
method: validate(Canvas3D) ???
public abstract class CgShader extends Shader
public class CgVertexShader extends CgShader
method: set/getShaderSource(String)
method: validate(Canvas3D) ???
public class CgFragmentShader extends CgShader
method: set/getShaderSource(String)
method: validate(Canvas3D) ???
</pre>
</ul>
<li>New ShaderAppearance class:</li>
<ul>
<pre>public class ShaderAppearance extends Appearance
method: set/getShaderProgram(ShaderProgram)
method: set/getShaderAttributeSet(ShaderAttributeSet)
</pre>
</ul>
<li>New ShaderAttributeSet class:</li>
<ul>
<pre>public class ShaderAttributeSet extends NodeComponent
method: put/get(ShaderAttribute)
...
</pre>
</ul>
</ul>
<p>Click on the following link for a current look at the <a
href="http://javadesktop.org/java3d/javadoc/1.4.0-latest/index.html">javadoc-generated
API definitions</a> for the proposed 1.4 API.
</p>
<h4>Example Usage</h4>
<p>This is an example code excerpt showing how one might use the new
programmable shader API in a Java 3D program.
</p>
<ul>
<pre>String vertexShaderFile = "my-vertex-shader-file-name";
String fragmentShaderFile = "my-fragment-shader-file-name";
String vertexShaderSource;
String fragmentShaderSource;
// Read GLSL vertex and fragment shader source code from text files
vertexShaderSource = StringIO.readFully(vertexShaderFile);
fragmentShaderSource = StringIO.readFully(fragmentShaderSource);
// Create GLSL vertex and fragment shader objects using the given source code
GLSLVertexShader vertexShader = new GLSLVertexShader(vertexShaderSource);
GLSLFragmentShader fragmentShader = new GLSLFragmentShader(fragmentShaderSource);
// Create the GLSL shader program object and attach the vertex and
// fragment shader objects; add an error listener
GLSLShaderProgram shaderProgram = new GLSLShaderProgram();
shaderProgram.setVertexShader(vertexShader);
shaderProgram.setFragmentShader(fragmentShader);
shaderProgram.addErrorListener(myGLSLErrorListener);
// Use GLSL shader program object in appearance
shaderAppearance.setShaderProgram(shaderProgram);
</pre>
</ul>
<h4>Shader Parameters</h4>
<p>Programmable shaders define two types of parameters: uniform and
varying. As the names imply, uniform parameters are constant (within a
primitive), while varying parameters can vary on per-vertex or
per-fragment basis.
</p>
<ol>
<li><b>Uniform parameters</b> (attributes) are those parameters whose
value is constant during the rendering of a primitive. Their values
may change from primitive to primitive, but are constant for each
vertex (for vertex shaders) or fragment (for fragment shaders) of a
single primitive. Examples of uniform parameters include a
transformation matrix, a texture map, lights, lookup tables,
etc.<br>
<br>
We have created a new ShaderAttributeSet for allowing applications to
specify uniform shader attributes. There are two ways in which values
can be specified for uniform attributes: explicitly, by providing a
value; and implicitly, by defining a binding between a Java 3D system
attribute and a uniform attribute. This functionality is provided by
two subclasses of ShaderAttribute: ShaderAttributeObject, which is
used to specify explicitly defined attributes; and
ShaderAttributeBinding, which is used to specify implicitly defined,
automatically tracked attributes. See the javadoc for the new <a
href="http://javadesktop.org/java3d/javadoc/1.4.0-latest/javax/media/j3d/ShaderAttributeSet.html">ShaderAttributeSet</a>
and <a
href="http://javadesktop.org/java3d/javadoc/1.4.0-latest/javax/media/j3d/ShaderAttribute.html">ShaderAttribute</a>
classes for more details.<br>
<br>
<b>Issues</b><br>
<ul>
<li>Should j3dAttrName be specified as a type-safe enum or object
instead of a String?
<ul><font color="gray"><li>No; we will use a String</li></font>
</ul></li>
<li>How do we handle passing arrays to the shader, especially for
system parameters such as lights? One possibility is:
<ul>
"var" - scalar variable "var"<br>
"arr[0]" - array element 0 of "arr"<br>
"arr[1,3]" - subarray composed of elements 1 through 3 of "arr"<br>
"arr[]" - entire array "arr"<br>
</ul>
Alternatively, an object with a string or type-safe enum, a state
(scalar, array element, subarray, or entire array), and indices (as
needed).
<ul><font color="gray"><li>TBD, but since they will be String objects, we will probably
do something like the first suggestion</li></font>
</ul></li>
</ul>
<br>
<b>Automatic variables</b><br>
Depending on the shading language (and profile) being used, several
Java 3D state attributes are automatically made available to the
shader program as pre-defined uniform attributes. The application
doesn't need to do anything to pass these attributes in to the shader
program. The implementation of each shader language (e.g., Cg, GLSL)
defines its own mapping from Java 3D attribute to uniform
variable name.<br>
<br>
A partial list of Java 3D attributes that are mapped to shader
attributes follows:
</li>
<br>
<table style="text-align: left;" border="1" cellspacing="2"
cellpadding="2">
<tbody>
<tr>
<td style="vertical-align: top; text-decoration: underline;">Java 3D
Attribute<br>
</td>
<td style="vertical-align: top; text-decoration: underline;">Cg
shader variable<br>
</td>
<td style="vertical-align: top; text-decoration: underline;">GLSL
shader variable<br>
</td>
</tr>
<tr>
<td style="vertical-align: top;">ModelViewProjection<br>
</td>
<td style="vertical-align: top;">glstate.matrix.mvp<br>
</td>
<td style="vertical-align: top;">gl_ModelViewProjectionMatrix<br>
</td>
</tr>
<tr>
<td style="vertical-align: top;">Light[<i>n</i>] pos<br>
</td>
<td style="vertical-align: top;">glstate.light[<i>n</i>].position </td>
<td style="vertical-align: top;">gl_LightSource[<i>n</i>].position </td>
</tr>
<tr>
<td style="vertical-align: top;">...<br>
</td>
<td style="vertical-align: top;">...<br>
</td>
<td style="vertical-align: top;">...<br>
</td>
</tr>
</tbody>
</table>
<br>
<li><b>Varying parameters</b> are those parameters that are specified
as per-vertex attributes. They are are interpolated across a primitive
similarly to colors and texture coordinates in the fixed function
pipeline.<br>
<br>
We need additional API to allow applications to pass in per-vertex
varying parameters...<br> TODO: Finish this...<br>
</li>
</ol>
<p>TODO: more info here.
</p>
<p><font color="gray">Page last updated —
$Date$
</font>
</p>
</body>
</html>
|