示例#1
1
frag_color phong_tangent_space_shader::fragment(
        const vec3& bary,
        const mat3& verts,
        const mat3x2& tex_coords,
        const mat3& vert_norms) const
{
    auto uv = bary_lerp(tex_coords[0], tex_coords[1], tex_coords[2], bary);
    auto objspace_norm = bary_lerp(vert_norms[0], vert_norms[1], vert_norms[2], bary);
    auto ts_normval = normalmap.get_from_ratio(uv[0], uv[1]);
    auto tanspace_norm = normalize(vec3(ts_normval.r - 127.5,
                                        ts_normval.g - 127.5,
                                        ts_normval.b - 127.5));

    // objspace and texture space verts
    auto o1 = verts[1] - verts[0];
    auto o2 = verts[2] - verts[0];
    auto t1 = tex_coords[1] - tex_coords[0];
    auto t2 = tex_coords[2] - tex_coords[0];

    auto tanspace_mat = mat2(t1.x, t2.x,
                             t1.y, t2.y);
    auto objspace_mat = mat3x2(o1.x, o2.x,
                               o1.y, o2.y,
                               o1.z, o2.z);

    // S * t1.x + T * t1.y = o1
    // S * t2.x + T * t2.y = o2
    //
    // [t1.x    t1.y]  *  [tan      =  [o1.x    o1.y   o1.z]
    //  t2.x    t2.y]      bitan]       o2.x    o2.y   o2.z]
    //
    //  tanspace_mat * tan_bitan_mat = objspace_mat
    //  inverse(tanspace_mat) * tanspace_mat * tan_bitan_mat = inverse(tanspace_mat) * objspace_mat
    //  I * tan_bitan_mat = inverse(tansapce_mat) * objspace_mat
    //  tan_bitan_mat = inverse(tanspace_mat) * objspace_mat
    auto tan_bitan_mat = transpose(inverse(tanspace_mat) * objspace_mat);
    auto tan_to_objspace = mat3(normalize(tan_bitan_mat[0]),
                                normalize(tan_bitan_mat[1]),
                                normalize(objspace_norm));
    auto norm = normalize(tan_to_objspace * tanspace_norm);

    // ambient color
    TGAColor ambient(5, 5, 5, 255);

    // specular color
    auto spec_val = specular.get_from_ratio(uv[0], uv[1]).raw[0];
    auto r = normalize(reflect(light_dir(), norm));
    auto spec_intensity = pow(max(0.0f, dot(r, to_cam)), spec_val);

    // diffuse color
    float diff_intensity = max(0.0f, dot(to_light(), norm));
    auto diff_color = diffuse.get_from_ratio(uv[0], uv[1]);

    diff_color.scale(diff_intensity + spec_intensity * .6);

    return frag_color {ambient + diff_color, true};
}
示例#2
0
frag_color phong_shader::fragment(
        const vec3& bary,
        const mat3& verts,
        const mat3x2& tex_coords,
        const mat3& vert_norms) const
{
    auto uv = bary_lerp(tex_coords[0], tex_coords[1], tex_coords[2], bary);
    auto normval = normalmap.get_from_ratio(uv[0], uv[1]);
    auto norm = normalize(vec3(normval.r - 127.5, normval.g - 127.5, normval.b - 127.5));

    // ambient color
    TGAColor ambient(5, 5, 5, 255);

    // specular color
    auto spec_val = specular.get_from_ratio(uv[0], uv[1]).raw[0];
    auto r = normalize(reflect(light_dir(), norm));
    auto spec_intensity = pow(max(0.0f, dot(r, to_cam)), spec_val);

    // diffuse color
    float diff_intensity = max(0.0f, dot(to_light(), norm));
    auto diff_color = diffuse.get_from_ratio(uv[0], uv[1]);

    diff_color.scale(diff_intensity + spec_intensity * .6);

    return frag_color {ambient + diff_color, true};
}
示例#3
0
void GLWidget::mouseMoveEvent(QMouseEvent *event) {
    last.x = event->x();
    last.y = event->y();

    vec3 begin = pointOnVirtualTrackball(first);
    vec3 end = pointOnVirtualTrackball(last);

    float dotProduct = dot(normalize(begin), normalize(end));
    float angle = acos(dotProduct);
    vec3 crossP = cross(begin, end);

    if(length(crossP) > .00001f)
    {
        rotationMatrix = rotate(mat4(1.0), angle, normalize(crossP)) * rotationMatrix;
        glUseProgram(cubeProg);
        glUniformMatrix4fv(cubeRotationMatrixLoc, 1, false, value_ptr(rotationMatrix));
        glUseProgram(gridProg);
        glUniformMatrix4fv(gridRotationMatrixLoc, 1, false, value_ptr(rotationMatrix));
        update();
    }


    first.x = last.x;
    first.y = last.y;
}
示例#4
0
frag_color normal_shader::fragment(
        const vec3& bary,
        const mat3& verts,
        const mat3x2& tex_coords,
        const mat3& vert_norms) const
{
    auto uv = bary_lerp(tex_coords[0], tex_coords[1], tex_coords[2], bary);
    auto normval = normalmap.get_from_ratio(uv[0], uv[1]);
    auto normal = normalize(vec3(normval.r - 127.5, normval.g - 127.5, normval.b - 127.5));
    float intensity = max(0.0f, dot(to_light(), normal));

    vec3 norm_color = normalize(bary_lerp(vert_norms[0], vert_norms[1],
                vert_norms[2], bary)) * 255.0f;
    TGAColor c(abs(norm_color.x), abs(norm_color.y), abs(norm_color.z), 255);
    c.scale(intensity);

    return frag_color {c, true};
}
示例#5
0
frag_color simple_normal_shader::fragment(
        const vec3& bary,
        const mat3& verts,
        const mat3x2& tex_coords,
        const mat3& vert_norms) const
{
    vec3 norm_color = normalize(bary_lerp(vert_norms[0], vert_norms[1],
                vert_norms[2], bary)) * 255.0f;
    TGAColor c(abs(norm_color.x), abs(norm_color.y), abs(norm_color.z), 255);

    return frag_color {c, true};
}
示例#6
0
frag_color simple_texture_shader::fragment(
        const vec3& bary,
        const mat3& verts,
        const mat3x2& tex_coords,
        const mat3& vert_norms) const
{
    auto norm = bary_lerp(vert_norms[0], vert_norms[1], vert_norms[2], bary);
    float intensity = max(0.0f, dot(to_light(), normalize(norm)));
    auto uv = bary_lerp(tex_coords[0], tex_coords[1], tex_coords[2], bary);
    auto color = tex.get_from_ratio(uv[0], uv[1]);
    color.scale(intensity);

    return frag_color {color, true};
}
示例#7
0
/*
 * Phillips wave spectrum, equation 40 with modification specified in equation 41
 */
float Ocean::phillips(int n_prime, int m_prime) const
{
   // Wavevector
   float kx = M_PI * (2 * n_prime - _N) / _length;
   float kz = M_PI * (2 * m_prime - _N) / _length;
   vec2  k(kx, kz);
   
   // Magnitude of wavevector
   float k_length = glm::length(k);
   
   // Wind speed
	float w_length = glm::length(_w);

   // If wavevector is very small, no need to calculate, just return zero
   if (k_length < 0.000001) return 0.0;
   
   // Precaculate k^2 and k^4
	float k_length2 = k_length  * k_length;
	float k_length4 = k_length2 * k_length2;

   // Cosine factor - eliminates waves that travel perpendicular to the wind
   float k_dot_w = dot(normalize(k), normalize(_w));
	float k_dot_w2  = k_dot_w * k_dot_w;
   
   
	float L         = w_length * w_length / _g;
	float L2        = L * L;
	
   // Something a bit extra to keep waves from exploding. Not in the paper.
	float damping   = 0.001;
	float l2        = L2 * damping * damping;
   
   // Phillips spectrum as described in eqn  40 with modification described in 41 to
   // suppress very small waves that cause convergence problems
	return _A * (exp(-1.0f / (k_length2 * L2)) / k_length4) * k_dot_w2 * exp(-k_length2 * l2);
}
示例#8
0
int main(int argc, char** argv) {
    /* Initialize logging. */
    START_EASYLOGGINGPP(argc, argv);
    LOG(TRACE) << "Logging initialized.";


    /* Initialize SDL. */
    LOG(TRACE) << "Initializing SDL...";
    int result = SDL_Init(SDL_INIT_VIDEO);
    if (result != 0) {
        LOG(FATAL) << "Could not initialize SDL: " << SDL_GetError();
    }
    window = SDL_CreateWindow(argv[0], 0, 0, (int)window_width,
                              (int)window_height,
                              SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
    if (window == nullptr) {
        LOG(FATAL) << "Could not create window: " << SDL_GetError();
    }
    SDL_ShowCursor(SDL_DISABLE);
    SDL_SetRelativeMouseMode(SDL_TRUE);
    frequency = SDL_GetPerformanceFrequency();
    time_last_frame = SDL_GetPerformanceCounter();
    LOG(INFO) << "Performance counter frequency: " << frequency;


    /* Initialize OpenGL. */
    LOG(TRACE) << "Initializing OpenGL...";
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
    SDL_GLContext gl_context = SDL_GL_CreateContext(window);
    if (gl_context == nullptr) {
        LOG(FATAL) << SDL_GetError();
    }
    glewExperimental = GL_TRUE;
    GLenum glewError = glewInit();
    if (glewError != GLEW_OK) {
        LOG(FATAL) << "Could not initialize GLEW: " << glewGetErrorString(glewError);
    }
    glEnable(GL_BLEND);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_VERTEX_ARRAY);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);


    /* Load assets. */
    LOG(TRACE) << "Loading assets...";
    shaders = new ShaderManager();
    {
        shader_terrain = shaders->get("terrain");
        shader_terrain->apply();
        glActiveTexture(GL_TEXTURE0);
        texture_terrain = new Texture("terrain");
        shader_terrain->updateUniform("tex", 0);
        terrain = new Terrain("heightmap.png");
        shader_terrain->updateUniform("max_height", terrain->getMaxHeight());
        auto world = mat4();
        world = translate(world, vec3(-terrain->getWidth() / 2.f,
                                      -terrain->getMaxHeight() / 2.f,
                                      -terrain->getDepth() / 2.f));
        shader_terrain->updateUniform("K_a", 0.1f);
        shader_terrain->updateUniform("K_d", 0.9f);
        shader_terrain->updateWorldMatrix(world);
        LOG(INFO) << "Maximum terrain height: " << terrain->getMaxHeight();
        LOG(INFO) << "Terrain width: " << terrain->getWidth();
        LOG(INFO) << "Terrain depth: " << terrain->getDepth();
    } {
        shader_skybox = shaders->get("skybox");
        shader_skybox->apply();
        glActiveTexture(GL_TEXTURE2);
        environment_map = new CubeMap("terrain_");
        shader_skybox->updateUniform("cubeMap", 2);
        auto world = mat4();
        world = scale(world, vec3(terrain->getWidth(),
                                  terrain->getWidth(),
                                  terrain->getDepth()));
        skybox = new Cube();
        shader_terrain->apply();
        shader_skybox->updateWorldMatrix(world);
    } {
        auto world = mat4();
        world = scale(world, vec3(terrain->getWidth() / 2.f,
                                  terrain->getMaxHeight() * 2.f,
                                  terrain->getDepth() / 2.f));
        shader_colour = shaders->get("colour");
        shader_colour->apply();
        shader_colour->updateWorldMatrix(world);
        origin = new Origin();
    } {
        auto world = mat4();
        world = translate(world, vec3(-terrain->getWidth() / 2.f,
                                      -terrain->getMaxHeight() / 2.f + 25.f,
                                      -terrain->getDepth() / 2.f));
        shader_water = shaders->get("water");
        shader_water->apply();
        shader_water->updateUniform("K_a", 0.1f);
        shader_water->updateUniform("K_d", 0.0f);
        shader_water->updateUniform("K_s", 0.9f);
        shader_water->updateWorldMatrix(world);
        water = new Grid(terrain->getDepth(), 1000.f);
    }


    /* Set up light. */
    auto light = Camera();
    light.eye = vec3(1024.0f, 1024.f, 1024.f);
    light.at = vec3(0.0f, 0.0f, 0.0f);
    light.up = vec3(0.0f, 0.0f, -1.0f);
    auto light_dir = normalize(vec3(0.f, 0.25f, -1.f));
    shader_terrain->apply();
    shader_terrain->updateUniform("light_dir", light_dir);
    shader_water->apply();
    shader_water->updateUniform("light_dir", light_dir);


    /* Set up view. */
    auto camera = Camera();
    auto camera_height = terrain->getMaxHeight() * 3.f;
    camera.eye = glm::vec3(0.f, camera_height, -terrain->getDepth() / 2.f);
    camera.at = glm::vec3(0, 0, 0);
    camera.up = glm::vec3(0, 1, 0);
    auto view = glm::lookAt(camera.eye, camera.at, camera.up);
    shaders->updateViewMatrices(view);


    /* Set up projection. */
    auto proj = glm::perspective(45.f, window_width / window_height, 100.f, 25000.f);
    shaders->updateProjectionMatrices(proj);


    /* Set up frame buffers. */
    frame_buffer_color = new ColorFrameBuffer(window_width, window_height);


    /* Main loop. */
    float angle = 0.0f;
    bool done = false;
    SDL_Event event;
    LOG(TRACE) << "Entering main loop...";
    while (!done) {
        while (SDL_PollEvent(&event) != 0) {
            if (event.type == SDL_QUIT) {
                done = true;
            } else if (event.type == SDL_KEYDOWN) {
                switch (event.key.keysym.sym) {
                    case SDLK_ESCAPE:
                        LOG(INFO) << "Exiting normally at user request...";
                        done = true;
                        break;
                    case SDLK_PRINTSCREEN:
                        LOG(INFO) << "Rendering screen shot...";
                        frame_buffer_color->bind();
                        draw();
                        frame_buffer_color->write();
                        frame_buffer_color->unbind();
                        break;
                    default:
                        break;
                }
            } else if (event.type == SDL_MOUSEMOTION) {
                const GLfloat X_SCALED = -(GLfloat)event.motion.xrel / window_width;
                const GLfloat Y_SCALED = -(GLfloat)event.motion.yrel / window_height;

                const GLfloat LEFT_RIGHT_ROT = X_SCALED * ANGLE_DELTA;
                const GLfloat UP_DOWN_ROT = Y_SCALED * ANGLE_DELTA;

                vec3 tempD(camera.at - camera.eye);
                vec4 d(tempD.x, tempD.y, tempD.z, 0.0f);

                vec3 right = cross(tempD, camera.up);

                mat4 rot;
                rot = rotate(rot, UP_DOWN_ROT, right);
                rot = rotate(rot, LEFT_RIGHT_ROT, camera.up);

                d = rot * d;

                camera.at.x = camera.eye.x + d.x;
                camera.at.y = camera.eye.y + d.y;
                camera.at.z = camera.eye.z + d.z;
            }
        }

        glm::vec3 direction = STEP * glm::normalize(camera.at - camera.eye);
        glm::vec3 right = STEP * glm::normalize(glm::cross(direction, camera.up));

        auto keys = SDL_GetKeyboardState(nullptr);
        if (keys[SDL_SCANCODE_W]) {
            camera.eye += direction;
            camera.at += direction;
        }
        if (keys[SDL_SCANCODE_S]) {
            camera.eye -= direction;
            camera.at -= direction;
        }
        if (keys[SDL_SCANCODE_D]) {
            camera.eye += right;
            camera.at += right;
        }
        if (keys[SDL_SCANCODE_A]) {
            camera.eye -= right;
            camera.at -= right;
        }
        if (keys[SDL_SCANCODE_SPACE]) {
            camera.eye += STEP * camera.up;
            camera.at += STEP * camera.up;
        }
        if (keys[SDL_SCANCODE_LCTRL]) {
            camera.eye -= STEP * camera.up;
            camera.at -= STEP * camera.up;
        }
        view = glm::lookAt(camera.eye, camera.at, camera.up);
        shaders->updateViewMatrices(view);

        draw();

        angle += 0.01f;
    }

    delete shaders;
    delete environment_map;
    delete frame_buffer_color;

    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;
}
示例#9
-1
void sceneRender()
{
    using glm::cross;
    using glm::clamp;
    using glm::vec3;
    using glm::normalize;

    // TODO: Save scene pixels as png
    int width = g_theScene->output_size.x;
    int height = g_theScene->output_size.y;
    const char* output = isEmpty(g_theScene->output) ? "out.png" : g_theScene->output;
    unsigned char* pixels = (unsigned char*) malloc(c_bpp * width * height);

    camera_t& cam = g_theScene->camera;
    float halfFov = cam.fov / 2;
    float tanFov = tan(halfFov);
    float halfWidth = width / 2.0f;
    float halfHeight = height / 2.0f;

    vec3 w = normalize(cam.look_from - cam.look_at);
    vec3 u = normalize(cross(cam.up, w));
    vec3 v = normalize(cross(u, w));

    ray_t ray;
    ray.origin = cam.look_from;

    ray_query_t best;

    float multi = tanFov / halfHeight;
    unsigned char* currentPixel = pixels;
    for (int y = 0; y < height; ++y)
    {
        float cy = halfHeight - (y + 0.5f);
        for (int x = 0; x < width; currentPixel += c_bpp, ++x)
        {
            // reset best query.
            best.obj = NULL;
            best.t = FLT_MAX;

            // Get Ray through pixel.
            float cx = (x + 0.5f) - halfWidth;
            float a = cx * multi;
            float b = cy * multi;

            vec3 rayDirection = normalize((a * u) + (b * v) - w);

            // Find intersection with scene.
            ray_query_t query;
            vec3* vertices = g_theScene->vertices;
            triangle_t* tri = g_theScene->triangles;
            for (int t = 0; t < g_theScene->triangle_count; ++t, ++tri)
            {
                glm::vec4 rayOriginT = tri->xform_inv * glm::vec4(cam.look_from, 1.0f);
                glm::vec4 rayDirectionT = tri->xform_inv * glm::vec4(rayDirection, 0.0f);

                ray.origin = vec3(rayOriginT.x, rayOriginT.y, rayOriginT.z);
                ray.direction = vec3(rayDirectionT.x, rayDirectionT.y, rayDirectionT.z);

                int* indices = tri->indicies;
                if (intersectRayTriangle(ray, vertices[indices[0]], vertices[indices[1]], vertices[indices[2]], query))
                {
                    query.obj = tri;
                    if (query.t < best.t) best = query;
                }
            }

            sphere_t* sph = g_theScene->spheres;
            for (int s = 0; s < g_theScene->sphere_count; ++s, ++sph)
            {
                glm::vec4 rayOriginT = sph->xform_inv * glm::vec4(cam.look_from, 1.0f);
                glm::vec4 rayDirectionT = sph->xform_inv * glm::vec4(rayDirection, 0.0f);

                ray.origin = vec3(rayOriginT.x, rayOriginT.y, rayOriginT.z);
                ray.direction = vec3(rayDirectionT.x, rayDirectionT.y, rayDirectionT.z);
                
                if (intersectRaySphere(ray, *sph, query))
                {
                    query.obj = sph;
                    if (query.t < best.t) best = query;
                }
            }

            // TODO: Light object
            if (best.obj != NULL)
            {
                material_t& mat = best.obj->material;
                vec3 color = mat.ambient;

                // final color conversion.
                currentPixel[0] = (unsigned char) (clamp(color.b, 0.0f, 1.0f) * 255.0f);
                currentPixel[1] = (unsigned char) (clamp(color.g, 0.0f, 1.0f) * 255.0f);
                currentPixel[2] = (unsigned char) (clamp(color.r, 0.0f, 1.0f) * 255.0f);
            }
        }
    }

    printf("Rendering scene to %s...\n", output);
    FIBITMAP *img = FreeImage_ConvertFromRawBits(pixels, width, height, width * c_bpp, c_bpp * 8, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, false);
    FreeImage_Save(FIF_PNG, img, isEmpty(g_theScene->output) ? "out.png" : g_theScene->output, 0);

    free(pixels);

    printf("Render complete!\n");
}