Войти
ПрограммированиеФорумГрафика

Instant Animated Grass

#0
1:49, 28 авг. 2009

Пробую сделать травку по документу
http://www.cg.tuwien.ac.at/research/publications/2007/Habel_2007_IAG/

Вообщем более менее шейдер получилось адаптировать под движок. Вроде получается, что-то похожее, но есть баги, и ХЗ как с ними боротся.

Если при старте примера посмотреть сразу вниз, то видно что, там результат похожый как на скринах в пейпере, но вот травка сразу начинает расползатся. Так же более менее похожий результат виден на цилиндре.

Вот самое лучшее что удалось добится:
Изображение

тут сама демка и шейдер в комплекте. Могу код шейдера прям в форум выложить.
http://mycop.xors3d.com/Grass.rar

З.Ы. Судя по всему метод хорош и даёт нормальный ФПС, да и местами можно соптимизировать ещё.
Признателен за любую помощь.


#1
3:10, 28 авг. 2009

Глюки просто ужасные!
На траву вообще не похоже.... кокойто травянистый Энвиромент маппинг %Р
Такое ощущение что эту самую травку курнул....

Отпусти меня о чудо трава | Instant Animated Grass
#2
12:08, 28 авг. 2009

Да, но если посмотреть прямо вниз, то пробивается кусок похожий на правду...
Кстати управление: мышка + В\А\С\Д

Вот повыбрасывал с шейдера всё лишнее:

// Vertex shader
void VSMain(in VSInput IN, out VSOutput OUT)
{
  OUT.oPosition = mul(IN.position, worldViewProj); //oPosition must be output to satisy pipeline.
  OUT.positionViewProj = OUT.oPosition;

  OUT.texCoord = IN.texCoord;
  OUT.texCoord2 = float2((IN.texCoord2.x+time*0.2)/2,(IN.texCoord2.y+time*0.2)/2); // offset second texture coordinate
                    

  OUT.vertColor = IN.vertColor;
  
  float3 eyeDirO = -(eyePositionO - IN.position) ; //eye vector in object space
  
  float3x3 TBNMatrix = float3x3(IN.tangent, IN.binormal, IN.normal); 

  OUT.eyeDirTan = normalize(mul(eyeDirO, TBNMatrix)); // eye vector in tangent space
}


void PSMain(in VSOutput IN,
  out float4 color  : COLOR,
  out float depth  : DEPTH )
{

  //Initialize increments/decrements and per fragment constants
  color = float4(0.0,0.0,0.0,0.0);
  depth = 0;

   float2 plane_offset = float2(0.0,0.0);          
   float3 rayEntry = float3(IN.texCoord.xy,0.0);
  float zOffset = 0.0;
  bool zFlag = 1;


   //The signs of eyeDirTan determines if we increment or decrement along the tangent space axis
  //plane_correct, planemod and pre_dir_correct are used to avoid unneccessary if-conditions. 
  
   float2 sign = float2(sign(IN.eyeDirTan.x),sign(IN.eyeDirTan.y));  
   float2 plane_correct = float2((sign.x+1)*GRASS_SLICE_NUM_INV_DIV2,
                                 (sign.y+1)*GRASS_SLICE_NUM_INV_DIV2);
   float2 planemod = float2(floor(rayEntry.x*PLANE_NUM)/PLANE_NUM,
                            floor(rayEntry.y*PLANE_NUM)/PLANE_NUM);
  float2 pre_dir_correct = float2((sign.x+1)*PLANE_NUM_INV_DIV2,
                                  (sign.y+1)*PLANE_NUM_INV_DIV2);


  int hitcount;
   [unroll]for(hitcount =0; hitcount < MAX_RAYDEPTH % (MAX_RAYDEPTH+1); hitcount++) // %([MAX_RAYDEPTH]+1) speeds up compilation.
   {

    //Calculate positions of the intersections with the next grid planes on the u,v tangent space axis independently.

     float2 dir_correct = float2(sign.x*plane_offset.x+pre_dir_correct.x,
                                 sign.y*plane_offset.y+pre_dir_correct.y);      
    float2 distance = float2((planemod.x + dir_correct.x - rayEntry.x)/(IN.eyeDirTan.x),
                             (planemod.y + dir_correct.y - rayEntry.y)/(IN.eyeDirTan.y));
           
     float3 rayHitpointX = rayEntry + IN.eyeDirTan *distance.x;   
      float3 rayHitpointY = rayEntry + IN.eyeDirTan *distance.y;
    
    //Check if we hit the ground. If so, calculate the intersection and look up the ground texture and blend colors.

      if ((rayHitpointX.z <= -GRASSDEPTH)&& (rayHitpointY.z <= -GRASSDEPTH))   
      {
        float distanceZ = (-GRASSDEPTH)/IN.eyeDirTan.z; // rayEntry.z is 0.0 anyway 

        float3 rayHitpointZ = rayEntry + IN.eyeDirTan *distanceZ;
      float2 orthoLookupZ = float2(rayHitpointZ.x,rayHitpointZ.y);
            
        color = (color)+((1.0-color.w) * tex2D(ground,orthoLookupZ));
        if(zFlag ==1) zOffset = distanceZ; // write the distance from rayEntry to intersection
        zFlag = 0; //Early exit here if faster.    
      }  
      else
     {
       
       float2 orthoLookup; //Will contain texture lookup coordinates for grassblades texture.

       //check if we hit a u or v plane, calculate lookup accordingly with wind shear displacement.
      if(distance.x <= distance.y)
       {
        
        float lookupX = -(rayHitpointX.z+(planemod.x+sign.x*plane_offset.x)*PREMULT)-plane_correct.x;
        orthoLookup=float2(rayHitpointX.y+(GRASSDEPTH+rayHitpointX.z),lookupX); 
        
        plane_offset.x += PLANE_NUM_INV; // increment/decrement to next grid plane on u axis
        if(zFlag==1) zOffset = distance.x;
      }
      else {
       
        float lookupY = -(rayHitpointY.z+(planemod.y+sign.y*plane_offset.y)*PREMULT)-plane_correct.y;
        orthoLookup = float2(rayHitpointY.x+(GRASSDEPTH+rayHitpointY.z) ,lookupY);
       
        plane_offset.y += PLANE_NUM_INV;  // increment/decrement to next grid plane on v axis
        if(zFlag==1) zOffset = distance.y;
          
        }
         
        color += (1.0-color.w)*tex2D(grassblades,orthoLookup);
   
        if(color.w >= 0.49){zFlag = 0;}  //Early exit here if faster.
      }
  }  

     color += (1.0-color.w)*AVERAGE_COLOR; //Fill remaining transparency in case there is some left. Can be replaced by a texture lookup

}
#3
15:05, 29 авг. 2009

Хотя бы идеи почему так может быть... И как можно поправить.

Прошло более 3 лет
#4
14:24, 27 ноя. 2012

Прошу прощения за некропост.
Попробовал такую же травку, получил такой же результат.
Уважаемый Render, ошибка нашлась?
Или может кто подскажет еще.
Благодарю.

ПрограммированиеФорумГрафика

Тема в архиве.