bool Primitive::Intersect( Ray& ray, Intersection& isect ) { Ray localRay(ray); localRay.o = Vec3d(worldToLocal * Vec4d(ray.o, 1.0)); localRay.d = Vec3d(worldToLocal * Vec4d(ray.d, 0.0)); if (!shape->Intersect(localRay, isect)) { return false; } ray.minT = localRay.minT; ray.maxT = localRay.maxT; if (localToWorld != Mat4d(1.0)) { isect.p = Vec3d(localToWorld * Vec4d(isect.p, 1.0)); isect.sn = Math::Normalize(normalLocalToWorld * isect.sn); isect.gn = Math::Normalize(normalLocalToWorld * isect.gn); isect.ss = Math::Normalize(Vec3d(localToWorld * Vec4d(isect.ss, 0.0))); isect.st = Math::Normalize(Vec3d(localToWorld * Vec4d(isect.st, 0.0))); } return true; }
void BSplineCurveEvaluator::evaluateCurve( const std::vector<Point>& controlPoints, std::vector<Point>& evaluatedPoints, const float& animationLength, const bool& beWrap) const { evaluatedPoints.clear(); if (!beWrap) { evaluatedPoints.push_back(Point(0, controlPoints.front().y)); evaluatedPoints.push_back(Point(animationLength, controlPoints.back().y)); } // a hack to make the endpoints controllable vector<Point> controlPointsCopy; if (beWrap) { Point start_p1 = Point((controlPoints.end() - 2)->x - animationLength, (controlPoints.end() - 2)->y); Point start_p2 = Point((controlPoints.end() - 1)->x - animationLength, (controlPoints.end() - 1)->y); Point end_p1 = Point((controlPoints.begin())->x + animationLength, (controlPoints.begin())->y); Point end_p2 = Point((controlPoints.begin() + 1)->x + animationLength, (controlPoints.begin() + 1)->y); controlPointsCopy.push_back(start_p1); controlPointsCopy.push_back(start_p2); controlPointsCopy.insert(controlPointsCopy.end(), controlPoints.begin(), controlPoints.end()); controlPointsCopy.push_back(end_p1); controlPointsCopy.push_back(end_p2); } else { controlPointsCopy.push_back(controlPoints.front()); controlPointsCopy.push_back(controlPoints.front()); controlPointsCopy.insert(controlPointsCopy.end(), controlPoints.begin(), controlPoints.end()); controlPointsCopy.push_back(controlPoints.back()); controlPointsCopy.push_back(controlPoints.back()); } const Mat4d basis = Mat4d( 1, 4, 1, 0, 0, 4, 2, 0, 0, 2, 4, 0, 0, 1, 4, 1) / 6.0; BezierCurveEvaluator bezierCurveEvaluator; for (size_t cnt = 0; cnt + 3 < controlPointsCopy.size(); ++cnt) { Vec4d param_x(controlPointsCopy[cnt].x, controlPointsCopy[cnt + 1].x, controlPointsCopy[cnt + 2].x, controlPointsCopy[cnt + 3].x); Vec4d param_y(controlPointsCopy[cnt].y, controlPointsCopy[cnt + 1].y, controlPointsCopy[cnt + 2].y, controlPointsCopy[cnt + 3].y); param_x = basis * param_x; param_y = basis * param_y; vector<Point> param_control; for (int i = 0; i < 4; ++i) { param_control.push_back(Point(param_x[i], param_y[i])); } vector<Point> param_evaluated; bezierCurveEvaluator.evaluateCurve(param_control, param_evaluated, animationLength, false); evaluatedPoints.insert(evaluatedPoints.end(), param_evaluated.begin(), param_evaluated.end()-2); } }
HINATA_NAMESPACE_BEGIN CornellBoxScene::CornellBoxScene( double aspect ) { // Fixed scene definition (Cornell Box) // Right primitives.push_back( std::make_shared<Primitive>( Mat4d::Identity(), std::make_shared<Sphere>(1e5, Vec3d(1e5+1, 0, 0)), std::make_shared<DiffuseBSDF>(Vec3d(0.75, 0.25, 0.25)))); // Left primitives.push_back( std::make_shared<Primitive>( Mat4d::Identity(), std::make_shared<Sphere>(1e5, Vec3d(-1e5-1, 0, 0)), std::make_shared<DiffuseBSDF>(Vec3d(0.25, 0.25, 0.75)))); // Top primitives.push_back( std::make_shared<Primitive>( Mat4d::Identity(), std::make_shared<Sphere>(1e5, Vec3d(0, 1e5+1, 0)), std::make_shared<DiffuseBSDF>(Vec3d(0.75)))); // Bottom primitives.push_back( std::make_shared<Primitive>( Mat4d::Identity(), std::make_shared<Sphere>(1e5, Vec3d(0, -1e5-1, 0)), std::make_shared<DiffuseBSDF>(Vec3d(0.75)))); // Back primitives.push_back( std::make_shared<Primitive>( Mat4d::Identity(), std::make_shared<Sphere>(1e5, Vec3d(0, 0, 1e5+7)), std::make_shared<DiffuseBSDF>(Vec3d()))); // Front primitives.push_back( std::make_shared<Primitive>( Mat4d::Identity(), std::make_shared<Sphere>(1e5, Vec3d(0, 0, -1e5-1)), std::make_shared<DiffuseBSDF>(Vec3d(0.75)))); //std::make_shared<GlossyConductorBSDF>(Vec3d(1), Vec3d(0.1), Vec3d(1.67), 0.08))); // Light auto light = std::make_shared<AreaLight>(Vec3d(30)); //auto lp = // std::make_shared<Primitive>( // Mat4d(1.0), // std::make_shared<Sphere>(0.15, Vec3d(0.5, 0.7, 0)), // //std::make_shared<Sphere>(0.15, Vec3d(0, 0.85, 0)), // std::make_shared<DiffuseBSDF>(Vec3d(0.75)), // light); auto mesh = std::make_shared<TriangleMesh>(); mesh->positions.push_back(Vec3d( 0.2, 0.9, 0.2)); mesh->positions.push_back(Vec3d(-0.2, 0.9, 0.2)); mesh->positions.push_back(Vec3d(-0.2, 0.9, -0.2)); mesh->positions.push_back(Vec3d( 0.2, 0.9, -0.2)); mesh->normals.push_back(Vec3d(0, -1, 0)); mesh->normals.push_back(Vec3d(0, -1, 0)); mesh->normals.push_back(Vec3d(0, -1, 0)); mesh->normals.push_back(Vec3d(0, -1, 0)); auto lp1 = std::make_shared<Primitive>( Math::Rotate(30.0, Vec3d(0, 0, 1)), std::make_shared<Triangle>(mesh, 0, 1, 3), std::make_shared<DiffuseBSDF>(Vec3d(0.75)), //std::make_shared<DiffuseBSDF>(Vec3d()), light); primitives.push_back(lp1); light->AddPrimitive(lp1); auto lp2 = std::make_shared<Primitive>( Math::Rotate(30.0, Vec3d(0, 0, 1)), std::make_shared<Triangle>(mesh, 1, 2, 3), std::make_shared<DiffuseBSDF>(Vec3d(0.75)), //std::make_shared<DiffuseBSDF>(Vec3d()), light); primitives.push_back(lp2); light->AddPrimitive(lp2); light->Initialize(); lights.push_back(light); // Ball 1 primitives.push_back( std::make_shared<Primitive>( Mat4d(1.0), std::make_shared<Sphere>(0.35, Vec3d(0.45, -0.65, 0.5)), //std::make_shared<DiffuseBSDF>(Vec3d(0.75)))); std::make_shared<DielecticBSDF>(Vec3d(1), Vec3d(1), 1, 1.544))); // Ball 2 primitives.push_back( std::make_shared<Primitive>( Mat4d(1.0), std::make_shared<Sphere>(0.35, Vec3d(-0.45, -0.65, -0.3)), std::make_shared<DiffuseBSDF>(Vec3d(0.75)))); //std::make_shared<GlossyConductorBSDF>(Vec3d(1), Vec3d(0.1), Vec3d(1.67), 0.05))); // Camera camera = std::make_shared<PerspectiveCamera>( Math::LookAt(Vec3d(0, 0, 6.99), Vec3d(0, 0, 0), Vec3d(0, 1, 0)), Math::Perspective(20.0, aspect, 0.1, 1000.0)); }
PoolTilesExample(void) : make_plane( Vec3f(), Vec3f(7.0f, 0.0f, 0.0f), Vec3f(0.0f, 0.0f,-7.0f), 48, 48 ), plane_instr(make_plane.Instructions()) , plane_indices(make_plane.Indices()) , make_shape() , shape_instr(make_shape.Instructions()) , shape_indices(make_shape.Indices()) , plane_vs(ObjectDesc("Plane vertex")) , shape_vs(ObjectDesc("Shape vertex")) , plane_fs(ObjectDesc("Plane fragment")) , shape_fs(ObjectDesc("Shape fragment")) , plane_camera_matrix(plane_prog, "CameraMatrix") , shape_camera_matrix(shape_prog, "CameraMatrix") , plane_camera_position(plane_prog, "CameraPosition") , width(800) , height(600) , refl_tex_side(width > height ? height : width) , tile_tex_side(64) { gl.RequireAtLeast(LimitQuery::MaxCombinedTextureImageUnits, 5); plane_vs.Source( "#version 140\n" "uniform vec3 LightPosition;" "uniform vec3 CameraPosition;" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "in vec4 Position;" "in vec2 TexCoord;" "out vec3 vertLightDir;" "out vec3 vertViewDir;" "out vec4 vertReflTexCoord;" "out vec2 vertTileTexCoord;" "void main(void)" "{" " gl_Position = ModelMatrix* Position;" " vertLightDir = normalize(LightPosition - gl_Position.xyz);" " vertViewDir = normalize(CameraPosition - gl_Position.xyz);" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" " vertReflTexCoord = gl_Position;" " vertTileTexCoord = TexCoord;" "}" ); plane_vs.Compile(); plane_fs.Source( "#version 140\n" "uniform sampler2D RandTex, PictTex, TileTex, NormTex;" "uniform sampler2D ReflectTex;" "uniform uint TileCount;" "uniform float Aspect;" "in vec3 vertLightDir;" "in vec3 vertViewDir;" "in vec4 vertReflTexCoord;" "in vec2 vertTileTexCoord;" "out vec4 fragColor;" "void main(void)" "{" " vec3 Normal = texture(" " NormTex, " " vertTileTexCoord * TileCount" " ).rgb;" " vec3 LightRefl = reflect(" " -normalize(vertLightDir)," " normalize(Normal)" " );" " float Diffuse = max(dot(" " Normal, " " vertLightDir" " ), 0.0);" " float Specular = max(dot(" " LightRefl," " vertViewDir" " ), 0.0);" " float PlasterLight = 0.3 + max(Diffuse, 0.0);" " float TileLight = 0.3 + pow(Diffuse, 2.0)*0.9 + pow(Specular, 4.0)*2.5;" " vec2 ReflCoord = vertReflTexCoord.xy;" " ReflCoord /= vertReflTexCoord.w;" " ReflCoord *= 0.5;" " ReflCoord += vec2(Aspect*0.5, 0.5);" " ReflCoord += vec2(Normal.x, Normal.z)*0.5;" " vec3 ReflColor = texture(" " ReflectTex, " " ReflCoord" " ).rgb;" " vec3 TileProps = texture(" " TileTex, " " vertTileTexCoord * TileCount" " ).rgb;" " float Pict = texture(PictTex, vertTileTexCoord).r;" " float Rand = texture(RandTex, vertTileTexCoord).r;" " float LightVsDark = " " mix( 0.1, 0.9, Pict)+" " mix(-0.1, 0.1, Rand);" " vec3 TileColor = mix(" " vec3(0.1, 0.1, 0.5)," " vec3(0.4, 0.4, 0.9)," " LightVsDark " " );" " vec3 PlasterColor = vec3(0.9, 0.9, 0.9);" " fragColor = vec4(" " mix(" " PlasterColor * PlasterLight," " TileColor * TileLight, " " TileProps.b" " ) +" " ReflColor * TileProps.g * 0.6," " 1.0" " );" "}" ); plane_fs.Compile(); plane_prog.AttachShader(plane_vs); plane_prog.AttachShader(plane_fs); plane_prog.Link(); plane_prog.Use(); Vec3f lightPos(3.0f, 2.5f, 2.0f); Uniform<Vec3f>(plane_prog, "LightPosition").Set(lightPos); Uniform<GLuint>(plane_prog, "TileCount").Set(tile_tex_side); Uniform<Mat4f>(plane_prog, "ModelMatrix").Set( ModelMatrixf::Translation(0.0f, -0.5f, 0.0f) ); std::vector<GLfloat> data; GLuint n_per_vertex; n_per_vertex = make_plane.Positions(data); plane_verts.Data(data); DSAVertexArrayAttribEXT(plane, plane_prog, "Position") .Setup<GLfloat>(plane_verts, n_per_vertex) .Enable(); n_per_vertex = make_plane.TexCoordinates(data); plane_texcoords.Data(data); DSAVertexArrayAttribEXT(plane, plane_prog, "TexCoord") .Setup<GLfloat>(plane_texcoords, n_per_vertex) .Enable(); // rand_tex.target = Texture::Target::_2D; rand_tex.Image2D( images::RandomRedUByte( tile_tex_side, tile_tex_side ) ); rand_tex.Filter(TextureFilter::Nearest); rand_tex.Wrap(TextureWrap::Repeat); Texture::Active(0); UniformSampler(plane_prog, "RandTex").Set(0); rand_tex.Bind(); // pict_tex.target = Texture::Target::_2D; pict_tex.Image2D(images::LoadTexture("pool_pictogram")); pict_tex.Filter(TextureFilter::Linear); pict_tex.Wrap(TextureWrap::Repeat); Texture::Active(1); UniformSampler(plane_prog, "PictTex").Set(1); pict_tex.Bind(); // auto tile_image = images::LoadTexture("small_tile"); // tile_tex.target = Texture::Target::_2D; tile_tex.Image2D(tile_image); tile_tex.MinFilter(TextureMinFilter::LinearMipmapLinear); tile_tex.MagFilter(TextureMagFilter::Linear); tile_tex.Wrap(TextureWrap::Repeat); tile_tex.GenerateMipmap(); Texture::Active(2); UniformSampler(plane_prog, "TileTex").Set(2); tile_tex.Bind(); // norm_tex.target = Texture::Target::_2D; norm_tex.Image2D( images::TransformComponents<GLfloat, 3>( images::NormalMap(tile_image), Mat4d( Vec4d(1.0, 0.0, 0.0, 0.0), Vec4d(0.0, 0.0, 1.0, 0.0), Vec4d(0.0,-1.0, 0.0, 0.0), Vec4d(0.0, 0.0, 0.0, 1.0) ) ) ); norm_tex.MinFilter(TextureMinFilter::LinearMipmapLinear); norm_tex.MagFilter(TextureMagFilter::Linear); norm_tex.Wrap(TextureWrap::Repeat); norm_tex.GenerateMipmap(); Texture::Active(3); UniformSampler(plane_prog, "NormTex").Set(3); norm_tex.Bind(); // reflect_tex.target = Texture::Target::_2D; reflect_tex.Image2D( 0, PixelDataInternalFormat::RGB, refl_tex_side, refl_tex_side, 0, PixelDataFormat::RGB, PixelDataType::UnsignedByte, nullptr ); reflect_tex.Filter(TextureFilter::Linear); reflect_tex.Wrap(TextureWrap::ClampToEdge); Texture::Active(4); UniformSampler(plane_prog, "ReflectTex").Set(4); reflect_tex.Bind(); rbo.Storage( PixelDataInternalFormat::DepthComponent, refl_tex_side, refl_tex_side ); fbo.target = Framebuffer::Target::Draw; fbo.AttachTexture( FramebufferAttachment::Color, reflect_tex, 0 ); fbo.AttachRenderbuffer( FramebufferAttachment::Depth, rbo ); shape_vs.Source( "#version 140\n" "uniform vec3 LightPosition;" "uniform mat4 ProjectionMatrix, ModelMatrix, CameraMatrix;" "in vec4 Position;" "in vec3 Normal;" "out vec3 vertNormal;" "out vec3 vertLightDir;" "out vec3 vertLightRefl;" "out vec3 vertViewDir;" "out vec3 vertViewRefl;" "out vec3 vertColor;" "void main(void)" "{" " gl_Position = " " ModelMatrix *" " Position;" " vertLightDir = LightPosition - gl_Position.xyz;" " vertNormal = mat3(ModelMatrix)*Normal;" " vertLightRefl = reflect(" " -normalize(vertLightDir)," " normalize(vertNormal)" " );" " vertViewDir = (" " vec4(0.0, 0.0, 1.0, 1.0)*" " CameraMatrix" " ).xyz;" " vertViewRefl = reflect(" " -normalize(vertViewDir)," " normalize(vertNormal)" " );" " vertColor = vec3(0.3, 0.3, 0.7);" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " gl_Position;" "}" ); shape_vs.Compile(); shape_fs.Source( "#version 140\n" "uniform sampler2D PictTex, TileTex;" "uniform uint TileCount;" "in vec3 vertNormal;" "in vec3 vertLightDir;" "in vec3 vertLightRefl;" "in vec3 vertViewDir;" "in vec3 vertViewRefl;" "in vec3 vertColor;" "out vec4 fragColor;" "void main(void)" "{" " float LtDist = length(vertLightDir);" " float Diffuse = dot(" " normalize(vertNormal), " " normalize(vertLightDir)" " ) / LtDist;" " float Specular = dot(" " normalize(vertLightRefl)," " normalize(vertViewDir)" " );" " vec3 LightColor = vec3(1.0, 1.0, 1.0);" " vec2 ReflTexCoord = -vec2(" " vertViewRefl.x," " vertViewRefl.z " " );" " ReflTexCoord *= 0.25;" " ReflTexCoord += vec2(0.5, 0.5);" " float Pict = texture(PictTex, ReflTexCoord).r;" " float LightVsDark = mix( 0.1, 0.9, Pict);" " vec3 TileColor = mix(" " vec3(0.2, 0.2, 0.6)," " vec3(0.5, 0.5, 0.9)," " LightVsDark" " );" " vec3 PlasterColor = vec3(0.7, 0.7, 0.7);" " vec3 FloorColor = mix(" " PlasterColor, " " TileColor, " " texture(TileTex, ReflTexCoord*TileCount).b" " );" " vec3 ReflColor = mix(" " vec3(0.5, 0.5, 0.4), " " FloorColor, " " pow(max((-vertViewRefl.y-0.5)*2.0, 0.0), 2.0)" " );" " fragColor = vec4(" " vertColor * 0.4 + " " ReflColor * 0.3 + " " (LightColor + vertColor)*pow(max(2.5*Diffuse, 0.0), 3) + " " LightColor * pow(max(Specular, 0.0), 64), " " 1.0" " );" "}" ); shape_fs.Compile(); shape_prog.AttachShader(shape_vs); shape_prog.AttachShader(shape_fs); shape_prog.Link(); shape_prog.Use(); Uniform<Vec3f>(shape_prog, "LightPosition").Set(lightPos); Uniform<Mat4f>(shape_prog, "ModelMatrix").Set( ModelMatrixf::Translation(0.0f, 0.6f, 0.0f) ); UniformSampler(shape_prog, "PictTex").Set(0); UniformSampler(shape_prog, "TileTex").Set(1); Uniform<GLuint>(shape_prog, "TileCount").Set(tile_tex_side); n_per_vertex = make_shape.Positions(data); shape_verts.Data(data); DSAVertexArrayAttribEXT(shape, shape_prog, "Position") .Setup<GLfloat>(shape_verts, n_per_vertex) .Enable(); n_per_vertex = make_shape.Normals(data); shape_normals.Data(data); DSAVertexArrayAttribEXT(shape, shape_prog, "Normal") .Setup<GLfloat>(shape_normals, n_per_vertex) .Enable(); // gl.ClearColor(0.5f, 0.5f, 0.4f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); }
void CatmullRomCurveEvaluator::evaluateCurve(const std::vector<Point>& controlPoints, std::vector<Point>& evaluatedPoints, const float& animationLength, const bool& beWrap) const { evaluatedPoints.clear(); vector<Point> controlPointsCopy; if (beWrap) { Point start_p1 = Point((controlPoints.end() - 2)->x - animationLength, (controlPoints.end() - 2)->y); Point start_p2 = Point((controlPoints.end() - 1)->x - animationLength, (controlPoints.end() - 1)->y); Point end_p1 = Point((controlPoints.begin())->x + animationLength, (controlPoints.begin())->y); Point end_p2 = Point((controlPoints.begin() + 1)->x + animationLength, (controlPoints.begin() + 1)->y); controlPointsCopy.push_back(start_p1); controlPointsCopy.push_back(start_p2); controlPointsCopy.insert(controlPointsCopy.end(), controlPoints.begin(), controlPoints.end()); controlPointsCopy.push_back(end_p1); controlPointsCopy.push_back(end_p2); } else { controlPointsCopy.push_back(Point(0, controlPoints.front().y)); controlPointsCopy.insert(controlPointsCopy.end(), controlPoints.begin(), controlPoints.end()); controlPointsCopy.push_back(Point(animationLength, controlPoints.back().y)); } const Mat4d basis = Mat4d( -1, 3, -3, 1, 2, -5, 4, -1, -1, 0, 1, 0, 0, 2, 0, 0) / 2.0; for (size_t cnt = 0; cnt + 3 < controlPointsCopy.size(); ++cnt) { const Vec4d param_x(controlPointsCopy[cnt].x, controlPointsCopy[cnt + 1].x, controlPointsCopy[cnt + 2].x, controlPointsCopy[cnt + 3].x); const Vec4d param_y(controlPointsCopy[cnt].y, controlPointsCopy[cnt + 1].y, controlPointsCopy[cnt + 2].y, controlPointsCopy[cnt + 3].y); for (int i = 0; i < SEGMENT; ++i) { const double t = i / (double) SEGMENT; const Vec4d param_time(t*t*t, t*t, t, 1); Point eval_point(param_time * basis * param_x, param_time*basis*param_y); // avoid wave curve occurs if (evaluatedPoints.empty() || eval_point.x > evaluatedPoints.back().x) { evaluatedPoints.push_back(eval_point); } } } if (!beWrap) { // avoid slope interpolate at the end if (controlPoints.back().x > evaluatedPoints.back().x) { evaluatedPoints.push_back(controlPoints.back()); } evaluatedPoints.push_back(Point(0, controlPoints.front().y)); evaluatedPoints.push_back(Point(animationLength, controlPoints.back().y)); } }