Flash与3D编程探秘(八)- 3D物体着色基础知识

FLARE3D安装包详细指南:提升你的3D Flash体验 在计算机图形学领域,FLARE3D 是一颗冉冉升起的新星,它以其创新的技术和流畅的用户体验,迅速占据了3D应用市场的有利地位。FLARE3D 的起源可以追溯到2009年,当一群富有激情的开发者决心创造一个既快速又高效的3D内容创作工具。凭借对3D渲染技术的深入理解,他们打造了FLARE3D,旨在提供给设计师和开发者一个强大的平台,用以构建交互式3D内容。 阅读详情

前面的文章讨论了如何使用线绘制物体的框架,可是往往模拟现实中的3D物体并不是只有框架。比如一本书或者是一块玻璃,它们都是具有填充的物体。虽然在程序里能够(或者我应该说很是不实际)真正的给物体进行填充,但是可以通过给物体的表面着色这个方法,使物体看起来更加3D,而如何给物体表面着色将是后面两篇文章讨论的重点。在这一篇文章中,我将介绍一些关于着色的基本知识,其中涉及到一些向量数学运算,如果你已经有这些数学背景的话,那么这些对你来说非常容易。如果对你还是新课题的话,也不要放弃,只要你有一直读前面的文章,相信下面的内容对你来说应该不会困难。

先来看一个给物体着色的例子,运行动画你会看到一个透明的金字塔在舞台上旋转,虽然很简单,不过拿来热身非常合适。程序的框架和上一篇中的正方体的例子大致一样,所以我就只把需要改动代码的地方解释一下。



透明的金字塔

 

制作步骤
1. 完全可以Copy前面例子的代码来使用,首先需要把前面例子正方体的点的定义删除,然后把构造这个金字塔的5个3D空间点添加到数组中。
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> //  we calculate all the vertex
var len  =   50 ;                                                    //  half of the bottom face width
//  now create the vertexes for the cube
var points  =  [
                
//         x        y        z
                vertex3d( 0 ,     - len,      0 ),                  //  top
                
                vertex3d(
- len,    len,      - len),             //  rear lower left
                vertex3d(len,    len,      - len),             //  rear lower right
                vertex3d(len,    len,     len),              //  front lower right
                vertex3d( - len,    len,     len),            //  front lower left
            ];

 

2. 写一个绘制函数,功能是把所有参数点连接起来,并且对连接后的区域着色。

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> //  draw the face with args, the vertex of the facet
function draw_face(... args)
{
    with (scene.graphics)
    {
        lineStyle(.
5 ,  0x7DBFC6 ,  1 );
        beginFill(
0xB3DADD , . 3 );
        moveTo(args[
0 ].x, args[ 0 ].y);
        
for  (var i  =   1 ; i  <  args.length; i ++ )
        {
            lineTo(args[i].x, args[i].y);
        }
    }
}

 

3. 在更新物体的update函数中,把前面画正方体的代码去掉,然后添加如下代码。按照顺序画出底面,正面,反面和两个侧面。

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> scene.graphics.clear();
//  now we start drawing the cube
//  bottom face
draw_face(pro[ 1 ], pro[ 2 ], pro[ 3 ], pro[ 4 ]);
//  front face
draw_face(pro[ 0 ], pro[ 1 ], pro[ 2 ]);
//  back face
draw_face(pro[ 0 ], pro[ 2 ], pro[ 3 ]);
//  left face
draw_face(pro[ 0 ], pro[ 3 ], pro[ 4 ]);
//  right face
draw_face(pro[ 0 ], pro[ 4 ], pro[ 1 ]);
建议

你可以尝试制作一些更加复杂的模型来训练你的空间感,比如制作一个旋转的三角房子,或者是一颗钻石。



一颗简单的钻石,点击选择是否填充表面

注意

通过上面的例子,你一定会注意到,设置场景的代码,project_pts等函数这些代码是一成不变的,完全可以把它们写成类,使用的时候直接调用即可。

 

注意

由于物体是透明的,所以有时候你会产生错觉,物体变形了,其实是人的大脑把表面看错位置了。

 

不透明物体 
Looks pretty cool!不过不知道你有没有发现,上面的例子中物体的表面都是透明的,因此不管物体的背面背对摄像机或者面对摄像机,程序都给它着色,降低了我们的工作量,但是却增加了CPU的负荷。那么如果物体不是透明的怎么使用Flash绘制呢?先来分析一下一个不透明物体是如何出现在摄像机的镜头中的:当物体一个表面背对着摄像机的时候,这个表面是不可见的,当这个面面对摄像机的时候,它是可见的。虽然这些道理我们都知道,但是程序并不知道哪个可见哪个不可见,也不知道何时给表面着色。怎样让程序判断这个表面是不是可见呢?

 

背面筛选
判断一个物体的表面是否可见叫做背面筛选(Backface Culling),这不是一个新的课题,有很多的办法实现它。一种方法是利用空间中三个点的位置关系来判断,虽然我不提倡,不过这种方法相对来说好理解,适用于小规模程序。第二种方法是利用物体表面的法线与摄像机的视线夹角来判断,这种方法比较正统,也是后面主要讨论的。在这篇文章里,我主要讲述前两种,以便于对比找出一种适合你的方法。

注意

当然还有其他的一些方法和技巧,比如说把物体的每个表面都放在不同的层,每一次刷新画面的时候都对所有层进行排序,以达到目的,这种方法的好处在于你能够控制每一个表面,以便于做出鼠标或者键盘事件响应。

 

利用空间三个点的位置关系筛选
第一点要清楚的是,空间的三个不共线的点确定一个面,这也是为什么使用三个点而不是四个的原因。下面的动画演示的是一个表面的三个点,你可以尝试拖动它们看看什么情况下这个面不可见。


利用三个点的关系判断表面是否可见

 

这种算法核心就是比较两个边的斜率,例如对于B点来说,(拖动)测试它沿BA和BC发射的两条直线是否重合,当它们重合时(BC斜率超过BA斜率时),变化表面BCA的可见性。

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> (b.y - a.y) / (b.x - a.x)  <  (c.y - a.y) / (c.x - a.x)

 

不过有一个问题,当三角形BCA旋转时,也会造成两条直线的斜率大小变化,于是再加上下面的判断:
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> a.x  <=  b.x  ==  a.x  >  c.x

把上面两个结合起来便得到一个完整判断,你完全可以依赖这种方法计算背面筛选,虽然看起来很简单,但是我做很多测试,并没有发现问题。不过要注意在判断时使用的ABC点的顺序,如果顺时针不对的话,那么使用逆时针CBA 顺序通常会解决问题。请注意,由于这篇文章篇幅过长,如何使用这个算法执行背面筛选将在下一篇中介绍。
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> if  (Number((b.y - a.y) / (b.x - a.x)  <  (c.y - a.y) / (c.x - a.x))  ^  Number(a.x  <=  b.x  ==  a.x  >  c.x))
{
     
return   true ;
}
return   false ;

 

Bitwise XOR ^
下面是一个例子:
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> 1001   ==   1111   ^   0110

我的解释是,当二进制运算两个位相同时,产生1,否则产生0,需要注意的是,在程序里适当的使用XOR等二进制运算时,会提高你的程序的运行速度。

 

上面的方法虽然很不错,不过精益求精,我还是要给大家介绍一个比较正统的背面筛选的方法,利用表面法线与视线夹角判断是表面否可见。但是由于这个课题有一些数学要求,因此我将放在下篇文章介绍。

 

 

向量

当你步入3D图形编程时,会与向量经常打交道。因此在介绍表面法线与视线夹角判断背面筛选之前,我想给大家快速介绍一些关于向量计算的数学知识。我想毕竟很多读者还不了解这些数学知识(笔者的确很笨的说,经常会想象大家也一样,真是非常抱歉),如果你对向量运算,矩阵运算非常熟悉的话,那么这后面的内容你可以略过。(请注意这里公式都是程序书写方式,比如乘号是“*“,除号是“/“)

 

向量OA

 

1. 首先你要清楚什么是向量(矢量,vector),空间中的两个点A和B,那么A->B就是一个向量,可以读成从A到B,它既有大小又有方向。同理假 设原点是O,给定空间中任意一点C,OC是从O到C的向量,我们把这个向量记为V。设点V的坐标为[a, b, c](在文章中我将一直使用横板向量书写方式),那么使用下面的公式来表示从原点O到C的向量:

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> V  =  a * i  +  b * j  +  c * k

其中i,j和k表示向量V在x,y和z轴的单位向量(unit vector)。


2. 在解释单位向量(unit vector)之前,你需要知道如何计算向量的大小,设向量V = [a, b, c],那么向量的大小(magnitude)我们记作|V|,计算公式是:
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> | V |   =  mag  =  sqrt(a * a  +  b * b  +  c * c)

要注意的是,mag是一个标量(scalar),它只有大小,没有方向。举一个例子,求向量V = [3, 4, 0]的大小:
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> | V |   =  sqrt( 3 * 3   +   4 * 4   +   0 * 0 )  =   5

 

3. 一个向量可以和一个标量相乘,产生一个新的向量,并且它们乘法遵循交换规则。设V = [a, b, c],i是一个标量,那么它们相乘的公式是:

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> i V  =  [i * a, i * b, i * c]

同理,一个向量除以一个标量,产生一个新的向量:
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> V  /  i  =  [a / i, b / i, c / i]


4. 知道了向量的大小和上面的除法公式后,V的单位向量就容易解决了:

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> Vu  =  V / mag  =  [a / mag, b / mag, c / mag]

我的解释是,把向量V在x,y和z轴上的分量分别除以mag,就得到一个新的向量Vu,这个向量就是V的单位向量,这个过程叫做normalize。(你可以反向思维,把单位向量Vu乘以mag,就得到向量V)

刚才求向量大小时,点的参照是基于原点的,如果向量V是由点A = [a, b, c]到B = [x, y, z]时,向量V的大小也就是AB之间的距离,我们可以使用下面的公式求出它们的距离:
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> D  =  sqrt((a - x) * (a - x)  +  (b - y) * (b - y)  +  (c - z) * (c - z))

 

5. 两个向量可以进行加减运算(addition和substraction),设V = [a, b, c],U = [x, y, z],那么它的和与差分别是:

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> U  +  V  =  [a + x, b + y, c + z]
U 
-  V  =  [a - x, b - y, c - z]

如下图所示(左图),设从O到A的向量为U,从A到B的向量为V,那么向量U+V就是OB。再来看一个2D的图示(右图),设向量OA = [6, 2, 0],向量OC = [2, 5.2, 0],那么:
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> OB  =  OA  +  OC  =  [ 8 ,  7.2 ,  0 ]

 

             

 

     向量相加

能够看出,在OA与OC所确定的平面,以OA与OC为两个相邻边做一个平行四边形,对角线与OB重合。

 

6. 向量U和V的数量积(dot product,也称为标量积、点积、点乘或内积)数量积产生一个标量,运算公式如下:

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> U ・ V  =   | U |   | V |  cos(a)

 

 数量积

 

其中a是U和V在3D空间中的夹角。如果已知两个向量,使用数量积我们就可以通过计算求得两个向量的夹角。如果,两个向量都是单位向量的话,它们的数量积就是它们夹角的余弦值:

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> Uu ・ Vu  =  cos(a)

举个例子,设U = [30, 40, 0],V = [3, 4, 5],那么U和V的数量积是:
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> U ・ V  =   30 * 3   +   40 * 4   +   0 * 5   =   250

U和V的大小分别是:
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> | U |   =   50
| V |   =   7

那么得到:
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> cos (a)  =   0.7
a 
=   46

数量积满足以下的代数性质:
交换率:
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> U ・ V  =  V ・ U

加法的分配率:
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> U ・ (V  +  P)  =  U ・ V  +  U ・ P

7. U和V的向量积(cross product,也称矢量积、叉积或者外积)产生一个向量,这个向量垂直于U和V,它的计算公式是:
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> U × V  =  n  | U |   | V |  sin(a)

 

 向量积

 

其中n为垂直于U和V的单位向量,a是U和V的夹角。向量积计算满足以下代数性质:

反交换率:
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> U × V  =   -  (V × U)

加法的分配率:
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> U × (V  +  P)  =  U × V  +  U × P

与标量乘法相容:
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> s (U × V)  =  sU × V  =  U × sV

给定空间两个向量U = [a, b, c],V = [x, y, z],那么U和V的向量积是:
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> U × V  =  [b * z  -  z * b, c * x  -  x * c, a * y  -  y * a]

OK,这些就是关于向量的基本知识,是不是有点太多了,没关系,你完全不必记住所有的公式,只要你在使用时知道为什么使用这个公式就可以了。关于向量和矩阵的运算这里就不再列举,如果在后面文章用到的话,我会详细介绍。

 

 

补充一些名词解释
法线(normal)的定义,三维平面上的法线是一条垂直于该平面的一个三维向量,法线可以通过平面上两条不平性的向量的向量积求得。

摄像机的视线是从摄像机的镜头到该平面某个点的向量,这里你可以理解为一束向量。

 

 

在程序里使用向量

下面试着使用前面所讲述的内容,把向量这个概念加入到程序里,为下面的学习做好基础。下面这个例子,来制作一个3D的平面,并且让它旋转。在这个程序并没有用到向量的运算,只不过我想让你把程序里所有与向量有关的Object都转换成Vector,这样你就能快速的明白使用Vector得必要性。基本的框架还是和前面的例子一样,完全可以Copy本文中第一个例子的源代码,我只把需要更改的地方解释一下。



引入向量概念


制作步骤(部分)

1. 首先要写一个向量类,把它命名为Vector.as,并且把它添加到工程里。我写了一个向量类,可以在附件中下载。你完全可以Copy使用,但是还是希望你能够明白每一个函数表达的意思。注意copy函数是一个复制函数,剩下的函数就麻烦你和上面的向量运算数学知识一一对照了。

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> /*  Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above notice and this permission notice shall be included in all copies
 * or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 * This class can be used only if you keep this claim intact
 * Zhou Yang 2008.11 yangzhou1030@gmail.com

 
*/
package
{
//  vector class
public  dynamic final  class  Vector
{
    
public  var x:Number;
    
public  var y:Number;
    
public  var z:Number;
    
//  constructor
    function Vector(x_3d  =   0.0 , y_3d  =   0.0 , z_3d  =   0.0 )
    {
        x 
=  x_3d;
        y 
=  y_3d;
        z 
=  z_3d;
    }
    
//  copy the x y z value from another vector
    
//  return false if parameter is not type of vector
     public  function copy(vector)                 //  return boolean
    {
        
if  (vector  is  Vector)
        {
            x 
=  vector.x;
            y 
=  vector.y;
            z 
=  vector.z;
            
return   1 ;
        }
        
return   0 ;
    }
    
//  vector addition
     public  function add(a)                         //  return vector
    {
        var v 
=   new  Vector();
        v.x 
=  x  +  a.x;
        v.y 
=  y  +  a.y;
        v.z 
=  z  +  a.z;
        
return  v;
    }
    
//  vector substraction
     public  function substract(a)                 //  return vector
    {
        var v 
=   new  Vector();
        v.x 
=  x  -  a.x;
        v.y 
=  y  -  a.y;
        v.z 
=  z  -  a.z;
        
return  v;
    }
    
//  multiply vector by a scalar
     public  function multiply(scalar)             //  return vector
    {
        var v 
=   new  Vector();
        v.x 
=  x * scalar;
        v.y 
=  y * scalar;
        v.z 
=  z * scalar;
        
return  v;
    }
    
//  devide vector by a scalar
     public  function devide(scalar)                 //  return vector
    {
        var v 
=   new  Vector();
        v.x 
=  x / scalar;
        v.y 
=  y / scalar;
        v.z 
=  z / scalar;
        
return  v;
    }
    
//  vector dot product of v
     public  function dot(v)                         //  return scalar
    {
        
return  x * v.x  +  y * v.y  +  z * v.z;
    }
    
//  cross product
     public  function cross(a)                     //  return vector
    {
        var v 
=   new  Vector();
        v.x 
=  y * a.z  -  z * a.y;
        v.y 
=  z * a.x  -  x * a.z;
        v.z 
=  x * a.y  -  y * a.x;
        
return  v;
    }
    
//  distance from this to vector a
     public  function distance(a)                     //  return scalar
    {
        var dx 
=  x  -  a.x;
        var dy 
=  y  -  a.y;
        var dz 
=  z  -  a.z;
        
return  Math.sqrt(dx * dx  +  dy * dy  +  dz * dz);
    }
    
//  vector magnitude
     public  function mag()                         //  return scalar
    {
        
return  Math.sqrt(x * x + y * y + z * z);
    }
    
//  return normal vector
     public  function normal()                     //  return vector
    {
        var v 
=   new  Vector();        
        var mag 
=   this .mag();
        
        
if  (mag  ==   0 )
            
return   0 ;

        v.x 
=  x / mag;
        v.y 
=  y / mag;
        v.z 
=  z / mag;
        
        
return  v;
    }
    
//  normalize vector this
    
//  return false if magnitude is 0
     public  function normalize()
    {
        var mag 
=   this .mag();
        
if  (mag  ==   0 )
            
return   0 ;

        x 
/=  mag;
        y 
/=  mag;
        z 
/=  mag;
        
        
return   1 ;
    }
}
}

 

2. 把场景的原点定义为一个向量:

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> var origin  =   new  Vector(stage.stageWidth / 2 , stage.stageHeight / 2 - 30 ,  0 );
//  create a scene to hold the polygon
var scene  =   new  Sprite();
scene.x 
=  origin.x;
scene.y 
=  origin.y;
this .addChild(scene);

 

3. 把摄像机所在的点和平面的旋转角度各定义为一个向量:

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> var camera  =   new  Vector( 0 ,  0 ,  60 );
//  this is the rotation of the polygon in 3d space
var axis_rotation  =   new  Vector();         //  default constructor init x y z to 0

 

4. 然后删除前面金字塔的顶点的定义,添加如下的代码,主要目的是定义空间中的四个点,当然这四个点在一个平面上,因为它们的z值都是0。

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> var vertexes  =  [
               
new  Vector( - 60 ,  - 60 ,  0 ),
               
new  Vector( 60 ,  - 60 ,  0 ),
               
new  Vector( 60 ,  60 ,  0 ),
               
new  Vector( - 60 ,  60 ,  0 )
               ];

 

5. 修改刷新画面的函数update,使用project函数把四个点映射到2D平面上,然后绘制两个组成四边形的三角形(绘制两个三角形是想让你明白,所有的物体表面都可以用三角形来绘制)。

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--> with (polygon.graphics)
{
    clear();
    lineStyle(.
5 ,  0x000000 ,  0 );                        //  clear out what was previously drawn
    beginFill( 0x6A83A6 ,  1 );                             //  draw red triangle
    draw_face(pro[ 0 ], pro[ 1 ], pro[ 2 ]);             //  notice the drawing order me used
    endFill();
    beginFill(
0xBD5E53 ,  1 );
    draw_face(pro[
3 ], pro[ 2 ], pro[ 0 ]);
    endFill();
}

 

感谢你能够读到这里,写了这些,肯定会有疏忽和遗漏的地方,如果你有什么不明白的话,可以和我联系。另外,我相信基本的向量运算应该已经难不住你了,剩下的就是如何在程序里运用这些数学知识对背面筛选,将在下一篇文章中介绍。So keep it up!


上一篇         目录          下一篇

非常抱歉,文中暂时不提供源文件下载,如果你需要源文件,请来信或者留言给我。笔者利用工作之余写这些文章,付出了很多汗水,希望读者和转载者能够尊重作者的劳动。

作者:Yang Zhou
出处:http://yangzhou1030.cnblogs.com
本文版权归作者和博客园共有,未经作者同意禁止转载,作者保留追究法律责任的权利。请在文章页面明显位置给出原文连接,作者保留追究法律责任的权利。
AI一键生成带货短视频:电商直播的未来 随着电子商务行业的快速发展,直播带货已成为一种极为有效的营销手段。然而,传统的人工直播方式存在诸多局限性,如人力成本高、主播培训周期长等问题。为了解决这些挑战,一种基于AI技术的一键生成带货视频解决方案应运而生——这就是“Anchor Crafter”。这项创新技术不仅能够自动创建高质量的带货视频,而且还能实现人物与商品之间的自然交互,极大地提升了用户体验。 阅读详情

相关推荐

intel-VROC raid卡驱动 centos7.9

u盘进入系统,按e,在出现下面在quiet前面输入inst.dd initcall_blacklist=vmd_drv_init 后按Ctrl和x,开始引导。进入系统,按e,在出现下面在quiet前面输入inst.dd inicll_blacklist=vmd_drv_init 后按Ctrl和x,开始引导。驱动完成后,在输入 c 回车, 引导过程开始,进入安装界面。输入1 ,选择这个ISO驱动文件里的rpm包。输入1 ,选择这个ISO驱动文件里的rpm包。vi编辑 /etc/default/grub。

dacming的博客 4546

3D渲染引擎着色方式的演化史

Forward rendering 最初始的渲染方式,原理是以mesh为单位进行渲染,在光栅化后,对每个PS进行计算时,根据光照进行着色计算,所以这种方式称为前向着色。弊端:1、如果像素被其他像素遮蔽了,就浪费了宝贵的处理结果;2、光源多起来后管理很麻烦,Shader也不好写。这样,Deferred rendering就应运而生了。 Deferred renderi

Crazy Engine的博客 2409

【Latex】【附安装文件】Miktex和TexStudio的安装与配置

这代表“构建并运行”,一般来说,我们只需要点这个按钮来运行Latex代码。保存一下代码文件,再运行一次,PDF文件会出现在与代码文件相同的文件夹下。安装完成后,你可能会跳转到一个页面中,你看到这个页面就意味着安装成功了。其实不需要你敲,你只要将下面的代码复制粘贴到你刚刚的文件中即可。成功安装MikTex后,我们需要进行更新,减少后续使用的麻烦。如果懂得将安装路径设置在你想要的盘中,你可以自己设置。双击上文的.exe文件后,你会看到如下画面。如果不懂,为避免不必要的麻烦,请直接点击“

未来就在脚下。 1万+

【笔记】unity渲染类名词术语概念总结(30个点)

1.线性追踪 亮度值是一个空间函数,而光线追踪做的事情其实是求这个函数在视线线段上的线积分 结果为:光线在视线方向上作用值之和 视线上的所有采样点的亮度之和能用来表示光线在介质中散射的效果 2.光线的衰减 简单的公式:i = l/d^2 [采样点的亮度值 = 光强度/(采样点-光源点)^2] 3.等式 d^2 = dot(d,d); 4.散射 公式:HG公式。就是输入指定方向和光线入射方向夹角的cos值,求出指定方向散射光线的亮度。 我们要计算的是朝着眼睛方向的散射光线亮度。 g:介质散射性质(值越.

折戟 4212

单片机如何获得5V电源

在单片机实际设计中,有时会需要在电路中用到5V电压源,那么这个常见的实验需求有哪些办法解决呢,我综合网上的资料,概括一下: 1)USB    这种方法在我们直接将单片机板与电脑连接调试的时候,算是简单又方便的办法了,但如果我所要得到的成品不直接连接外部的器件,这就得舍弃。     常用的,USB/5V插头线,这是一种专门的电源线,一端是USB通用接口,可以直插USB端口,另一端是内正外负电压

Echo_Ana的博客 3万+

Python3 ACM模式输入输出全攻略:从牛客网到华为机试的实战技巧

本文详细解析了Python3在ACM模式下的输入输出处理技巧,针对牛客网、华为机试等在线评测系统。文章从input()函数本质出发,总结了六种高频输入模式的处理模板,并提供了链表、二叉树等数据结构的I/O实战方案,最后给出性能优化与常见避坑指南,帮助开发者高效应对算法笔试。

zero1的博客 1000

D3D中的颜色和着色

颜色表示法在Direct3D中,颜色是使用RGB三部分来描述的。也就是说,我们要分别指定红、绿和蓝三种颜色的值。混合这三个颜色决定最终的颜色。利用这三种颜色我们能够表现数万种颜色。我们使用两种不同的结构来存储RGB数据。这第一种是D3DCOLOR,它实际上是一个DWORD类型即32位。在D3DCOLOR类型中的这些位按照8-bit被分为4个部分,每一部分存储的是该色的亮度值。如图4.1所示

gogoda的专栏 3888

Hermes Agent 彩蛋大盘点:藏在终端里的浪漫

本文主要介绍了Hermes Agent 彩蛋大盘点:藏在终端里的浪漫,希望能对使用Hermes Agent的同学们有所帮助。 文章目录 1. 前言 2. Spinner 动画 3. Kawaii 表情 4. 思考动词 THINKING_VERBS 5. 皮肤主题 6. 启动 Banner 7. 工具 Emoji 8. 内置人格 9. SOUL.md —— Agent 的灵魂 10. BOOT.md —— 启动自动执行 11. 随机 Tips 12. 统计总览

weixin_43178406的博客 7万+

android学习笔记之3D---多边形着色(颜色)

     上次学习了绘制2D多边形,我们可以使用OpenGL通过顶点数据绘制出一些图形,但是可以看出我们绘制的图形都是单色的,可想而知我们没有对图形进行着色。     对图形着色有两种方式:1. 光滑着色   2. 平面着色。  平滑着色:     我们对上一个实例中的三角形进行平滑着色,是将三角形的三个顶点的不同颜色混合在一起,就是色彩的混色。     首先为三角形的每个顶点设置一个颜色,和定义三角形数组相似。不同的是,颜色值有(r,g,b,a)      r:red     g:green     b:

GEOLO的专栏 3709

SCI一区论文投稿终极技巧:Expert Systems With Applications;Knowledge-Based Systems

投稿计算机1区论文(如KBS、ESWA)的核心技巧包括:1)关键词选择需平衡范围与相关性,避免过细或过泛;2)研究内容聚焦单一核心创新点,避免内容分散;3)必须设计消融实验量化创新点的贡献;4)公开实验代码和数据集,确保可验证性;5)合理使用AI工具仅辅助写作,核心内容需自主完成;6)实验数据必须真实可靠。特别强调1区期刊对创新性和实验严谨性的高要求,需避免常见拒稿原因如内容分散、缺乏验证等。这些策略可提高投稿成功率,但前提是研究本身具有实质性创新。

ZhangJiqun&191cm&85kg 1161

AutoSAR系列讲解(入门篇)2.4-Runnables可运行实体

讲解一下Runnable和其工程的实际映射

雪云飞星的博客 3万+

Flash Stage3D 学习笔记(一)

本文参考来源: http://www.adobe.com/devnet/flashplayer/articles/how-stage3d-works.html http://www.ashan.org/post-267.html http://www.pixelbender.cn/?p=381   1.Stage3D简介 Stage3D是Adobe为了提高的Flash 3D应用程序渲染

myquark的专栏 2689

[QMT量化交易小白入门]-七十九、增加标的后,五年回测收益率达到了2493%

本专栏主要是介绍QMT的基础用法,常见函数,写策略的方法,也会分享一些量化交易的思路,大概会写100篇左右。QMT的相关资料较少,在使用过程中不断的摸索,遇到了一些问题,记录下来和大家一起沟通,共同进步。

木头大左的博客 1580

Flash与3D编程探秘 - 文章目录

日期:2008年10月 介绍 对学习Flash CS3和Actionscript 3.0中的3D编程感兴趣?You come to the right place!在文章中,我将陆续的介绍在Flash中使用Actionsript进行3D编程一些理论和实例。这是一篇初级到中级难度的学习资料,如果你具有一些基本的数学和几何知识,那对你来说不会太难。请注意:这并不是针对Flash C...

weixin_30838921的博客 130

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Flash 3D引擎Away3D完全指南:从零搭建你的第一个3D世界(入门必读)

Away3D 是一款免费开源的 Flash 3D 引擎,专为 Flash Player 11 的 Stage3D 硬件加速接口打造,让你在浏览器中就能构建真实的三维场景。本指南面向零基础新手,带你认识 Away3D Flash 3D 引擎的核心概念,并用不到 20 行代码搭建出你的第一个 3D 世界,最后附上功能地图与常见坑位提示,是入门必读的完整教程。 ## 一、认识 Away3D:免费开源的

gitblog_00003的博客 701

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Molehill 3D APIs - GPU硬件加速的Flash 3D API

Flash 3D API - Molehill亮相MAX:http://labs.adobe.com/technologies/flash /molehill/ 原文:http://jamesli.cn/blog/?p=371 “Molehill” 是即将在Adobe ® Flash® 平台出现的支持显卡加速的3D底层API。这组底层API会让3D开发 者 利用GPU性能得到惊人的效率提升。这是什么概念呢? 今天, Adobe Flash Player 10.1可以在大约30Hz下渲染几

wkyb608的专栏 947

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

如何快速上手Away3D:Flash Player 11的3D开发环境与快速开始教程

**Away3D** 是一款面向 Flash Player 11 的经典 3D 引擎,使用 ActionScript 3 开发,基于 Stage3D(AGAL/AGALM)硬件加速渲染,为 Flash 开发者提供了完整的 3D 开发环境:场景图、几何体、材质光照、模型解析、骨骼动画、粒子系统与立体渲染。本篇是一份快速开始教程,带你从环境搭建到第一个 3D 场景,几分钟内跑通 Away3D 核心功能

gitblog_00695的博客 385

Flash Stage3D 学习笔记(二)

本文参考来源: http://www.adobe.com/devnet/flashplayer/articles/hello-triangle.html http://www.adobe.com/devnet/flashplayer/articles/what-is-agal.html http://www.adobe.com/devnet/flashplayer/articles/

myquark的专栏 2731

flash3D开发基础------- Stage3D 的工作原理(转)

要求 必备知识 建议使用Flash Professional来构建应用程序的一个基本的了解。 以往的经验ActionScript 3的开发也是必需的。 用户级别 中级 必需产品 Flash Builder 4.5 Premium (下载试用版)Flash Professional CS5.5 (下载试用版) 在如何使用Stage3D系列中的第一个教程中,你

netinnet的专栏 4510

如何渲染3D立体画面:Away3D红蓝3D立体渲染完全指南

Away3D 是一款面向 Flash Player 11 的开源 3D 渲染引擎,其 [src/away3d/stereo/](https://link.gitcode.com/i/8b6fdb34e15243af9c734b076187299b) 立体渲染模块可以让你用几行代码,在普通屏幕上呈现红蓝 3D(Anaglyph)或隔行 3D 效果——戴上红蓝眼镜,屏幕里的 3D 场景立刻"跳"出平面

gitblog_01105的博客 213

flash3D开发基础------- 顶点和片段着色器2(转)

要求 必备知识 最好对 Stage3D API 有基本的了解。最好拥有使用 VertexBuffer 的经验。在完成本教程之前,一定要阅读这个关于 Stage3D 的系列的上一篇教程(Stage3D 的工作原理)。 用户级别 中级 必需产品 Flash Builder 4.5 Premium (下载试用版)Flash Professional CS5.5 (下载

go含羞草 309

Flash Stage3D Molehill 学习笔记(1)

  Adobe的Stage3D技术已经出来很长时间了。一直忙于工作零零散散的学习了一些,最近在工作中也遇到了不少Stage3D的技术问。所以决定从今天起系统化的学习Stage3D. 在学习Stage3D技术前首先需要了解下“常见的3D显像术语”与“常见的3D编码术语”。 常见的3D显像术语: 网格(Mesh)   3D世界中的模型被称做网格。这些网格使用 3DMAX、Maya 或者其他3...

weixin_33941350的博客 146

Molehill 初识--flash 3d 开发基础

Molehill的基本架构 如何使用Molehill底层API在舞台上绘制一个三角形: 在舞台上初始化一个3D环境创建顶点和片段使用着色器处理顶点与片段调用显卡并显示结果 Molehill 底层API中最重要的一个就是Context3D,它是一个三维空间的处理环境,负责创建并处理三维对象的各个要素比如顶点、片段、透视等等,并将处理的结果使用AGAL(Adobe Graphics

lake1314的专栏 1109

Molehill 3D APIs - Flash 3D API

Flash 3D API - Molehill亮相MAX:http://labs.adobe.com/technologies/flash/molehill/ 我的同事Thibault Imbert来介绍这个大家期待已久的Flash 3D API – Molehill “Molehill” 是即将在Adobe® Flash® 平台出现的支持显卡加速的3D底层API。这组底层API会让3D开发者...

weixin_30650039的博客 181
上一篇: Flash与3D编程探秘(七)- 3D物体框架
下一篇: 欢迎大家一起as3.0 or flex 研究
coding_most
博客等级 码龄15年 13粉丝 38原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值