Sophie

Sophie

distrib > * > cooker > x86_64 > by-pkgid > 0243c8b7bca94179c78b9bd6ac76c033 > files > 291

cg-examples-3.0.0018-0.1.x86_64.rpm


// buffer_lighting.cg - Cg 2.0 example demonstrating use of buffers to
//                      contain uniform material, transform, and lighting
//                      parameters

#define MAX_LIGHTS 2

typedef struct {
  float4 ambient;
  float4 diffuse;
  float4 specular;
  float4 shine;
} Material;

typedef struct {
  float4x4 modelview;
  float4x4 inverse_modelview;
  float4x4 modelview_projection;
} Transform;

typedef struct {
  bool enabled;
  float3 ambient;
  float3 diffuse;
  float3 specular;
  float k0, k1, k2;
} LightSourceStatic;

// Light data that is mostly static
typedef struct {
  float3 global_ambient;
  LightSourceStatic source[MAX_LIGHTS];
} LightSetStatic;

typedef struct {
  float4 position;
} LightSourcePerView;

// Light data that changes as the view changes
typedef struct {
  LightSourcePerView source[MAX_LIGHTS];
} LightSetPerView;

// Compute the squared distance a direction vector covers.
float lengthSquared(float3 v)
{
  return dot(v,v);
}

void vertex_lighting(float4 position_obj : POSITION,
                     float3 normal_obj   : NORMAL,

                 out float4 oPosition : POSITION,
                 out float4 oColor    : COLOR,

             uniform Material        material        : BUFFER[0],
             uniform Transform       transform       : BUFFER[1],
             uniform LightSetStatic  lightSet        : BUFFER[2],
             uniform LightSetPerView lightSetPerView : BUFFER[3])
{
  float4 vertex_eye = mul(transform.modelview, position_obj);
  float3 position_eye = vertex_eye.xyz / vertex_eye.w;
  float3 normal_eye   = mul(float3x3(transform.inverse_modelview), normal_obj);

  float3 surface_normal = normalize(normal_eye);

  float3 totalRadiance = lightSet.global_ambient;

  int i;
  
  for (i=0; i<2; i++) {
    const LightSourceStatic source = lightSet.source[i];
    const float4 light_position = lightSetPerView.source[i].position;

    if (source.enabled) {
      float3 light_vector;
      float attenuation;

      if (light_position.w != 0.0) {
        // Positional (finite) light
        light_vector = light_position.xyz/light_position.w - position_eye;

        attenuation = 1.0 / (source.k0 + 
                             source.k1*length(light_vector) +
                             source.k2*lengthSquared(light_vector));
      } else {
        // Direction (infinite) light
        light_vector = light_position.xyz;
        attenuation = 1.0;
      }

      float3 light_direction = normalize(light_vector.xyz);
      float3 view_direction = normalize(-position_eye.xyz);
      float3 half_angle_direction = normalize(view_direction + light_direction);

      float LdotN = dot(light_direction, surface_normal);
      float diffuse = max(0.0, LdotN);

      float HdotN = dot(half_angle_direction, surface_normal);
      float specular = (LdotN > 0) ? pow(max(0.0, HdotN), material.shine.x) : 0;

      float3 lighting = material.ambient.rgb * source.ambient.rgb +
                        diffuse * material.diffuse.rgb * source.diffuse.rgb +
                        specular * material.specular.rgb * source.specular.rgb;

      float3 radiance;
      radiance = attenuation * lighting;
      totalRadiance += radiance;
    }
  }

  oPosition = mul(transform.modelview_projection, position_obj);
  oColor = float4(totalRadiance, material.diffuse.a);
}

void vertex_transform(float4 position_obj : POSITION,
                      float4 color        : COLOR,
                      float3 normal_obj   : NORMAL,

                  out float4 oPosition : POSITION,
                  out float4 oColor    : COLOR,

              uniform Material        material        : BUFFER[0],
              uniform Transform       transform       : BUFFER[1],
              uniform LightSetStatic  lightSet        : BUFFER[2],
              uniform LightSetPerView lightSetPerView : BUFFER[3])
{
  oColor = color;

  oPosition = mul(transform.modelview_projection, position_obj);
}