GRK/cw 4/exercises 4.html

102 lines
8.7 KiB
HTML
Raw Normal View History

2022-01-12 16:07:16 +01:00
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>exercises 4</title>
<style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
</style>
<link rel="stylesheet" href="style.css" />
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
<![endif]-->
</head>
<body>
<h2 id="i-phong-illumination-model">I Phong illumination model</h2>
<h3 id="i.0.-do-it-if-you-havent-done-previous-exercises-connected-to-shaders">I.0. (Do it if you havent done previous exercises connected to shaders)</h3>
<p>Took at the files <strong>shader_4_1.vert</strong> i <strong>shader_4_1.frag</strong>. Note how <em>normal vectors</em> are sent from <strong>vertex shader</strong> to <strong>fragment shader</strong> with variable <code>interpNormal</code>. Files shader_4_2.vert i shader_4_2.frag wont be used for now.</p>
<h3 id="i.1.-calculate-diffuse-phong-lightning-intensity-in-the-fragment-shader">I.1. Calculate diffuse Phong lightning intensity in the fragment shader:</h3>
<ol type="a">
<li>Send a light source. For now we will use directional light source, thus the light will be described by a unit vector:</li>
</ol>
<ul>
<li><p>Send to the fragment shader a variable of type <code>uniform vec3</code> (name it eg. <code>lightDir</code>), it will contain the light direction:</p></li>
<li><p>Do it the same way as <code>objectColor</code> is sent. Only difference is that the light direction is independent form a object, thus call of <code>glUniform3f</code> should be done only once before any draw call. Call <code>glUseProgram(program)</code> before sending the value.</p></li>
<li><p>As a light direction pick any unit vector. (You can take any nonzero vector and normalize it)</p></li>
</ul>
<ol start="2" type="a">
<li>Calculate diffusion intensity in fragment shader:</li>
</ol>
<ul>
<li><p>normalize the normal vector before using it (averaging during rasterization could have changed their size).</p></li>
<li><p>Intensity is equal to a dot product of surface normal vector and inverse light direction vector. Use the function <code>dot</code>.</p></li>
<li><p>Intensity cannot be negative. clamp it to zero from bellow with max function: <code>x = max(x, 0.0)</code></p></li>
</ul>
<ol start="3" type="a">
<li>Use calculated intensity to modify object color:</li>
</ol>
<ul>
<li>Multiply RGB values of the fragment wth the diffusion intensity.</li>
</ul>
<h3 id="i.2.-why-spaceship-illumination-is-not-changing-with-rotation">I.2. Why spaceship illumination is not changing with rotation?</h3>
<p>(Normal vectors are in local model space and the light direction vector is in world space)</p>
<p>All vertex normal vectors have to be transformed into world space:</p>
<ul>
<li><p>Send the model matrix of the object drawn as a separate variable to the vertex shader (<code>uniform mat4</code>).</p></li>
<li><p>Multiply the normal vector in the shader with the model matrix before sending it to the fragment shader.</p></li>
<li><p>The <strong>w</strong> coordinate of the normal vector has to be set to 0 before multipication with the model matrix. This is because the normal vector is a direction and not a point in homogeneous coordinates. We do not want to translate it during homogenization.</p></li>
</ul>
<h3 id="i.3.-add-specular-phong-lighting-to-the-model.">I.3. Add specular Phong lighting to the model.</h3>
<ol type="a">
<li>Define a vector describing the view direction (it depends on the surface and camera positions):</li>
</ol>
<ul>
<li><p>Send the camera position (<code>cameraPos</code>) as another variable to the fragment shader.</p></li>
<li><p>Analogously to the normal vectors of the vertex shader, send the vertex positions from vertex to fragment shader (vertexPosition) in world space (multiplied with the modelMatrix). This time around the vectors represent points and not directions - the <strong>w</strong> coordinate of the vertex positions has to be set to 1. In the result of rasterization we will recive fragment position in the fragment shader.</p></li>
<li><p>Calculate vector <strong>V</strong> (<em>view direciton vecor</em>) as a normalized difference of the camera position and the fragment position.</p></li>
</ul>
<ol start="2" type="a">
<li>Calculate specular light intensity in the fragment shader:</li>
</ol>
<ul>
<li><p>Obtain the reflected light direction <strong>R</strong> using the glsl function <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/reflect.xhtml"><code>reflect</code></a>. Remember to that light direction vector must be inverse.</p></li>
<li><p>Calculate the light intensity: dot product of <strong>V</strong> i <strong>R</strong>, clamped to zero ( <code>max(...,0.0)</code> )and then raised to high power (np. 8, 50, 1000), which is a measure of brilliancy.</p></li>
</ul>
<ol start="3" type="a">
<li>The shaded pixel color is: objectColor * diffuse + vec3(1.0) * specular. This describes the simplest case when the reflected light color is white.</li>
</ol>
<h3 id="i.4.-create-planetary-system---one-stationary-sphere-in-the-center-and-a-few-orbiting-planets.-at-least-one-planet-should-have-some-moons.">I.4. Create planetary system - one stationary sphere in the center and a few orbiting planets. At least one planet should have some moons.</h3>
<h3 id="i.5.-a-planetary-system-should-be-lit-by-a-sun-therefore-change-directional-lighting-to-point-lightning">I.5. A planetary system should be lit by a sun, therefore change directional lighting to point lightning :</h3>
<ul>
<li><p>Instead of sending (in <code>lightDir</code>) light direction, send the sun position to the fragment shader (the same that you set in the exercise above) as <code>uniform vec3</code> (call it <code>lightPos</code>).</p></li>
<li><p>Calculate the light direction by subtracting the sun position from the fragment position. Normalize the result and save it in the <code>lightDir</code> variable.</p></li>
<li><p>Sun will be black, dont worry about it, it will be fixed in the next task.</p></li>
</ul>
<h3 id="i.6.-light-source-is-inside-of-the-sphere-that-represents-the-sun-thus-it-is-black.-to-fix-it-create-another-shader-that-will-be-responsible-for-rendering-the-sun.">I.6. Light source is inside of the sphere that represents the sun, thus it is black. To fix it create another shader, that will be responsible for rendering the sun.</h3>
<p>Goal of this exercise is to create a shader (<strong>shader_4_sun.vert</strong>_ i <strong>shader_4_sun.frag</strong>), that will be responsible only for rendering the sun. Previous shaders (<strong>shader_4_1.vert</strong>_ i <strong>shader_4_1.frag</strong>) should still render other objects.</p>
<ol type="a">
<li>initialize <em>program</em> (shaders):</li>
</ol>
<ul>
<li><p>Files <strong>shader_4_sun.vert</strong> and <strong>shader_4_sun.frag</strong> are identical to <strong>4_1</strong> before your modifications, they will be starting point for sun shader.</p></li>
<li><p>Create global variable <code>GLuint programSun</code> which will be used to store sun shader address. Create <em>program</em> with <code>shaderLoader.CreateProgram</code> analogously to creation of <code>program</code> from <strong>shader_4_1.vert</strong> i <strong>shader_4_1.frag</strong> (input values are paths to vertex and fragment shaders <strong>shader_4_sun.vert</strong> i <strong>shader_4_sun.frag</strong>).</p></li>
</ul>
<ol start="2" type="a">
<li>Im more complex projects different types of objects are drawn with different shaders, thus architecture, that will allow it, is required in the application. Set appropriate <em>program</em> for sun rendering</li>
</ol>
<p>-function <code>drawObject</code> uses the global function <code>program</code>, to point drawing shaders. Add a function argument, which should contain a program address used in rendering.</p>
<p>-add appropriate program to <code>drawObject</code> calls.</p>
<h3 id="i.7.-change-sun-shader-to-more-realistic.">I.7.* Change sun shader to more realistic.</h3>
<p>On the picture bellow you can see a sun. It is darker on the corners, try to get a similar effect. Vectors from previous points will be useful, especially normal vector and the vector <strong>V</strong>.</p>
<p><img src="https://wi-images.condecdn.net/image/DEGypMQdE59/crop/1020/f/sunmeta.jpg" /></p>
</body>
</html>