#0 

02-02-2011 14:21:41

Metallizer
Abonné
Lieu: Région Parisienne
Date d'inscription: 07-01-2007
Messages: 100
Site web

Edit: Problème résolu, voir le message #7 pour la solution
--------------------------------------

Salut à tous.

Je cherche à modifier l'opacité de triangles que je dessine manuellement dans le video driver.

Code c++ :


texture = videoDriver->getTexture("maTexture.png");
material.setTexture(0, texture);
material.Lighting = false;
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
material.DiffuseColor = video::SColor(100,255,255,255);

vertices[0] = video::S3DVertex(-100, 100, 0.1, 1, 1, 0, video::SColor(100,255,255,255), 0, 0);
vertices[1] = video::S3DVertex(100, 100, 0.1, 1, 0, 0, video::SColor(100,255,255,255), 1, 0);
vertices[2] = video::S3DVertex(-100, -100, 0.1, 0, 1, 1, video::SColor(100,255,255,255), 0, 1);
vertices[3] = video::S3DVertex(100, -100, 0.1, 0, 0, 1, video::SColor(100,255,255,255), 1, 1);

core::matrix4 mat;
u16 indices[] = {0,2,3, 2,1,3, 1,0,3, 2,0,1};
videoDriver->setMaterial(material);
videoDriver->setTransform(video::ETS_VIEW, mat);
videoDriver->drawIndexedTriangleList(vertices, 4, indices, 4);
videoDriver->setTransform(video::ETS_WORLD, mat);



Je pensais qu'il suffisait de modifier les paramètres de mon materiau et notamment DiffuseColor mais visiblement ça ne prend pas en compte la composante alpha.
J'ai aussi essayé de modifier la couleur de chaque vertex mais là aussi l'alpha est ignoré.

Quelqu'un aurait une idée ?

Dernière modification par Metallizer (27-04-2012 17:50:56)

Hors ligne


#1 

02-02-2011 17:58:40

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 910
Corrections: 2
Site web

tu peut passer par un shader:

Code c++ :


uniform sampler2D T0;
uniform float density;
void main (void)
{
    vec4 texel0  = texture2D(T0, gl_TexCoord[0].st);
    gl_FragColor = density*texel0*gl_Color;
}


ou T0 est une texture et densiter est la trasparence...

sinon je ne c'est pas je ne me suis jamais pencher sur la question, en tout cas j'est étudier les api graphique et ce n'est pas disponible en realtime sans séparer les objects au rendue
si j'ai bien comprit se que tu cherchais, sinon tu peut jouer avec l'alpha de la texture enfin .... hmm

Dernière modification par Magun (02-02-2011 18:02:19)

Hors ligne


#2 

02-02-2011 22:26:51

Metallizer
Abonné
Lieu: Région Parisienne
Date d'inscription: 07-01-2007
Messages: 100
Site web

Ah oué carrément un shader... j'aurais aimé m'en passer pour un truc aussi bête. Et en plus, j'ai un petit soucis, j'ai déjà affecté un type de matériau à mon objet :

Code c++ :

material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;



Si je change pour un shader, je vais perdre la couche alpha de ma texture... hmm

Bref cette histoire n'est pas simple. J'ai vu sur des forums que certains intervenaient directement sur la texture mais c'est assez bof parce que ça signifie que si on veut appliquer une opacité différente à chaque node mais que ces nodes ont la même texture, ils sont tous concernés par l'opacité...

Je continue mes recherches de mon côté, n'hésitez pas si vous avez d'autres idées ^^

Hors ligne


#3 

03-02-2011 12:40:00

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 910
Corrections: 2
Site web

non tu ne perd pas la couche alpha

Code c++ :

newMaterialType2 = gpu->addShaderMaterialFromFiles(vsFileName, psFileName, mc, video::EMT_TRANSPARENT_ALPHA_CHANNEL);

Hors ligne


#4 

03-02-2011 13:42:55

Metallizer
Abonné
Lieu: Région Parisienne
Date d'inscription: 07-01-2007
Messages: 100
Site web

Ah oui d'accord, c'est vrai que j'avais oublié qu'on passait un MaterialType qui sert de base.

Je vais voir pour le shader mais sinon, j'avais une autre piste, à toi de me dire si c'est faisable : combiner deux MaterialType. Comme tu l'as vu, j'applique un video::EMT_TRANSPARENT_ALPHA_CHANNEL pour que ma texture conserve sa transparence. Est-ce qu'il est possible de combiner avec un video::EMT_TRANSPARENT_VERTEX_ALPHA ? J'ai pu rendre mon node semi transparent en modifiant la composante Alpha de chaque vertex.

Apparemment il est possible de créer des MaterialType personnalisés (IMaterialRenderer) mais jusqu'à présent, je ne suis tombé que sur des solutions qui mettent en pratique du DirectX. J'aimerais que mon jeu reste compatible OpenGL...

Dernière modification par Metallizer (03-02-2011 13:44:19)

Hors ligne


#5 

04-02-2011 00:17:11

Metallizer
Abonné
Lieu: Région Parisienne
Date d'inscription: 07-01-2007
Messages: 100
Site web

Edit: Ce méthode n'a pas été retenue, voir le message #7 pour la solution
--------------------------------------

Bon finalement j'ai opté pour le shader et ça marche nickel, merci pour ton aide wink

J'ai défini une structure qui permet de lister les shaders disponibles qu'on peut appliquer à des nodes :

Code c++ :

struct Shaders {
  s32 opacity;
};



Les membres de cette structure sont définis en début de programme :

Code c++ :

void initShaders() {
  shaders.opacity = 0;
  if(gpu) {
    OpacityShaderCallback* cb = new OpacityShaderCallback();
    shaders.opacity = gpu->addHighLevelShaderMaterialFromFiles(
      "maTexture.png", "shader/opacity.vert", video::EVST_VS_1_1,
      "vertexMain", "shader/opacity.frag", video::EPST_PS_1_1,
      cb, video::EMT_TRANSPARENT_ALPHA_CHANNEL
    );
    cb->drop();
  }
}



J'ai également défini un Callback pour ce shader :

Code c++ :

class OpacityShaderCallback : public video::IShaderConstantSetCallBack {
  public:
    const video::SMaterial* usedMaterial;
    virtual void OnSetMaterial(const video::SMaterial& material) {
      usedMaterial = &material;
    }
    virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData) {
      // On récupère les informations de la couleur diffuse qui seront passés au shader
      f32 vColor[4] = {
        usedMaterial->DiffuseColor.getRed() / 255.0f,
        usedMaterial->DiffuseColor.getGreen() / 255.0f,
        usedMaterial->DiffuseColor.getBlue() / 255.0f,
        usedMaterial->DiffuseColor.getAlpha() / 255.0f
      };
      services->setVertexShaderConstant("maTexture.png", vColor, 4);
    }
};



J'applique le shader au node :

Code c++ :

texture = videoDriver()->getTexture("maTexture.png");
material.setTexture(0, texture);
material.Lighting = false;
// Stockage de l'opacité dans la matériau
material.DiffuseColor.setAlpha(100);
material.MaterialType = (video::E_MATERIAL_TYPE)shaders.opacity;



Le vertex shader :

Code:

// Récupération de la couleur diffuse du matériau du node
uniform vec4 vColor;

void main(void) {
  gl_FrontColor = vColor;
  gl_Position = ftransform();
  gl_TexCoord[0] = gl_MultiTexCoord0;
}

Le pixel shader :

Code:

uniform sampler2D T0;

void main(void) {
  vec4 col = texture2D(T0, gl_TexCoord[0].st);
  gl_FragColor = col * gl_Color;
}

Dernière modification par Metallizer (27-04-2012 17:50:20)

Hors ligne


#6 

04-02-2011 19:54:00

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 910
Corrections: 2
Site web

super alors, désoler si je n'est pue te répondre ... coupure d'internet .... hmm
bref, je te propose de faire un topic dans Routine sur le forum, histoire que les nouveaux sans inspire wink

Hors ligne


#7 

27-04-2012 17:46:36

Metallizer
Abonné
Lieu: Région Parisienne
Date d'inscription: 07-01-2007
Messages: 100
Site web

Je reviens sur ce topic 1 an après car j'ai trouvé une solution au problème initial et qui n'utilise aucun shader ! big_smile

Donc le truc c'est de pouvoir agir sur l'opacité d'un node qui utilise une texture avec canal alpha.
La solution m'a été donnée par un des admins qui s'occupent du moteur :

Le matériau à utiliser est EMT_ONETEXTURE_BLEND

Code c++ :

// Type de matériau pour faire des "mélanges
Material.MaterialType = video::EMT_ONETEXTURE_BLEND;

// On utilise cette fonction pour combiner l'alpha de la texture avec l'alpha des vertices
Material.MaterialTypeParam = video::pack_texureBlendFunc(
  video::EBF_SRC_ALPHA,
  video::EBF_ONE_MINUS_SRC_ALPHA,
  video::EMFN_MODULATE_1X,
  video::EAS_TEXTURE | video::EAS_VERTEX_COLOR
);
     
// On modifie l'alpha de chaque vertex
Vertices[0].Color.setAlpha(Opacity);
Vertices[1].Color.setAlpha(Opacity);
Vertices[2].Color.setAlpha(Opacity);
Vertices[3].Color.setAlpha(Opacity);

Dernière modification par Metallizer (27-04-2012 17:47:56)

Hors ligne


#8 

28-04-2012 12:04:56

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 910
Corrections: 2
Site web

intéressant merci pour l'info wink

Hors ligne


Options Liens officiels Caractéristiques Statistiques Communauté
Corrections
irrlicht
irrklang
irredit
irrxml
xhtml 1.0
css 2.1
Propulsé par FluxBB
Traduit par FluxBB.fr
883 membres
1429 sujets
11121 messages
Dernier membre inscrit: Saidov17
67 invités en ligne
Aucun membre connecté
RSS Feed