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

Slides:



Advertisements
Hasonló előadás
© Kozsik Tamás Különböző nyelvekhez igazítás Internationalization - i18n.
Advertisements

II. Grafikus felhasználói interfész
© Kozsik Tamás Appletek A Java nyelv elsődleges számú reklámja HTML oldalak aktívvá tevéséhez Kisalkalmazás WEB-böngésző által futtatott Java.
Objektum Orientált Programozás Visual Basicben. 2 Objektumok Object – egy dolog, tárgy, „valami” –Command button, text box, stb. Jellemzők –Properties.
Cells(sor száma, oszlop száma)
HADOOP Korszerű Adatbázisok Elérés, Belépés Elérés: eszakigrid109.inf.elte.hu Belépés: felhasználó/jelszó: neptun-kód Manager oldalak:
OS INTEGRÁCIÓ képek Hub integráció Egy gyorsindító az appunknak a hubban Extrák és megosztás Az appunk induláskor megkapja a képet.
Csala Péter ANDN #4. 2 Tartalom  C# - ban előre definiált típusok  Változók  Változókkal műveletek  Elágazás  Ciklus.
Bevezetés a Java programozásba
Java programozási nyelv 3. rész – Osztályok I.
C# tagfüggvények.
C# tagfüggvények.

Entity framework Krizsán Zoltán
SPRING FRAMEWORK bemutatása
V 1.0 Szabó Zsolt, Óbudai Egyetem, Haladó Programozás Eseménykezelés ismétlés Névtelen metódusok (anonymous methods)
Számítógépes grafika OpenGL 1. gyakorlat.
6. előadás Parametrikus polimorfizmus. Generikus programozás. Az Ada sablonok.
Kivételkezelés.
VFP Form programozás Form szerkesztő elemei vezérlő elemek
JavaScript a gyakorlatban. 7. Gyakorlat DHTML  Fa-struktúrájú menük létrehozása  Legördülő menük létrehozása.
V 1.0 OE-NIK HP 1 Programozási Paradigmák és Technikák Eseménykezelés Névtelen metódusok (anonymous methods)
Számítógépes Grafika 2. gyakorlat Programtervező informatikus (esti) 2011/2012 őszi félév.
Bátyai Krisztián NetAcademia Oktatóközpont oktató, fejlesztő MCT, MCPD
Szoftvertechnológia alapjai Java előadások Förhécz András, doktorandusz tárgy honlap:
Objektum orientált programozás a gyakorlatban
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
1 Hernyák Zoltán Web: Magasszintű Programozási Nyelvek I. Eszterházy.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
1 Hernyák Zoltán Web: Magasszintű Programozási Nyelvek I. Eszterházy.
1 Hernyák Zoltán Web: Magasszintű Programozási Nyelvek I. Eszterházy.
1 AAO folytatás ++ Csink László. 2 Rekurzív bináris keresés (rendezett tömbben) public static int binker(int[] tomb, int value, int low, int high) public.
Javascript Microsoft által készített kiegészítése Statikus típusosság Nagy projektek Windows 8 fejlesztésénél WinRT egy részét ebben írták Nyílt forráskódú,
Effect framework, HLSL shader László Szécsi. forráskódban elérhető egyszerűsíti a shaderek fordítását, rajzolási állapot beállítását – pass: egy ilyen.
1 Verseny 2000 gyakorlat ASP. 2 Gyakorlat Web létrehozása: Frontpage 2000 New Web:
Java programozási nyelv Filekezelés
Java programozási nyelv Adatbekérés konzolról
Generics Krizsán Zoltán. Bemutató A.NET 2.0 verziótól. A.NET 2.0 verziótól. Típusparaméter Típusparaméter Más nyelvben ez a template (sablon). Más nyelvben.
További lehetőségek Weblapok programozása. Nyelvek csoportosítása Leíró nyelv (HTML, XML, …) Programozási nyelv  Szerver oldali (PHP, ASP, …)  Kliens.
A Visual Basic nyelvi elemei
Illés Zoltán ELTE Informatikai Kar
Számítógépes Grafika 4. gyakorlat Programtervező informatikus (esti)‏ 2009/2010 őszi félév.
1 Mivel foglalkoz(t)unk a laborokon? 1.Labor: Word alapok Excel alapok: Excel alapok: Cellahivatkozás, munkalapfüggvény, diagram varázsló, trendvonal 2.
5. előadás Parametrikus polimorfizmus. Generikus programozás. Az Ada sablonok.
Számítógépes Grafika 3. gyakorlat Programtervező informatikus (esti)‏ 2009/2010 őszi félév.
Számítógépes Grafika 5. gyakorlat Programtervező informatikus (esti)‏ 2009/2010 őszi félév.
Példa. Az ábrázolás szemléltetése.  = ({stack, elem },{ create :  stack; push : stack elem  stack}),  = ( {vector, nat, elem}, { create c :  vector.
1Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Programozás I. 6. gyakorlat.
Vizualizáció és képszintézis Térfogati textúrák kezelése (Dart + GLSL) Szécsi László.
Széles körben elérhető Professzionális grafikus futtató környezet.
Grafikus szoftver Szirmay-Kalos László. Interaktív programok felépítése input csővezeték output csővezeték.
Krizsán Zoltán, iit C# osztályok 2 Adattagok  Osztály hatáskörben definiált változó.  Formája: [attribútum] [módosító] típus azonosító [=kezdő érték][,
Szécsi László 3D Grafikus Rendszerek 17. előadás
A grafikus hardware programozása
Vizualizáció és képszintézis
Vizualizáció és képszintézis
YUI február YUI szeptember YUI3
Vizualizáció és képszintézis
Hernyák Zoltán Magasszintű Programozási Nyelvek I.
gg004-Mesh project copy-paste-rename gg002-App folder
JavaScript a böngészőben
Ghost Hunter Game logic/HUD.
Fejlett Webes Technológiák II.
Fejlett Webes Technológiák II.
B M Java Programozás 5. Gy: Java alapok IT A N Adatkezelő 1.rész
JavaScript a böngészőben
Függvénysablonok használata
Előadás másolata:

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

Dart telepítés

Új project

Teszt

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

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

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'); }

Teszt

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(); }

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); }

Teszt

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

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

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);

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);

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'); }

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); }

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

Teszt

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;

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

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 = ;

Camera class Matrix4 viewMatrix; Matrix4 projMatrix; Matrix4 viewDirMatrix;

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;

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(); }

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; }

Camera update void update(double dt) { yaw += mouseDelta.x * ; 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();

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;

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(); }

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

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(); }

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

Még mindig ez

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

Ú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; }

Ú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); }

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

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);

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

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 * 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;

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; }

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); }

Valami van

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

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

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);

trace függvény vec3 trace(inout vec4 e, inout vec4 d, inout float contrib) { float bestT = ; 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]; }

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

„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;

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; }

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 * 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 = g; vec3 i1 = min( g.xyz, l.zxy ); vec3 i2 = max( g.xyz, l.zxy ); // x0 = x * C.xxx; // x1 = x0 - i * C.xxx; // x2 = x0 - i * C.xxx; // x3 = x * 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; // *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_ = ; // 1.0/7.0 vec3 ns = n_ * D.wyz - D.xzx; vec4 j = p * floor(p * ns.z * ns.z); // mod(p,7*7) vec4 x_ = floor(j * ns.z); vec4 y_ = floor(j * x_ ); // mod(j,N) vec4 x = x_ *ns.x + ns.yyyy; vec4 y = y_ *ns.x + ns.yyyy; vec4 h = 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))* ; //vec4 s1 = vec4(lessThan(b1,0.0))* ; vec4 s0 = floor(b0)* ; vec4 s1 = floor(b1)* ; 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) ) ); }

Ray tracing!