Az előadás letöltése folymat van. Kérjük, várjon

Az előadás letöltése folymat van. Kérjük, várjon

Vizualizáció és képszintézis Sugárkövetés (Dart + GLSL) Szécsi László.

Hasonló előadás


Az előadások a következő témára: "Vizualizáció és képszintézis Sugárkövetés (Dart + GLSL) Szécsi László."— Előadás másolata:

1 Vizualizáció és képszintézis Sugárkövetés (Dart + GLSL) Szécsi László

2 Dart telepítés

3 Új project

4 Teszt

5 index.html <script data-pub-inline src="packages/browser/dart.js">

6 main.dart library ufoRaytracer; import 'dart:html'; import 'dart:web_gl' as WebGL; import 'dart:typed_data';

7 Globális output változó és App class DivElement output; class App { void init(String canvasId) {} } App app = new App(); void main() { output = querySelector("#output"); app.init('#container'); }

8 Teszt

9 Canvas, context, rajzolás-esemény class App { WebGL.RenderingContext gl; CanvasElement canvas; int get width => canvas.width; int get height => canvas.height; void init(String canvasId) { canvas = querySelector(canvasId); gl = canvas.getContext('experimental-webgl'); if (gl == null) { canvas.parent.text = ">>> Browser does not support WebGL <<<"; return; } // Measure the canvas element. canvas.width = canvas.parent.client.width; canvas.height = 800; // TODO: set up scene here requestRedraw(); }

10 Canvas, context, rajzolás-esemény void update(double time) { gl.viewport(0, 0, width, height); gl.clearColor(0.6, 0.0, 0.3, 1.0); gl.clearDepth(1.0); gl.clear(WebGL.RenderingContext.COLOR_BUFFER_BIT | WebGL.RenderingContext.DEPTH_BUFFER_BIT); // TODO: draw scene here requestRedraw(); } void requestRedraw() { window.requestAnimationFrame(update); }

11 Teszt

12 New file in web: quad.dart main.dart importok után quad.dart part 'quad.dart'; part of ufoRaytracer;

13 quad.dart class Quad { WebGL.Buffer vertexBuffer; WebGL.Shader vertexShader; WebGL.Shader fragmentShader; WebGL.Program program; int _positionAttributeIndex;

14 Quad.createResources konstruktor Quad.createResources(WebGL.RenderingContext gl){ vertexBuffer = gl.createBuffer(); gl.bindBuffer(WebGL.RenderingContext.ARRAY_BUFFER, vertexBuffer); gl.bufferDataTyped(WebGL.RenderingContext.ARRAY_BUFFER, new Float32List.fromList( [ -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0 ] ), WebGL.RenderingContext.STATIC_DRAW);

15 Quad.createResources konstruktor folyt. vertexShader = gl.createShader(WebGL.RenderingContext.VERTEX_SHADER); gl.shaderSource(vertexShader, ''' attribute vec2 vPosition; void main() { gl_Position = vec4(vPosition, 0.99, 1); } ''' ); gl.compileShader(vertexShader); output.text += gl.getShaderInfoLog(vertexShader); fragmentShader = gl.createShader(WebGL.RenderingContext.FRAGMENT_SHADER); gl.shaderSource(fragmentShader, ''' void main() { gl_FragColor = vec4(1, 1, 0, 1); } '''); gl.compileShader(fragmentShader); output.text += gl.getShaderInfoLog(fragmentShader);

16 Quad.createResources konstruktor program = gl.createProgram(); gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); gl.linkProgram(program); output.text += gl.getProgramInfoLog(program); _positionAttributeIndex = gl.getAttribLocation(program, 'vPosition'); }

17 Quad.draw void draw(WebGL.RenderingContext gl) { gl.useProgram(program); gl.bindBuffer(WebGL.RenderingContext.ARRAY_BUFFER, vertexBuffer); gl.enableVertexAttribArray(_positionAttributeIndex); gl.vertexAttribPointer(_positionAttributeIndex, 2, WebGL.RenderingContext.FLOAT, false, 8, 0); // 0 offset gl.drawArrays(WebGL.RenderingContext.TRIANGLE_STRIP, 0, 4); }

18 main.dart: App class Quad quad; // TODO: set up scene here quad = new Quad.createResources(gl); // TODO: draw scene here quad.draw(gl);

19 Teszt

20 New file in web: camera.dart main.dart camera.dart import 'dart:math' as Math; import 'package:vector_math/vector_math.dart'; part 'camera.dart'; part of ufoRaytracer;

21 Új függőség pubspec.yaml dupla klikk Dependencies / Add... vector_math

22 Camera class class Camera { Vector3 position = new Vector3(0.0, 0.0, 0.0); Vector3 ahead = new Vector3(0.0, 0.0, 1.0); Vector3 right = new Vector3(1.0, 0.0, 0.0); double yaw = 0.0; double pitch = 0.0; double fov = 0.5; double aspect = 1.0; double nearPlane = 0.1; double farPlane = 1000.0;

23 Camera class Matrix4 viewMatrix; Matrix4 projMatrix; Matrix4 viewDirMatrix;

24 Camera class double speed = 0.5; Vector2 lastMousePosition = new Vector2(0.0, 0.0); Vector2 mouseDelta = new Vector2(0.0, 0.0); bool wPressed = false; bool aPressed = false; bool sPressed = false; bool dPressed = false; bool qPressed = false; bool ePressed = false;

25 Camera class Camera() { viewMatrix = makeViewMatrix(position, position+ahead, new Vector3(0.0, 1.0, 0.0)).transpose(); projMatrix = makePerspectiveMatrix(fov, aspect, nearPlane, farPlane).transpose(); viewDirMatrix = makeViewMatrix(new Vector3(0.0, 0.0, 0.0), ahead, new Vector3(0.0, 1.0, 0.0)).transpose(); viewDirMatrix.multiply(projMatrix); viewDirMatrix.invert(); }

26 Camera class void keydown(int keyCode) { if(keyCode == KeyCode.W) wPressed = true; if(keyCode == KeyCode.A) aPressed = true; if(keyCode == KeyCode.S) sPressed = true; if(keyCode == KeyCode.D) dPressed = true; if(keyCode == KeyCode.E) ePressed = true; if(keyCode == KeyCode.Q) qPressed = true; } void keyup(int keyCode) { if(keyCode == KeyCode.W) wPressed = false; if(keyCode == KeyCode.A) aPressed = false; if(keyCode == KeyCode.S) sPressed = false; if(keyCode == KeyCode.D) dPressed = false; if(keyCode == KeyCode.E) ePressed = false; if(keyCode == KeyCode.Q) qPressed = false; }

27 Camera update void update(double dt) { yaw += mouseDelta.x * -0.002; pitch += mouseDelta.y * 0.002; if(pitch > 3.14/2.0) pitch = 3.14/2.0; if(pitch < -3.14/2.0) pitch = -3.14/2.0; mouseDelta = new Vector2(0.0, 0.0); ahead = new Vector3(Math.sin(yaw)*Math.cos(pitch), -Math.sin(pitch), Math.cos(yaw)*Math.cos(pitch) ); right = ahead.cross( new Vector3(0.0, 1.0, 0.0) ).normalize();

28 Camera update if(wPressed) position += ahead * speed * dt; if(sPressed) position -= ahead * speed * dt; if(aPressed) position -= right * speed * dt; if(dPressed) position += right * speed * dt; if(qPressed) position -= new Vector3(0.0,1.0,0.0) * speed * dt; if(ePressed) position += new Vector3(0.0,1.0,0.0) * speed * dt;

29 Camera update viewMatrix = makeViewMatrix(position, position+ahead, new Vector3(0.0, 1.0, 0.0)).transpose(); viewDirMatrix = makeViewMatrix(new Vector3(0.0, 0.0, 0.0), ahead, new Vector3(0.0, 1.0, 0.0)).transpose(); viewDirMatrix.multiply(projMatrix); viewDirMatrix.invert(); }

30 main.dart: App class Camera camera = new Camera(); double lastTime = 0.0; void update(double time) { double dt = (time - lastTime) / 1000.0; lastTime = time; // TODO: draw scene here camera.update(dt);

31 main.dart: App class bool ownMouse = false; void clicked(Event event) { canvas.requestPointerLock(); } void pointerLockChange(Event event) { ownMouse = (canvas == document.pointerLockElement); } void keydown(KeyboardEvent event) { if (!ownMouse) return; camera.keydown(event.keyCode); } void keyup(KeyboardEvent event) { if (!ownMouse) return; camera.keyup(event.keyCode); } void mouseMove(MouseEvent event) { if (!ownMouse) return; camera.mouseDelta += new Vector2( event.movement.x.toDouble(), event.movement.y.toDouble()); event.preventDefault(); }

32 App.init document.onPointerLockChange.listen(pointerLockChange); canvas.onClick.listen(clicked); document.onKeyDown.listen(keydown); document.onKeyUp.listen(keyup); document.onMouseMove.listen(mouseMove);

33 Még mindig ez

34 Quad.draw új paraméter: kamera void draw(WebGL.RenderingContext gl, Camera camera)

35 Új VS uniform mat4 viewDirMatrix; attribute vec2 vPosition; varying vec3 viewDir; void main(void) { vec4 position = vec4(vPosition, 0.99, 1); gl_Position = position; vec4 hViewDir = position * viewDirMatrix; viewDir = hViewDir.xyz / hViewDir.w; }

36 Új PS precision highp float; varying vec3 viewDir; uniform vec3 eye; void main() { vec4 d = vec4(normalize(viewDir), 0.0); gl_FragColor = vec4(d.xyz, 1); }

37 Quad WebGL.UniformLocation _viewDirMatrixLocation; WebGL.UniformLocation _eyeLocation; _viewDirMatrixLocation = gl.getUniformLocation(program,'viewDirMatrix'); _eyeLocation = gl.getUniformLocation(program,'eye');

38 Quad.draw Float32List viewDirMatrixData = new Float32List(16); camera.viewDirMatrix.copyIntoArray(viewDirMatrixData, 0); gl.uniformMatrix4fv(_viewDirMatrixLocation, false, viewDirMatrixData); gl.uniform3f(_eyeLocation, camera.position.x, camera.position.y, camera.position.z);

39 Egér kattintás után egérmozgatás forgat

40 Quadric metszés float intersectClippedQuadric( mat4 A, mat4 B, vec4 e, vec4 d) { float a = dot( d, A * d); float b = dot( e, A * d) + dot(d, A * e ); float c = dot( e, A * e ); float discr = b * b - 4.0 * a * c; if ( discr < 0.0 ) return -1.0; float sqrt_discr = sqrt( discr ); float t1 = (-b + sqrt_discr)/2.0/a; float t2 = (-b - sqrt_discr)/2.0/a;

41 Quadric metszés vec4 hit1 = e + d * t1; vec4 hit2 = e + d * t2; if( dot( hit1, B * hit1) > 0.0) t1 = -1.0; if( dot( hit2, B * hit2) > 0.0) t2 = -1.0; float t = (t1<t2)?t1:t2; if(t < 0.0) t = (t1<t2)?t2:t1; return t; }

42 main void main() { vec4 d = vec4(normalize(viewDir), 0.0); vec4 e = vec4(eye, 1.0); mat4 A = mat4( 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0,-1.0); mat4 B = mat4( 4.0, 0.0, 0.0, 0.0, 0.0, 0.81, 0.0, 0.0, 0.0, 0.0, 0.25, 0.0, 0.0, 0.0, 0.0,-1.0); float t = intersectClippedQuadric(A, B, e, d); if(t < 0.0) gl_FragColor = vec4(d.xyz, 1); else gl_FragColor = vec4(0.5, 0.5, 0.5, 1.0); }

43 Valami van

44 További feladat: getQuadricNormal vec3 getQuadricNormal(mat4 A, vec4 hit) { return ????; } // adjuk vissza a normált, mint színt

45 Színtér uniform mat4 quadrics[32]; uniform vec4 materials[16]; Float32List quadricData = new Float32List(16*32); Float32List materialData = new Float32List(16*4);

46 Quad.createResources: színtérépítés (példa) Matrix4 A = makeSphere(); A.copyIntoArray(quadricData, 0); Matrix4 B = makeSphere(); Matrix4 scaler = new Matrix4.diagonal3(new Vector3(0.5, 2.0, 0.9)); B.multiply(scaler); scaler.transpose(); B = scaler.multiply(B); B.copyIntoArray(quadricData, 16); Vector4 wallMaterial = new Vector4(1.0, 1.0, 1.0, 0.0); wallMaterial.copyIntoArray(materialData, 0); { Matrix4 B = makeSphere(); Matrix4 scaler = new Matrix4.diagonal3(new Vector3(0.5, 2.0, 0.9)); B.multiply(scaler); scaler.transpose(); B = scaler.multiply(B); B.copyIntoArray(quadricData, 32); Matrix4 A = makeSphere(); A.copyIntoArray(quadricData, 48); } Vector4 mirrorMaterial = new Vector4(0.0, 0.0, 0.0, 0.3); mirrorMaterial.copyIntoArray(materialData, 4);

47 trace függvény vec3 trace(inout vec4 e, inout vec4 d, inout float contrib) { float bestT = 10000.0; vec4 bestMaterial; mat4 bestQuadric; for(int i=0; i<2; i++) { float t = intersectClippedQuadric(quadrics[2*i], quadrics[2*i+1], e, d); if(t > 0.0 && t < bestT) { bestT = t; bestQuadric = quadrics[2*i]; bestMaterial = materials[i]; }

48 trace függvény if(bestT > 9999.0) return d.xyz; // háttér vec4 hit = e + d*bestT; vec3 normal = getQuadricNormal(bestQuadric, hit); // árnyalás, szín return

49 „Rekurzió” a mainben vec4 outColor = vec4(0.0, 0.0, 0.0, 1.0); float contrib = 1.0; for(int iReflection=0; iReflection<2; iReflection++) { outColor.xyz += trace(e, d, contrib); if(contrib < 0.05) break; } gl_FragColor = outColor;

50 Contrib számítása a trace-ben float g = contrib; contrib *= bestMaterial.w; if( bestMaterial.w < 0.01 ) { return lokális árnyalás * g; } else { e = hit - vec4(normal, 0.0) * 0.001; d.xyz = reflect(d.xyz, -normal); return lokális árnyalás; }

51 Zajfüggvény procedurális textúrázáshoz vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec4 mod289(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec4 permute(vec4 x) { return mod289(((x*34.0)+1.0)*x); } vec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; } float snoise(vec3 v) { const vec2 C = vec2(1.0/6.0, 1.0/3.0) ; const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); // First corner vec3 i = floor(v + dot(v, C.yyy) ); vec3 x0 = v - i + dot(i, C.xxx) ; // Other corners vec3 g = step(x0.yzx, x0.xyz); vec3 l = 1.0 - g; vec3 i1 = min( g.xyz, l.zxy ); vec3 i2 = max( g.xyz, l.zxy ); // x0 = x0 - 0.0 + 0.0 * C.xxx; // x1 = x0 - i1 + 1.0 * C.xxx; // x2 = x0 - i2 + 2.0 * C.xxx; // x3 = x0 - 1.0 + 3.0 * C.xxx; vec3 x1 = x0 - i1 + C.xxx; vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y // Permutations i = mod289(i); vec4 p = permute( permute( permute( i.z + vec4(0.0, i1.z, i2.z, 1.0 )) + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) + i.x + vec4(0.0, i1.x, i2.x, 1.0 )); // Gradients: 7x7 points over a square, mapped onto an octahedron. // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) float n_ = 0.142857142857; // 1.0/7.0 vec3 ns = n_ * D.wyz - D.xzx; vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7) vec4 x_ = floor(j * ns.z); vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N) vec4 x = x_ *ns.x + ns.yyyy; vec4 y = y_ *ns.x + ns.yyyy; vec4 h = 1.0 - abs(x) - abs(y); vec4 b0 = vec4( x.xy, y.xy ); vec4 b1 = vec4( x.zw, y.zw ); //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0; //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0; vec4 s0 = floor(b0)*2.0 + 1.0; vec4 s1 = floor(b1)*2.0 + 1.0; vec4 sh = -step(h, vec4(0.0)); vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ; vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ; vec3 p0 = vec3(a0.xy,h.x); vec3 p1 = vec3(a0.zw,h.y); vec3 p2 = vec3(a1.xy,h.z); vec3 p3 = vec3(a1.zw,h.w); //Normalise gradients vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); p0 *= norm.x; p1 *= norm.y; p2 *= norm.z; p3 *= norm.w; // Mix final noise value vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); m = m * m; return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3) ) ); }

52 Ray tracing!


Letölteni ppt "Vizualizáció és képszintézis Sugárkövetés (Dart + GLSL) Szécsi László."

Hasonló előadás


Google Hirdetések