unity shader android,GitHub - CatDroid/UnityShaderLabStudy: Unity Shader入门精要 学习demo

不透明物体渲染,需要关闭深度写入的原因

传统的半透明混合总是会在物体交叉、渲染重叠的情况下,出现错误的混合效果。如果开启深度写入,会令到渲染错误很明显,而关掉的话影响较小一点

开启深度写入的半透明效果

深度测试的意义在于舍弃片元与否。

深度写入的意义在于深度测试的基础上,要不要覆盖深度缓冲,即重新设立深度测试的标准。

对于半透明的渲染, 是可以同时开启深度测试和深度写入的。方法是使用2个Pass。一个先只负责保证像素级片元深度正确,一个负责渲染 (左边)

如果没有配合深度写入来保证像素级的深度关系 (右边,关闭深度写入,直接透明混合)

9b84824bfc006e0090a587fb06df09f4.png

Aplha 透明度测试

透明度边界处有锯齿,所以透明效果在边缘处参差不齐,因为边界处纹理的透明度的变化精度问题

5761253df00106298fc05c4bd7ce3f4a.png

复杂遮挡关系的模型 使用 开启深度写入的半透明效果

开启深度写入的半透明效果: 第一打开深度写入 关闭颜色写入ColorMask 0 ; 第二次关闭深度写入 打开颜色写入

这样可以处理 模型本身有复杂的遮挡关系,或者包含复杂的非凸网络的时候

因为在cpu端,无法对模型进行像素级排序

在unity中,可以不自己写shader来实现模型深度写入,SubShader会一个个Pass执行

Pass

{

ZWrite On

ColorMask 0 // ColorMask A | RGB | 0

// 不需要shader去做片元着色 只是写入深度信息

}

Pass

{

Tags

{

"LightMode" = "ForwardBase"

}

ZWrite Off

ColorMask RGBA

Blend SrcAlpha OneMinusSrcAlpha

CGPROGRAM

..... 片元和顶点着色器

ENDCG

}

面剔除

三个设置

设置正面是逆时针 ( 默认 glFrontFace(GL_CCW); ) ,还是顺时针( GL_CW ),

剔除正面还是反面 ( glCullFace(GL_BACK); )

开关面剔除 glEnable( GL_CULL_FACE ); 默认关闭

Unity3d 中 Quad 是一个平面正方形 ,Unity在默认情况下渲染引擎剔除了物体背面,如果Quad能够在Scene场景被看到,应该是一个内部有颜色的正方形,如果对着” Scene场景摄像机” 是 Quad的背面的话,点击Quad物体,看到只是一个框

Unity3d 区别与OpenGL

默认背面剔除

默认是顺时针表示正面,逆时针表示背面

8983e741e0296692b97eda16a79f3b97.png

Quad%E8%83%8C%E9%9D%A2%E5%AF%B9%E7%9D%80%E5%9C%BA%E6%99%AF%E6%91%84%E5%83%8F%E6%9C%BA.png

Unity3d 摄像机

摄像机沿着自己的z轴旋转,不会影响场景中物体/三角形在镜头前的正面和背(现实世界也是,旋转手机不会导致前方物体的朝着摄像机的一面发生变化)

每个摄像机可以设置不同的Target Display,在GameView中可以选择不同的Display,从而可以看到不同摄像机的画面

留意摄像机的z轴方向是对应世界坐标系中的那个轴

Unity3D 旋转正方向

旋转正方向是左手螺旋法则

总结

透明度双面渲染---- 先后分别打开cull front和cull back 面剔除 后渲染个一次 ---- 应用于,显示透明物体内部

打开深度写入的半透明效果--- 先关闭colormask写入打开深度写入,渲染一次模型后,再打开color写入关闭深度写入但保持深度检测,再渲染一次模型----- 应用于,模型本身有复杂遮挡关系

RenderType和Queue的作用

Camera.SetReplacementShader("shader1","RenderType")

首先在场景中找到标签中包含该字符串(这里为"RenderType")的shader,

再去看具有""RenderType"标签的shader,其"RenderType"的值(比如TransparentCutOut,Opaque,Transparent)然后去shader1中查找与"RenderType"的值一样的subShader进行替换

RenderType 内置值

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

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

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

Background: Skybox shaders. 天空盒着色器。

Overlay: GUITexture, Halo, Flare shaders. 光晕着色器、闪光着色器。

TreeOpaque: terrain engine tree bark. 地形引擎中的树皮。

TreeTransparentCutout: terrain engine tree leaves. 地形引擎中的树叶。

TreeBillboard: terrain engine billboarded trees. 地形引擎中的广告牌树。

Grass: terrain engine grass. 地形引擎中的草。

GrassBillboard: terrain engine billboarded grass. 地形引擎何中的广告牌草。

渲染路径

光源的类型: 平行光 点光源 聚光灯 面光源(烘焙)

光源的属性: 颜色 强度 衰减 位置 方向

渲染路径: SubShader.Tags.LightMode

向前渲染

ForwardBase 只有一个逐像素的是平行光 + 所有逐顶点+所有SH(球谐函数)光源

ForwardAdd 其他逐像素的光源(会影响物体) 每个光源执行一遍Pass

延迟渲染

Defered 需要支持MRT(多渲染目标)

顶点照明渲染

Vertex最快的渲染路径,计算所有光源对物体的照明,逐顶点处理 目前作为遗留路径

向前渲染光源的处理方式(光源照亮物体的方式):

场景中会有很多光源,对于向前渲染路径,unity会把光源分类,分类是区分每个光源照亮物体的方式,可以是逐顶点,逐像素,SH方式

依据

光源的类型

光源的渲染模式(important,not-important)

光源分类

(对物体?平行光不计算衰减?因为没有位置属性?)最亮的平行光 逐像素处理 -- ForwardBase?ForwardAdd?

Not Important 的光源 逐顶点或者SH光源 ---ForwardBase

Import的光源 逐像素

根据1,3得到的逐像素光源数量少于Quality Settings中逐像素光源数量 就会有更多光源以逐像素方式

一定数量的光源会按照'逐像素'处理

最多4个光源按照'逐顶点'处理

剩下按照'SH方式'处理

Shader中应该提供 逐像素或者逐顶点 的SubShader ??

ForwardBase的SubSharder 可以逐像素 包含其他逐顶点 和 SH

ForwardAdd的SubSharder 只是逐像素

?? 对于分配到 逐顶点 处理 的光源,会走 RenderType是ForwardBase的SubSharder

编译指令

#pragma multi_compile_fwdbase

#pragma multi_compile_fwdadd

保证在shader中使用光照衰减等内置光照变量,会被正确赋值

“向前渲染”的内置变量和函数

内置变量名

类型

描述

_LightColor0

float4

该Pass处理的逐像素光源的颜色

_WorldSpaceLightPos0

float4

_WorldSpaceLightPos0.xyz是该Pass处理的逐像素光源的位置,.z = 0 平行光 .z !=0 其他光源类型

_LightMatrix0

float4x4

从世界空间到光源空间,光强衰减纹理

unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0

float4

仅用于Base Pass 前4个非重要点光源 在世界空间坐标

unity_4LightAtten0

float4

仅用于Base Pass 前4个非重要点光源 衰减因子

unity_LightColor

half4[4]

仅用于Base Pass 前4个非重要点光源 颜色

内置函数名字

描述

float3 WorldSpaceLightDir(float4 v)

仅用于向前渲染,输入模型空间中的顶点位置,输出世界空间中,该点到光源的光照方向

float3 UnityWorldSpaceLightDir(float4 v)

仅用于向前渲染,输入世界空间中的顶点位置,输出世界空间中,该点到光源的光照方向

float3 ObjSpaceLIghtDir(float4 v)

仅用于向前渲染, 输入模型空间中的顶点位置,返回模型空间中,该点的光照方向

float3 shade4PointLights(..)

仅用于向前渲染,计算4个点光源的光照,参数是4个非重要光源(照亮物体方式会分类成逐顶点或者SH)的 位置unity_4LightPosX0 ,颜色 unity_LightColor ,衰减因子 unity_4LightAtten0

实例

环境光/自发光,只在 Base Pass片元中 计算一次 Addtional Pass不作计算

Bass Pass 中处理最重要的平行光 ;如果场景中有多个平行光,unity会选择最亮的给到BassPass做逐像素处理,其他平行光会按照在Bass Pass逐顶点或在Additional Pass 中逐像素处理。如果场景中没有任何平行光,那么Bass Pass会当做全黑的光源处理。对于Base Pass来说,逐像素处理的一定是平行光

改变

#include “AutoLight.cginc”

Upgrade NOTE: replaced ‘_LightMatrix0’ with ‘unity_WorldToLight’

粒子系统

Unity On Android

File->Build Settings,在弹出框的“Build System”下选择Android选项,勾选“Export Project”

如果没有安装android打包工具,将会提示下载,如下链接

Unity 在C#脚本层导出一些android平台的接口API,对于跨平台,C#脚本层通过宏定义 UNITY_ANDROID 来区分

使用插件可以使C#脚本,直接调用android C/C++的函数,间接调用android java的函数

Unity支持3个不同的脚本后端,根据不同的目标平台, Mono, .Net, IL2CPP , 通用windows平台只支持.Net和IL2CPP

[Menu]--[Edit]--[Preferences]--[External Tools]--[Android]--[SDK/NDK location]

到处工程到Android Studio

包含 libunity.so libil2cpp.so libmain.so 和 libs/unity-classes.jar

UnityAndroidFirstDemo-0.1-v1.symbols.zip 符号库 (非常大)

.

├── arm64-v8a

│   ├── libil2cpp.so.debug

│   ├── libil2cpp.sym

│   └── libunity.sym.so

└── armeabi-v7a

├── libil2cpp.so.debug

├── libil2cpp.sym

└── libunity.sym.so

Unity3D_%E5%AF%BC%E5%87%BAAndroid%E5%B7%A5%E7%A8%8BBuild%E8%AE%BE%E7%BD%AE.png

Unity3D_%E5%AF%BC%E5%87%BAAndroid%E5%B7%A5%E7%A8%8BPlayer%E8%AE%BE%E7%BD%AE.png

由于默认导出时Appliatcon模块,所以可以修改为Library模块

Settings.gradle

include(':unity')

project(':unity').projectDir = new File(settingsDir,'../UnityOnAndroid/')

build.gradle

apply plugin: 'com.android.library'

android {

defaultConfig {

...

//applicationId 'com.hanlon.firstDemo'

// bundle {

// language {

// enableSplit = false

// }

// density {

// enableSplit = false

// }

// abi {

// enableSplit = true

// }

// }

AndroidMainfest.xml

去掉

android:theme

android:icon

android:label

获取全部移动到 activity中

去掉 UnityPlayerActivity 的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值