True Impostor technical principles and practice summary

True Impostor technology

basic introduction

Impostor, intent "pretenders", is a very simple mesh using an optimization technique to simulate real mesh model, we can efficiently draw a large number of similar models in the scene without the need to draw a large number of polygons. Impostor technique is a model that is interposed between Billboard and mesh, to achieve the full angle display details of model vertices simultaneously saving. Impostor The two-dimensional texture mapping onto a rectangular Mesh, artifacts precision simulation model, the method may be implemented in real time, the data may be calculated in advance and stored in the good memory. Impostor model actually only in some entirely accurate angle (sample angle), the movement of the camera angle change in the accuracy of the transition must be reduced until the switch to a completely precise angle. Impostor model supports the original self-emission, reflection, refraction and other characteristics, at a sampling sufficiently basic real ones.

Billboard,Multi-Billboard

Traditional Billboard Billboard technical principle is much simpler to use a quadrilateral mesh to show a texture map and monitor the position of the camera to give a direction vector by poor product operation so that mesh is always facing the camera, camouflage model to achieve the effect of this approach in the case where the distance and the Y-axis is the center of symmetry model works well, such as some single trees or grasses.

Billboard display only a single surface model, derived as a star after billboard methods, such as analog certain grasses, the plurality of stacked billboard star plugged together, show details of the model more complicated. At the same time as the number billboard superimposed, it will also increase the number of vertices, mesh will be more complex, increasing the memory consumption.

Billboard applies only to model the details of the distance less demanding, can significantly reduce the performance requirements. Billboard also in many cases need to reduce performance requirements, rendering a large scale model (such as grasslands, forests) a method of universal application, is an image based renderring ideas. In addition, this simple billboard difficult to support the real lighting effects such as shadows.

Impostor texture space

Texture mapping is the basis Impostor space technology. Mapping into three main: Spherical (spherical space), Octahedron (octahedral space), Hemi-Octahedron (octahedral half space).

Conversion achieved spatial mapping two-dimensional data and three-dimensional data, i.e., compressed data decompression process. Impostor sampled three-dimensional data is actually collected, it is to be saved to a two-dimensional texture map by compression, when drawing Impostor finally decompressed two-dimensional texture data need to implement the model map corresponding to different display angles.

Spherical below shows the spherical space is two-dimensional texture map, corresponding to the number of vertices on the same latitude in the same, leading to more intense closer to the apex poles, poles of the two edges corresponding to the vertex in the vertical two-dimensional texture vertex distribution is not uniform, resulting in both edge portions of the texture data down too dense resulting in a large number of repeat accuracy waste.
http

Therefore, in order to save accuracy, we select the mapping method other two octahedron and Hemi-Octahedron.

The following animated gif shows the two space intuitive process mapping. Visible on both vertex mapping space is evenly distributed, avoiding the waste of spherical space mapping accuracy caused. In addition, with regard to the choice of these two cases to be divided: In the case of the bottom of the display models that do not require, in order to further optimize the recommended choice Hemi-Octahedron space map. And if you need all-round display model you can only select Octahedron.

https://storage.googleapis.com/wzukusers/user-22455410/images/5aade979ada89fPZkHZz/Grid_Animation.gif

Octahedron example, the following code is the spatial texture mapping transformation function:

			float2 VectortoOctahedron( float3 N )
			{
				N /= dot( 1.0, abs( N ) ); // 等同于:N/= abs(N.x)+abs(N.y)+abs(N.z)
				if( N.z <= 0 )
				{
				    N.xy = ( 1 - abs( N.yx ) ) * ( N.xy >= 0 ? 1.0 : -1.0 );
				}
				return N.xy;
			}
			
			float3 OctahedronToVector( float2 Oct )
			{
				float3 N = float3( Oct, 1.0 - dot( 1.0, abs( Oct ) ) );
				if(N.z< 0 )
				{
				    N.xy = ( 1 - abs( N.yx) ) * (N.xy >= 0 ? 1.0 : -1.0 );
				}
				return normalize( N);
			}

Example of use: VectortoOctahedron(objectCameraDirection.xzy)*0.5 + 0.5, wherein the model coordinate system objectCameraDirection camear direction vector with respect to the model, i.e., the calculation result is a two-dimensional texture corresponding to the texture coordinates.

Impostor baking space sampling

Impostor main sampling sampling accuracy provided, texture space mapping algorithms uniform take a snapshot of the model, the output diffuse texture (color and transparency of the object), the normal map (after lighting for calculating shadow and the like) from different angles, according to the mapping Mask (for background clip clipped) channel data and the like (in the case of the general set).

Amplify Impostor插件烘焙Impostor的方法很简单,在模型上加上AmplifyImpostor.cs脚本,创建Impostor对象并设置到Impostor Assets上,然后设置纹理分辨率(Texture Size)、理采样帧数(Axis Frames),编辑Imspostor的mesh形状(Billboard mesh),以及选择烘焙设置(Bake Preset)等。最后点击Bake Impostor就可以实现一键烘焙。

Here Insert Picture Description

例如选择基本的Custom Preset输出的结果为三张贴图:AlbedoAlpha、NormalDepth、Mask。
插件提供的另一种用于标准延迟渲染通道的StandardDefferd设置输出则为四张贴图:AlbedoAlpha、NormalDepth、SpecularSmoothness、EmissionOcclusion。

Amplify Impostor基本使用教程

视差映射POM

纹理空间是通过多角度采样得到的不同角度的纹理贴图,然后根据相机的位置来更换不同的贴图,但是在贴图直接更换的瞬间会有不连续的突变,为了实现平滑的过渡达到True Impostor的效果,需要加入视差映射POM(Parallax mapping)技术。

视差映射方法的基本原理是,根据当前相机位置确定当前对应的采样贴图片段,然后将当前贴图临近的贴图进行加权融合采样,实现平滑过渡,达到接近真实模型的效果。以Octahedron空间为例,每个贴图片段邻近的有三个片段,对三个邻近片段进行加权融合得到最终的采样颜色。

对整个纹理空间进行POM是一个比较耗费的过程,一般至少需要9x9的采样空间才能实现平滑过渡。

Billborad Impostor简化版实现

Demo下载

Impostor texture sampling technique by multi-angle space conversion disparity plus smooth texture mapping POM Impostor show different views of the model. But POM is a more cost process, in the game if you do not use Impostor to show the details of the model near (near real models directly replace the mesh model), you can remove the POM process, a direct replacement when changing the camera angle texture mapping can be.

Demo widget used baking in AmplifyImpostor three maps (bake preset select custom) Impostor as the data, the Demo BillboardImpostor.shader achieved Impostor simplified version, only a simple addition of the effect of diffuse reflection.

The complete code is as follows:

// 用来展示BillboardImpostor模型
Shader "ImpostorDemo/BillboardImpostor"
{
	Properties
	{
		[NoScaleOffset]_Albedo("Impostor Albedo & Alpha", 2D) = "white" {}
		[NoScaleOffset]_Normals("Impostor Normal & Depth", 2D) = "white" {}
		[NoScaleOffset]_Mask("Mask", 2D) = "white" {}
		[HideInInspector]_AI_Frames("Impostor Frames", Float) = 0
		[HideInInspector]_AI_ImpostorSize("Impostor Size", Float) = 0
		_AI_Clip("Impostor Clip", Range( 0 , 1)) = 0.5
		
		_DiffuseColor ("DiffuseColor", Color) = (1,1,1,1)
		_Diffuse ("Diffuse", Range(0,1)) = 1.0
	}

	SubShader
	{
		CGINCLUDE
		#pragma target 3.0
		#define UNITY_SAMPLE_FULL_SH_PER_PIXEL 1
		ENDCG
		Tags { "RenderType"="Opaque" "Queue"="Geometry" "DisableBatching"="True" "ImpostorType"="Octahedron" }
		Cull Back
		Pass
		{
			ZWrite On
			Name "ForwardBase"
			Tags { "LightMode"="ForwardBase" }

			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "UnityCG.cginc"
			#include "Lighting.cginc"
			
			uniform sampler2D _Albedo; // 颜色
			uniform sampler2D _Normals; // 法线
			uniform sampler2D _Mask;// mask
			uniform float _AI_Frames; // 切片规模
			uniform float _AI_ImpostorSize; // impostor resolution
			uniform float _AI_Clip; // 透明背景裁剪程度
			
			// 漫反射强度
			uniform float4 _DiffuseColor;
			uniform float _Diffuse;

			// Octahedron空间纹理映射变换
			float2 VectortoOctahedron( float3 N )
			{
				N /= dot( 1.0, abs( N ) ); // 等同于:N/= abs(N.x)+abs(N.y)+abs(N.z)
				if( N.z <= 0 )
				{
				    N.xy = ( 1 - abs( N.yx ) ) * ( N.xy >= 0 ? 1.0 : -1.0 );
				}
				return N.xy;
			}
			
			float3 OctahedronToVector( float2 Oct )
			{
				float3 N = float3( Oct, 1.0 - dot( 1.0, abs( Oct ) ) );
				if(N.z< 0 )
				{
				    N.xy = ( 1 - abs( N.yx) ) * (N.xy >= 0 ? 1.0 : -1.0 );
				}
				return normalize( N);
			}
			
			inline void OctaImpostorVertex( inout appdata_full v, inout float4 uvsFrame1)
			{
				float framesXY = _AI_Frames;
				float prevFrame = framesXY - 1;
				float2 fractions = 1.0 / float2( framesXY, prevFrame );
				float fractionsFrame = fractions.x;
				float fractionsPrevFrame = fractions.y;
				float UVscale = _AI_ImpostorSize;

				float3 worldOrigin = float3(unity_ObjectToWorld[0].w, unity_ObjectToWorld[1].w, unity_ObjectToWorld[2].w);

				float3 worldCameraPos = _WorldSpaceCameraPos;

				// 模型空间:origin到相机的方向
				float3 objectCameraDirection = normalize( mul( worldCameraPos - worldOrigin, (float3x3)unity_WorldToObject ) );
				// 模型空间:相机的位置
				float3 objectCameraPosition = mul( unity_WorldToObject, float4( worldCameraPos, 1 ) ).xyz;
				float3 upVector = float3( 0,1,0 );
				//float3 objectCameraDirection = UNITY_MATRIX_V[2].xyz;

				// 模型水平竖直向量
				float3 objectHorizontalVector = normalize( cross( objectCameraDirection, upVector ) );
				float3 objectVerticalVector = cross( objectHorizontalVector, objectCameraDirection );

				float2 uvExpansion = ( v.texcoord.xy - 0.5f ) * UVscale;
				float3 billboard = objectHorizontalVector * uvExpansion.x + objectVerticalVector * uvExpansion.y;

				float2 cameraPos = VectortoOctahedron(objectCameraDirection.xzy)*0.5 + 0.5;
				float colFrame = round(abs(cameraPos.x) * (framesXY-1));
				float rowFrame = round(abs(cameraPos.y) * (framesXY-1));
				// 纹理坐标
				uvsFrame1 = 0;
				uvsFrame1.xy = (v.texcoord.xy + float2(colFrame, rowFrame)) * fractionsFrame;

				// 顶点
				v.vertex.xyz = billboard;
				v.normal.xyz = objectCameraDirection;
			}

			struct v2f_surf {
				UNITY_POSITION(pos);
				float4 UVsFrame117 : TEXCOORD5;
				float4 viewPos17 : TEXCOORD6;
			};

		    // 顶点
			v2f_surf vert (appdata_full v ) {
				UNITY_SETUP_INSTANCE_ID(v);
				v2f_surf o;
				UNITY_INITIALIZE_OUTPUT(v2f_surf,o);
				UNITY_TRANSFER_INSTANCE_ID(v,o);
				UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
				OctaImpostorVertex( v, o.UVsFrame117 ); ///
				o.pos = UnityObjectToClipPos(v.vertex); // 顶点投影坐标

				// 漫反射
				float3 worldlight = normalize(_WorldSpaceLightPos0.xyz);
				float3 worldnormal = normalize(mul((float3x3)unity_ObjectToWorld,v.normal));
				float3 diffuse = _LightColor0.rgb * _DiffuseColor * _Diffuse * saturate(dot(worldnormal,worldlight));
				o.viewPos17 = float4(diffuse,0);
				return o;
			}

			// 片段着色
			fixed4 frag (v2f_surf IN) : SV_Target {				
				float4 blendedAlbedo = tex2D( _Albedo, float3( IN.UVsFrame117.xy, 0) );
				float alpha = blendedAlbedo.a - _AI_Clip;
				clip(alpha);
				return (blendedAlbedo + IN.viewPos17);
			}
			ENDCG
		}
		
	}
}

Use Demo scene TreeForest.scene in Billborad Impostor technology to achieve a simple forest scene, made Impostor trees, rocks and grass, near real showcase model, far from showing Impostor model.

Here Insert Picture Description

to sum up

Impostor is a mesh model directly between the billboard and a technical product, increasing the tradeoff for reducing the number of model vertices details and contradictions, together with its simplified version BILLBORAD Impostor implemented, the relationship between them as follows (3d model detail from less to multiple):

Billborad — Multi Billborad — BillBoard Impostor — True Impostor — Mesh(model)

Reference article

Octahedral Impostor from Ryan Brucks

True Impostors - GPU Gems 3

Published 109 original articles · won praise 403 · views 880 000 +

Guess you like

Origin blog.csdn.net/cordova/article/details/86668678