unity 在sceneunity3d改变模型颜色有颜色框怎么用

Unity使用着色器为游戏添加颜色的方法 VR资源
今天为大家分享一位游戏开发学生与他的小型团队,在为期5天的课堂Game Jam中使用Unity制作小游戏《Color Wars》的过程,以及其中使用着色器为游戏画面添加各种颜色的方法。
他们制作的《Color Wars》是一款非常简单的2.5D多人对战游戏,玩家可以射击敌人,为敌人或者为场景加上颜色。游戏效果如下:
所有游戏的特效魔法背后,都是最原始的3D模型、图片与人物精灵来组成整个场景。这些组成场景的元素都有其颜色及纹理。
其中比较棘手的部分是需要在Alpha通道中屏蔽所有元素的颜色。换而言之,默认情况下,屏幕的整个Alpha通道都是黑色的,直到玩家开始喷射油漆,才会使被油漆溅到区域的Alpha通道变为白色。然后图像效果就是其原有颜色与灰度进行混合。
从上图可以看出,使用Projector将喷漆绘制到物体表面并创建颜色遮罩。每个Projector都使用程序化动态生成,在子弹(空中飞行的白点)接触到某个表面时进行初始化。Projector带有一个盒式碰撞体,当子弹落在Projector上时,不会初始化新的Projector,而是让原先的Projector变大。这样漆量会变多,而场景中的Projector数量却保持不变。
默认情况下,Unity标准着色器会为所有不透明对象的Alpha通道写入1。所以下面使用自定义着色器来替换Unity标准着色器。新建一个标准表面着色器,将其表面函数替换为如下:
void surf (Input IN, inout SurfaceOutputStandard o)
&&&&&&&&fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _C
&&&&&&&&o.Albedo = c.
&&&&&&&&o.Metallic = _M
&&&&&&&&o.Smoothness = _G
&&&&&&&&o.Alpha = 0;&
下面这行很重要,用于避免Unity更改自定义的Alpha值。将#pragma那行代码改为如下:
#pragma surface surf Standard fullforwardshadows keepalpha
注意,该技巧不可用于Unity中的延迟渲染管线,因为它重写了G-Buffer中的Alpha通道来存储遮罩数据。
当子弹撞击某个表面时就会在撞击处动态生成Unity Projector。这些Projector带有自定义材质与自定义着色器。材质纹理是一张带有Alpha通道喷溅形状图,本文示例使用的纹理如下图:
注意,纹理导入设置中要将Wrap Mode设为&Clamp&而非&Repeat&。用于Projector材质的着色器从Unity提供的ProjectorLight修改而来,代码如下:
Shader &Projector/ProjectAlpha&
&&&&&&&&Properties
&&&&&&&&&&&&&&&&_ShadowTex (&Cookie&, 2D) = &gray& {}
&&&&&&&&Subshader
&&&&&&&&&&&&&&&&Tags { &Queue&=&Transparent&}
&&&&&&&&&&&&&&&&Pass
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&&&&ZWrite Off
&&&&&&&&&&&&&&&&&&&&&&&&Blend Zero One, One One
&&&&&&&&&&&&&&&&&&&&&&&&Offset -1, -1
&&&&&&&&&&&&&&&&&&&&&&&&CGPROGRAM
&&&&&&&&&&&&&&&&&&&&&&&&#pragma vertex vert
&&&&&&&&&&&&&&&&&&&&&&&&#pragma fragment frag
&&&&&&&&&&&&&&&&&&&&&&&&#pragma multi_compile_fog
&&&&&&&&&&&&&&&&&&&&&&&&#include &UnityCG.cginc&
&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&struct Input
&&&&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&&&&float4 vertex : POSITION;
&&&&&&&&&&&&&&&&&&&&&&&&float3 normal : NORMAL;
&&&&&&&&&&&&&&&&&&&};
&&&&&&&&&&&&&&&&&&&&&&&&struct v2f
&&&&&&&&&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&float4 uvShadow : TEXCOORD0;
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&UNITY_FOG_COORDS(2)
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&float4 pos : SV_POSITION;
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&fixed nv : COLOR0;
&&&&&&&&&&&&&&&&&&&&&&&&};
&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&float4x4 unity_P
&&&&&&&&&&&&&&&&&&&&&&&&float4x4 unity_ProjectorC
&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&v2f vert (Input v)
&&&&&&&&&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&v2
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&o.uvShadow = mul(unity_Projector, v.vertex);
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&UNITY_TRANSFER_FOG(o,o.pos);
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&float3 normView = normalize(float3(unity_Projector[2][0], unity_Projector[2][1], unity_Projector[2][2]));
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&float nv = dot(v.normal, normView);
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&o.nv = nv & 0 ? 1 : 0;
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&return o;
&&&&&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&sampler2D _ShadowT
&&&&&&&&&&&&&&&&&&&&&&&&sampler2D _FalloffT
&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&fixed4 frag (v2f i) : COLOR
&&&&&&&&&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&fixed4 texS = tex2Dproj (_ShadowTex, UNITY_PROJ_COORD(i.uvShadow));
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&fixed4 res = fixed4(1, 1, 1, texS.a );
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&res.a *= i.
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&UNITY_APPLY_FOG_COLOR(i.fogCoord, res, fixed4(1,1,1,1));
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&return
&&&&&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&&&&&ENDCG
&&&&&&&&&&&&&&&&}
下面来介绍其中最为重要的混合部分。
当着色器计算某个像素的颜色时,该颜色必须作用于屏幕上该点已经存在的像素颜色之上。默认情况下,新的像素会完全覆盖原有像素,但新像素也可以与原有像素进行混合。混合通常用于让对象呈透明或半透明效果,当然也可以实现很多其它的炫酷特效。
关键字Blend可以包含在Subshader或Pass标签中,甚至对同一个着色器的不同Pass进行混合。添加Blend关键字后,必须写入混合因子。混合因子如下:
Src指向着色器用于计算的颜色。Dst指向屏幕上已有的像素颜色。着色器用于计算的颜色会与第一个因子相乘,而屏幕上已有颜色会与第二个因子相乘。将两个结果相加,就是最终写到屏幕的颜色。
所以&Blend SrcAlpha One&会将自身Alpha值与当前着色器计算的颜色相乘,此时屏幕上的颜色暂未改动。然后再将屏幕颜色计算后的结果与前者相加。还可以使用逗号分隔两组因子,逗号前的混合选项用于计算颜色,逗号后的混合选项仅计算Alpha通道。可以查阅Unity文档了解更多关于混合的内容。
用于Projector的着色器就是&Blend Zero One, One One&,&Zero One&移除了飞溅纹理的颜色,使用子弹所飞溅到的表面颜色。&One One&将飞溅物的Alpha值与表面Alpha值相加。
现在使用上面的着色器与材质来生成Projector,应该将场景视图的Alpha通道设为白色。
颜色与灰度
现在可以随意修改Alpha通道,但还未达到最终效果。下面利用Alpha遮罩来创建游戏所需的图像特效。
首先,创建要使用图像特效的着色器。在Unity中新建默认的Image Effect Shader,然后将片段代码替换为如下:
fixed4 frag (v2f i) : SV_Target
&&&&&&&&fixed4 col = tex2D(_MainTex, i.uv);
&&&&&&&&fixed3 bnw = dot(col.rgb, float3(0.3, 0.59, 0.11));
&&&&&&&&col.rgb = lerp(bnw, col.rgb, col.a);
&&&&&&&&return
可以随意更改bnw变量以达到理想的混合效果。最后还需要新建脚本来运行该图像特效。脚本非常简单,代码如下:
using System.C
using System.Collections.G
using UnityE
using UnityStandardAssets.ImageE
[ExecuteInEditMode]
[ImageEffectAllowedInSceneView]
public class AlphaColorSwitch : ImageEffectBase
&&&&&&&&void OnRenderImage ( RenderTexture source, RenderTexture destination )
&&&&&&&&&&&&&&&&Graphics.Blit ( source, destination, material );
注意,这里用到了ImageEffectBase,该资源在Unity标准资源库中。导入标准资源库后,将脚本绑定到相机(确保将相机的渲染模式设为Forward)上,并将公共的着色器变量设为前面提到的着色器。
到此就可以向场景中喷射油漆啦!
本文提到的实现方式还存在一些限制,不一定适合所有的应用场景,但对于《Color War》这款游戏来说已足够。主要存在以下两点限制:
1、采用Alpha遮罩就意味着没有Alpha通道,也不支持延迟渲染。这也许可以使用模板、命令缓冲区甚至多渲染目标来解决。
2、项目使用的自定义着色器过多,这种做法并不推荐。如果您的项目可以使用延迟渲染解决其它问题,那么这个问题也就不存在了。
本文为大家分享了在Unity中利用着色器来实现喷绘效果的过程,文中的解决方法仅作为一种思路参考,不一定适用于所有项目。大家也可以按照项目的实际需求,来选取更加适合的解决方案。
<font color=#-12<font color=#-10<font color=#-09<font color=#-09<font color=#-09<font color=#-09<font color=#-09<font color=#-08<font color=#-08<font color=#-08
想知道在Unity中如何将游戏中角色对话的唇型与面部微表情达到次时代的水准吗?想知道...
近日,RLTY CHK工作室的联合创始人Nick Robinson发布了一篇文章,以媒体天师麦克卢汉...
VR设计师和开发者们开始着手如何让VR环境及体验更加有趣、逼真。以下是一些关于如何为room...
笔者在为《幻想装置》和《工作模拟》制作出混合现实的预告片以后,研究了更深层次的VR...
关于用EasyAR SDK 搭建AR 开发环境的教程,我已经写过很多了,不懂得朋友可以看下我之...1811人阅读
unity性能优化(1)
图形化调试可以加速开发。
例如在战斗中,可能需要知道所有单位的仇恨&#20540;,如果这些信息全打log的话,很难有直观感受,
而如果在Scene窗口里,单位头顶有一个球,越红表示仇恨越高,越暗表示仇恨越低,那么调试起来比打log直观多了。
【一 图形化调试】
Unity中图形化调试主要4种
Debug.Draw
Gizmos.Draw
Graphic.DrawMesh
只需在Scene窗口显示的调试图像
&&&&&一直显示的&OnDrawGizmos &#43;&Gizmos.Draw
&&&&&选中显示的&OnDrawGizmosSelected&&#43;&Gizmos.Draw
&&&&&脚本控制的 Update &#43; Debug.Draw
需要在实际设备屏幕显示的调试图像
&&&&Update&#43;Graphic.DrawMesh
&&&&OnRenderObject&#43;GL
Graphic.DrawMesh和Debug.Draw&&&调用一致,都是在Update系里
Graphic.DrawMesh和GL&&&&&&&显示类&#20284;,都在各个窗口显示,并且可以设置材质。
四种方式比较
(1)Debug.Draw
=1=一般在Update/Fixed Update/LateUpdate里调用
=2=只在Scene窗口里显示
=3=并且不能设置材质
&&&&&void&Update()
&&&&&&&&Debug.DrawLine&(worldPos1,&worldPos2,Color.yellow);
(2)Gizmos.Draw
=1=在OnDrawGizmos&/OnDrawGizmosSelected里调用
=2=只在Scene窗口里显示
=3=并且不能设置材质
&&&&public&void&OnDrawGizmosSelected()&{
&&&&&&&&Gizmos.DrawLine(Vector3.zero,&new&Vector3(0,3f,0));
(3)Graphic.DrawMesh
=1=一般在Update/Fixed Update/LateUpdate里调用
=2=实际屏幕和Scene窗口都能显示
=3=可以设置材质
&&&&&&&&&void&Update()
&&&&&&&&&&&&Graphics.DrawMesh(mesh,&worldPos,&worldRotation,&material,&0);
=1=一般在物体的OnRenderObject 或者相机的OnPostRender里调用
=2=实际屏幕和Scene窗口都能显示
=3=可以设置材质
一个GL.Begin/GL.End里的渲染是自动合并的,一般是一个Drawcall
画一些线,三角可以。用GL.TRIANGLES&显示整个Mesh的话会超卡。
例:渲染线框
&&&&&&void&OnRenderObject()
&&&&&&&&mat.SetPass(0);
&&&&&&&&&GL.wireframe&=&true;
&&&&&&&&&GL.Color&(new&Color&(1,1,&0,&0.8F));
&&&&&&&&GL.PushMatrix();
&&&&&&&&GL.Begin(GL.TRIANGLES);
&&&&&&&&for(int&i=0;i&&/span&mesh.triangles.Length-2;i&#43;=3)
&&&&&&&&&&&&GL.Vertex(mesh.vertices[mesh.triangles[i]]);
&&&&&&&&&&&&GL.Vertex(mesh.vertices[mesh.triangles[i&#43;1]]);
&&&&&&&&&&&&GL.Vertex(mesh.vertices[mesh.triangles[i&#43;2]]);
&&&&&&&&GL.End();
&&&&&&&&GL.PopMatrix();
&&&&&&&&&&&&&&GL.wireframe&=&false;
GL除了可以用来调试,可以拿来做功能,例如LineRenderer,地&#26684;等。
GL即Graphics Library。Low-Level Graphics Library。计算matrices,发出类&#20284;OpenGL的immediate模式的渲染指令,和其他低级图像任务。Graphic.DrawMesh()比GL更高效。
GL立即绘制函数只用当前material的设置。因此除非你显示指定mat,否则mat可以是任何材质。并且GL可能会改变材质。
GL是立即执行的,如果你在Update()里调用,它们将在相机渲染前执行,相机渲染将会清空屏幕,GL效果将无法看到。
通常GL用法是
在camera上贴脚本,并在OnPostRender()里执行。
也可以挂在任何GameObject上,在OnRenderObject()里执行。
或者挂在物体上
1.GL的线等基本图元并没有uv. 所有是没有贴图纹理影射的,shader里仅仅做的是单色计算或者对之前的影像加以处理。
2.GL所使用的shader里必须有Cull off指令,否则显示会变成如下
3. 如果是线,颜色是GL.Color(&new Color(1,1,1,0.5f)
);设置的颜色
&&&如果是GL.TRIANGLES或者是GL.QUADS,则颜色是shader里的颜色。
GL.PushMatrix()
保存matrices至matrix stack上。
GL.PopMatrix()
从matrix stack上读取matrices。
GL.LoadPixelMatrix()
改变MVP矩阵,使得transform里的xy 直接对应像素,(0,0)表示屏幕viewport的左下角,z的范围是(-1,1),该函数改变camera的参数,所以需要GL.PushMatrix()保存和GL.PopMatrix()读取。
GL.Vertex3()的取&#20540;范围从左下角的(0,0,0) 至右上角的(Screen.width,Screen.height,0)
GL.LoadOrtho()
设置ortho perspective,即水平视角。After calling LoadOrtho, the viewing frustum goes from (0,0,-1) to (1,1,100). 主要用于在纯2D里绘制图元。
GL.Vertex3()的取&#20540;范围从左下角的(0,0,0) 至右上角的(1,1,0)
OnPostRender()
只有物体上有激活的摄像机时,才会调用的函数,当摄像机完成渲染场景,绘制了所有物体以后调用。
OnPostRender可以变成co-routine,加yield语句即可。
WaitForEndOfFrame()
等待至 所有绘制之后,end of frame, 就在展示frame到屏幕之前。可以做截图。可以在任何物体上使用该函数。
例1:屏幕画线
using&UnityE
using&System.C
public class&GLTest :&MonoBehaviour&{
&&public Material&
&&&&void&OnPostRender() {
&&&&&&&&if&(!mat) {
&&&&&&&&&&&&Debug.LogError(&Please Assign a material
on the inspector&);
&&&&&&&&&&&&return;
&&&&&&&&GL.PushMatrix(); //保存当前Matirx
&&&&&&&&mat.SetPass(0); //刷新当前材质
&&&&&&&&GL.LoadPixelMatrix();//设置pixelMatrix
&&&&&&&&GL.Color(Color.yellow);
&&&&&&&&GL.Begin(GL.LINES);
&&&&&&&&GL.Vertex3(0,&0,&0);
&&&&&&&&GL.Vertex3(Screen.width,&Screen.height,&0);
&&&&&&&&GL.End();
&&&&&&&&GL.PopMatrix();//读取之前的Matrix
using&System.IO;
using&UnityE
using&System.C
public class&ScreenShot :&MonoBehaviour&{
&&&&void&Start() {
&&&&&&&&StartCoroutine(UploadPNG() );
&&&&IEnumerator UploadPNG() {
&&&&&&&&yield return new WaitForEndOfFrame();
print (&yuuuuu&);
&&&&&&&&int&width =&Screen.
&&&&&&&&int&height =&Screen.
&&&&&&&&Texture2D&tex =&new&Texture2D(width, height,&TextureFormat.RGB24,&false);
&&&&&&&&tex.ReadPixels(new&Rect(0,&0,
width, height),&0,&0);
&&&&&&&&tex.Apply();
&&&&&&&&byte[] bytes = tex.EncodeToPNG();
File.WriteAllBytes(Application.dataPath&#43;&/ss.png&,bytes);
UnityEditor.AssetDatabase.Refresh();
例3:展示Alpha
using&UnityE
using&System.C
public class&GLTest :&MonoBehaviour&{
public Shader&
public Texture2D&t2d;
&&private Material&
void&Start()
mat =&new&Material(shader);
mat.mainTexture = t2d;
&&&&void&OnPostRender() {
&&&&&&&&if&(!mat) {
&&&&&&&&&&&&Debug.LogError(&Please Assign a material
on the inspector&);
&&&&&&&&&&&&return;
&&&&&&&&GL.PushMatrix();
&&&&&&&&mat.SetPass(0);
&&&&&&&&GL.LoadOrtho();
&&&&&&&&GL.Begin(GL.QUADS);
&&&&&&&&GL.Vertex3(0,&0,&0.1F);
&&&&&&&&GL.Vertex3(1f,&0,&0.1F);
&&&&&&&&GL.Vertex3(1f,&1,&0.1F);
&&&&&&&&GL.Vertex3(0,&1,&0.1F);
&&&&&&&&GL.End();
&&&&&&&&GL.PopMatrix();
Shader&&Custom/GLDrawLine&&{
Properties&{
_MainTex (&Base (RGB)&,&2D) =&&white&&{}
SubShader&{
&&&&Pass&{
Blend&DstAlpha zero
Color(1,1,1,1)
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:67561次
排名:千里之外
转载:131篇
(1)(1)(1)(17)(2)(3)(5)(3)(1)(17)(40)(5)(2)(10)(4)(4)(5)(2)(10)
(window.slotbydup = window.slotbydup || []).push({
id: '4740881',
container: s,
size: '200,200',
display: 'inlay-fix'unity3d的射击教程中导入的模型颜色很暗啊_unity3d吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:75,873贴子:
unity3d的射击教程中导入的模型颜色很暗啊收藏
想做个我们学校的射击游戏,模型做好了,但导到了射击教程中变得很暗,该怎么增加亮度?
网站建设,快速实现全网营销,费用超低
很简单,shader属性你没改,默认是Diffuse,一般模型改成Unlit—Texture,透明的模型改成Unlit—transparent,如果之前你的模型烘焙贴图加了灯光的话
还有,注意光源。
我想请教下玻璃,水晶类的材质需要烘焙么?我是说在3dmax中?
不用max,爱莫能助
登录百度帐号推荐应用Unity3D Scene窗口不显示模型和软件图标?_百度知道
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。
Unity3D Scene窗口不显示模型和软件图标?
如图,game窗口中有的东西,scene里没有,不是模型大小问题!
我有更好的答案
把layers中的default选上就好了
采纳率:100%
为您推荐:
其他类似问题
unity3d的相关知识
等待您来回答

我要回帖

更多关于 unity scene 的文章

 

随机推荐