• Delete geometry outside camera view throughout timeline


    这幅图可以清楚的看到摄像机运动的轨迹,并且产生优美的能量图

    一:非sopsolver法

    经常遇到做特效只想留摄像机看到的部分,但是摄像机一直会运动。一般做法就是用sopsolver来记录摄像机运动看到的区域,删除看不到的区域。

    但是还有一种方法直接从原理入手。

    1,先记录摄像机的worldtransform在每一个帧上。此时成为了一个python的列表

    2,记录的camera matrix list应该放入点属性,刚好创建你摄像机key动画的范围点数。摄像机运动100帧,就把这100帧的camera matrices记录到每个点上。每个点带一个4*4 矩阵。

    3,开始用for循环获取这些记录点的矩阵。

    4,在你的要剔除几何体开始操作,用for循环首先获取每一个点矩阵数据,然后当前几何体的位置转换到摄像机空间。最后转到NDC空间。

    初始化:accum 变量

    for循环{

      4,NDC space应该先将point position转换到摄像机空间,此时已经可以用这个转换后空间来留下摄像机区域。但是这个不太灵活,数据太大。

      5,接着转换到摄像机空间,然后再做pespective projection矩阵。

      6,做透视除法。转换到ndc space。

      7,用ndc space

      8,满足ndc剔除条件

      accum+=1

      or: accum+=0

    }

    9,accum/= 记录了多少帧。

    10,根据accum来删除几何体操作。

     

    python的代码主要获取摄像机所有运动的矩阵,并且 放到 一个点数 刚好等于摄像机运动了多少帧的几何体上

    node = hou.pwd()
    geo = node.geometry()
    
    # Add code to modify contents of geo.
    # Use drop down menu to select examples.
    
    frameStart = node.parm("start").eval()
    frameEnd = node.parm("end").eval()
    fps = 24.0
    
    # add detail attribute to save our frame range that is camera key range
    geo.addAttrib(hou.attribType.Global, "startFrame", frameStart)
    geo.addAttrib(hou.attribType.Global, "endFrame", frameEnd)
    
    # get camera node:
    camNode = hou.node("/obj/cam1")
    
    matrix_list = []      # this is our camera matrix here
    for frame in range(frameStart,frameEnd+1,1):
        time = float(frame)/ fps 
        camWorldMatrix = camNode.worldTransformAtTime(time).inverted()  # get camera at time!
        camWorldMatrix = camWorldMatrix.asTuple()
        matrix_list.append(camWorldMatrix)
    
    # add a array attrib in every point, our point is our frame
    geo.addArrayAttrib(hou.attribType.Point, "mats", hou.attribData.Float, 1)
    
    for it in geo.iterPoints():
        ptnum = it.number()  # get point number , start with 0
        it.setAttribValue("mats", matrix_list[ptnum])

    attrib_to_hitour_accumulate节点就创建个accum属性:

    f@accum = 0;

    range_delete节点执行剔除:

    // accum the frame range
    
    int sf = detail(1, "startFrame");
    int ef = detail(1, "endFrame");
    int npts = npoints(1);
    // range loop our points , cal the weight of there camera matrices!
    for(int i=0; i< npts ; i++)
    {
        float mat[];
        mat = point(1,"mats", i);
        matrix mat44 = set(mat); 
        vector camP = @P * mat44;
        camP = normalize(camP);
        
        int condition1 = camP.x < -0.5 || camP.x > 0.5;
        int condition2 = camP.y < -0.4 || camP.y > 0.3;
        int condition3 = camP.z > 0;
        
        int condition = condition1 || condition2 || condition3  ;
        if(condition ) {
            @accum += 0;
        }
        else{
            @accum += 1;
        }
    }
    
    @accum = @accum / npts;
    @Cd = @accum;
    if(@accum <= 0) 
    {
        removepoint(geoself(),@ptnum);
    }

    事实上你可以看到我为了简单起见,上面的条件只是用的摄像机空间的位置(normalized),并没有要做ndc。

    正常应该按照我上面要转换ndc,再来剔除好点:

     

     snippt代码:

    float focal = 50;
    float aperture = 35.9999;
    float zoom = focal / aperture;
    float image_aspect = 1280.0 / 720.0f;
    float near = 1.0f;
    float far = 10000.0f;
    matrix proj = perspective(zoom,image_aspect,1, near,far) ;
    mat = proj;

    二:简单剔除法,以下可以使用sopsolver来做:

    houdini也提供了一个直接转换ndc的节点:toNDC(camera, P)但是这个没办法在我们这里面用,因为必须手动实现透视除法:如下。如果你不想直接算出来摄像机区域的话:

    v@uv = toNDC("/obj/cam1",@P);
    
    if(@uv[0] < -0.1 || @uv[0] > 1.2)
    {
        removepoint(geoself(),@ptnum);
    }
    
    if(@uv[1] < -0.1 || @uv[1] > 1.2)
    {
        removepoint(geoself(),@ptnum);
    }

    不直接算出来区域,当然也可以用投射这个方法:

     

    if(@uv[0] < -0.1 || @uv[0] > 1.2)
    {
        removepoint(geoself(),@ptnum);
    }
    
    if(@uv[1] < -0.1 || @uv[1] > 1.2)
    {
        removepoint(geoself(),@ptnum);
    }
    
    if(@uv[2] < 0.3 )
    {
        removepoint(geoself(),@ptnum);
    }

    还有一种简单的方法用vdb生成体积,拿体积判断删除。

  • 相关阅读:
    云通信
    PullToRefreshGridView上拉刷新,下拉加载
    数据库开源框架GreenDao的使用解析
    RxJava2.0的使用详解
    ButterKnife的使用详解
    Jquery设置完颜色后hover不生效的解决办法
    jquery使用css函数设置背景色无效解决办法
    SpringBoot如何返回页面
    如何创建一个SpringBoot多模块项目
    连接mysql报错java.sql.SQLException: The server time zone value '�й���׼ʱ��' is unrecognized...解决方法
  • 原文地址:https://www.cnblogs.com/gearslogy/p/13154193.html
Copyright © 2020-2023  润新知