Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(888)

Side by Side Diff: samples/openglui/src/raytrace.dart

Issue 12186002: Canvas API. There are still a number of things to do: (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « samples/openglui/src/openglui_raytrace.dart ('k') | samples/openglui/web/canvas_tests.html » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4 //
5 // This sample is based upon the Ray Tracer sample by Jonas Sicking at:
6 // http://www.khronos.org/webgl/wiki/Demo_Repository
7
8 /**
9 * A sample GL application.
10 */
11 library raytrace;
12
13 import 'gl.dart';
14 import 'dart:math' as Math;
15
16 // Note: The first line of the fragment shader ("precision mediump float")
17 // is not portable. It is required for WebGL and OpenGL ES. Desktop OpenGL
18 // does not use precision specifiers. Some desktop systems treat this as a
19 // no-op and some treat it as a syntax error. In particular, this line needs
20 // to be removed to this this shader on a MAc.
21 const FRAGMENT_PROGRAM = """
22 // TODO(vsm): Remove this ifdef. It's a temporary workaround to get
23 // this sample running on the Mac desktop emulator.
24 #ifdef GL_ES
25 precision mediump float;
26 #endif
27
28 const vec3 lightDir = vec3(0.577350269, 0.577350269, -0.577350269);
29 varying vec3 vPosition;
30 uniform vec3 cameraPos;
31 uniform vec3 sphere1Center;
32 uniform vec3 sphere2Center;
33 uniform vec3 sphere3Center;
34
35 bool intersectSphere(vec3 center, vec3 lStart, vec3 lDir,
36 out float dist) {
37 vec3 c = center - lStart;
38 float b = dot(lDir, c);
39 float d = b*b - dot(c, c) + 1.0;
40 if (d < 0.0) {
41 dist = 10000.0;
42 return false;
43 }
44
45 dist = b - sqrt(d);
46 if (dist < 0.0) {
47 dist = 10000.0;
48 return false;
49 }
50
51 return true;
52 }
53
54 vec3 lightAt(vec3 N, vec3 V, vec3 color) {
55 vec3 L = lightDir;
56 vec3 R = reflect(-L, N);
57
58 float c = 0.3 + 0.4 * pow(max(dot(R, V), 0.0), 30.0) + 0.7 * dot(L, N);
59
60 if (c > 1.0) {
61 return mix(color, vec3(1.6, 1.6, 1.6), c - 1.0);
62 }
63
64 return c * color;
65 }
66
67 bool intersectWorld(vec3 lStart, vec3 lDir, out vec3 pos,
68 out vec3 normal, out vec3 color) {
69 float d1, d2, d3;
70 bool h1, h2, h3;
71
72 h1 = intersectSphere(sphere1Center, lStart, lDir, d1);
73 h2 = intersectSphere(sphere2Center, lStart, lDir, d2);
74 h3 = intersectSphere(sphere3Center, lStart, lDir, d3);
75
76 if (h1 && d1 < d2 && d1 < d3) {
77 pos = lStart + d1 * lDir;
78 normal = pos - sphere1Center;
79 color = vec3(0.0, 0.0, 0.9);
80 if (fract(pos.x / 1.5) > 0.5 ^^
81 fract(pos.y / 1.5) > 0.5 ^^
82 fract(pos.z / 1.5) > 0.5) {
83 color = vec3(1.0, 0.0, 1.0);
84 }
85 else {
86 color = vec3(1.0, 1.0, 0.0);
87 }
88 }
89 else if (h2 && d2 < d3) {
90 pos = lStart + d2 * lDir;
91 normal = pos - sphere2Center;
92 color = vec3(0.9, mod(normal.y * 2.5, 1.0), 0.0);
93 }
94 else if (h3) {
95 pos = lStart + d3 * lDir;
96 normal = pos - sphere3Center;
97 color = vec3(0.0, clamp(sphere3Center.y/1.5, 0.0, 0.9),
98 clamp(0.9 - sphere3Center.y/1.5, 0.0, 0.9));
99 }
100 else if (lDir.y < -0.01) {
101 pos = lStart + ((lStart.y + 2.7) / -lDir.y) * lDir;
102 if (pos.x*pos.x + pos.z*pos.z > 30.0) {
103 return false;
104 }
105 normal = vec3(0.0, 1.0, 0.0);
106 if (fract(pos.x / 5.0) > 0.5 == fract(pos.z / 5.0) > 0.5) {
107 color = vec3(1.0);
108 }
109 else {
110 color = vec3(0.0);
111 }
112 }
113 else {
114 return false;
115 }
116
117 return true;
118 }
119
120 void main(void)
121 {
122 vec3 cameraDir = normalize(vPosition - cameraPos);
123
124 vec3 p1, norm, p2;
125 vec3 col, colT, colM, col3;
126 if (intersectWorld(cameraPos, cameraDir, p1,
127 norm, colT)) {
128 col = lightAt(norm, -cameraDir, colT);
129 colM = (colT + vec3(0.2)) / 1.2;
130 cameraDir = reflect(cameraDir, norm);
131 if (intersectWorld(p1, cameraDir, p2, norm, colT)) {
132 col += lightAt(norm, -cameraDir, colT) * colM;
133 colM *= (colT + vec3(0.2)) / 1.2;
134 cameraDir = reflect(cameraDir, norm);
135 if (intersectWorld(p2, cameraDir, p1, norm, colT)) {
136 col += lightAt(norm, -cameraDir, colT) * colM;
137 }
138 }
139
140 gl_FragColor = vec4(col, 1.0);
141 }
142 else {
143 gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
144 }
145 }
146 """;
147
148 const VERTEX_PROGRAM = """
149 attribute vec2 aVertexPosition;
150 attribute vec3 aPlotPosition;
151
152 varying vec3 vPosition;
153
154 void main(void)
155 {
156 gl_Position = vec4(aVertexPosition, 1.0, 1.0);
157 vPosition = aPlotPosition;
158 }
159 """;
160
161 loadShader(final type, final program) {
162 final shader = gl.createShader(type);
163 gl.shaderSource(shader, program);
164 gl.compileShader(shader);
165 if (gl.getShaderParameter(shader, WebGLRenderingContext.COMPILE_STATUS) != tru e) {
166 final error = gl.getShaderInfoLog(shader);
167 log(error);
168 throw new Exception("Shader compilation error: $error");
169 }
170
171 return shader;
172 }
173
174 var shaderProgram;
175 var aVertexPosition;
176 var aPlotPosition;
177 var cameraPos;
178 var sphere1Center;
179 var sphere2Center;
180 var sphere3Center;
181 var ratio;
182
183 void initShaders() {
184 var vertexShader = loadShader(WebGLRenderingContext.VERTEX_SHADER,
185 VERTEX_PROGRAM);
186 var fragmentShader = loadShader(WebGLRenderingContext.FRAGMENT_SHADER,
187 FRAGMENT_PROGRAM);
188
189 shaderProgram = gl.createProgram();
190 if (shaderProgram == 0) {
191 throw new Exception("Could not create program.");
192 }
193
194 gl.attachShader(shaderProgram, vertexShader);
195 gl.attachShader(shaderProgram, fragmentShader);
196 gl.linkProgram(shaderProgram);
197
198 if (gl.getProgramParameter(shaderProgram, WebGLRenderingContext.LINK_STATUS) ! = true) {
199 final error = gl.getProgramInfoLog(shaderProgram);
200 throw new Exception("Program compilation error: $error");
201 }
202
203 gl.useProgram(shaderProgram);
204
205 aVertexPosition = gl.getAttribLocation(shaderProgram, "aVertexPosition");
206 gl.enableVertexAttribArray(aVertexPosition);
207
208 aPlotPosition = gl.getAttribLocation(shaderProgram, "aPlotPosition");
209 gl.enableVertexAttribArray(aPlotPosition);
210
211 cameraPos = gl.getUniformLocation(shaderProgram, "cameraPos");
212 sphere1Center = gl.getUniformLocation(shaderProgram, "sphere1Center");
213 sphere2Center = gl.getUniformLocation(shaderProgram, "sphere2Center");
214 sphere3Center = gl.getUniformLocation(shaderProgram, "sphere3Center");
215 }
216
217 // TODO(gram): This should go away at some point. For now it is a kludge
218 // to allow us to run same .dart file with WebGL and natively; the WebGL
219 // version will set this to true.
220 var wrapVertexArray = false;
221
222 wrapVertices(a) => wrapVertexArray ? (new Float32Array.fromList(a)) : a;
223
224 void initBuffers() {
225 var vertexPositionBuffer = gl.createBuffer();
226 gl.bindBuffer(WebGLRenderingContext.ARRAY_BUFFER, vertexPositionBuffer);
227 var vertices = [
228 1.0, 1.0,
229 -1.0, 1.0,
230 1.0, -1.0,
231 -1.0, -1.0,
232 ];
233
234 gl.bufferData(WebGLRenderingContext.ARRAY_BUFFER, wrapVertices(vertices),
235 WebGLRenderingContext.STATIC_DRAW);
236 gl.bindBuffer(WebGLRenderingContext.ARRAY_BUFFER, vertexPositionBuffer);
237 gl.vertexAttribPointer(aVertexPosition, 2, WebGLRenderingContext.FLOAT,
238 false,0, 0);
239
240 var plotPositionBuffer = gl.createBuffer();
241 gl.bindBuffer(WebGLRenderingContext.ARRAY_BUFFER, plotPositionBuffer);
242 gl.vertexAttribPointer(aPlotPosition, 3, WebGLRenderingContext.FLOAT,
243 false, 0, 0);
244 }
245
246 class Vector {
247 var x;
248 var y;
249 var z;
250 Vector(this.x, this.y, this.z);
251 }
252
253 // TODO(gram): This should be using vector_math.
254 crossProd(v1, v2) =>
255 new Vector(v1.y*v2.z - v2.y*v1.z,
256 v1.z*v2.x - v2.z*v1.x,
257 v1.x*v2.y - v2.x*v1.y);
258
259 Vector normalize(v) {
260 var l = 1 / Math.sqrt(v.x*v.x + v.y*v.y + v.z*v.z);
261 return new Vector( v.x*l, v.y*l, v.z*l );
262 }
263
264 vectAdd(v1, v2) => new Vector( v1.x + v2.x, v1.y + v2.y, v1.z + v2.z );
265
266 vectSub(v1, v2) => new Vector( v1.x - v2.x, v1.y - v2.y, v1.z - v2.z );
267
268 vectMul(v, l) => new Vector( v.x*l, v.y*l, v.z*l );
269
270 void pushVec(v, arr) {
271 arr.addAll([v.x, v.y, v.z]);
272 }
273
274 var t = 0;
275
276 void drawScene() {
277 var x1 = Math.sin(t * 1.1) * 1.5;
278 var y1 = Math.cos(t * 1.3) * 1.5;
279 var z1 = Math.sin(t + Math.PI/3) * 1.5;
280 var x2 = Math.cos(t * 1.2) * 1.5;
281 var y2 = Math.sin(t * 1.4) * 1.5;
282 var z2 = Math.sin(t*1.25 - Math.PI/3) * 1.5;
283 var x3 = Math.cos(t * 1.15) * 1.5;
284 var y3 = Math.sin(t * 1.37) * 1.5;
285 var z3 = Math.sin(t*1.27) * 1.5;
286
287 var cameraFrom = new Vector(
288 Math.sin(t * 0.4) * 18,
289 Math.sin(t * 0.13) * 5 + 5,
290 Math.cos(t * 0.4) * 18 );
291 var cameraTo = new Vector(0.0, 0.0, 0.0);
292 var cameraPersp = 6.0;
293 var up = new Vector(0.0, 1.0, 0.0);
294 var cameraDir = normalize(vectSub(cameraTo, cameraFrom));
295
296 var cameraLeft = normalize(crossProd(cameraDir, up));
297 var cameraUp = normalize(crossProd(cameraLeft, cameraDir));
298 // cameraFrom + cameraDir * cameraPersp
299 var cameraCenter = vectAdd(cameraFrom, vectMul(cameraDir, cameraPersp));
300
301 // cameraCenter + cameraUp + cameraLeft * ratio
302 var cameraTopLeft = vectAdd(vectAdd(cameraCenter, cameraUp),
303 vectMul(cameraLeft, ratio));
304 var cameraBotLeft = vectAdd(vectSub(cameraCenter, cameraUp),
305 vectMul(cameraLeft, ratio));
306 var cameraTopRight = vectSub(vectAdd(cameraCenter, cameraUp),
307 vectMul(cameraLeft, ratio));
308 var cameraBotRight = vectSub(vectSub(cameraCenter, cameraUp),
309 vectMul(cameraLeft, ratio));
310
311 var corners = [];
312 pushVec(cameraTopRight, corners);
313 pushVec(cameraTopLeft, corners);
314 pushVec(cameraBotRight, corners);
315 pushVec(cameraBotLeft, corners);
316
317 gl.bufferData(WebGLRenderingContext.ARRAY_BUFFER, wrapVertices(corners),
318 WebGLRenderingContext.STATIC_DRAW);
319
320 gl.uniform3f(cameraPos, cameraFrom.x, cameraFrom.y, cameraFrom.z);
321 gl.uniform3f(sphere1Center, x1, y1, z1);
322 gl.uniform3f(sphere2Center, x2, y2, z2);
323 gl.uniform3f(sphere3Center, x3, y3, z3);
324
325 gl.drawArrays(WebGLRenderingContext.TRIANGLE_STRIP, 0, 4);
326
327 t += 0.03;
328 if (t > Math.PI * 200) {
329 t -= Math.PI * 200;
330 }
331 }
332
333 void setup(int width, int height) {
334 initShaders();
335 gl.clearColor(0.0, 0.0, 0.0, 1.0);
336 gl.clearDepth(1.0);
337 initBuffers();
338 resize(width, height);
339 }
340
341 void resize(int width, int height) {
342 ratio = width / height;
343 gl.viewport(0, 0, width, height);
344 t -= 0.03;
345 drawScene();
346 }
347
348 void update() {
349 drawScene();
350 }
351
352 /*
353 TODO(gram): below are the current entry points for input events for the
354 native code version. We need to integrate these somehow with the WebGL
355 version:
356
357 onMotionDown(num when, num x, num y) {}
358 onMotionUp(num when, num x, num y) {}
359 onMotionMove(num when, num x, num y) {}
360 onMotionCancel(num when, num x, num y) {}
361 onMotionOutside(num when, num x, num y) {}
362 onMotionPointerDown(num when, num x, num y) {}
363 onMotionPointerUp(num when, num x, num y) {}
364 onKeyDown(num when, int flags, int keycode, int metastate, int repeat) {}
365 onKeyUp(num when, int flags, int keycode, int metastate, int repeat) {}
366 onKeyMultiple(num when, int flags, int keycode, int metastate, int repeat) {
367 }
368 */
369
OLDNEW
« no previous file with comments | « samples/openglui/src/openglui_raytrace.dart ('k') | samples/openglui/web/canvas_tests.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698