Cvičenie 1: Generovanie vzoru šachovnice

V tomto cvičení sa naučíte, ako vygenerovať vzor šachovnice pomocou shader programu.

Ukážka kódu

#define ROZMER_POLICKA 16

vec3 sachovnica(vec2 uv, float t){
  
  vec3 farba;
  
  vec3 cierna = vec3(0.0, 0.0, 0.0);
  vec3 biela = vec3(1.0, 1.0, 1.0);
  
  int x = int(uv.x * iResolution.x);
  int y = int(uv.y * iResolution.y);
  
  
  //TODO vytvorte sachovnicu
  
  
  
  if (true) farba = cierna;
  else farba = biela;
  
  return farba;
}



void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
  // Normalized pixel coordinates (from 0 to 1)
  vec2 uv = fragCoord/iResolution.xy;

  // Output to screen
  fragColor = vec4(sachovnica(uv, iTime),1.0);
}
      

Pokyny

  1. Skopírujte a vložte kód do shader editora.
  2. Upravte kód tak, aby ste vytvorili vzor šachovnice.
  3. Spustite shader program a skontrolujte výsledok.
  4. Pridajte filter 11×11 fragmentov.
  5. Pridajte animáciu v smere nejakého 2D vektora.
  6. Pridajte kružnicu s polomerom 5 políčok šachovnice.

Tipy

Cvičenie 2: Rasterizácia úsečky

V tomto cvičení sa naučíte, ako generovať úsečky.

Ukážka kódu

vec3 line2(vec2 a0, vec2 a1, vec2 fragCoord){

    vec3 white = vec3(1.0, 1.0, 1.0);
    vec3 black = vec3(0.0, 0.0, 0.0);
    
    vec2 v = a1 - a0;
    
    float m;//smernica
    
    //TODO vygenerujte usecku
    
    
    return white;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec3 col = vec3(1.0);
    
    float tetha = iTime*2.0;
    
    mat2 S;//vytvorte skalovaciu maticu
    
    mat2 R;//vytvorte rotacnu maticu
    
    //vytvorte trojuholnik ABC
 
 
    //posunte trojuholnik
 
    // Output to screen
    fragColor = vec4(col, 1.0);
}

Pokyny

  1. Skopírujte a vložte kód do shader editora.
  2. Upravte kód tak, aby ste vytvorili úsečku.
  3. Spustite shader program a skontrolujte výsledok.
  4. Vytvorte trojuholnik.
  5. Škálujte trojuholník pomocou matice.
  6. Rotujte trojuholník okolo jeho stredu/ťažiska a posuňte ho do stredu okna.
  7. Vytvorte v strede obrazovky plný fixný štvorec 10 × 10 (Slnko), čiarkovaný trojuholník (Zem) s preponou 10 rotujúci okolo svojho stredu a Slnka, čiarkovaný štvorec 5 × 5 (Mesiac) rotujúci okolo svojho stredu a Zeme.

Tipy

Cvičenie 3: Generovanie 3D kocky

V tomto cvičení sa naučíte, ako vygenerovať 3D kocku pomocou shader programu.

Ukážka kódu

vec3 line(vec2 a0, vec2 a1, vec2 fragCoord){

    vec3 white = vec3(1.0, 1.0, 1.0);
    vec3 black = vec3(0.0, 0.0, 0.0);
    
    vec2 v = a1 - a0;
    
    float m;
    
    if (abs(v.x) > abs(v.y)){
    
        if (a0.x > a1.x) {
            vec2 tmp = a0;
            a0 = a1;
            a1 = tmp;
        }
    
        if (fragCoord.x >= a0.x && fragCoord.x <= a1.x){
        
            m = v.y / v.x;

            float dx = fragCoord.x - a0.x;
            float y = a0.y + m*dx;
            
            
            if (floor(fragCoord.y) == floor(y)) return black;
        }
    }else{
    
        if (a0.y > a1.y) {
            vec2 tmp = a0;
            a0 = a1;
            a1 = tmp;
        }
    
        if (fragCoord.y >= a0.y && fragCoord.y <= a1.y){
        
            m = v.x / v.y;

            float dy = fragCoord.y - a0.y;
            float x = a0.x + m*dy;
            
            
            if (floor(fragCoord.x) == floor(x)) return black;
        }
    }
    
    return white;
}


vec3 dashed_line(vec2 a0, vec2 a1, vec2 fragCoord){

    vec3 white = vec3(1.0, 1.0, 1.0);
    
    float l = length(fragCoord - a0);
    
    if (int(l / 4.0) % 2 == 0) return line(a0, a1, fragCoord);
    else return white;
}


float f = 1000.0;

vec3 quad(vec3 a00, vec3 a10, vec3 a11, vec3 a01, vec2 fragCoord){
    
    vec3 col = vec3(1.0);
    
    //TO DO naprogramujte vykreslovanie stvorca
    
   
    return col;
}


void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec3 col = vec3(1.0);
    
    float tetha = iTime*2.0;
  
    //TO DO vytvorte skalovaciu maticu 3x3
     
    //TO DO vytvorte rotacnu maticu okolo Z aj okolo X
    
    
    //TO DO vykreslite kocku
  
 
    // Output to screen
    fragColor = vec4(col, 1.0);
}
      

Pokyny

  1. Skopírujte a vložte kód do shader editora.
  2. Upravte kód tak, aby ste vytvorili štvorec.
  3. Transformujte 3D suradnice do 2D, kde vzdialenosť stredu premietania a priemetne je f.
  4. Rozhodnite či je stena odvrátena, ak áno, vykreslite hrany čiarkovanou čiarou.
  5. Kocku naškálujte a rotujte okolo stredu.

Tipy

Cvičenie 4: Generovanie 3D sféry

V tomto cvičení sa naučíte, ako vygenerovať 3D sféru pomocou shader programu.

Ukážka kódu


float f = 500.0;


float sphere_intersection(vec3 sphere_c, float radius, vec3 ray_o, vec3 
ray_d){

    float result = 0.0;
    
    //TO DO result bude vzdialonost priesecnika od pociatku luca
    // ak nenajdeme priesecnik tak result bude 0
    
    return result;
}


void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec3 col = vec3(1.0);
    
    float tetha = iTime*2.0;
    
    vec3 ray_o;//pociatok luca
    
    vec3 ray_d;//normalizovany smer luca
       
    vec3 sphere_c = vec3(0, 0, -200);
   
    float d = sphere_intersection(sphere_c, 100.0, ray_o, ray_d);
    
    vec3 l_pos = vec3(500);//poloha svetla
    
    mat3 RY = mat3(vec3(cos(tetha), 0, sin(tetha)), vec3(0, 1, 0), 
vec3(-sin(tetha),0 , cos(tetha))) ;
   
    l_pos *= RY;
   
    if (d > 0.0) {
        // TO DO naprogramujte Blinn–Phong osvetl. model
    }
 
    // Output to screen
    fragColor = vec4(col, 1.0);
}

      

Pokyny

  1. Skopírujte a vložte kód do shader editora.
  2. Upravte kód tak, aby ste generovali lúče pre algoritmus „ray casting“.
  3. Počiatok lúčov bude v (0, 0, f) a priemetňa v rovine XY.
  4. Nájdite priesečník lúča a sféry.
  5. Naprogramujte „Blinn–Phong“ osvetľovací model.
  6. Rotujte zdroj svetla okolo osi Y.
  7. Pridajte šachovnicu do roviny Y=-200. Bude difúzne osvetlená.
  8. Pridajte tieň pod sféru.
  9. Skúste znížiť aliasing šachovnice.

Tipy

Cvičenie 5: Mandelbrotova fraktálová množina

V tomto cvičení sa naučíte, ako vygenerovať Mandelbrotovu množinu.

Ukážka kódu


struct Complex {
	float r, i;
};

float magnitude(Complex c){
	return sqrt(c.r*c.r + c.i*c.i);
}


const int max_iteration = 200;

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{

	float scale = iTime*200.0;
    
	float jx;// prepocitajte suradnice bodu
	float jy;//na suradnice v komplexnej rovine


			

	while (iteration < max_iteration) {
					
			
	}
		
	vec4 color; 
		
	if (iteration < 10)
			color = vec4(0.0, 0.0, 0.0, 1.0);	
	else if (iteration < 20)
			color = vec4( 0.173, 0.008, 0.22, 1.0);
	else if (iteration < 40)
			color = vec4(0.271, 0.063, 0.329, 1.0);	
	else if (iteration < 80)
			color = vec4(0.49, 0.286, 0.549, 1.0);	
	else if (iteration < 160)
			color = vec4(0.616, 0.447, 0.663, 1.0);	
	else color = vec4(0.376, 0.157, 0.439, 1.0);	


 	// Output to screen
	fragColor = color;
}
      

Pokyny

  1. Skopírujte a vložte kód do shader editora.
  2. Vytvorte funkciu na násobenie a funkciu na sčitovanie komplexných čísel.
  3. Prepočítajte pozíciu fragmentu na súradnice bodu v komplexnej rovine.
  4. Posuňte stred okna do bodu reprezentujúceho komplexné číslo -3⁄2 + 0i.
  5. Zistite vo while cykle, či bude postupnosť divergovať.
  6. Vytvorte animáciu, tak že budete škálovať komplexnú rovinu okolo bodu okolo stredu okna.

Tipy

Cvičenie 6: Simulácia vĺn na vodnej hladine

Na tomto cvičení sa naučíte, ako iteratívne simulovať vodné vlny na plytkej vode.

Ukážka kódu


float kernel[] = float[](1.000000, 0.678259, 0.156359, 
-0.065368, -0.064453, -0.031422, -0.014943, -0.008284, 
-0.005187, -0.003499, -0.002484);


float rand(vec2 co){
    return fract(sin(dot(co, vec2(12.9898, 78.233))) * 
43758.5453);
}

// Pseudo-random value in half-open range [0:1].
float random( float seed ) { 

   uint x = floatBitsToUint(seed);
   x += ( x << 10u );
   x ^= ( x >>  6u );
   x += ( x <<  3u );
   x ^= ( x >> 11u );
   x += ( x << 15u ); 
   
   const uint ieeeMantissa = 0x007FFFFFu; // binary32 
mantissa bitmask
   const uint ieeeOne      = 0x3F800000u; // 1.0 in IEEE 
binary32

    x &= ieeeMantissa;                     // Keep only 
mantissa bits (fractional part)
    x |= ieeeOne;                          // Add 
fractional part to 1.0

    float  f = uintBitsToFloat( x );       // Range [1:2]
    return f - 1.0;   


}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv = fragCoord/iResolution.xy;
     
    //ComputeVerticalDerivative
    float vd = 0.0;
    vec2 coords;
    
    if (all(lessThan(fragCoord.xy, iResolution.xy - 6.0)) 
&& all(greaterThanEqual(fragCoord.xy, vec2(6)))){
        for(int iix=-6;iix<=6;iix++)
        {
            for(int iiy=-6;iiy<=6;iiy++)
            {
                coords = (fragCoord + vec2(iix, 
iiy))/iResolution.xy;
                vd += kernel[int(round(length(vec2(iix, 
iiy))))] * texture(iChannel1, coords).r;
            }
        }
    }
    
    float dt = iTimeDelta;//0.03;//
	float alpha = 0.3;
    float gravity = 9.8 * dt * dt;
	
			
    float adt = alpha*dt;
	float adt2 = 1.0/(1.0+adt);
    
    
    float height = texture(iChannel1, uv).r;
    float previous_height = texture(iChannel0, uv).r;
    
    height = height*(2.0-adt)-previous_height-gravity*vd;
	height *= adt2;
      
    if (rand(uv*10.0)  < 0.00001) 
      if(  random(iTime/100.0) < 0.01  ) 
        height += 0.01;
 //if (fragCoord.x <= 6.0 && fragCoord.y <= 6.0 && iTime == 
0.0) 
 //       height += 0.5;
       
    fragColor = vec4(vec3(height),1.0);
}

      

Pokyny

  1. Vytvorte **Buffer A**, do ktorého sa skopíruje obsah **Buffer B**.
  2. Vytvorte **Buffer B**, do ktorého sa skopíruje obsah **Buffer C**.
  3. Vytvorte **Buffer C**, do ktorého skopírujete uvedený kód.
  4. Vypočítajte **normály** z hĺbkovej mapy v textúre **Buffer C** a zobrazte vodnú hladinu.

Tipy