Android Programjaim

Android, Flutter/Dart, Kotlin, Java, Unity, HarmonyOS

GLSL, shader transparency, átlátszóság, kivágás stb GLSL alatt

2012. június 06. 10:20 - lacas8282

GL_ONE                                vec4(1.0)
GL_ZERO                               vec4(0.0)
GL_SRC_COLOR                      gl_FragColor
GL_SRC_ALPHA                      vec4(gl_FragColor.a)
GL_DST_COLOR                      pixel_color
GL_DST_ALPHA                      vec4(pixel_color.a)
GL_ONE_MINUS_SRC_COLOR     vec4(1.0) - gl_FragColor
GL_ONE_MINUS_SRC_ALPHA     vec4(1.0 - gl_FragColor.a)
GL_ONE_MINUS_DST_COLOR     vec4(1.0) - pixel_color
GL_ONE_MINUS_DST_ALPHA     vec4(1.0 - pixel_color.a)

gl_FragColor=src
pixel_color  =dst


példa, vegyünk két képet, a háttér kép egy egyszerű kép, az előtér kép háttere fekete, előtérben pedig egy transparent-es kép van. (pl füst) azt akarjuk elérni, hogy a fürsös képből a fekete színeket teljesen kiszedjük, de úgy, hogy a háttér kép szépen látszódjon alatta (tehát nem sima kivágás, inkább maszkolás)
fixed pipeline-ban ez így ment kb:

háttérkép kirajzolása
transparency beállítása (GL10.GL_SRC_ALPHA, GL10.GL_ONE)
előtér kép kirajzolása a raszterbeállításokkal

Ez az eset két esetben volt jó/rossz

amennyiben 1 db plane-re akartunk rajzolni 2 textúrát, akkor ugye nem ment, mivel két plane-es a dolog. valamint GLES1.x-ben nem volt még shader, amivel pofon egyszerűen lehetett volna ezt megírni.

nézzük, hogy menne ez 1 db plane-el, amin van 2 db textúra, ami ugyanezt csinálja

A fregmens shaderbe kell 2 db textúra, amit majd kívűlről megadunk:

        "uniform sampler2D uDiffuseTexture;\n" +
        "uniform sampler2D uNormalTexture;\n" +

és végül a mainbe kell:

        "    vec4 src = texture2D(uDiffuseTexture, vec2(vTextureCoord.x, vTextureCoord.y));\n" +
        "    vec4 dst = texture2D(uNormalTexture, vec2(vTextureCoord.x, vTextureCoord.y )*alpha;\n" +
        "    vec4 res = SRC_FACTOR + DST_FACTOR;\n"+
        "    gl_FragColor = res;\n" +

az SRC_FACTOR: GL_SRC_ALPHA azaz "vec4(src.a)*src"
a DST_FACTOR: GL_DST_COLOR azaz "dst"
 

az alpha lehet az a float típusú alfa, amivel azt akarjuk elérni, hogy a második textúra 20%-ban legyen átlátszó az elsőn. ezis egy uniform.

GLSL transparencyről fontos olvasmány

komment

Opengl-es 2.0 Shaderek, GLSL bemutatás 1. rész

2012. június 06. 10:00 - lacas8282

Egy kis áttekintés a shaderekről (árnyalók) eredeti forrás

Az árnyaló gyakorlatilag c/c++ szintű, magasszintű nyelv, a GLSL-el gyakorlatilag kis programocskákat tudunk írni, ami közvetlen a GPU-ba kerül.

Két shader létezik ugyebár, Vertex, és Fragment shader.

Vertex árnyaló: minden egyes vertexen végrehajtódik, tehát amikor kirajzolsz vmit a glDrawArrays-el, akkor a shader minden egyes ponton végrehajtódik. Ha a vertex shadert használod, akkor gyakorlatilag akármit le tudsz programozni.

mik ezek:

      Vertex transzformáció, Normál transzformáció, Normalizálás és scale, Fény,

Textúra koord generálás és transzformáció (tehát ami régen a fixed pipeline-ban voltak)

Fragment árnyaló: A "fregmens" árnyaló az  összes fregmensen végrehajtódik, amit a raszterizáció állít elő. Nah ez egy szép mondat, gyakorlatilag: lehet vele a kép színeit manipulálni, fényeket előállítani, diffúziót, színezést, ködöt, alphablendet, alphatestet, stb.

adattípusok

vec2, vec3, vec4		2D, 3D and 4D float típusú vektor
ivec2, ivec3, ivec4		2D, 3D and 4D integer típusú vektor
bvec2, bvec3, bvec4		2D, 3D and 4D boolean típusú vektor
mat2, mat3, mat4		2x2, 3x3, 4x4 float típusú mátrixok
sampler1D, sampler2D, sampler3D		1D, 2D and 3D textúrák
samplerCube				Cube Map textúra
sampler1Dshadow, sampler2Dshadow	1D and 2D depth-component texture

Attribútumok, uniformisok, és varying-ok

3 típusú input/output van egy shaderben, ezek
uniforms, attributes és varyings

uniforms ezek csak olvashatóak, pl a fény, a fény színe, ezek nem változnak a renderelés alatt, mindkettő shaderbe megtalálhatóak

attributes  csak a vertex shaderben van, és input étékek, amik minden vertexen végrehajtódnak, pl pozició, normál

varyings adatátadásra szolgál a vertex és a fragment shader között, (vertexből a fregmensbe pontosabban, fordítva nem) a fregmens shaderben csak olvasható, de a vertexben írható is

Beépített típusok
GLSL beépített attributúmok a vertex shader-ben:

gl_Vertex			4D vektor a vertex pozició
gl_Normal			3D vektor a vertex normál
gl_Color			4D vektor a vertex szín
gl_MultiTexCoordX		4D vektor a textúra koord a textura unit X-nél
gl_ModelViewMatrix		4x4 Matrix a model-view matrix.
gl_ModelViewProjectionMatrix	4x4 Matrix a model-view-projection matrix.
gl_NormalMatrix			3x3 Matrix az inverz transponse model-view matrix.
				Ez a matrix a normal transzformációkhoz kell.
gl_Position			4D vektor az utolsó feldolgozott vertex pozicióban.

Fregmens shaderben:
 

gl_FragColor			4D vektor az utolsó feldolgozott szín amit a framebufferbe írunk
gl_FragDepth			float a mélységet írhatjuk vele a framebufferbe

Példák:

uniform sampler2D my_color_texture;
uniform mat4 my_texture_matrix;

varying vec3 vertex_to_light_vector;
varying vec3 vertex_to_eye_vector;
 
attribute vec3 tangent;
attribute vec3 binormal;

float my_float = 1;           //nem működik, mivel az 1 az integer, nincs automatikus cast
float my_new_float = 1.0; //működik, mert float, nem kell "f" a float mögé, mint a javaban

tehát magyarázat:

uniformos részek: egy olyan változó amit később tudunk a külső GLES2.0 proginkból állítgatni. sampler2D megmondja, hogy textúráról van szó. mat4, egy matrix4 nyilván, uniform tehát kívűlről állítgathatjuk.

varyingos részek: ezek Vec3-ak, tehát float típsú vektor3-ak, ezek azért varyingok, hogy elérhessük őket később a fragment shaderből is. ekkor ugyanott ugyanígy deklarálnunk kell.

floatok: hiba ha integert adunk meg nekik, nincs automatikus típuskonverzió.

Beépített funkciók:
 

dot		dot product
cross		cross product
texture2D	egy textúra
normalize	normalizál egy vektort
clamp		clamping a vector to a minimum and a maximum

folyt köv.
 

komment
süti beállítások módosítása