barriers / 阅读 / 详情

Unity Shader-渲染队列,ZTest,ZWrite,Early-Z(转)

2023-07-25 12:05:04
共1条回复
慧慧
* 回复内容中包含的链接未经审核,可能存在风险,暂不予完整展示!

简介

在渲染阶段,引擎所做的工作是把所有场景中的对象按照一定的策略(顺序)进行渲染。最早的是画家算法,顾名思义,就是像画家画画一样,先画后面的物体,如果前面还有物体,那么就用前面的物体把物体覆盖掉,不过这种方式由于排序是针对物体来排序的,而物体之间也可能有重叠,所以效果并不好。所以目前更加常用的方式是z-buffer算法,类似颜色缓冲区缓冲颜色,z-buffer中存储的是当前的深度信息,对于每个像素存储一个深度值,这样,我们屏幕上显示的每个像素点都会进行深度排序,就可以保证绘制的遮挡关系是正确的。而控制z-buffer就是通过ZTest,和ZWrite来进行。但是有时候需要更加精准的控制不同类型的对象的渲染顺序,所以就有了渲染队列。今天就来学习一下渲染队列,ZTest,ZWrite的基本使用以及分析一下Unity为了Early-Z所做的一些优化。

Unity中的几种渲染队列

首先看一下Unity中的几种内置的渲染队列,按照渲染顺序,从先到后进行排序,队列数越小的,越先渲染,队列数越大的,越后渲染。

Unity中设置渲染队列也很简单,我们不需要手动创建,也不需要写任何脚本,只需要在shader中增加一个Tag就可以了,当然,如果不加,那么就是默认的渲染队列Geometry。比如我们需要我们的物体在Transparent这个渲染队列中进行渲染的话,就可以这样写:

我们可以直接在shader的Inspector面板上看到shader的渲染队列:

另外,我们在写shader的时候还经常有个Tag叫RenderType,不过这个没有Render Queue那么常用,这里顺便记录一下:

Opaque : 用于大多数着色器(法线着色器、自发光着色器、反射着色器以及地形的着色器)。

Transparent :用于半透明着色器(透明着色器、粒子着色器、字体着色器、地形额外通道的着色器)。

TransparentCutout : 蒙皮透明着色器(Transparent Cutout,两个通道的植被着色器)。

Background : 天空盒着色器。

Overlay : GUITexture,镜头光晕,屏幕闪光等效果使用的着色器。

TreeOpaque : 地形引擎中的树皮。

TreeTransparentCutout : 地形引擎中的树叶。

TreeBillboard : 地形引擎中的广告牌树。

Grass : 地形引擎中的草。

GrassBillboard : 地形引擎何中的广告牌草。

相同渲染队列中不透明物体的渲染顺序

拿出Unity,创建三个立方体,都使用默认的bump diffuse shader(渲染队列相同),分别给三个不同的材质(相同材质的小顶点数的物体引擎会动态合批),用Unity5带的Frame Debug工具查看一下Draw Call。(Unity5真是好用得多了,如果用4的话,还得用NSight之类的抓帧)

可以看出,Unity中对于不透明的物体,是采用了从前到后的渲染顺序进行渲染的,这样,不透明物体在进行完vertex阶段,进行Z Test,然后就可以得到该物体最终是否在屏幕上可见了,如果前面渲染完的物体已经写好了深度,深度测试失败,那么后面渲染的物体就直接不会再去进行fragment阶段。(不过这里需要把三个物体之间的距离稍微拉开一些,本人在测试时发现,如果距离特别近,就会出现渲染次序比较乱的情况,因为我们不知道Unity内部具体排序时是按照什么标准来判定的哪个物体离摄像机更近,这里我也就不妄加猜测了)

相同渲染队列中半透明物体的渲染顺序

透明物体的渲染一直是图形学方面比较蛋疼的地方,对于透明物体的渲染,就不能像渲染不透明物体那样多快好省了,因为透明物体不会写深度,也就是说透明物体之间的穿插关系是没有办法判断的,所以半透明的物体在渲染的时候一般都是采用从后向前的方法进行渲染,由于透明物体多了,透明物体不写深度,那么透明物体之间就没有所谓的可以通过深度测试来剔除的优化,每个透明物体都会走像素阶段的渲染,会造成大量的Over Draw。这也就是粒子特效特别耗费性能的原因。

我们实验一下Unity中渲染半透明物体的顺序,还是上面的三个立方体,我们把材质的shader统一换成粒子最常用的Particle/Additive类型的shader,再用Frame Debug工具查看一下渲染的顺序:

半透明的物体渲染的顺序是从后到前,不过由于半透相关的内容比较复杂,就先不在这篇文章中说了,打算另起一篇。

自定义渲染队列

Unity支持我们自定义渲染队列,比如我们需要保证某种类型的对象需要在其他类型的对象渲染之后再渲染,就可以通过自定义渲染队列进行渲染。而且超级方便,我们只需要在写shader的时候修改一下渲染队列中的Tag即可。比如我们希望我们的物体要在所有默认的不透明物体渲染完之后渲染,那么我们就可以使用Tag{“Queue” = “Geometry+1”}就可以让使用了这个shader的物体在这个队列中进行渲染。

还是上面的三个立方体,这次我们分别给三个不同的shader,并且渲染队列不同,通过上面的实验我们知道,默认情况下,不透明物体都是在Geometry这个队列中进行渲染的,那么不透明的三个物体就会按照cube1,cube2,cube3进行渲染。这次我们希望将渲染的顺序反过来,那么我们就可以让cube1的渲染队列最大,cube3的渲染队列最小。贴出其中一个的shader:

其他的两个shader类似,只是渲染队列和输出颜色不同。

通过渲染队列,我们就可以自由地控制使用该shader的物体在什么时机渲染。比如某个不透明物体的像素阶段操作较费,我们就可以控制它的渲染队列,让其渲染更靠后,这样可以通过其他不透明物体写入的深度剔除该物体所占的一些像素。

PS:这里貌似发现了个问题,我们在修改shader的时候一般不需要什么其他操作就可以直接看到修改后的变化,但是本人改完渲染队列后,有时候会出现从shader的文件上能看到渲染队列的变化,但是从渲染结果以及Frame Debug工具中并没有看到渲染结果的变化,重启Unity也没有起到作用,直到我把shader重新赋给材质之后,变化才起了效果...(猜测是个bug,因为看到网上还有和我一样的倒霉蛋被这个坑了,本人的版本是5.3.2,害我差点怀疑昨天是不是喝了,刚实验完的结果就完全不对了...)

**ZTest(深度测试)和ZWrite(深度写入) **

上一个例子中,虽然渲染的顺序反了过来,但是物体之间的遮挡关系仍然是正确的,这就是z-buffer的功劳,不论我们的渲染顺序怎样,遮挡关系仍然能够保持正确。而我们对z-buffer的调用就是通过ZTest和ZWrite来实现的。

首先看一下ZTest,ZTest即深度测试,所谓测试,就是针对当前对象在屏幕上(更准确的说是frame buffer)对应的像素点,将对象自身的深度值与当前该像素点缓存的深度值进行比较,如果通过了,本对象在该像素点才会将颜色写入颜色缓冲区,否则否则不会写入颜色缓冲。ZTest提供的状态较多。 ZTest Less(深度小于当前缓存则通过, ZTest Greater(深度大于当前缓存则通过),ZTest LEqual(深度小于等于当前缓存则通过),ZTest GEqual(深度大于等于当前缓存则通过),ZTest Equal(深度等于当前缓存则通过),ZTest NotEqual(深度不等于当前缓存则通过),ZTest Always(不论如何都通过)。注意,ZTest Off等同于ZTest Always,关闭深度测试等于完全通过。

下面再看一下ZWrite,ZWrite比较简单,只有两种状态, ZWrite On(开启深度写入)和ZWrite Off(关闭深度写入) 。当我们开启深度写入的时候,物体被渲染时针对物体在屏幕(更准确地说是frame buffer)上每个像素的深度都写入到深度缓冲区;反之,如果是ZWrite Off,那么物体的深度就不会写入深度缓冲区。但是,物体是否会写入深度,除了ZWrite这个状态之外,更重要的是需要深度测试通过,也就是ZTest通过,如果ZTest都没通过,那么也就不会写入深度了。就好比默认的渲染状态是ZWrite On和ZTest LEqual,如果当前深度测试失败,说明这个像素对应的位置,已经有一个更靠前的东西占坑了,即使写入了,也没有原来的更靠前,那么也就没有必要再去写入深度了。所以上面的ZTest分为通过和不通过两种情况,ZWrite分为开启和关闭两种情况的话,一共就是四种情况:

1.深度测试通过,深度写入开启:写入深度缓冲区,写入颜色缓冲区;

2.深度测试通过,深度写入关闭:不写深度缓冲区,写入颜色缓冲区;

3.深度测试失败,深度写入开启:不写深度缓冲区,不写颜色缓冲区;

4.深度测试失败,深度写入关闭:不写深度缓冲区,不写颜色缓冲区;

Unity中默认的状态(写shader时什么都不写的状态)是ZTest LEqual和ZWrite On,也就是说默认是开启深度写入,并且深度小于等于当前缓存中的深度就通过深度测试,深度缓存中原始为无限大,也就是说离摄像机越近的物体会更新深度缓存并且遮挡住后面的物体。如下图所示,前面的正方体会遮挡住后面的物体:

写几个简单的小例子来看一下ZTest,ZWrite以及Render Queue这几个状态对渲染结果的控制。

让绿色的对象不被前面的立方体遮挡,一种方式是关闭前面的蓝色立方体深度写入:

通过上面的实验结果,我们知道,按照从前到后的渲染顺序,首先渲染蓝色物体,蓝色物体深度测试通过,颜色写入缓存,但是关闭了深度写入,蓝色部分的深度缓存值仍然是默认的Max,后面渲染的绿色立方体,进行深度测试仍然会成功,写入颜色缓存,并且写入了深度,因此蓝色立方体没有起到遮挡的作用。

另一种方式是让绿色强制通过深度测试:

这个例子中其他立方体的shader使用默认的渲染方式,绿色的将ZTest设置为Always,也就是说不管怎样,深度测试都通过,将绿色立方体的颜色写入缓存,如果没有其他覆盖了,那么最终的输出就是绿色的了。

那么如果红色的也开了ZTest Always会怎么样?

在红色立方体也用了ZTest Always后,红色遮挡了绿色的部分显示为了红色。如果我们换一下渲染队列,让绿色在红色之前渲染,结果就又不一样了:

更换了渲染队列,让绿色的渲染队列+1,在默认队列Geometry之后渲染,最终重叠部分又变回了绿色。可见,当ZTest都通过时,上一个写入颜色缓存的会覆盖上一个,也就是说最终输出的是最后一个渲染的对象颜色。

再看一下Greater相关的部分有什么作用,这次我们其他的都使用默认的渲染状态,绿色的立方体shader中ZTest设置为Greater:

这个效果就比较好玩了,虽然我们发现在比较深度时,前面被蓝色立方体遮挡的部分,绿色的最终覆盖了蓝色,是想要的结果,不过其他部分哪里去了呢?简单分析一下,渲染顺序是从前到后,也就是说蓝色最先渲染,默认深度为Max,蓝色立方体的深度满足LEqual条件,就写入了深度缓存,然后绿色开始渲染,重叠的部分的深度缓存是蓝色立方体写入的,而绿色的深度值满足大于蓝色深度的条件,所以深度测试通过,重叠部分颜色更新为绿色;而与红色立方体重合的部分,红色立方体最后渲染,与前面的部分进行深度测试,小于前面的部分,深度测试失败,重叠部分不会更新为红色,所以重叠部分最终为绿色。而绿色立方体没有与其他部分重合的地方为什么消失了呢?其实是因为绿色立方体渲染时,除了蓝色立方体渲染的地方是有深度信息的,其他部分的深度信息都为Max,蓝色部分用Greater进行判断,肯定会失败,也就不会有颜色更新。

有一个好玩的效果其实就可以考ZTest Greater来实现,就是游戏里面经常出现的,当玩家被其他场景对象遮挡时,遮挡的部分会呈现出X-光的效果;其实是在渲染玩家时,增加了一个Pass,默认的Pass正常渲染,而增加的一个Pass就使用Greater进行深度测试,这样,当玩家被其他部分遮挡时,遮挡的部分才会显示出来,用一个描边的效果渲染,其他部分仍然使用原来的Pass即可。

Early-Z技术

传统的渲染管线中,ZTest其实是在Blending阶段,这时候进行深度测试,所有对象的像素着色器都会计算一遍,没有什么性能提升,仅仅是为了得出正确的遮挡结果,会造成大量的无用计算,因为每个像素点上肯定重叠了很多计算。因此现代GPU中运用了Early-Z的技术,在Vertex阶段和Fragment阶段之间(光栅化之后,fragment之前)进行一次深度测试,如果深度测试失败,就不必进行fragment阶段的计算了,因此在性能上会有很大的提升。但是最终的ZTest仍然需要进行,以保证最终的遮挡关系结果正确。前面的一次主要是Z-Cull为了裁剪以达到优化的目的,后一次主要是Z-Check,为了检查,如下图:

Early-Z的实现,主要是通过一个Z-pre-pass实现,简单来说,对于所有不透明的物体(透明的没有用,本身不会写深度),首先用一个超级简单的shader进行渲染,这个shader不写颜色缓冲区,只写深度缓冲区,第二个pass关闭深度写入,开启深度测试,用正常的shader进行渲染。其实这种技术,我们也可以借鉴,在渲染透明物体时,因为关闭了深度写入,有时候会有其他不透明的部分遮挡住透明的部分,而我们其实不希望他们被遮挡,仅仅希望被遮挡的物体半透,这时我们就可以用两个pass来渲染,第一个pass使用Color Mask屏蔽颜色写入,仅写入深度,第二个pass正常渲染半透,关闭深度写入。

关于Early-Z技术可以参考ATI的论文Applications of Explicit Early-Z Culling以及PPT,还有一篇Intel的文章。

Unity渲染顺序总结

如果我们先绘制后面的物体,再绘制前面的物体,就会造成over draw;而通过Early-Z技术,我们就可以先绘制较近的物体,再绘制较远的物体(仅限不透明物体),这样,通过先渲染前面的物体,让前面的物体先占坑,就可以让后面的物体深度测试失败,进而减少重复的fragment计算,达到优化的目的。Unity中默认应该就是按照最近距离的面进行绘制的,我们可以看一下Unity官方的文档中显示的:

从文档给出的流程来看,这个Depth-Test发生在Vertex阶段和Fragment阶段之间,也就是上面所说的Early-Z优化。

简单总结一下Unity中的渲染顺序: 先渲染不透明物体,顺序是从前到后;再渲染透明物体,顺序是从后到前

Alpha Test(Discard)在移动平台消耗较大的原因

从本人刚刚开始接触渲染,就开始听说移动平台Alpha Test比较费,当时比较纳闷,直接discard了为什么会费呢,应该更省才对啊?这个问题困扰了我好久,今天来刨根问底一下。还是跟我们上面讲到的Early-Z优化。正常情况下,比如我们渲染一个面片,不管是否是开启深度写入或者深度测试,这个面片的光栅化之后对应的像素的深度值都可以在Early-Z(Z-Cull)的阶段判断出来了;而如果开启了Alpha Test(Discard)的时候,discard这个操作是在fragment阶段进行的,也就是说这个面片光栅化之后对应的像素是否可见,是在fragment阶段之后才知道的,最终需要靠Z-Check进行判断这个像素点最终的颜色。其实想象一下也能够知道,如果我们开了Alpha Test并且还用Early-Z的话,一块本来应该被剃掉的地方,就仍然写进了深度缓存,这样就会造成其他部分被一个完全没东西的地方遮挡,最终的渲染效果肯定就不对了。所以,如果我们开启了Alpha Test,就不会进行Early-Z,Z Test推迟到fragment之后进行,那么这个物体对应的shader就会完全执行vertex shader和fragment shader,造成over draw。有一种方式是使用Alpha Blend代替Alpha Test,虽然也很费,但是至少Alpha Blend虽然不写深度,但是深度测试是可以提前进行的,因为不会在fragment阶段再决定是否可见,因为都是可见的,只是透明度比较低罢了。不过这样只是权宜之计,Alpha Blend并不能完全代替Alpha Test。

关于Alpha Test对于Power VR架构的GPU性能的影响,简单引用一下官方的链接以及一篇讨论帖:

最后再附上两篇参考文章

http://blog.c**.net/candycat1992/article/details/41599167

http://blog.c**.net/arundev/article/details/7895839

相关推荐

shader是什么,有什么用?

2D图形,就是无论你如何移动视角,地面上的建筑物、花草树木样子都不会变,而3D图形则不 同,随着视角的变换,你看到的物体也在变化,从正面变成侧面,越远的物体越小,越近的越大,与现实生活中人眼看到的情景非常相似。   shader就是专门用来渲染3D图形的一种技 术,通过shader,程序设计人员可以自己编写显卡渲染画面的算法,使画面更漂亮、更逼真。 几年前并没有shader这个东西,所以那时候的显卡,就不 支持shader,而只支持固定管线渲染,游戏画面也没有现在的酷。   shader又分两种 ,一种是顶点shader(3D图形都是由一个一个三角形组 成的,顶点shader就是计算顶点位置,并为后期像素渲染做准备的),另一种是像素shader,像素shader顾名思义,就是以像素为单位,计算光 照、颜色的一系列算法。   几 个不同的图形API有各自的shader语言:  在DirectX中,顶点shader叫做 vertex shader ,像素shader叫做 pixel shader;   在OpenGL中,顶点shader也叫做 vertex shader ,但像素shader叫做 fragment shader。   此外显卡芯片厂商nVidia还推出CG显卡编程语言,也支持 shader。   shader 有很多不同的版本:  所以,即使你的显卡支持shader,但可能版本不够高,所以无法支持比较新的游戏使用的 shader。   一般来说,大部分游 戏都支持不同版本的shader,为的是让尽可能多的机器都能运行,为此需要做很多额外的工作。   除了显卡不够新之外,不同显卡厂商对shader的支持也不尽相同,所以同一个游戏,一样的 设置,在n卡和ATI的卡上,表现可能大不一样。   另外,安装官方最新的驱动程序也是必要的。如果你安装了错误的驱动程序,甚至是随便从网上下载一个显卡驱动,那么即使你的显卡支持 shader,也可能跑不了需要shader支持的程序,包括但不限于网络游戏! 三个level:
2023-07-24 19:19:131

shader是什么意思

shader的意思是:著色器;着色程序。短语:pixel shader:像素着色器。着色器(Shader)是用来实现图像渲染的,用来替代固定渲染管线的可编辑程序。其中Vertex Shader(顶点着色器)主要负责顶点的几何关系等的运算,Pixel Shader(像素着色器)主要负责片源颜色等的计算。着色器替代了传统的固定渲染管线,可以实现3D图形学计算中的相关计算,由于其可编辑性,可以实现各种各样的图像效果而不用受显卡的固定渲染管线限制。相关例句:1、Visually designing shader programs and effect files.视觉设计着色程序和效果文件。2、Fixed visual artefacts in building placing shader.固定的视觉文物建筑放置着色。3、I set a composition shader into the diffuse channel.我在传播路径中设置一个构图着色器。4、Fixed a visual error in Ocean shader texture lookup.固定的视觉错误在海洋着色纹理查找。5、This shader produces the effect of an exploding fireball.这个材质产生一个爆炸的火球。
2023-07-24 19:19:201

3dmax中的shader作用是啥

shader便是专业用于3D渲染3d图纸形的一种技 术,根据shader,编程设计工作人员能够 自身撰写独立显卡3D渲染界面的优化算法,使界面更好看、更真实。两年前并没有shader这个东西,因此那时的独立显卡,也不 适用shader,而只适用固定不动管道3D渲染,游戏画面都没有如今的酷。  shader又分二种,一种是端点shader(3d图纸形全是由一个一个三角形组 成的,端点shader便是测算端点部位,并为中后期清晰度3D渲染做准备的),另一种是清晰度shader,清晰度shader说白了,便是以清晰度为企业,测算光 照、色调的一系列优化算法。Shader Model(在3d图纸形行业常被通称SM)便是“提升3D渲染模块方式”。实际上,Shader(着色器)是一段可以对于三维目标开展实际操作、并被GPU所实行的程序流程。根据这种程序流程,程序猿就可以得到绝大多数要想的3d图纸形实际效果。在一个三维情景中,一般包括好几个Shader。这种Shader含有的承担对三维目标表层开展解决,有的承担对三维目标的纹路开展解决。早在微软公司公布DirectX 8时,Shader Model的定义就发生在这其中了,并依据实际操作目标的不一样被分成对端点开展各种各样实际操作的Vertex Shader(端点3D渲染模块)和对清晰度开展各种各样实际操作的Pixel Shader(清晰度3D渲染模块)。
2023-07-24 19:20:031

shader中文是什么意思

shadern.著色器; 着色程序;[例句]Diffuse Shader Material has only two properties-a color and a texture.漫反射着色器材质只有两个属性-颜色和纹理。
2023-07-24 19:20:101

显卡的Shader(着色器)频率是什么

显卡的Shader(着色器)频率是什么显卡的Shader(着色器)频率是什么?显卡是计算机的一个重要组件,它的作用是将计算机中的数据转换为图像信号输出到显示器上。而Shader(着色器)则是指显卡中的一种特殊的计算单元,它们主要负责图像的渲染工作。Shader虽然是其中之一,但它却是显卡中最基础、最重要的组成部分之一。Shader分别有顶点着色器、像素着色器、几何着色器、计算着色器和外壳着色器等多种,每一种着色器都有着不同的功能。而Shader(着色器)频率则是显卡的一个重要指标,它是指显卡提供Shader运行的速度。Shader频率一般由显卡制造商在设计时设定,并显示在显卡的技术参数中。通常来说,Shader频率越高显卡性能越好。在现代显卡中,Shader频率已经越来越高,现已经达到了几个GHz的级别。这也就意味着显卡可以更加快速高效地进行图形渲染工作,使得我们可以在更短的时间内享受到更加流畅的视觉体验。当然,除了Shader频率之外,显卡性能还有很多指标,例如显存大小、显存频率等等,这些指标也都影响着显卡的性能。总的来说,Shader(着色器)频率是显卡中一个非常重要且不可忽视的指标。它的高低对于显卡的性能有着很大的影响,因此在选择显卡时,我们可以根据自己的需求来选择一个适合自己的显卡。
2023-07-24 19:20:171

unity中的shader的效果有哪些

  如果是进行3d游戏开 发的话,想必您对着两个词不会陌生。Shader(着色器)实际上就是一小段程序,它负责将输入的Mesh(网格)以指定的方式和输入的贴图或者颜色等组 合作用,然后输出。绘图单元可以依据这个输出来将图像绘制到屏幕上。输入的贴图或者颜色等,加上对应的Shader,以及对Shader的特定的参数设 置,将这些内容(Shader及输入参数)打包存储在一起,得到的就是一个Material(材质)。之后,我们便可以将材质赋予合适的 renderer(渲染器)来进行渲染(输出)了。  所以说Shader并没有什么特别神奇的,它只是一段规定好输入(颜色,贴图等)和输出(渲染器能够读懂的点和颜色的对应关系)的程序。而Shader开发者要做的就是根据输入,进行计算变换,产生输出而已。  Shader大体上可以分为两类,简单来说  表面着色器(Surface Shader) - 为你做了大部分的工作,只需要简单的技巧即可实现很多不错的效果。类比卡片机,上手以后不太需要很多努力就能拍出不错的效果。  片段着色器(Fragment Shader) - 可以做的事情更多,但是也比较难写。使用片段着色器的主要目的是可以在比较低的层级上进行更复杂(或者针对目标设备更高效)的开发。
2023-07-24 19:20:241

备注shader是什么意思?

shader常见的英文名音译是沙伯。是一个女孩子用的英文名。最早出现于英语,shader是个简单的名字,叫shader的人的品格通常始终不渝、性格豪爽。
2023-07-24 19:20:311

shader几何运算效果

shader几何运算效果为草地效果草地效果有多种实现方法,我所了解的比较常见的有Billborad,星型结构,还有就是用GPU实时渲染,也就是用Geometry Shader生成面片双面渲染。前两种方法虽然效率比较高但是实现的效果有限,第三种方法则可以根据我们的需要实现更细致的效果。在这不得不提一句,我第一次看到Geometry Shader实现的效果时,我不禁感叹这真的是一个狂拽酷炫的东西,作为一个处于顶点着色器和片元着色器之间的着色器,它相比较顶点着色器具有更高的灵活性,因为我们可以方便的使用GPU添加和删除图元,相比较于片元着色器它又更加直观。我们可以用几何着色器实现非常多花里胡哨的功能,其中之一就是模拟草地。但是效果酷炫带来的代价就是它的效率不是很高,它不像vertex和fragment shader可以高度并行运算,而且低版本的图形库是不支持这个功能的。不过好消息是根据我的调查,从两年多前的骁龙835处理器的Areno 540开始就支持OpenGL ES3.2了,而这个版本的一个新特性就是支持Geometry Shader!!!所以随着硬件的发展,在移动端以及非旗舰性能的PC端大量使用GS应该也不是一个久远的事情了。
2023-07-24 19:20:381

如何学习shader

学什么都得用心学
2023-07-24 19:20:472

unity shader有什么用

Unity所有的渲染工作都离不开shader
2023-07-24 19:21:072

买的shader不能用

购买的Shader不能使用的原因是版本不兼容或配置问题。购买的Shader需要与使用的软件版本兼容才能正常使用,如未及时更新软件或选择不兼容版本,可能导致无法运行。此外,可能还需要配置正确的路径和环境,否则也无法使用。Shader是用来实现图像渲染的,用来替代固定渲染管线的可编辑程序。其中VertexShader主要负责顶点的几何关系等的运算,PixelShader主要负责片源颜色等的计算。
2023-07-24 19:21:151

如何管理shader

使用shader的流程:1. 编译vertex shader或者fragment shader;2. 链接shader;3. 初始化需要向shader传递的变量;(如:getUniformLocation)4.在render函数中,实时传递shader变量。(如:setUniformLocation)问题症结在第三步,对于不同的shader,需要初始化的shader变量不同,也很难预测开发者需要向shader传递哪些变量。解决这个问题的方法是:抽象一个shaderNode父类,完成shader的前面2个步骤,并提供一个抽象接口(如:virtual void buildCustomUniforms() = 0;)来完成第三步的初始化,让所有继承的子类来实现这个接口。举例:ShaderNode:所有shader的父类,提供公共接口的实现,如shader的编译和链接,shader从后台切换回来时reload函数的实现。CustomShader:开发者自定义的shader,继承ShaderNode,并实现抽象接口buildCustomUniforms。在buildCustomUniforms中初始化自定义的shader变量。ShaderCache:全局shader cache的持有者,使用shader_dec来描述所持有的ShaderNode。shader_dec:ShaderNode的描述结构体,包括vertex shader和fragment shader的文件名,查找key和ShaderNode指针(回调具体ShaderNode的reload函数)。
2023-07-24 19:21:241

Shader频率的shader频率简介

shader频率=着色器频率,即显示芯片内部实际负责渲染部分的频率,是显示核心中对性能影响最大的指标。shader=着色器,渲染器shader频率和GPU核心频率及显存频率一样重要甚至更重要,若进行显卡超频,超流处理器频率可以获得更大的性能提升,而产生的多余热量要小于给GPU及显存超频产生的热量。
2023-07-24 19:21:311

Shader的频率越高越好吗?

是的shader频率越高,性能就越高
2023-07-24 19:21:473

Shader 怎么读

http://dict.youdao.com/search?q=Shader&keyfrom=fanyi.smartResult
2023-07-24 19:21:541

UNITY自带的SHADER放在哪个目录的

建立工程的时候可以选择导入,这样就在你的工程目录下的AssetsStandardAssets(Mobile)Shaders中。U3D本身的shader其实是在软件安装目录的...UnityEditorStandardPackages中
2023-07-24 19:22:042

UNITY自带的SHADER放在哪个目录的

一般你在建立工程的时候可以选择导入,这样就在你的工程目录下的AssetsStandard Assets (Mobile)Shaders 中。U3D本身的shader其实是在软件安装目录的...UnityEditorStandard Packages中
2023-07-24 19:22:241

shader如何读取模型颜色

1、通过纹理采样来获取表面颜色。2、控制着颜色的显示,让模型显示出贴图的颜色。Shader是用来实现图像渲染的,用来替代固定渲染管线的可编辑程序。
2023-07-24 19:22:311

请教Vertex Shader跟Fragment Shader应用差别

我觉得这是有点奇怪的说法。关键不在Vertex Shader到底在做什麼,而是要搞清楚他处理的对象是甚麼。如果你要操作的是每个顶点的东西,那要用Vertex Shader,一旦经过光栅化後,位置固定而且变成片元(不一定是最终像素,所以叫做Fragment),你在Fragment Shader就是操作这些东西。(虽然後者是可以改变片元的深度值)不然你也可以在Fragment Shader里面变换法向量的,只是在Vertex Shader里面就先变换好法向量後,再利用硬体去插值会比较快。所以话再说回来,我认为你应该要重新看下绘图管线。从Programmable Pipeline重新认知下,或许才可以真正解决你的问题。
2023-07-24 19:22:541

Shader的编写到底应该是美术的事情还是程序的事

从定位来讲,应该是美术的事情。。。。但现实情况是,美术的学习毅力一般都比较差。。大部分都学不会(说到底还是不想学)。。。。而程序员的学习耐性比较强,否则他也做不了程序员。。。因此美术便常常把这个任务,硬生生的推给程序。。。SHADER虽然是代码,但完全是靠死记硬背的东西,和程序员的逻辑思维能力,半点关系都没有。。。而SHADER写的好不好,取决于审美能力。。。死记硬背难道不是人人都会的吗?难道只有程序员才可以死记硬背?所以从现实角度讲,本该美术学,但美术"学不会"。。。程序可以学会。。但这确实不是程序该学的东西。。。。。毕竟程序的强项,绝对不是审美。。。简单说,程序什么都学得会,因为他肯学。。。被虐的习惯了,也就万能了。。除了绘画要看天赋之外,程序学美工的那些软件,也就是几天的事儿。。。只要程序原意,只要几天时间,就可以变成一个"不太会画画的二流美工"。。而全职的美工,除了画画大半在天赋之外,其实普遍都是不学无术的混子。。。即便给他几年时间,他也无法变成一个“不太懂前端的二流程序员”。3D美工会好一些,因为一般3D美工的软件,学习难度会远大于2D美工,其中相对的高手,一般可以写一些表达式,表达式其实也是一种相对简单的编程(俗称傻瓜式编程)。。2D美工则基本属于"除了画画和装B之外,啥也不会,啥也不想学"。。
2023-07-24 19:23:011

unity溶解shader要怎么制作

最近也在学习shader,几篇博客供题主入门。1、首先来两篇最最基础文章对shader有大体的认识。这两篇文章会分析shader中的一行行代码,讲解语法和作用并加以扩展。读完后就基本了解了shader中的属性、Tags、LOD、光照模型等是怎么回事。猫都能学会的Unity3D Shader入门指南(一)猫都能学会的Unity3D Shader入门指南(二)2、然后可以看《Unity Shader and Effect Cookbook》,或者它的中文版《Unity着色器和屏幕特效开发秘笈》。这本书会展示shader中的各个方面,如漫反射着色、纹理贴图、镜面反射等等。可能由于这本书方方面面都有涉及,有时会忽略一些比较关键的细节,而这恰恰使初学者困惑。有一位博主记录下了根据这本书学习的笔记,题主可以直接看博客来学习:【Unity Shaders】概述及Diffuse Shading介绍3、在第2步的过程中,你可能需要查阅shader中各个概念函数的更详细的情况,这时你会需要Unity官方手册以及Cg教程:Unity - Manual: ShadersUnity - Manual: Shader ReferenceThe Cg Tutorial4、学习shader的时候,你不仅想知道怎么用,可能还想了解它背后的机制,那这篇文章你肯定不能错过:【Unity Shaders】初探Surface Shader背后的机制5、这些都熟练了,对shader也都比较熟悉了。你可以尝试去创造属于自己的shader,也可以去Shadertoy BETA寻求灵感,感受shader的鬼斧神工。
2023-07-24 19:23:221

Shader笔记——3D数学基础

在3D世界中,为了确定不同顶点所在的位置,需要使用坐标表示,二坐标的数值是基于一个固定的参照点进行定位的,这个点就是坐标原点。 通常情况下,原点的坐标一般都是(0,0)。 如果把所有的坐标汇集在一起管理,那就构成了一个坐标系。一个完整的坐标系会包含原点,方向和坐标。 3D中涉及各种坐标系,从维度进行区分,所有坐标系可以分为平面直角坐标系和空间直角坐标系。 在空间坐标系中,根据坐标方向的不同又可以分为左手坐标系和右手坐标系。 若将大拇指设定为x轴,食指设定为y轴,中指设定为z轴,左右手坐标系如图: 在数学中,坐标属于标量,只表示大小,不表示方向。 而同时表示长度和方向信息的,称之为向量(Vector),或者叫“矢量”。顶点的法线向量,切线向量等都是向量。 假设二维向量 a 的起点A,终点为B,使用B的坐标减去A的坐标,即可计算出个向量 a 。 二维向量 a 的计算公式如下: 若将公式推广到三维空间,假设三维向量 a 的起点A,终点B,则三维向量 a 的计算公式如下: 如果俩个向量的长度相等但方向相反,则这俩个向量互为相反向量。 零向量的相反向量是它本身。 从几何的角度来讲,将一个向量的起点作为终点,而原本的终点作为起点,最终得到的向量就是原向量的相反向量。 假设向量 a 的起点A,终点B, a 的相反向量 b ,表示如下: 向量包含长度和方向,向量的长度被称为向量的模。如向量 a 的模表示为| a |。 如图通过勾股定理,求得 二维向量 a 的模长计算公式为: 如图通过俩次勾股定理,求得 “单位向量”是指模长为1的向量。 在很多情况下向量的方向比向量的长度更值得关注,如灯光的照射方向,摄像机的查看方向等。为了计算方便,可将这种向量转变为单位向量,这个转变的过程称为向量的标准化(Normalize)。 从代数的角度来讲,一个非零向量除以自身的长度,既可以将自身长度缩放为1。零向量的长度为0,在数学中0作为被除数没有意义。 因此非零向量 a 的标准化向量为: 单位向量与原向量相比,只是长度发生了改变,方向保持不变。 从几何的角度来讲,向量的加法运算满足三角形法则。 向量的加法运算可以推广到多个数量相加,最终结果是从第一个向量的起点指向最后一个向量的终点,长度为起点与终点之间的距离。 从代数的角度来讲,向量的加法就是将相同的分量进行相加。 向量的减法运算可以理解为一向量与另一向量的相反向量做加法运算,同样满足三角形法则。 向量 a 和 b 的减法运算转变为与相反向量的加法运算: 相同起点的俩个向量相减,得到的向量为第二个向量的终点指向第一个向量的终点,长度为俩终点之间的距离。 从代数的角度来讲,向量的减法运算就是将相同的分量相减。计算公式如下: 将向量乘以一个标量,可产生向量缩放的效果。如图: 假设向量 a =(x,y,z),向量缩放k倍公式为: 向量 a 和 b 的点积写作 a . b 。 在代数中,点积又叫做内积,俩个向量点积的结果就是对应所有分量相乘之后的和。点积的结果是数值。 点积计算公式为: 在几何中,俩个向量点积的结果就是一个向量在另外一个向量上的投影长度与这个向量长度的积。 点积的计算公式为: 向量的叉积又称为外积,叉积的结果是向量。向量 a 和 b 的叉积写作 a × b 。 叉积的计算公式为: 在几何中,叉积得到的向量与 a 和 b 所在平面垂直,长度等于向量 a 和 b 组成的平行四边形的面积,该向量被称为法向量。如图: 假设将叉乘的俩个向量颠倒顺序, b 与 a 叉乘所得向量的方向将会朝下。 常用的向量运算法则如下所示: 向量可以使用横向排列的数组表示,假设纵向上继续排列相同维度的数组,最后组成的数组就是——矩阵(Matrix)。 向量的维度表示表示该向量所包含数的个数,同样的,矩阵的维度表示了该矩阵所包含的行和列的数量。通常使用r(raw的首字母缩写)表示行数,使用c(column的首字母缩写)表示列数,而矩阵本身则使用黑斜体大写字母表示,如 M 。 一个3×3的矩阵 M 以及所对应的所有分量可以如下表示: 行数和列数相等的矩阵称为方阵。 方阵中行号和列号相等的分量称为对角元素,其他分量称为非对角元素。非对角元素全为0的矩阵称为对角矩阵。 在对角矩阵中,对角元素全为1的矩阵叫作单位矩阵。 任何矩阵乘以单位矩阵,最终得到的结果与原矩阵相同。单位矩阵对于矩阵的作用就像1对于标量的作用一样。 假设将一个r×c的矩阵 M 沿着对角线翻转,得到的新矩阵称为矩阵 M 的转置矩阵(Transpose Matrix)。 转置矩阵的重要法则:将一个矩阵转置之后再进行转置,得到的矩阵与原矩阵相同,公式如下: 跟向量类似,矩阵也可以与标量相乘,中间不需要写运算符号,相乘之后的结果与原矩阵维数相同,然后将每个分量乘上这个标量。公式如下: 当第一个矩阵的列数等于第二个矩阵的行数,这俩个矩阵才可以相乘,得到矩阵的行数等于第一个矩阵的行数,列数等于第二个矩阵的列数。 在Shader中,向量也可以与矩阵相乘,相乘的时候可以把向量看作行数为1或列数为1的矩阵。 向量(x,y,z)可以横向写成1×3的矩阵,被称为行向量: 也可以写成3×1的矩阵,被称为列向量: 向量与矩阵相乘的几何意义是实现向量的空间变换。 在3D中,所有的变换都是通过矩阵完成的,包括常用的平移,旋转,缩放,除此之外,还有坐标空间之间的变换也是通过矩阵完成的。 假设向量 v = (x,y,z),可以表示为 假设平面坐标系的俩个坐标向量分别为 p = (1,0), q =(0,1),绕原点逆时针旋转角度之后如图: 左右手坐标系中的旋转方向完全不同,俩种坐标系中的旋转方向的判断方法:先伸出与坐标系对应的那只手,握住旋转轴并且保持大拇指的朝向与旋转轴的正方向一致,其余四指的朝向即为旋转的正方向。如图,弧线箭头所示的方向即为右手坐标系的旋转正方向。 左右俩种坐标系对应的旋转方向归纳如下: 这里只讲解绕坐标轴旋转的情况。 将空间坐标系绕x轴旋转,空间坐标系中的旋转方向如图: x轴上的所有坐标都不会发生改变,从x轴正方向朝负方向观察坐标系,y轴和z轴的旋转情况完全跟平面坐标系的旋转情况一样,如图: 最终绕x轴旋转角度的变换矩阵为: 空间坐标系绕y轴的旋转方向如图: 从y轴正方向朝负方向观察坐标系,x轴和z轴的旋转情况如图: 空间坐标系绕z轴的旋转方向如图: 从z轴正方向朝负方向观察坐标系,x轴和y轴的旋转情况如图:
2023-07-24 19:23:301

Unity Shader - 深度图基础及应用

深度图里存放了 [0,1] 范围的 非线性分布 的深度值,这些深度值来自 NDC 坐标。 在延迟渲染中,深度值默认已经渲染到G-buffer;而在前向渲染中,你需要去 申请 ,以便Unity在背后利用Shader Replacement将RenderType为Opaque、渲染队列小于等于 2500 并且有 ShadowCaster Pass 的物体的深度值渲染到深度图中。 第一步:在C#中设置Camera.main.depthTextureMode = DepthTextureMode.Depth; 可以在主摄像机的Camera组件下看见提示: 这表明了主摄像机渲染了深度图 第二步:在Shader中声明_CameraDepthTexture 第三步:访问深度图 利用覆盖屏幕的uv值和深度图中的深度,我们可以重建出物体在世界空间中的坐标。 主要有以下两种方法: 首先要在C#脚本中传递当前的VP逆矩阵: 然后在Shader中首先制造NDC坐标: 利用当前的VP逆矩阵将NDC坐标转换到世界空间: 具体用法可以到下面的MotionBlur例子中查看。 首先需要知道,Post Process实际上是渲染一个覆盖屏幕的Quad,因此屏幕四个角对应摄像机的视椎体四个角。 首先是算出摄像机到四个角的向量: 假设有个绿点在toTopLeft所在线上,利用相似三角形,可以得到: 而depth是能够在Shader中获得的,因此我们只需要传递toTopLeft / near到Shader中就能计算出toGreen: 在Vertex中判断出对应顶点所在的向量: 可以看到uv值和对应的索引值正好是二进制的关系,所以可以如下求出: 你可能奇怪这样只能求到4个角线上的点,但vertex到fragment的过程中是有个东西叫插值的,这个 插值 正好能把每个像素所在的向量求出。 然后我们就能在fragment中求出世界坐标了: 具体的用法可以到下面的垂直雾效例子中找到。 输出[0,1]范围的深度值即可,如下: 思路是判断当前物体的深度值与深度图中对应的深度值是否在一定范围内,如果是则判定为相交。 首先访问当前物体的深度值: 然后访问深度图。由于此时不是Post Process,因此需要利用投影纹理采样来访问深度图: 最后就是进行相交判断: 在相交高亮效果的基础上,加上 半透明 和 边缘高亮 ,就能制造出一个简单的能量场效果: 思路是让雾的浓度随着深度值的增大而增大,然后进行的原图颜色和雾颜色的插值: 思路与相交高亮效果类似,只是这里是Post Process。自定义一个[0,1]变化的值_CurValue,根据_CurValue与深度值的差进行颜色的插值: 利用上面提到的第二种重建世界空间坐标的方法得到世界空间坐标,判断该坐标的Y值是否在给定阈值下,如果是则混合原图颜色和水的颜色: 利用上面提到的第二种重建世界空间坐标的方法得到世界空间坐标,让雾的浓度随着Y值变化: 思路是取当前像素的附近4个角,分别计算出两个对角的深度值差异,将这两个差异值相乘就得到我们判断边缘的值。 首先是得到4个角: 然后是得到这4个角的深度值: 最后就是根据对角差异来得到判断边缘的值: 运动模糊主要用在竞速类游戏中用来体现出速度感。这里介绍的运动模糊只能用于 周围物体不动,摄像机动 的情景。 思路是利用上面提到的重建世界坐标方法得到世界坐标,由于该世界坐标在摄像机运动过程中都是不动的,因此可以将该世界空间坐标分别转到摄像机运动前和运动后的坐标系中,从而得到两个NDC坐标,利用这两个NDC坐标就能得到该像素运动的轨迹,在该轨迹上多次取样进行模糊即可。 首先是得到世界坐标(这里使用提到的第一种重建方法): 然后是计算出运算前后的NDC坐标: 最后就是在轨迹上多次取样进行模糊: 景深是一种聚焦处清晰,其他地方模糊的效果,在摄影中很常见。 思路是首先渲染一张模糊的图,然后在深度图中找到聚焦点对应的深度,该深度附近用原图,其他地方渐变至模糊图。 第一步是使用SimpleBlur Shader渲染模糊的图,这里我只是简单地采样当前像素附近的9个点然后平均,你可以选择更好的模糊方式: 第二步就是传递该模糊的图给DepthOfField Shader: 第三步就是在DepthOfField Shader中根据焦点来混合原图颜色和模糊图颜色: https://github.com/KaimaChen/Unity-Shader-Demo/tree/master/UnityShaderProject Unity Docs - Camera"s Depth Texture Unity Docs - Platform-specific rendering differences 神奇的深度图:复杂的效果,不复杂的原理 SPECIAL EFFECTS WITH DEPTH GPU Gems - Chapter 27. Motion Blur as a Post-Processing Effect 《Unity Shader 入门精要》 《Unity 3D ShaderLab 开发实战详解》
2023-07-24 19:23:381

怎样使显卡设置Shader Model 3.0?

不需要设置,也无法设置。支持Shader Model 3.0的显卡,这功能自己就会运行。你这问题就像是问 4核cpu怎么设置4核一个道理。如果显卡不支持,有些游戏例如 鬼泣4 就没办法玩了。
2023-07-24 19:23:462

我的显卡shaders的n/a没有显示数值

如果你说的是GPU-Z里的Shader那一栏后面的数值,那么N/A的意思不是说没有,而是说和GPU Clock同频,现在的显卡基本都是这样的,Shader频率和和GPU频率是同频的,如果GPU频率的这一项数值是1000MHz,则说明Shader频率也是1000MHz。如果你说的Shader是最上面的那个Shader,一般如果识别不出来,不会显示成N/A,而是会显示成“Unknown”,建议更新GPU-Z或者软件的版本,如果是其他的软件,这个解决的思路大概也是通用的。
2023-07-24 19:23:551

shader的property能填入啥

properties一般定义在着色器的起始部分,我们可以在Shader书写的时候定义多种多样的属性,而使用Shader的时候可以直接在材质检视面板(Material Inspector)里编辑这些属性,取不同的值或者纹理。这可以说是Unity贴心&可见即所得的又一体现吧。以Unity自带的BasicVertex Lighting 基本顶点光照为例,一张很直观的图就是这样:需要注意,Properties块内的语法都是单行的。每个属性都是由内部名称开始,后面括号中是显示在检视面板(Inspector)中的名字和该属性的类型。等号后边跟的是默认值。在Properties{}中定义着色器属性,在这里定义的属性将被作为输入提供给所有的子着色器。每一条属性的定义的语法是这样的:_Name("Display Name", type) = defaultValue[{options}]11_Name - 属性的名字,简单说就是变量名,在之后整个Shader代码中将使用这个名字来获取该属性的内容Display Name - 这个字符串将显示在Unity的材质编辑器中作为Shader的使用者可读的内容type - 这个属性的类型,可能的type所表示的内容有以下几种:Color - 一种颜色,由RGBA(红绿蓝和透明度)四个量来定义;2D - 一张2的阶数大小(256,512之类)的贴图。这张贴图将在采样后被转为对应基于模型UV的每个像素的颜色,最终被显示出来;Rect - 一个非2阶数大小的贴图;Cube - 即Cube map texture(立方体纹理),简单说就是6张有联系的2D贴图的组合,主要用来做反射效果(比如天空盒和动态反射),也会被转换为对应点的采样;Range(min, max) - 一个介于最小值和最大值之间的浮点数,一般用来当作调整Shader某些特性的参数(比如透明度渲染的截止值可以是从0至1的值等);Float - 任意一个浮点数;Vector - 一个四维数;defaultValue 定义了这个属性的默认值,通过输入一个符合格式的默认值来指定对应属性的初始值(某些效果可能需要某些特定的参数值来达到需要的效果,虽然这些值可以在之后在进行调整,但是如果默认就指定为想要的值的话就省去了一个个调整的时间,方便很多)。Color - 以0~1定义的rgba颜色,比如(1,1,1,1);2D/Rect/Cube - 对于贴图来说,默认值可以为一个代表默认tint颜色的字符串,可以是空字符串或者"white",“black”,“gray”,"bump"中的一个Float,Range - 某个指定的浮点数Vector - 一个4维数,写为 (x,y,z,w)另外还有一个{option},它只对2D,Rect或者Cube贴图有关,在写输入时我们最少要在贴图之后写一对什么都不含的空白的{},当我们需要打开特定选项时可以把其写在这对花括号内。如果需要同时打开多个选项,可以使用空白分隔。可能的选择有ObjectLinear, EyeLinear, SphereMap, CubeReflect, CubeNormal中的一个,这些都是OpenGL中TexGen的模式,具体的留到后面有机会再说。所以,一组属性的申明看起来也许会是这个样子的://Define a color with a default value of semi-transparent blue_MainColor ("Main Color", Color) = (0,0,1,0.5) //Define a texture with a default of white_Texture ("Texture", 2D) = "white" {} 12341234属性案例代码:Properties { Property [Property …] }定义属性块,其中可包含多个属性,其定义如下:name (“display name”, Range (min, max)) =number定义浮点数属性,在检视器中可通过一个标注最大最小值的滑条来修改。name (“display name”, Color) =(number,number,number,number)定义颜色属性name (“display name”, 2D) = “name” {options }定义2D纹理属性name (“display name”, Rect) = “name”{ options }定义长方形(非2次方)纹理属性name (“display name”, Cube) = “name”{ options }定义立方贴图纹理属性name (“display name”, Float) = number定义浮点数属性name (“display name”, Vector) =(number,number,number,number)定义一个四元素的容器(相当于Vector4)属性一些细节说明包含在着色器中的每一个属性通过name索引(在Unity中, 通常使用下划线来开始一个着色器属性的名字)。属性会将display name显示在材质检视器中,还可以通过在等符号后为每个属性提供缺省值。对于Range和Float类型的属性只能是单精度值。对于Color和Vector类型的属性将包含4个由括号围住的数描述。对于纹理(2D, Rect, Cube) 缺省值既可以是一个空字符串也可以是某个内置的缺省纹理:“white”, “black”, “gray” or"bump"。
2023-07-24 19:24:091

unity 获取shader属性shader中有哪些属性如何使用

可以用getcomponent的方法GetComponent(Renderer).sharedMaterial.SetVector("_Point",Vector4(1.0, 0.0, 0.0, 1.0));GetComponent(Renderer).sharedMaterial.SetFloat("_DistanceNear",10.0);GetComponent(Renderer).sharedMaterial.SetColor("_ColorNear",Color(1.0, 0.0, 0.0));GetComponent(Renderer).sharedMaterial.SetColor("_ColorFar",Color(1.0, 1.0, 1.0));
2023-07-24 19:24:161

[Unity][翻译]云朵Shader步骤分解

人工翻译自Alexandre Stroukoff的文章《CLOUDS SHADER BREAKDOWN》,原文链接: http://astroukoff.blogspot.com/2019/09/clouds-shader-breakdown.html 在正文之前,先说下作者的制作过程,大致分为三步: 从作者的介绍来看,第一步目的是创建云朵模型,第二步目的是烘焙光照,理论上也可以用别的软件来做,并且提前烘焙光照意味着云朵在引擎中是静态不受光照的,这点需要注意,文章末尾也有关于动态光照的说明。 前两步作者只是简单介绍了一下,并且视频很糊,就不贴了,以下是正片,文章中的引用段是我的注释。 我根据ThatGameCompany的游戏《Sky 光遇》制作了一个云朵Shader,本篇文章是关于它的一个小小的步骤分解。 效果中作用最大的是云朵Mesh本身,其次是烘焙光照,我使用Houdini + 3ds Max来生成它们。在这篇文章中我仅注重于介绍Shader部分,Shader使用Amplify Shader Editor(ASE)制作。 第一步连接Vertex Color(顶点色)到Emission(自发光),为了显示先前(在3ds Max中)烘焙的光照,我使用了一个0.454545的指数来校正顶点色(因为sRGB/Linear/Gamma叭啦叭啦)。 大量的三角面能带来更丝滑的移位效果,如果性能上吃得消, Tesselation (曲面细分)是个好办法,在左侧面板勾上“tesselation”选项,选择distance based模式。 调整距离与tesselation参数直到你和你的电脑都满意为止,这里调一个非常近的距离就不错。 现在好玩的来了,我加了一个 Noise Generator(噪声生成器) ,这个节点很方便,它可以根据世界位置生成3D噪声。使用3D噪声比较吃性能,你可以换成Simplex(单形噪声),我很确定整个效果都可以用噪声纹理和UV搞定。我用世界坐标乘以一个浮点数,用作噪声节点的“Size”输入,这个浮点数用来控制噪声的tiling。 并且 从-1/1 映射到 0/1 ,避免出现负值。 在Debug输入中加入了这个(指上面的浮点数)。 现在,不直接使用World Position,而是 将它乘以一个Vector3("NoiseScaleA") ,这样可以 对噪声做非统一缩放 ,非常方便!(就像对Mesh进行缩放一样,但你只是缩放输入位置)。这里我沿Z轴对噪声进行拉伸示范一下效果。 是时候加点移动了,很直接,在我将缩放后的世界坐标连接到噪声之前,我 增加一个Vector3,令时间与它相乘 ,这样就可以控制 噪声移动的方向 。 现在将它连到 Local Vertex Offset ,并与两个东西相乘: 我决定 把噪声重复3次 。复制所有参数,并且把它们加在一起。这让我想起了以前做过的一个项目(卡通火山碎屑噪声)。思路很简单:对于每个噪声,将力度降低一半,双倍tiling,双倍速度,然后再调整! 每个噪声之间的关系 很重要,这里我只调整Strength(力度),单独调整噪声很容易(将除当前噪声外的所有力度调为0),然后调整力度。 对于渐变的边缘,使用透明材质和 Depth Fade节点 简单设置。 这一部分比较取巧(hack),但它增添了许多细节。大体上来说我就是添加了一个黑白的云朵纹理,并使用Triplanar Mapping(三面映射)采样,为了让Triplanar Mapping动起来,我使用了来自噪声C的修改后的世界位置(看下面的图1),并且我让所有东西与噪声A相乘来“抹去”这里那里的纹理(看下面的图2)。 我使用了Register/Get Local Var节点,避免我的连线乱得像兜里打结的耳机线,ASE的这个功能真是太棒了。 你可以看到加入云朵纹理后的效果,真系好靓! 仓库地址: https://github.com/AlexStrook/UnlitClouds 备注:
2023-07-24 19:24:471

向CG高手求教?请问shader和render有什么差别呢?各自的中文对应词汇应该是什么?

render是渲染,是指把数学公式或者图形数据转换为三维空间图像的过程shader是着色器,shading是着色,是指将虚拟三维对象表面进行光照着色,不同表面会有不同的亮度
2023-07-24 19:24:541

Unity毛发材质shader笔记

本文主要参考了: Fur Effects - Teddies, Cats, Hair .... Unity Fur Shader 皮毛着色器 原文主要介绍了如何使用多个layer(pass)来模拟毛发的体积感,其中每个pass之间采用alpha混合,沿着法线越往外的layer的alpha为0的区域越大,以模拟毛发从根部到顶部越来越尖的效果。 具体计算的每层的alpha的方式是使用一张噪声图,然后对取到的噪声使用一个clamp操作,低于阈值的噪声值其alpha为0。这个阈值越往外越高,使得毛发从根部到顶端越来越窄。 因为毛发越靠近根部越密集,可以认为越靠近根部会吸收更多的环境光。于是我们给靠近根部的毛发颜色一个衰减,可以看到图中添加AO后相比没有时更富有层次感和体积感。 然而仅有AO在某些情况下仍然不能得到较好的效果。例如当观察者视角和光照视角比较接近时,对于单色纹理往往看到的会是大片混合在一起的缺少对比度的相似毛发颜色,从而削弱了材质的效果。 我们认为光线在单根毛发表面同样会发生漫反射,因此可以近似的认为毛发背光的一面较暗(阴影部分)。加入了单根阴影的渲染可以让每一根毛发不再产生相同(或者相似)的颜色,从而增加了材质的层次感。我们可以看到上图的放大效果中,第二张图我们能够更容易的分辨出每一根毛发的形状。 这里具体的实现方式是:将光线方向通过TBN矩阵转换到表面UV空间取xz分量得到一个UVOffset方向,然后在fragment shader中采样并计算原始UV的alpha和偏移后的UV的alpha,如果alpha的差是大于0的话那么显然这个部位就是背光部分。 这里我的想法是采用一种类似头发高光的各向异性高光(Kajiya-Kay),原理这里就不讲了,具体就是拿毛发的切向量和半角向量取sin值。 实践中取切向量的方式是在vertex shader中拿当前顶点的位置减去上一层顶点的位置。 不过最后出来效果还不是特别好,高光表现的不太连续给人很大的噪点感,另外明显能看到面与面之间的差别。 对于面与面之间的这个问题应该增加面数就能解决,这里采用的是自带的sphere所以可以理解。我个人想法是之后还需要对tangent做一下处理,目前感觉来看高光主要集中在毛发尖端。 部分光线会穿过毛发内部进入观察者的眼镜,因此我们可以加入透射效果增强毛发的质感。这里我们可以添加一个和光源方向无关的来自环境光的rim light,以及来自光源的透射光。 直射光的透射方程仍然使用dot(-V,L)取一个指数幂控制扩散大小,最后也要乘以1 - dot(N,L),以避免背面不会被光线照射到的部分也出现透射光。 第二个博客中实现了原文中的基础效果和力场效果,使得毛发收到类似重力的影响。本次实践我将毛发的力场与物体的运动相结合,制造出了一种动态效果,不仅能看到形态上的变化,也能看到反射的高光根据运动的变化而变化。 类似的效果不仅能做皮毛,也能做成草地之类的效果,同时还能再引入一个纹理去变化顶点的位置来模拟草地被风吹拂的动态效果。
2023-07-24 19:25:021

获取shader中某个变量的值

在写shader时,经常想要看看某个变量在运行时的值是多少,通过两步实现: 1.在shader中添加一个方法,把某个值变为一个颜色,其中R存储存储mod(对255取模)的值,g通道存储余数(除以255)的值,然后把该颜色设置为gl_FragColor输出。 2.在shader外面获取经过该shader渲染后的CVPixelbuffer,在获取第一个像素的颜色,从而计算出shader中传输出来的值
2023-07-24 19:25:091

如何debug shader

1.正确安装DirectX:在Custom Setup步骤时,选择DirectX Uitlities->DirectX extentions forvisual Studio.net2.正确设置DirectX:在控制面板中,打开DirectX,Direct3D属性页,选择Using Debug vision ofDirect3D, Enumerate Reference Rasterizer, Enable Shader Debugging 等关键选项。3.创建合理的D3D设备。CreateDevice的其中一个参数用D3DDEVTYPE_REF,虽然用D3DDEVTYPE_HAL也可以调试Vertex Shader,但是调试Pixel shader 必须用D3DDEVTYPE_REF参数来创建Device。4.编译shader file。把编译函数D3DXCreateEffectFromFile的dwShaderFlags设置为D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT| D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT。当然也可以别的参数可以选择,比如D3DXSHADER_DEBUG。但设置上面两项就可以。5.启动程序。不用debug->start,而是用debug->Direct3D->Start Direct3D Debugging.6.OK了,接下去就像调试cpp去调试shader 文件,设各种断点(比如条件断点),查看变量,汇编代码等等。在程序断下来时,还可以在Debug->Direct3D->RenderTarget/RenderTexture看到当前的纹理或目标纹理。7. 学会调试,才会更深入理解程序!
2023-07-24 19:25:161

会写shader的程序值多少钱

为一个在国外混生活的技术美术,觉得有必要来回答一下:D写shader这个事情,有两类人应该会:1,技术美术。2,图形程序员。技术美术应该从审美角度,写出最漂亮的效果,当然也要留意效率。图形程序员主要是从效率的角度,把技美写的shader优化到最快,当然也要兼顾效果尽量不要打折扣。国内来说,我是美术科班出身的。程序员朋友也很多,据我的了解,中国的教育制度是完全没有同时培养美术和程序的课程的。国外的大学,说实话这方面没有比国内好很多,只是资源更丰富一点,想学得好,还是靠自学。这里突然想到一个事情,为什么国内的美术学编程障碍大:英语! 反正我高考那会,英语都不算成绩就是了。我英语也是出国之后重头学的。总之国外呢,比国内好点,因为AAA的大公司有成熟的流水线和人员培训,加上老外读代码没有语言障碍,所以美术转技美比较容易。所以技美绝对数量多。你抱怨的,美术没有程序素养,这个,咳~ 实在,没办法,人家是美术,为什么要有程序素养。。。。 美术跟程序解释补色,估计也会遇到同样的问题。。。。
2023-07-24 19:25:231

unity骨骼动画用什么shader

Unity的骨骼动画一般使用的是Unity自带的StandardShader。根据查询相关公开信息显示,这种shader可以允许在3D模型上调整基本的光照效果,同时它允许为3D模型添加基本的材质效果,例如镜面反射、环境反射等。还可以调整材质的贴图,并且通过混合不同的贴图来创建复杂的贴图效果。
2023-07-24 19:25:301

如何系统的学习 Unity 3D 中的 shader 编写

这会是个比较漫长的学习过程(一)国内引进出版的书籍国内引进或出版的图形学书籍很多,但是大部分是糟粕,看它们是浪费时间3D数学基础:图形与游戏开发这本可以补数学基础,矩阵变换,线性代数啥的图形着色器:理论与实践(第2版)这本是比较新的讲 opengl shader 的DirectX 9.0 3D游戏开发编程基础这本是国内出版或引进的 d3d 书籍中唯一能看的(二)国内没有引进的书籍,可以下载电子版或上淘宝买打印版OpenGL Shading Language可以认为是 glsl 的圣经Introduction to 3D Game Programming: With Directx 11可以认为是 d3d11 的圣经,这本是 DirectX 9.0 3D游戏开发编程基础 的升级版(三)个人推荐3D数学基础:图形与游戏开发DirectX 9.0 3D游戏开发编程基础Introduction to 3D Game Programming: With Directx 11
2023-07-24 19:25:402

《Unity Shader入门精要》笔记(三)

二维笛卡尔坐标系: x轴、y轴朝向并非固定,如:OpenGL和DirectX使用了不同的二维笛卡尔坐标系。 三维笛卡尔坐标系: 标准基矢量:互相垂直,且长度为1的基矢量。 正交基:互相垂直,但长度不为1的基矢量。 以手的大拇指作为 +x 轴,食指作为 +y 轴,中指作为 +z 轴,将3根手指互相垂直,可以用左手示意的坐标系,为左手坐标系: 可以用右手示意的坐标系,为右手坐标系: 左手坐标系和右手坐标系无法通过旋转实现坐标轴指向重合。 左手坐标系和右手坐标系分别对应 左手法则 和 右手法则 ,用来在坐标系中定义旋转的正方向,下图4个手指指向的方向即为正方向: Unity的模型空间和世界空间使用的是左手坐标系,注意观看下图红、绿、蓝轴在右上角分别对应x轴、y轴、z轴: Unity的观察空间使用的是右手坐标系。观察空间,就是以摄像机作为原点的坐标系,在这个坐标系中,摄像机的前向是z轴的负方向,与模型/世界空间的定义相反。即:z轴坐标的减少意味着场景深度的增加。 点是n维空间(游戏中主要是用二维、三维空间)中的一个位置,没有大小、宽度的概念。 二维空间点的表示: p = (x, y) 三维空间点的表示: p = (x, y, z) 矢量是n为空间中包含模和方向的有向线段,没有位置的概念。 矢量的模:矢量的长度,非负数。 矢量的方向:矢量在空间中的指向。 矢量的表示与点类似, v = (x, y),v = (x, y, z),v = (x, y, z, w) 。 为区分点和矢量,在变量书写上,标量用小写字母表示,如:a, b, x, y, z等;矢量用小写的粗体字母表示,如: a , b , u , v 等。 矢量通常有一个箭头表示: 标量是只有模,没有方向的量,比如:距离、速度等。 矢量无法与标量进行加减运算,但是可以进行乘法或除法运算。 矢量与标量的乘法: kv = (kv x , kv y , kv z ) 矢量可以被非0的标量除,但是矢量无法作为除数: 从几何意义上看,一个矢量 v 和一个标量k相乘,意味着对矢量 v 进行一个大小为|k|的缩放。若k<0,则矢量方向取反,如下图: 两个矢量加减,即:两个矢量的对应分量进行加减,公式如下: a + b = (a x +b x , a y +b y , a z +b z ) a - b = (a x -b x , a y -b y , a z -b z ) 从几何意义上看,矢量加法,即:把矢量 a 的头连接到矢量 b 的尾,然后画一条从 a 的尾到 b 的头的矢量,来得到 a 和 b 相加后的矢量,如下图所示: 也可以理解为:一个点从 a 的尾进行位置偏移 a ,在进行位置偏移 b ,就等同于进行了 a + b 的位置偏移,这被称为矢量加法的 三角形定则 。 矢量的减法类似: 在图形学中,矢量通常用于描述位置偏移(简称位移)。我们可以利用矢量的加法和减法来计算一点相对于另一点的位移。 矢量的模是一个标量,可以理解为矢量在空间中的长度。表示符号通常是在矢量的两边加上竖线,比如:| v |。 三维矢量的模的计算公式: 其他维度的矢量的模计算类似,都是对每个分量平方相加后开根号。几何意义,可用下图解释: 单位矢量指模为1的矢量,也被称为被归一化的矢量(normalized vector)。通常用在只关心方向,不关心模的矢量,比如:模型的发现方向、光源方向等。 把非零矢量转换成单位矢量的过程叫 归一化 。 单位矢量的表示为: 单位矢量的公式: 零矢量:每个分量的值都为0的矢量,如: v = (0, 0, 0)。零矢量不能被归一化,因为除法运算时,分母不能为0。 从几何意义上看,对于二维空间,单位矢量就是从圆心出发、到圆边界的矢量: 对于三维空间,单位矢量就是从圆心出发、到球面的矢量。 在Unity Shader中,会经常遇到法线方向、光源方向,这些矢量不一定是归一化后的矢量,计算的时候需要将这些矢量归一化成单位矢量。 矢量的乘法有两种类型:点积(dot product)、叉积(cross product)。 矢量的点积,也叫内积。点积的运算表示: a · b ,中间的点不能省略。 点积公式一 : a · b = (ax, ay, az) · (bx, by, by) = axby + ayby + azbz 点积满足交换律: a · b = b · a 点积的几何意义: 投影 。 投影的值可能是负数,投影结果的正负号与 a 、 b 两个矢量的方向有关:方向相反,结果小于0;方向相同,结果大于0;方向垂直,结果等于0。 性质一: 点积可结合标量乘法 (k a )· b = a ·(k b )=k( a · b ) k的几何意义是:对矢量进行缩放。 性质二: 点积可结合矢量加减法 a ·( b + c ) = a · b + a · c 将 c 换成- c 就是减法的版本。 性质三: 一个矢量与自身点积的结果是该矢量模的平方 v · v = v x v x + v y v y + v z v z = | v | 2 可以用矢量点积的形式来求矢量的模,Shader中常用模的平方来直接做比较或运算,目的是减少开放带来的性能消耗。 点积公式二 : a · b = | a || b |cosθ 公式二的证明: 假设对两个单位矢量进行点积 如下图所示: 由上图可知,cosθ对应的直角边是: a · b 的点积( b 矢量在 a 矢量的投影),且 cosθ = 直角边 / 斜边 ,则 a · b 的点积 = cosθ * 斜边 ,因为单位矢量 b 的模是1(斜边长度为1),所以: a · b 的点积 = cosθ,也就是两个单位矢量的点积为夹角的cos值。 再由之前性质一,可得推导公式二: 由公式二可知,点积可用于求两个矢量的夹角: 叉积,也叫外积。与点积不同,叉积的结果仍然是矢量,而非标量。 叉积的表示: a x b ,叉号不能省略。叉积的计算公式如下: a x b = (a x , a y , a z ) x (b x , b y , b z ) = (a y b z -a z b y , a z b x -a x b z , a x b y -a y b x ) 具体的记法,可以这样: 叉积不满足交换律,即: a x b ≠ b x a ;但是叉积满足反交换律,即: a x b = - ( b x a )。 叉积不满足结合律,即:( a x b ) x c ≠ a x ( b x c )。 叉积的几何意义: 对两个矢量进行叉积的结果,会得到同时垂直于这两个矢量的新矢量。 叉积的模 公式: | a x b | = | a || b |sinθ 这容易联想到平行四边形求面积: 面积A = | b | h = | b | (| a | sinθ) = | a || b |sinθ 叉积的方向 从几何意义可知,两个矢量的叉积,会得到垂直于两个矢量的新矢量,但是与其垂直的有两个向量。这时前面学到的 左/右手坐标系 就派上用场了,它用来确定叉积得到新矢量的方向朝哪边。 将大拇指与a同向,食指与b同向,中指指向的方向就是叉积结果的方向,所以使用左、右手就会得到不同的朝向,如下图: 同理,左右手法则也通用可以用来判断,如下图: 矩阵(Matrix),就是有m x n个标量组成的长方形数组,通常用方括号在左右两侧围住这些数字,大概像这样: 有些资料也会用圆括号或花括号,其实都一样的。 矩阵有行、列之分,上图的数组就是三行四列。以3x3矩阵为例,它可以写成: mij表示这个元素在矩阵M的第i行、第j列。 矢量,我们通常写成: a = (x, y, z),可以看出矢量与矩阵一样,也是个数组。将矢量按照矩阵的写法,可以看成是 n x 1 的列矩阵或 1 x n 的行矩阵,n对应矢量的维度。 以矢量 v = (3, 8, 6)举例,写成行矩阵: [3, 8, 6] 写成列矩阵: 为什么要和矢量联系起来?因为Shader中经常会将法线(矢量)进行坐标变换,而坐标变换是矩阵的几何意义,所以需要运用矩阵的运算来将法线从模型空间转变成世界空间。(后续会学到) 与矢量类似,矩阵和标量相乘后,结果仍然是一个矩阵。公式如下: 矩阵和矩阵相乘后,结果也是矩阵。新的矩阵的维度与两个原矩阵的维度有关。一个 rxn 的矩阵A和一个 nxc 的矩阵B相乘后,得到的结果AB是一个 rxc 大小的矩阵。需要注意, 第一个矩阵的列数必须和第二个矩阵的行数相等,才能相乘 。 比如:矩阵A的维度是 4x3 ,矩阵B的维度是 3x6 ,则AB的维度是 4x6 。 矩阵乘法的表达式: 假设有 rxn 的矩阵A和 nxc 的矩阵B,相乘后得到一个 rxc 的矩阵C = AB,那么C中的每个元素Cij等于A的第i行所对应的矢量和B的第j列所对应的矢量进行点乘的结果,即: 简单解释为: 对于每个元素c ij ,找到A中的第 i 行和B中的第 j 列,把他们对应的元素相乘后再加起来,这个和就是c ij 。 性质一: 矩阵乘法不满足交换律: AB ≠ BA 性质二: 矩阵乘法满足结合律: (AB)C = A(BC) 、 ABCDE = ((A(BC))D)E = (AB)(CD)E 方块矩阵,简称方阵。指行数和列数相等的矩阵,比如: 3x3 、 4x4 的矩阵。 方块矩阵独有的: 对角元素 ——行号和列号相等的元素。只有对角元素非0的矩阵叫 对角矩阵 。 对角元素都为1的对角矩阵,叫做单位矩阵,用I n 表示,比如: 单位矩阵特性:任何矩阵和它相乘的结果还是原来的矩阵。相当于标量中1的地位。 MI = IM = M 转置矩阵实际是对原矩阵的一种运算,即转置运算。一个 rxc 的矩阵M,其转置表示成M T ,是一个 cxr 的矩阵,本质是原来的矩阵行、列对换。 性质一: 矩阵转置的转置等于原矩阵。 (M T ) T = M 性质二: 矩阵串联的转置,等于反向串联各个矩阵的转置。 (AB) T = B T A T 只有方阵才有逆矩阵,逆矩阵表示为M -1 。一个矩阵与它的逆矩阵相乘,结果是一个单位矩阵: MM -1 = M -1 M = I 有点标量里面倒数的味道。 不是所有方阵都有对应逆矩阵,比如:所有元素都为0的矩阵。 如果一个矩阵有对应的逆矩阵,则它是 可逆的 或 非奇异性的 ; 相反,则它是 不可逆的 或 奇异性的 。 判断矩阵是否可逆: 矩阵的 行列式 不为0,则它是可逆的。 参考视频链接: https://www.bilibili.com/video/BV1aW411Q7x1?p=2 性质一: 逆矩阵的逆矩阵是原矩阵本身。 (M -1 ) -1 = M 性质二: 单位矩阵的逆矩阵是它本身。 I -1 = I 性质三: 转置矩阵的逆矩阵是逆矩阵的转置。 (M T ) -1 = (M -1 ) T 性质四: 矩阵串联相乘后的逆矩阵等于反串联各个矩阵的逆矩阵。 (AB) -1 = B -1 A -1 (ABCD) -1 = D -1 C -1 B -1 A -1 矩阵的几何意义是 变换 ,逆矩阵表示还原这个变换,或这个变换的反向变换。 使用变化矩阵M对矢量 v 进行一次变换,然后再使用逆矩阵M -1 进行一次变换,会得到原来的矢量v。 M -1 (M v ) = (M -1 M) v = I v = v 正交矩阵是特殊的方阵。一个方阵M和它的转置矩阵的乘积是单位矩阵,则这个矩阵是正交的。 MM T = M T M = I 有逆矩阵的性质MM -1 = M -1 M = I可以得出正交矩阵的逆矩阵是它的转置矩阵: M T = M -1 正交矩阵可以用转置矩阵的运算代替逆矩阵的运算,因为逆矩阵计算更复杂。 怎样判定一个矩阵是正交矩阵?来看一下它有哪些定义。 因为: 所以: 于是可以得到以下结论: 一个矢量(比如:平行光的方向、表面发现方向),既可以写成行矩阵的形式,也可以写成列矩阵的形式,但是当它和矩阵相乘时,使用行矩阵还是列矩阵对其乘法的书写次序和结果值是有影响的。 假设有一个矢量 v = (x, y, z),写成行矩阵是: v = [x y z],写成列矩阵是: v = [x y z] T (这里使用转置符号表示列矩阵的写法,纯粹为了排版)。另外有一个矩阵M: 当M和行矩阵相乘时,写法为: v M = [xm 11 +ym 21 +zm 31 xm 12 +ym 22 +zm 32 xm 13 +ym 23 +zm 33 ] 当M和列矩阵相乘时,写法为: 可以看到两者相乘的书写次序和结果里面元素也是不一样的。 Unity中通常把矢量当做列矩阵,所以相乘时,矢量是放在矩阵的右侧的,且阅读顺序也是从右到左。例如: CBA v = (C(B(A v ))) 表示先对 v 进行A矩阵变换,再进行B矩阵变换,最后进行C矩阵变换。
2023-07-24 19:25:481

shader是什么意思?

2D图形,就是无论你如何移动视角,地面上的建筑物、花草树木样子都不会变,而3D图形则不 同,随着视角的变换,你看到的物体也在变化,从正面变成侧面,越远的物体越小,越近的越大,与现实生活中人眼看到的情景非常相似。   shader就是专门用来渲染3D图形的一种技 术,通过shader,程序设计人员可以自己编写显卡渲染画面的算法,使画面更漂亮、更逼真。 几年前并没有shader这个东西,所以那时候的显卡,就不 支持shader,而只支持固定管线渲染,游戏画面也没有现在的酷。   shader又分两种 ,一种是顶点shader(3D图形都是由一个一个三角形组 成的,顶点shader就是计算顶点位置,并为后期像素渲染做准备的),另一种是像素shader,像素shader顾名思义,就是以像素为单位,计算光 照、颜色的一系列算法。   几 个不同的图形API有各自的shader语言:  在DirectX中,顶点shader叫做 vertex shader ,像素shader叫做 pixel shader;   在OpenGL中,顶点shader也叫做 vertex shader ,但像素shader叫做 fragment shader。   此外显卡芯片厂商nVidia还推出CG显卡编程语言,也支持 shader。   shader 有很多不同的版本:  所以,即使你的显卡支持shader,但可能版本不够高,所以无法支持比较新的游戏使用的 shader。   一般来说,大部分游 戏都支持不同版本的shader,为的是让尽可能多的机器都能运行,为此需要做很多额外的工作。   除了显卡不够新之外,不同显卡厂商对shader的支持也不尽相同,所以同一个游戏,一样的 设置,在n卡和ATI的卡上,表现可能大不一样。   另外,安装官方最新的驱动程序也是必要的。如果你安装了错误的驱动程序,甚至是随便从网上下载一个显卡驱动,那么即使你的显卡支持 shader,也可能跑不了需要shader支持的程序,包括但不限于网络游戏! 三个level:
2023-07-24 19:26:111

shader是什么意思?

2D图形,就是无论你如何移动视角,地面上的建筑物、花草树木样子都不会变,而3D图形则不 同,随着视角的变换,你看到的物体也在变化,从正面变成侧面,越远的物体越小,越近的越大,与现实生活中人眼看到的情景非常相似。   shader就是专门用来渲染3D图形的一种技 术,通过shader,程序设计人员可以自己编写显卡渲染画面的算法,使画面更漂亮、更逼真。 几年前并没有shader这个东西,所以那时候的显卡,就不 支持shader,而只支持固定管线渲染,游戏画面也没有现在的酷。   shader又分两种 ,一种是顶点shader(3D图形都是由一个一个三角形组 成的,顶点shader就是计算顶点位置,并为后期像素渲染做准备的),另一种是像素shader,像素shader顾名思义,就是以像素为单位,计算光 照、颜色的一系列算法。   几 个不同的图形API有各自的shader语言:  在DirectX中,顶点shader叫做 vertex shader ,像素shader叫做 pixel shader;   在OpenGL中,顶点shader也叫做 vertex shader ,但像素shader叫做 fragment shader。   此外显卡芯片厂商nVidia还推出CG显卡编程语言,也支持 shader。   shader 有很多不同的版本:  所以,即使你的显卡支持shader,但可能版本不够高,所以无法支持比较新的游戏使用的 shader。   一般来说,大部分游 戏都支持不同版本的shader,为的是让尽可能多的机器都能运行,为此需要做很多额外的工作。   除了显卡不够新之外,不同显卡厂商对shader的支持也不尽相同,所以同一个游戏,一样的 设置,在n卡和ATI的卡上,表现可能大不一样。   另外,安装官方最新的驱动程序也是必要的。如果你安装了错误的驱动程序,甚至是随便从网上下载一个显卡驱动,那么即使你的显卡支持 shader,也可能跑不了需要shader支持的程序,包括但不限于网络游戏! 三个level:
2023-07-24 19:26:181

什么是Shader

2D图形,就是无论你如何移动视角,地面上的建筑物、花草树木样子都不会变,而3D图形则不 同,随着视角的变换,你看到的物体也在变化,从正面变成侧面,越远的物体越小,越近的越大,与现实生活中人眼看到的情景非常相似。   shader就是专门用来渲染3D图形的一种技 术,通过shader,程序设计人员可以自己编写显卡渲染画面的算法,使画面更漂亮、更逼真。 几年前并没有shader这个东西,所以那时候的显卡,就不 支持shader,而只支持固定管线渲染,游戏画面也没有现在的酷。   shader又分两种 ,一种是顶点shader(3D图形都是由一个一个三角形组 成的,顶点shader就是计算顶点位置,并为后期像素渲染做准备的),另一种是像素shader,像素shader顾名思义,就是以像素为单位,计算光 照、颜色的一系列算法。   几 个不同的图形API有各自的shader语言:  在DirectX中,顶点shader叫做 vertex shader ,像素shader叫做 pixel shader;   在OpenGL中,顶点shader也叫做 vertex shader ,但像素shader叫做 fragment shader。   此外显卡芯片厂商nVidia还推出CG显卡编程语言,也支持 shader。   shader 有很多不同的版本:  所以,即使你的显卡支持shader,但可能版本不够高,所以无法支持比较新的游戏使用的 shader。   一般来说,大部分游 戏都支持不同版本的shader,为的是让尽可能多的机器都能运行,为此需要做很多额外的工作。   除了显卡不够新之外,不同显卡厂商对shader的支持也不尽相同,所以同一个游戏,一样的 设置,在n卡和ATI的卡上,表现可能大不一样。   另外,安装官方最新的驱动程序也是必要的。如果你安装了错误的驱动程序,甚至是随便从网上下载一个显卡驱动,那么即使你的显卡支持 shader,也可能跑不了需要shader支持的程序,包括但不限于网络游戏! 三个level:
2023-07-24 19:26:281

什么是Shader

2D图形,就是无论你如何移动视角,地面上的建筑物、花草树木样子都不会变,而3D图形则不 同,随着视角的变换,你看到的物体也在变化,从正面变成侧面,越远的物体越小,越近的越大,与现实生活中人眼看到的情景非常相似。   shader就是专门用来渲染3D图形的一种技 术,通过shader,程序设计人员可以自己编写显卡渲染画面的算法,使画面更漂亮、更逼真。 几年前并没有shader这个东西,所以那时候的显卡,就不 支持shader,而只支持固定管线渲染,游戏画面也没有现在的酷。   shader又分两种 ,一种是顶点shader(3D图形都是由一个一个三角形组 成的,顶点shader就是计算顶点位置,并为后期像素渲染做准备的),另一种是像素shader,像素shader顾名思义,就是以像素为单位,计算光 照、颜色的一系列算法。   几 个不同的图形API有各自的shader语言:  在DirectX中,顶点shader叫做 vertex shader ,像素shader叫做 pixel shader;   在OpenGL中,顶点shader也叫做 vertex shader ,但像素shader叫做 fragment shader。   此外显卡芯片厂商nVidia还推出CG显卡编程语言,也支持 shader。   shader 有很多不同的版本:  所以,即使你的显卡支持shader,但可能版本不够高,所以无法支持比较新的游戏使用的 shader。   一般来说,大部分游 戏都支持不同版本的shader,为的是让尽可能多的机器都能运行,为此需要做很多额外的工作。   除了显卡不够新之外,不同显卡厂商对shader的支持也不尽相同,所以同一个游戏,一样的 设置,在n卡和ATI的卡上,表现可能大不一样。   另外,安装官方最新的驱动程序也是必要的。如果你安装了错误的驱动程序,甚至是随便从网上下载一个显卡驱动,那么即使你的显卡支持 shader,也可能跑不了需要shader支持的程序,包括但不限于网络游戏! 三个level:
2023-07-24 19:26:381

3dmax中的shader功能是什么

自带
2023-07-24 19:26:453

unity shader有什么好处

你好,Shader就是在GPU上运行的程序叫做着色器程序(一般的程序在CPU上执行指令)。Unity Shader使用的是NVIDIA公司的Cg标准语言,可以处理顶点着色、像素着色任务。Unity中的游戏对象只要是可视的,就一定会调用shader渲染,最简单的shader就是diffuse类型,就是你给对象涂个什么颜色,这个对象在白光下就是什么颜色。一般来讲游戏中的 材质=shader+贴图和其它数据,要想表现特殊的材质,比如镜面反射、水面、塑料等,就需要编程shader(Unity中有一些默认的shader)。
2023-07-24 19:26:531

unity 用什么shader

  如果是进行3d游戏开 发的话,想必您对着两个词不会陌生。Shader(着色器)实际上就是一小段程序,它负责将输入的Mesh(网格)以指定的方式和输入的贴图或者颜色等组 合作用,然后输出。绘图单元可以依据这个输出来将图像绘制到屏幕上。输入的贴图或者颜色等,加上对应的Shader,以及对Shader的特定的参数设 置,将这些内容(Shader及输入参数)打包存储在一起,得到的就是一个Material(材质)。之后,我们便可以将材质赋予合适的 renderer(渲染器)来进行渲染(输出)了。  所以说Shader并没有什么特别神奇的,它只是一段规定好输入(颜色,贴图等)和输出(渲染器能够读懂的点和颜色的对应关系)的程序。而Shader开发者要做的就是根据输入,进行计算变换,产生输出而已。  Shader大体上可以分为两类,简单来说  表面着色器(Surface Shader) - 为你做了大部分的工作,只需要简单的技巧即可实现很多不错的效果。类比卡片机,上手以后不太需要很多努力就能拍出不错的效果。  片段着色器(Fragment Shader) - 可以做的事情更多,但是也比较难写。使用片段着色器的主要目的是可以在比较低的层级上进行更复杂(或者针对目标设备更高效)的开发。
2023-07-24 19:27:141

怎么打开自带的shader文件

UNITY自带的SHADER放在:AssetsStandard Assets (Mobile)Shaders 中,导入的时候会自动从这里加载所有的shaders工具。Shader程序的基本结构因为着色器代码可以说专用性非常强,因此人为地规定了它的基本结构。一个普通的着色器的结构应该是这样的:首先是一些属性定义,用来指定这段代码将有哪些输入。接下来是一个或者多个的子着色器,在实际运行中,哪一个子着色器被使用是由运行的平台所决定的。子着色器是代码的主体,每一个子着色器中包含一个或者多个的Pass。在计算着色时,平台先选择最优先可以使用的着色器,然后依次运行其中的Pass,然后得到输出的结果。最后指定一个回滚,用来处理所有Subshader都不能运行的情况(比如目标设备实在太老,所有Subshader中都有其不支持的特性)。需要提前说明的是,在实际进行表面着色器的开发时,将直接在Subshader这个层次上写代码,系统将把用户的代码编译成若干个合适的Pass。
2023-07-24 19:27:211

Shader 3.0是什么意思?

Shader Model 3.0是最新DirectX 9.0c的标准 作为Microsoft DirectX 9.0c API的重要组成部分,Shader Model 3.0由Pixel Shader 3.0和Vertex Shader 3.0两个着色语言规范组成。请参考 http://baike.baidu.com/view/15762.htm?fr=ala0_1_1
2023-07-24 19:27:341

unity shader中有哪些属性如何使用

如果是进行3d游戏开 发的话,想必您对着两个词不会陌生。Shader(着色器)实际上就是一小段程序,它负责将输入的Mesh(网格)以指定的方式和输入的贴图或者颜色等组 合作用,然后输出。绘图单元可以依据这个输出来将图像绘制到屏幕上。输入的贴图或者颜色等,加上对应的Shader,以及对Shader的特定的参数设 置,将这些内容(Shader及输入参数)打包存储在一起,得到的就是一个Material(材质)。之后,我们便可以将材质赋予合适的 renderer(渲染器)来进行渲染(输出)了。所以说Shader并没有什么特别神奇的,它只是一段规定好输入(颜色,贴图等)和输出(渲染器能够读懂的点和颜色的对应关系)的程序。而Shader开发者要做的就是根据输入,进行计算变换,产生输出而已。Shader大体上可以分为两类,简单来说表面着色器(Surface Shader) - 为你做了大部分的工作,只需要简单的技巧即可实现很多不错的效果。类比卡片机,上手以后不太需要很多努力就能拍出不错的效果。片段着色器(Fragment Shader) - 可以做的事情更多,但是也比较难写。使用片段着色器的主要目的是可以在比较低的层级上进行更复杂(或者针对目标设备更高效)的开发。
2023-07-24 19:27:531

请问在Unity的像素Shader里返回的颜色的计算模式是什么样的?

shader是一个框架,它里面带有材质和颜色等等内容修改颜色可以用renderer.material.color
2023-07-24 19:28:014

UNITY自带的SHADER放在哪个目录的

注意到网上的Shader代码中的最后一行FallBack "Specular"没有?该语句的意思是如果没有找到适合该Shader的硬件,那么自动匹配Unity3D自带的Specular Shader。那么答案就很清楚了:Unity3D自带的Shader必须全面的针对几乎所有可能出现的硬件,所以要添加尽量多的分支来满足要求。每一个分支匹配不同的硬件。而网上下载的Shader往往只需要考虑几种硬件就可以了。一般Shader作者会标明是否匹配移动平台,适应OpenGL ES1,2,3还是需要DX11支持等信息。如果没有标明那么你就只能自己尝试了。
2023-07-24 19:28:082

UNITY自带的SHADER放在哪个目录的

一般你在建立工程的时候可以选择导入,这样就在你的工程目录下的AssetsStandard Assets (Mobile)Shaders 中。U3D本身的shader其实是在软件安装目录的...UnityEditorStandard Packages中
2023-07-24 19:28:231

怎么通过脚本修改shader属性值

用SetColor()函数具体看官方脚本手册的Material类例子是:functionStart(){//设置glossy着色器以便使用高光颜色renderer.material.shader=Shader.Find("Glossy");//设置高光色为红色renderer.material.SetColor("_SpecColor",-
2023-07-24 19:28:301