Forums Développement Multimédia

Aller au contenu

Un contour apparaît avec context3D !

CODE Actionscript

3 réponses à ce sujet

#1 sealjay

    Ceinture Blanche

  • Members
  • Pip
  • 12 messages

Posté 05 December 2012 - 23:37 PM

Bonjour à tous,

Je ne parviens pas à trouver d'infos sur ce phénomène.

J'affiche un bête quad vertex sur du gpu avec une texture transparente. Le soucis c'est la qualité de rendu :

Image attachée: herbe.png

A gauche un simple bitmap qui affiche le bitmapdata. A droite le rendu du même bitmapData utilisé en texture via context3D.

Voila le code que j'utilise pour faire ce test :


import flash.display.Stage3D;
import flash.display3D.Context3D;
import flash.display3D.Context3DRenderMode;
import flash.display3D.VertexBuffer3D;
import flash.display3D.IndexBuffer3D;
import flash.display3D.Program3D;
import flash.display.BitmapData;
import flash.display3D.textures.Texture;
import flash.display3D.Context3DTextureFormat;
import flash.display3D.Context3DBlendFactor;
import flash.display.Bitmap;

var stage3D:Stage3D = stage.stage3Ds[0]
stage3D.addEventListener(Event.CONTEXT3D_CREATE, onContext);
stage3D.requestContext3D(Context3DRenderMode.AUTO);
function onContext(evt:Event){
var context:Context3D;
context = stage3D.context3D;
context.configureBackBuffer(stage.stageWidth,stage.stageHeight,0,false)
context.enableErrorChecking = true;
context.setCulling('none');
context.setBlendFactors(Context3DBlendFactor.SOURCE_ALPHA, Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA);

// texture
var bd:BitmapData = new BitmapData(256,256,true,0x00000000)
var clip:Herbe = new Herbe();
bd.draw(clip,null,null,'add');
var bm:Bitmap = new Bitmap(bd);
addChild(bm);
bm.scaleY = -1
bm.y = 230
bm.x = 100


var texture:Texture = context.createTexture(bd.width,bd.height,Context3DTextureFormat.BGRA,false);
texture.uploadFromBitmapData(bd);
context.setTextureAt(0,texture);

/// mon sprite
var vertexes:Vector.<Number> = Vector.<Number>([0,0,
                         1,0,
                         1,1,
                         0,1
                         ]);
var indexes:Vector.<uint> = Vector.<uint>([0,1,2,2,3,0]);

var vertexBuffer:VertexBuffer3D = context.createVertexBuffer(vertexes.length/2,2);
vertexBuffer.uploadFromVector(vertexes,0,vertexes.length/2);
context.setVertexBufferAt(0,vertexBuffer,0,"float2"); // pos
var indexBuffer:IndexBuffer3D = context.createIndexBuffer(indexes.length);
indexBuffer.uploadFromVector(indexes,0,indexes.length);


/// shaders
var vsAssembler:AGALMiniAssembler=new AGALMiniAssembler();
vsAssembler.assemble("vertex",([
                 "mov v0, va0",
                 "mov op, va0"
                 ]).join("\n"));
var fsAssembler:AGALMiniAssembler=new AGALMiniAssembler();
fsAssembler.assemble("fragment",([
                 "tex ft0, v0, fs0 <2d,linear>",
                 "mov oc, ft0",
                 ]).join("\n"));
               
var program:Program3D = context.createProgram();
program.upload(vsAssembler.agalcode,fsAssembler.agalcode)
context.setProgram(program);


context.clear(0.1,0.7,0.1)
context.drawTriangles(indexBuffer,0,2);
context.present()
}
 

Le seul moyen que j'ai trouvé c'est d'élever l'alpha dur frag shader au cube pour que ça ne se voit plus. :


fsAssembler.assemble("fragment",([
                 "tex ft0, v0, fs0 <2d,linear>",
                 "mul ft0.w,ft0.w,ft0.w",
                 "mul ft0.w,ft0.w,ft0.w",
                 "mul ft0.w,ft0.w,ft0.w",
                 "mov oc, ft0",
                 ]).join("\n"));
 

Mais biensur on modifie la façon de rendre l'alpha et mine de rien c'est un calcul au niveau pixel que j'aurai bien aimé éviter.

Est-ce que ça parle à quelqu'un ?

Merci à tous.

#2 sealjay

    Ceinture Blanche

  • Members
  • Pip
  • 12 messages

Posté 06 December 2012 - 00:44 AM

J'ai fini par trouver le soucis. C'est une bête histoire d'alpha prémultiplié envoyé par flash dans son bitMapData.

Du coup en faisant un :


context.setBlendFactors(Context3DBlendFactor.ONE, Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA);

Vais faire des test.

#3 tlecoz

  • Honoris
  • PipPipPipPipPipPipPipPip
  • 3486 messages

Posté 06 December 2012 - 01:32 AM

Hello !

http://pixelante.com...tage3d-tutorial

++
:)

#4 Jean-Marc Le Roux

    Ceinture Noire

  • Minko
  • PipPipPipPipPipPipPip
  • 210 messages

Posté 06 December 2012 - 22:09 PM

Stage3D utilise les BitmapData "tels quels" et ne fait pas de prémultiplication alpha. Mais il faut effectivement utiliser le bon mode de blending si on ne veut pas que l'alpha soit simplement écrasé dans le backbuffer :)

Citation

context.setBlendFactors(Context3DBlendFactor.ONE, Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA);

C'est effectivement les coefficients à utiliser pour un blending alpha.
Il y'a aussi le blending additif souvent utilisé, notamment pour les particules :

Citation

BlendingSource.SOURCE_ALPHA | BlendingDestination.ONE

Pour plus d'explication sur les problématiques liées à l'alpha, je pense que le thread suivant du forum minko pourrait t'aider :

http://forums.mediab...a-transparence/

a+



1 utilisateur(s) li(sen)t ce sujet

0 membre(s), 1 invité(s), 0 utilisateur(s) anonyme(s)