Jump to content

  • Log In with Google      Sign In   
  • Create Account

Alundra

Member Since 19 Jul 2011
Offline Last Active Today, 06:43 PM

#5198680 Outline effect on selected objet

Posted by Alundra on 16 December 2014 - 08:17 PM

Hi all,

I want to achieve a correct outline shader because post-process edge detection shows all edge, not only the outline.

The effect needed to be is like this image : http://i.stack.imgur.com/ubl0J.jpg

I only see to render second time the object with scaling on it using the camera up and camera right vector using one color.

A better way exists to achieve this effect correctly ?

Thanks for the help




#5198427 Cannot understand behaviour of BoundingFrustum created from projection matrix...

Posted by Alundra on 15 December 2014 - 04:15 PM

I want to rotate by 90 degrees the image that is rendered in viewport. No problem if it gets distorted due to different aspect ratio. I've already handled that.

Why not just rotate the view by 90 degrees :

World * View * DirectX::XMMatrixRotationZ(-DirectX::XM_PI / 2.0f) * Projection;




#5193705 Having two arrays in the scene ?

Posted by Alundra on 19 November 2014 - 07:52 PM

Interesting what you said, but I spoke only of a basic scene with array of actor, my data are in component like all modern design but I don't do threading system actually.

I though the problem was clear, that's only question of the parent-child update and saving, since I use an array of actor not ordered, the rendering has 0 problem but update and save give problems.

The solution for the save load I found is to store an hierarchy based on index of the array to then on the load AddChild but using the array of root actor that can be avoided to store all root+children recursively, for the update of the scene update root+children recursively too.

The question is : Is it the good way to remove the problem ?




#5193688 Having two arrays in the scene ?

Posted by Alundra on 19 November 2014 - 04:36 PM

Hi,

I have a flat array for my scene which is not ordered parent-child so a parent can be after a child.

For the rendering never problem this array is used to render each component needed.

For the update if you update recursively you can have child updated twice if a parent is after a child.

The solution of this problem I found is to have one flat array not ordered and one array with all root.

One problem of this is if you have only root item in the array without children, you have 2 same array.

The render scene code uses the flat array and the update and save of the scene use the root array.

Is it a good solution or a better one exists and needs to be used ?

Thanks for the help




#5184405 Implementing SAO

Posted by Alundra on 01 October 2014 - 02:21 PM

Is this algo better than HBAO ?

HBAO = 2008, this algo = 2012.




#5181636 Deferred omni/point light issues

Posted by Alundra on 19 September 2014 - 03:57 PM

You can compute the view ray using this vertex shader and use this pixel shader when rendering the sphere geometry (use an icosahedron for better perf) :

void main()
{
  gl_Position = WorldViewProjection * InVertex;
  vec2 NDCPosition = gl_Position.xy / gl_Position.w;
  OutTexCoord0 = 0.5 * NDCPosition + 0.5;
  OutViewRay = vec3( NDCPosition.x * TanHalfFov * Aspect,
                     NDCPosition.y * TanHalfFov,
                     1.0 );
}

Here the pixel shader :

void main()
{ 
  vec3 Position = OutViewRay * texture( DepthMap, OutTexCoord0 ).r;
  vec3 LightVec = normalize( LightPosition - Position );
  float NdotL = dot( Normal, LightVec );
  if( NdotL > 0.0 )
  {
    ...
  }
}

But it's better to not do that because if the sphere (or icosahedron) is culled on a part, you will not have lighting on the culled part.

This culling problem is when a sphere is culled by the far plane.




#5181611 Deferred omni/point light issues

Posted by Alundra on 19 September 2014 - 02:25 PM

Hey TheChubu !

You have inversed the light direction in the vertex shader :

passLightDir = (mv * inPosition) - pLight.viewCenter;

You are doing : LightDir = SurfacePos - LightPos.

The good calcule is : LightDir = LightPos - SurfacePos.

passLightDir = pLight.viewCenter - (mv * inPosition);

Since your inPosition is vec3 you should do :

passLightDir = pLight.viewCenter - (mv * vec4(inPosition,1.0));

The reason is without the w component on the vector to 1.0, it will just rotate the position but not translate it.

You should compute the LightDir in the pixel shader to avoid problems (just return the view space position in the vertex shader and use it in the pixel shader).

Why not compute the LightDir in the vertex shader ? Because if your geometry is culled you will not have lighting on a large part.

Don't forget to add : if( NdotL > 0.0 ) before add the specular to avoid artifacts.




#5180543 PBR (blurry reflections)

Posted by Alundra on 15 September 2014 - 03:45 PM

Here the metallic part :

SURFACE_DATA SurfaceData;
float4 DiffuseData = DiffuseMap.Sample( LinearSampler, Input.TexCoord );
float4 FinalBaseColor = BaseColor * DiffuseData;
SurfaceData.DiffuseColor = FinalBaseColor.rgb - (FinalBaseColor.rgb * Metallic);
SurfaceData.SpecularColor = lerp( 0.08f * Specular, FinalBaseColor.rgb, Metallic );

Here the compute spec factor function used in lighting :

float3 ComputeSpecFactor( in SURFACE_DATA SurfaceData, in float3 LightDirection, in float NdotL )
{
  // Variables used to compute the lighting factor.
  float3 ViewDirection = normalize( -SurfaceData.Position );
  float3 HalfDirection = normalize( LightDirection + ViewDirection );
  
  // Compute the lighting factors.
  float NdotH = max( 0.0f, dot( SurfaceData.Normal, HalfDirection ) );
  float NdotV = max( 0.0f, dot( SurfaceData.Normal, ViewDirection ) );
  float VdotH = max( 0.0f, dot( ViewDirection, HalfDirection ) );
  
  // Generalized microfacet specular.
  float D = D_GGX( Roughness, NdotH );
  float G = G_Schlick( Roughness, NdotV, NdotL );
  float3 F = F_Schlick( SurfaceData.SpecularColor, VdotH );
  
  // Return the specular factor.
  return D * G * F;
}

About the reflection, did you tried the importance sampling like in the paper of Brian Karis ?

One thing is when using metallic to 1.0f you have black diffuse color and only specular is visible.

Here the filter of envmap from unreal paper :

float3 PrefilterEnvMap( float Roughness, float3 R )
{
  float3 N = R;
  float3 V = R;
  float3 PrefilteredColor = 0;
  const uint NumSamples = 1024;
  for( uint i = 0; i < NumSamples; i++ )
  {
    float2 Xi = Hammersley( i, NumSamples );
    float3 H = ImportanceSampleGGX( Xi, Roughness, N );
    float3 L = 2 * dot( V, H ) * H - V;
    float NoL = saturate( dot( N, L ) );
    if( NoL > 0 )
    {
      PrefilteredColor += EnvMap.SampleLevel( EnvMapSampler , L, 0 ).rgb * NoL;
      TotalWeight += NoL;
    }
  }
  return PrefilteredColor / TotalWeight;
}

Here how to combine all that to have the specular value (from unreal paper) :

float3 ApproximateSpecularIBL( float3 SpecularColor , float Roughness, float3 N, float3 V )
{
  float NoV = saturate( dot( N, V ) );
  float3 R = 2 * dot( V, N ) * N - V;
  float3 PrefilteredColor = PrefilterEnvMap( Roughness, R );
  float2 EnvBRDF = IntegrateBRDF( Roughness, NoV );
  return PrefilteredColor * ( SpecularColor * EnvBRDF.x + EnvBRDF.y );
}



#5165530 State Machine

Posted by Alundra on 08 July 2014 - 06:18 AM


As example, I use a mix of behavior trees and FSM, my fsm are integrated in my BTs and look something like this:
int state = getState();
if(state==INIT) {
...start movement...
state = MOVE;
} else if(state==MOVE) {
// check if target reached
if(targetReached()) {
state=DONE;
} else if(movementBlocked()) {
state=BLOCKED;
} else if(state==BLOCKED) {
if(timeoutReached()) {
state=MOVE;
}
}
setState(state);
You dont need any fancy, tool supported, generic state machine for simple stuff like this. More complex stuff is handled by my BTs.

This is what I have in my character animation state machine using if/else without state machine system :

enum TPlayerState
{
  PS_IDLE = 0,
  PS_MOVE = 1
};

// Animation state machine.
if( m_MoveDirection != DE::CVector2( 0.0f, 0.0f ) )
{
  ...
  m_PlayerState = PS_MOVE;
}
else
{
  // Check if we changed of state.
  if( m_PlayerState != PS_IDLE )
  {
    ...
    m_PlayerState = PS_IDLE;
  }
}
Go to AIGameDev.com, join for free (this will give you a restricted access), and read e.g. the articles / listen the recordings

Thanks for the link didn't knew that one smile.png




#5164743 Frustum sphere

Posted by Alundra on 04 July 2014 - 08:27 AM

Hi all,

Here my code to compute a bounding sphere from camera + near + far :

void ExtractFrustumSphere( CCameraActor* Camera, const float Near, const float Far, CVector3* Center, float* Radius )
{
  // Get the camera component.
  CCameraComponent* CameraComponent = static_cast< CCameraComponent* >( Camera->GetComponent( 0 ) );
 
  // Camera params.
  const CVector3 CameraPos = Camera->GetWorldTranslationVector();
  const CVector3 CameraRight = Camera->GetRightVector();
  const CVector3 CameraForward = Camera->GetForwardVector();
  const CVector3 CameraUp = Camera->GetUpVector();
 
  // Tangent values.
  const float TanFOVX = CMath::Tan( CameraComponent->GetAspectRatio() * CameraComponent->GetFieldOfView() * 0.5f );
  const float TanFOVY = CMath::Tan( CameraComponent->GetAspectRatio() );
  
  // Compute the half distance.
  const float HalfDistance = 0.5f * ( Far - Near );
  
  // Compute the center.
  *Center = CameraPos + CameraForward * ( Near + HalfDistance );
  
  // Compute the radius.
  *Radius = ( ( CameraRight * TanFOVX + CameraUp * TanFOVY + CameraForward ) * HalfDistance ).Length();
}

I'm not sure if I use the correct way to compute the radius.

I think this is wrong because for a near of 0.1f and a far of 100.0f with a FOV of QUATER_PI, I have 246 of radius.

What is wrong in the calcule of the radius ?

Thanks for the help.

 

EDIT :

I saw I used a bad value for TanFOVY, I have changed to use :

const float TanFOVX = CMath::Tan( CameraComponent->GetAspectRatio() * CameraComponent->GetFieldOfView() * 0.5f );
const float TanFOVY = CMath::Tan( CameraComponent->GetFieldOfView() * 0.5f );

I Have a radius of 68 for the same values I said before, Is it the correct answer ?




#5159275 I hate my code....How do you structure your code for a game?

Posted by Alundra on 09 June 2014 - 09:26 AM

You can write a whole game without class, look at quake source code, it's a monster source code without one class.

If you say you use class because others use class, that only mean you don't understand what class give you.




#5159102 I hate my code....How do you structure your code for a game?

Posted by Alundra on 08 June 2014 - 11:16 AM

It's nice to not like your code, because then you want more and more.

The best way to have a good code is to practice more and more until you have more results with less code.

It's called the experience and you can't get it without working on projects.




#5153765 Screen Space Reflection Optimization

Posted by Alundra on 15 May 2014 - 07:24 AM

Hi all,

I'm interested working on screen space reflection because it's the future.

Here the actual code I have, learned from a book :

struct PS_INPUT
{
  float4 Position : SV_POSITION;
  float3 Normal   : NORMAL;
  float4 Tangent  : TANGENT;
  float2 TexCoord : TEXCOORD0;
  float4 PosVS    : TEXCOORD1;
};

cbuffer PROJECTION_CBUFFER : register( b0 )
{
  float4x4 Projection;
  float4 PerspectiveValues;
};

cbuffer SSR_CBUFFER : register( b1 )
{
  float ViewAngleThreshold;
  float EdgeDistThreshold;
  float DepthBias;
  float ReflectionScale;
};

Texture2D DiffuseMap : register( t0 );
Texture2D DepthMap : register( t1 );
SamplerState LinearSampler : register( s0 );
SamplerState PointSampler : register( s1 );

float ConvertZToLinearDepth( in float DepthValue )
{
  return PerspectiveValues.z / (DepthValue - PerspectiveValues.w);
}

float3 PosFromDepth( in float2 uv, in float LinearDepth )
{
  return float3( PerspectiveValues.xy * uv * LinearDepth, LinearDepth );
}

static const float PixelSize = 2.0f / 720.0f;
static const int NumSteps = 1280;

float4 main( in PS_INPUT Input ) : SV_TARGET
{
  // Normalize the normal.
  float3 NormalVS = normalize( Input.Normal );
  
  // Compute the camera to pixel direction.
  float3 EyeToPixel = normalize( Input.PosVS.xyz );
  
  // Compute the reflected view direction.
  float3 ReflectVS = reflect( EyeToPixel, NormalVS );
  
  // The initial reflection color for the pixel.
  float4 ReflectColor = float4( 0.0f, 0.0f, 0.0f, 0.0f );
  
  // Check the angle using threshold.
  if( ReflectVS.z >= ViewAngleThreshold )
  {
    // Fade the reflection as the view angles gets close to the threshold.
    float ViewAngleThresholdInv = 1.0f - ViewAngleThreshold;
    float ViewAngleFade = clamp( 3.0f * (ReflectVS.z - ViewAngleThreshold) / ViewAngleThresholdInv, 0.0f, 1.0f );
    
    // Transform the View Space Reflection to clip-space.
    float3 PosReflectVS = Input.PosVS.xyz + ReflectVS;
    float3 PosReflectCS = mul( float4( PosReflectVS, 1.0f ), Projection ).xyz / PosReflectVS.z;
    float3 ReflectCS = PosReflectCS - Input.Position.xyz;
    
    // Resize Screen Space Reflection to an appropriate length.
    float ReflectScale = PixelSize / length( ReflectCS.xy );
    ReflectCS *= ReflectScale;
    
    // Compute the first sampling position in screen-space.
    float2 SampPos = float2( 0.5f, -0.5f ) * (Input.Position.xy + ReflectCS.xy) + 0.5f;
    
    // Find each iteration step in screen-space.
    float2 Step = ReflectCS.xy * float2( 0.5f, -0.5f );
    
    // Build a plane laying on the reflection vector.
    float4 RayPlane;
    float3 Right = cross( EyeToPixel, ReflectVS );
    RayPlane.xyz = normalize( cross( ReflectVS, Right ) );
    RayPlane.w = dot( RayPlane.xyz, Input.PosVS.xyz );
    
    // Iterate over the texture searching for intersection.
    for( int CurStep = 0; CurStep < NumSteps; ++CurStep )
    {
      // Get the current depth.
      float CurDepth = DepthMap.SampleLevel( PointSampler, SampPos, 0.0f ).x;
      
      // Reconstruct the position from depth.
      float CurDepthLin = ConvertZToLinearDepth( CurDepth );
      float3 CurPos = PosFromDepth( Input.Position.xy + ReflectCS.xy * ((float)CurStep + 1.0f), CurDepthLin );
      
      // The intersection happens between two positions on the oposite sides of the plane.
      if( RayPlane.w >= dot( RayPlane.xyz, CurPos ) + DepthBias )
      {
        // Compute the actual position on the ray for the given depth value.
        float3 FinalPosVS = Input.PosVS.xyz + (ReflectVS / abs(ReflectVS.z)) * abs(CurDepthLin - Input.PosVS.z + DepthBias);
        float2 FinalPosCS = FinalPosVS.xy / PerspectiveValues.xy / FinalPosVS.z;
        SampPos = float2( 0.5f, -0.5f ) * FinalPosCS.xy + 0.5f;
        
        // Get the value at the current screen space location.
        ReflectColor.rgb = DiffuseMap.SampleLevel( LinearSampler, SampPos, 0.0f ).rgb;
        
        // Fade out samples as they get close to the texture edges.
        float EdgeFade = clamp( distance( SampPos, float2( 0.5f, 0.5f ) ) * 2.0f - EdgeDistThreshold, 0.0f, 1.0f );
        
        // Compute the fade value.
        ReflectColor.a = min( ViewAngleFade, 1.0f - EdgeFade * EdgeFade );
        
        // Apply the reflection scale.
        ReflectColor.a *= ReflectionScale;
        
        // Advance past the final iteration to break the loop.
        CurStep = NumSteps;
      }
      
      // Advance to the next sample.
      SampPos += Step;
    }
  }
  
  // Return the reflect color.
  return ReflectColor;
}

This part is because it's fixed-size for test :

static const float PixelSize = 2.0f / 720.0f;
static const int NumSteps = 1280;

The problem is that cost very a lot.

Does a way exists to have a quality value ?

Thanks




#5151209 what happens when std::vector is left empty?

Posted by Alundra on 03 May 2014 - 10:21 AM

To be more clear about the 12 and 24 bytes, it's because vector (and all array class in general) stores length,capacity and pointer of data.

At the end you have 2 size_t and one data pointer of the type of the vector, in x86 each is 4 bytes, in x64 each is 8 bytes.




#5149832 Unmaintainable code

Posted by Alundra on 27 April 2014 - 05:25 AM

Wow theres one hell of an if statement in there:

You can see a lot of hard coded value in this hell too, this file is a joke from A to Z.

Imagine the scene : "We have to change the jump height value"
Programmer of this file : "WHAT ?!"






PARTNERS