Teapot Tea pot with WebGL (2) Phong shading

Source: Internet
Author: User
Tags pow

Applying Phong shading in the fragment shader makes the teapot more realistic. Even if the teapot is a single color, as long as the position of the light source changes, or the position of the eye changes, see the various parts of the teapot color is not necessarily the same shade. The so-called Phong shading is a method of determining the color of each pixel phong this person proposes.

In general, what kind of teapot do we want to see? We hope it is the same as the real, there is light it, so the light of the place is bright, the place is not in the dark, the place of the light and bright reflected light.

Point E sees that p has color because photons run from P to E. The point P has photons, unless p is the light source, otherwise the photon must have come from somewhere else. One of the other places is the light source, with the light shining on the p. However, if there is no direct light, such as the room to pull the curtains, you can still see p, because the P-point around the countless points (other parts of the teapot, cups, tables, etc.) are emitting photons to it. This is the other place of the second, the environment.

Summarize a point P (not the light source), was seen at E Point, indicating

1. There are photons running from other places to P.

Two possible sources, one is the light source, the other is the environment.

The photon from the 2.P Point ran to E.

The photon reaching P has three possible, one is absorbed to produce heat, the second is to penetrate inside and scatter out, third is directly from the surface reflection out. Absorption is not considered, the remaining part of the scattering, part of the reflection, scattering refers to this part of the photon from P out to run in all directions (of course, along the line), there is a direction e,e will see scattered light. The scattered light often represents the P original color, the reflected light is almost irrelevant to the color of p, because it does not enter the interior of p but changes direction at p, it is the original light. Because the environment gives p photons from all directions, it is not good to analyze their reflection direction, the number is not small, so it is generally believed that the photons that reach p from the environment are scattered out.

The photon intensity that reaches p in the environment is fixed, and it reaches the same photon strength as other p1,p2 in the teapot. But the same light source, to the teapot each P,P1,P2 photon strength is not fixed. The magnitude of this intensity is related to the angle of incidence. The Lambertian indicates that the intensity of the light source L reaches P can be represented by the strength of the cos (the angle of the normal vector N of P and the opposite direction vector L of the incident light) *l, which is the strength of N=normalize (n), L=normalize (L), Dot (n,l) *l. Dot (n,l) may be less than 0, less than 0 means light is shining from the back of P, so no photons run to P,max (0, Dot (n,l)) *l strength.

The direction of the reflective part of the light source can be calculated, is the vector R. The smaller the angle between the E-p and R, the more reflection is received. It is also possible to see the angle between the vector h and N, H=normalize (e-p+l).

Color of P-point = ambient light intensity and color * scatter coefficient + light source intensity with color *max (0, Dot (n,l)) * Scatter coefficient + light source intensity with color *pow (dot (h,n), P)

The scattering coefficient is closely related to the color of P itself. The POW is to quickly reduce the highlight size, otherwise the highlighting is not true. P is the smoothing factor.

The POW (dot (h,n), P) is an improved Phong shading. Phong proposed is the POW (max (0,dot (r,e-p)), p). The difference is that when E-p and R are obtuse, the modified Phong shading still produce reflected light. The smooth surface is still rough and microfacets in all directions.


This browser DoNot support WebGL. </canvas> <script src= "./examples/lib/cuon-matrix.js" ></script> <script src= "./TEAPOTDATA.J S "></script> <script>functionMain () {//alert ("BB");    //Get WebGL Context    varViewPort = document.getElementById ("ViewPort"); varGL = Viewport.getcontext ("WebGL") | | Viewport.getcontext ("Experimental-webgl"); varVertex_shader = "attribute vec4 a_position;\n" + "attribute vec3 a_vnomal;\n" + "varying vec4 v_position;\n" + "Varying vec3 v_vnomal;\n" + "uniform mat4 u_modelmatrix;\n" + "uniform mat4 u_viewmatrix;\n" + "Uniform mat4 u_  projmatrix;\n "+" void main () \ n "+" {\ n "+" gl_position = u_projmatrix*u_viewmatrix*u_modelmatrix*a_position;\n " + "v_position = a_position;\n" + "V_vnomal = a_vnomal;\n" + "}\n";//Ray Vector L is not linear interpolation, must be in the Fragmentshader, so each fragment to take it corresponding to the vertex in the space position (position can be interpolated). Use a position and light source position to calculate the L.         var Fragment_shader = "#ifdef gl_es\n" + "precision mediump float;\n" + "#endif \ n" + "uniform vec3 u_eyeposition \ n "+" uniform vec3 u_pointlightposition;\n "+" varying vec4 v_position;\n "+" varying vec3 v_vnomal;\n "+" V OID main () \ n "+" {\ n "+" vec4 Pointlightcolor = VEC4 (1.0, 1.0, 1.0, 1.0); \ n "+" vec4 pointlightstrength = V EC4 (1.0, 1.0, 1.0, 1.0); \ n "+" vec4 Envlightcolor = VEC4 (1.0, 1.0, 1.0, 1.0); \ n "+" vec4 envlightstrength = ve C4 (0.3, 0.3, 0.3, 1.0); \ n "+" vec4 Matrilcolor = VEC4 (1.0, 1.0, 1.0, 1.0); \ n "+" float p = 6.0;\n "+" ve C3 L = Normalize (VEC3 (u_pointlightposition.x-v_position.x, U_POINTLIGHTPOSITION.Y-V_POSITION.Y, u_  POINTLIGHTPOSITION.Z-V_POSITION.Z)); \ n "+" vec3 e = Normalize (VEC3 (u_eyeposition.x-v_position.x, U_EYEPOSITION.Y   -V_POSITION.Y, u_eyeposition.z-v_position.z)); \ n "+" vec3 n = v_vnomal;\n "+" n = normalize (n); \ n "+" float NL = dot (n, l); \ n "+" if (nl< 0.0) nl=0.0;\n "+" vec3 h = normalize (e+l); \ n "+" float HN = dot (h, n); \ n "+" Gl_fragcolor = Matrilcolo r*envlightcolor*envlightstrength+matrilcolor*pointlightcolor*pointlightstrength*nl+pointlightcolor* Pointlightstrength*pow (hn,p); \ n "+"}\n "; /*var vertex_shader = "attribute vec4 a_position;\n" + "uniform mat4 u_modelmatrix;\n" + "Uniform mat4 u_viewma trix;\n "+" uniform mat4 u_projmatrix;\n "+" void main () \ n "+" {\ n "+" gl_position = U_projmatrix*u_viewmatri        x*u_modelmatrix*a_position;\n "+"}\n "; var fragment_shader = "#ifdef gl_es\n" + "precision mediump float;\n" + "#endif \ n" + "void main () \ n" + "{\ N "+" Gl_fragcolor = VEC4 (1.0, 0.0, 0.0, 1.0); \ n "+"}\n ";*/    varprogram =Createprogram (GL, Vertex_shader, Fragment_shader); if(!Program ) {        return;    } gl.useprogram (program); Gl.program=Program ; vara_position, U_modelmatrix, U_viewmatrix, U_projmatrix, A_vnomal, U_eyeposition, u_pointlightposition; A_position= Gl.getattriblocation (Gl.program, "a_position"); A_vnomal= Gl.getattriblocation (Gl.program, "A_vnomal"); U_modelmatrix= Gl.getuniformlocation (Gl.program, "U_modelmatrix"); U_viewmatrix= Gl.getuniformlocation (Gl.program, "U_viewmatrix"); U_projmatrix= Gl.getuniformlocation (Gl.program, "U_projmatrix"); U_eyeposition= Gl.getuniformlocation (Gl.program, "u_eyeposition"); U_pointlightposition= Gl.getuniformlocation (Gl.program, "u_pointlightposition"); if(A_position < 0 | | A_vnomal < 0 | |!u_modelmatrix | |!u_viewmatrix | |!u_projmatrix | |!u_eyeposition | |u_pointlightposition) {Alert ("Failed to get store location from Progrom"); return; }               //The following code snippet creates a vertex buffer and binds the vertices to it    varTeapotvpropertiesdata =Gl.createbuffer (); Gl.bindbuffer (GL. Array_buffer, Teapotvpropertiesdata); //alert ("BB" +teapotdata);Gl.bufferdata (GL. Array_buffer, Teapotdata.vertexpositions, GL.    Static_draw); varVfsize =TeaPotData.vertexPositions.BYTES_PER_ELEMENTS; Gl.vertexattribpointer (A_position,3, GL. FLOAT,false, Vfsize * 3, vfsize * 0 );        Gl.enablevertexattribarray (a_position); varTeapotnpropertiesdata =Gl.createbuffer (); Gl.bindbuffer (GL.    Array_buffer, Teapotnpropertiesdata); Gl.bufferdata (GL. Array_buffer, Teapotdata.vertexnormals, GL.    Static_draw); varVnfsize =TeaPotData.vertexNormals.BYTES_PER_ELEMENT; Gl.vertexattribpointer (A_vnomal,3, GL. FLOAT,false, Vnfsize * 3, vnfsize * 0);              Gl.enablevertexattribarray (A_vnomal); //The following code snippet creates a vertex buffer and binds the indices to itTeapotpropertiesindex =Gl.createbuffer (); Gl.bindbuffer (GL.      Element_array_buffer, Teapotpropertiesindex); Gl.bufferdata (GL. Element_array_buffer, Teapotdata.indices, GL.     Static_draw); varIINDEX =teaPotData.indices.length; varIFSIZE = TeaPotData.indices.BYTES_PER_ELEMENT;//new Uint16array (indices)        varEyeposition =NewFloat32array ([0.0, 0.0, 100.0]); varPointlightposition =NewFloat32array ([0.0, 0.0, 50.0]);    GL.UNIFORM3FV (U_eyeposition, eyeposition);        GL.UNIFORM3FV (U_pointlightposition, pointlightposition); varModelmatrix =NewMatrix4 (); varViewmatrix =NewMatrix4 (); varProjmatrix =NewMatrix4 (); Viewmatrix.setlookat (eyeposition[0], eyeposition[1], eyeposition[2], 0.0, 0.0, 0.0, 0, 1, 0); Projmatrix.setperspective (30,VIEWPORT.WIDTH/VIEWPORT.HEIGHT,1,100);//modelmatrix.setrotate (0, 0, 1, 0);modelmatrix.setidentity (); //viewmatrix.setidentity ();    //projmatrix.setidentity ();GL.UNIFORMMATRIX4FV (U_modelmatrix,false, modelmatrix.elements); GL.UNIFORMMATRIX4FV (U_viewmatrix,false, viewmatrix.elements); GL.UNIFORMMATRIX4FV (U_projmatrix,false, projmatrix.elements); Gl.clearcolor (0.0, 0.0, 0.0, 1.0); Gl.clear (GL. Color_buffer_bit||GL.    Depth_buffer_bit); //Gl.drawarrays (GL. Triangles, 0, N);Gl.drawelements (GL. Triangles, IINDEX, GL. Unsigned_short, IFSIZE * 0);} functionCreateprogram (GL, Vshadersource, Fshadersource) {varVshader =Createshader (GL, GL.    Vertex_shader, Vshadersource); varFshader =Createshader (GL, GL.    Fragment_shader, Fshadersource); if(!vshader | |!Fshader) {        return NULL; }    varprogram =Gl.createprogram (); if(!Program ) {        return NULL;    } gl.attachshader (program, Vshader);    Gl.attachshader (program, Fshader);    Gl.linkprogram (program); varlinked =gl.getprogramparameter (program, GL.    Link_status); if(!linked) {Alert ("Failed to link program" +Gl.getprograminfolog (program));        Gl.deleteprogram (program);        Gl.deleteshader (Fragmentshader);        Gl.deleteshader (vertexshader); return NULL; }    returnProgram ; }        functionCreateshader (GL, type, source) {varShader =Gl.createshader (type); if(!shader) {Alert ("Failed to create" + type + "shader"); return NULL;    } gl.shadersource (shader, source);    Gl.compileshader (shader); varCompiled =Gl.getshaderparameter (shader, gl.compile_status); if(!compiled) {Alert ("Failed to compile shader" +Gl.getshaderinfolog (shader));        Gl.deleteshader (shader); return NULL; }        returnShader;} </script> </body>

Teapot using WebGL to draw tea pots (2) Phong shading

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.