[Geiv] Chapter 7: High-Performance GPU Rendering solution for the shader

Source: Internet
Author: User

Chapter 7: shader

Efficient GPU Rendering solution

This chapter describes the basic knowledge of the coloring tool and the supported interfaces provided by geiv. The example is illustrated with the "gradient Gaussian blur" as the clue.

[Background information] [limitations of the computer's central processor]

In the "digital image processing" course of the University, the teacher explained the basic algorithm of Gaussian blur. C # is used for basic implementation. Gaussian blur. Simply put, the Gaussian weight template is used to re-calculate and fill each pixel of the image to achieve the blur effect.

In the course. Blur an image of X based on the given template and blur coefficient. 0.48 million pixels need to be calculated, although the core series CPU has been popularized in the machine room. However, this process still takes 2 ~ 3 seconds.

So there is such a problem: in the game, we often see that the screen is blurred to a clear dynamic change. Even the next generation of GBA, SFC, and other game hosts still have this effect. In terms of hardware performance, our PC should be much higher than those of these next-generation game consoles, and the 2-or 3-second computation results have clearly told me that we want to perform more efficient fuzzy computation, it is impossible to achieve the expected efficiency by calculating the pixel point from the ground to the ground. If you want to finish 60 images with different blur degrees in one second, you need to find another path.

Why can't game consoles with low computing performance achieve smooth computation with high-performance CPUs? I think it is because of the difference in CPU structure that there are many types of PC tasks. The process is complex. A complex instruction set system is required. However, the CPU of the game machine is mainly produced by images. You only need to use a few simplified instruction systems for images.

All in all, to ensure the versatility of the CPU in complex tasks, the computer's CPU is not good at graphic operations. In addition, in some cases, the graphic operation efficiency is quite low.


[Graphics processor GPU]

To make up for the defects in CPU processing graphics, the GPU was born. GPU is a processor generated for graphic operations. Currently, mainstream Gaming PCs have a high-performance GPU. I will not mention the detailed concepts here. I believe that anyone who is engaged in computer science will know about them first or second.


[Use GPU computing resources in programming]

In most development scenarios, whether it is C or Java. The code we typed is undoubtedly executed on the CPU. So how can we display and call GPU resources? In OpenGL, in addition to the frequently used fixed-pipeline programming, it also provides more flexible functions. It agrees that developers use the coloring language (glsl, a type of C language) to write a program named "shader", compile and execute it on the GPU, and take over some of the GPU's built-in functions.


[OpenGL shader overview]

The author's resume is limited. Here I will only introduce it. The specific concept can be used to take an examination of the book "OpenGL coloring language". It has a very detailed introduction to the colorator and glsl.

An OpenGL shader (hereinafter referred to as a shader) is composed of a vertex shader and a fragment shader. Most of the work they are responsible for is different, with only a small portion of the intersection.

OpenGL provides a complete API for the verification, compilation, connection, and setting of the number of samples for the coloring tool. You only need to support the video card. In the OpenGL context, you can obtain the coloring tool program from the source file, no other environment is required.

The purpose of writing a shadow. It is used to realize fixed pipelines such as fuzzy, atomizing, and luminous, and enrich the image performance. Many game engines package the coloring machine-related APIs in OpenGL to the upper layer. I also used this solution during design.


[Built-in shader]

In geiv, five system splitters are built in, which are retained at the beginning of the design. This is not because it is "frequently used" (I feel that the coloring tool is usually very targeted and generally very difficult to use frequently ).

In turn:

Sd_anticolor: change the target color to reverse color.

Sd_emboss_mode9: embossed effect. The following mode9 indicates that it uses a 3x3 template to meet General requirements. To improve accuracy, it can expand the template to 4x4 \ 5x5.

Sd_gaussian_mode9: Gaussian blur

Sd_laplacian_mode9: Sharpen

Sd_mean_mode9: Mean


[Set a color filter for the element]

In geiv. The object that uses the shaderprogram is an element, and the setshaderprogram method is used to pin the colorant to the corresponding element. For example:

Obj t = ues. creatobj (uesi. bgindex); T. addglimage (0, 0 ,". /mdls.jpg "); T. setshaderprogram (sysshader. sd_gaussian_mode9); // bind the system shader to the metadata T.


[Set the number of uniform partitions]

The uniform modifier (not a data type) indicates that variables in a glsl are passed in externally. In addition, it will not change (different from attribute) during the entire coloring machine operation. For example, for Fuzzy changes, the variable "Blur" is of the uniform type.

In glsl. An array has many forms. Float [] can represent a one-dimensional linear floating point group. Vect2 represents a point, while vec2 [] represents a one-dimensional linear floating point "number pair" group, similar to vect3 \ 4, there is no ready-made structure data in Java. That is to say, when setting the number of uniform partitions, we must specify our data source (one-dimensional linear array) and the way to map the variables to glsl.

In the geiv primitive class. The setshaderuniform (string uniformname, object value, inttpflag) method can be used to set the number of coloring ers bound to this element. The number of coloring ERs in this method is:

The uniformname is the name of the variable in the shadow.

Value is a data source. Currently, only float [], float [], or a single float type are supported.

Tpflag is the specified ing method. You can directly reference the static value of shadercontroller.

It can be one of the following values:

Afloat and floats correspond to a single float value and a one-dimensional float array respectively.

Vertxs indicates an array composed of X points. Each element of the array includes an X-dimensional vector. The given data source must be a one-dimensional linear array of X integers, which will be filled with these X-Dimensional Vectors in sequence. For example, when tp_vert2s is used, the first two elements of the one-dimensional array of the data source constitute the first vector element of the colorant Vector Array.

Vertex represents an X-dimensional vector. The size of the array of the given one-dimensional data source must be X.


[Customize the user shadow]

In addition to the ready-made pasters in sysshader, you can also use your own paintors.

In the engine handle uesi, wrap and simplify OpenGL to generate the coloring machine API:

Uesi. createshaderprogram (string spname, string vppath, string fppath );

Number of shards:

Spname is the name of the shadow.

Vppath is the source file path of the vertex coloring tool, such as "./vp.txt ".

Fppath is the source file path of the fragment shader.

Then, we only need to bind the spname to the element by using the API that sets the coloring device. Same as the font library we introduced earlier. Spname also has a global effect and can be bound to elements in other contexts.


[Instance-gradient Gaussian Blur]

You can find the sample and resources under [GitHub] sample \ sample-shader.

Main. Java

package com.geiv.test;import geivcore.R;import geivcore.UESI;public class Main{public static void main(String[] args) {UESI UES = new R();new Guassion(UES);}}
Guassion. Java

Package COM. geiv. test; import geivcore. serialtask; import geivcore. uesi; import geivcore. enginesys. shadercontroller. shadercontroller; import geivcore. enginesys. shadercontroller. sysshader; import geivcore. enginedata. canonical. canexpos; import geivcore. enginedata. OBJ. OBJ; import Java. AWT. event. keyevent; import Java. util. arrays; public class guassion implements serialtask {uesi ues; float [] g_aryverticaloffset; f Loat [] vertstatic; float bur = 600f; // The bur is used as the Blur factor, and the static offset (vertstatic) is divided by the Blur factor to obtain the number (g_aryverticaloffset) of different offsets ). Because the glsl context uses the OpenGL coordinate format, which is different from geiv, the initial factor is calculated and converted to 600 fobj t; Public guassion (uesi UES) {This. ues = ues; t = ues. creatobj (uesi. bgindex); T. addglimage (0, 0 ,". /mdls.jpg "); T. setshaderprogram (sysshader. sd_gaussian_mode9); // you can specify the color filter T. setshaderuniform (sysshader. na_weightargs, sysshader. br_gaussian_mode9, shadercontroller. tp_floats); // set the number of unfiorm metrics. The Normalized Weight template and its name in the glsl context are given. They can be directly referenced by sysshader. Vertstatic = new float [] {-1,-1, 0,-1, 1,-1-1, 0, 0, 0, 1, 0-1, 1, 0, 1, 1, 1}; // offset template. If you cannot understand it, you can refer to the following figure g_aryverticaloffset = arrays. copyof (vertstatic, vertstatic. length); For (INT I = 0; I <g_aryverticaloffset.length; I ++) {g_aryverticaloffset [I] = vertstatic [I]/BUR;} t. setshaderuniform (sysshader. na_offsetargs, g_aryverticaloffset, shadercontroller. tp_vert2s); // sets the uniform offset T. setposition (canexpos. pos_center); T. show (); ues. addserialtask (this) ;}@ overridepublic void serial (INT clock) {// mount a scanned keyboard Input. When the z key is pressed, the bur is added. Reset the offset and reset the uniform.

When the X key is pressed, the opposite is true. If (UES. getkeystatus (keyevent. vk_z) {T. setshaderuniform (sysshader. na_offsetargs, g_aryverticaloffset, shadercontroller. tp_vert2s); bur + = 4f; For (INT I = 0; I <g_aryverticaloffset.length; I ++) {g_aryverticaloffset [I] = vertstatic [I]/BUR ;}} else if (UES. getkeystatus (keyevent. vk_x) {T. setshaderuniform (sysshader. na_offsetargs, g_aryverticaloffset, shadercontroller. tp_vert2s); bur-= 4f; For (INT I = 0; I <g_aryverticaloffset.length; I ++) {g_aryverticaloffset [I] = vertstatic [I]/BUR ;}}}}

The ↓ ing of the Offset template is actually like this:

In addition, there are two source codes of Gaussian fuzzy coloring machine.

Vertex shader:

attribute float sys_pIndex;void main(void){gl_TexCoord[0] = gl_MultiTexCoord0;gl_Position = ftransform();}

The Vertex coloring er does not write any substantive functions. It is shared by many segment coloring ers.

Gaussian-fragment shader:
Const int Limit = 9; // weight template size uniform sampler2d g_filtertexture; // Our texture uniform float g_aryweight [weight]; // weight Array Uniform vec2 g_aryoffset [g_iweightnumber]; // offset-even if nine grids are used, there is no rule that they must be adjacent grids. The offset describes the actual pixel distance between weight template cells. The higher the value, the higher the fuzzy degree.

Void main (void) {vec4 vec4sum = vec4 (0.0); For (INT I = 0; I <g_iweightnumber; ++ I) {vec4sum + = texture2d (g_filtertexture, gl_texcoord [0]. st + g_aryoffset [I]) * g_aryweight [I]; // here is the actual computing process. That is to say, to replace the portion where we used to allow the CPU to calculate pixels one by one.

Gl_texcoord [0] is the bound texture No. 0 (images in OpenGL can be bound to multiple textures ). The St is the location, a vec2 type; the location and offset are added to get the offset location. Then, obtain the corresponding rgba four-dimensional Vector Based on the texture and offset, which is a vec4 type. Furthermore, multiply our vec4 by the Normalized Weight. And add it to vec4sum. Because it is the Normalized Weight, rgba will not cross the border.

} Gl_fragcolor = vec4sum; // finally, we enter the calculated rgba result into the texture.

}


Finally, run the result (when you press the X key ):


↑ Can observe the dynamic process from clear to fuzzy.

[Summary]

This chapter describes the usage of the coloring tool and the corresponding APIs in geiv.

The coloring tool is used to achieve the effect that is hard to describe on fixed pipelines.

The coloring er is executed on the GPU, and the rendering efficiency of the image is much higher than that of the direct CPU operation.



Copyright Disclaimer: original blog article in this article. Blog posts cannot be reproduced without consent.

[Geiv] Chapter 7: High-Performance GPU Rendering solution for the shader

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.