shader entry Essentials study notes 22 advanced texture - cube texture - reflection refraction environment mapping

I. Introduction

Cube Texture mapping is an implementation environment, the cube texture and consists of six images.
Sampling is the starting by extending to the outside center of the cube, with one of six intersecting texture occurs, the result is calculated from the sample to the intersection.

Cube texture benefits: simple and fast, fresh fruit is good, Disadvantages: When the scene changes need to regenerate the cube texture, and can not be self-reflective, so we need to make use of convex body.

Second, sky boxes

Skybox use is the cube texture mapping.

A method for simulating background of the game, its Skybox material, using six texture, which texture Wrap Mode 6 needs to be set Clamp, need to intercept the boundary value, to prevent the phenomenon of mismatch.

There are three attributes: Tint Color material for controlling the overall color, Exposure box for adjusting the brightness of the sky, Rotation sky box for adjusting the rotation angle of the + y-axis direction.

Sky box is rendered after all opaque objects, the grid behind the use of a cube or a sphere segment.

Third, create a cube environment texture mapping

Cube texture map is typically used to simulate the environment of metallic material.

Create a cube environment texture mapping method in three ways:

1. Create a special layout directly from the textures

Then we need to provide a special texture layout, such as a cube expand cross floor plan, panoramic layout. Then we textures Texture Type is set to Cubemap can, in physics-based rendering, we usually use a HDR image to generate high-quality Cubemap.
The official recommended to use this method, it can be compressed texture data, and support for edge correction, smooth reflection, HDR and other functions.

2. Create a Cubemap resource manual, then 6 Figure assigned to him

3. generated by the script

public class RenderCubemapWizard : ScriptableWizard {
	
	public Transform renderFromPosition;  //在这个指定的位置动态创建摄像机
	public Cubemap cubemap;  //获取得出的cubemap
	
	void OnWizardUpdate () {      //编辑器更新时调用
		helpString = "Select transform to render from and cubemap to render into";   //提示
		isValid = (renderFromPosition != null) && (cubemap != null);  //设置按钮是否可以点击
	}
	
	void OnWizardCreate () {   //当向导被打开或只要用户在向导改变了某些东西时被调用。
		// create temporary camera for rendering
		GameObject go = new GameObject( "CubemapCamera");
		go.AddComponent<Camera>();
		// place it on the object
		go.transform.position = renderFromPosition.position;
		// render into cubemap		
		go.GetComponent<Camera>().RenderToCubemap(cubemap);  //渲染出cubemap
		
		// destroy temporary camera
		DestroyImmediate( go );//销毁摄像机
	}
	
	[MenuItem("GameObject/Render into Cubemap")]
	static void RenderCubemap () {
		ScriptableWizard.DisplayWizard<RenderCubemapWizard>(
			"Render cubemap", "Render!");
	}
}

After we created GameObject in the scene, and the code assigned to come up with a menu bar entry interface renderFromPosition.
Then create a Cubemap cube texture (Create> Legacy> Cubemap), in order to allow a smooth script can render images into a cube texture, we need to check Readable option.

Using the above obtained texture rendering window code means, which Face size greater options rendered larger cube texture resolution dedicated memory and more.

Fourth, reflection

Metallic reflective coating can be similar to the same effect, probably thinking obtain Reflectance viewing direction and the normal line direction of the incident light source to give the direction of the texture sample in the correlation calculation in this direction.

Shader "Unity Shaders Book/Chapter 10/Reflection" {
	Properties {
		_Color ("Color Tint", Color) = (1, 1, 1, 1)	
		_ReflectColor ("Reflection Color", Color) = (1, 1, 1, 1)	 //控制反射颜色
		_ReflectAmount ("Reflect Amount", Range(0, 1)) = 1			//控制材质的反射程度
		_Cubemap ("Reflection Cubemap", Cube) = "_Skybox" {}		//环境映射纹理,就是那个cubemap立方体纹理,在材质中进行替换赋值
	}
	SubShader {
		Tags { "RenderType"="Opaque" "Queue"="Geometry"}   //用于不透明的几何物体。。。
		
		Pass { 
			Tags { "LightMode"="ForwardBase" }
			
			CGPROGRAM
			
			#pragma multi_compile_fwdbase
			
			#pragma vertex vert
			#pragma fragment frag
			
			#include "Lighting.cginc"
			#include "AutoLight.cginc"
			
			fixed4 _Color;
			fixed4 _ReflectColor;
			fixed _ReflectAmount;
			samplerCUBE _Cubemap;
			
			struct a2v {
				float4 vertex : POSITION;
				float3 normal : NORMAL;
			};
			
			struct v2f {
				float4 pos : SV_POSITION;
				float3 worldPos : TEXCOORD0;
				fixed3 worldNormal : TEXCOORD1;
				fixed3 worldViewDir : TEXCOORD2;
				fixed3 worldRefl : TEXCOORD3;
				SHADOW_COORDS(4)  //用于衰减和阴影计算,三剑客之一
			};
			
			v2f vert(a2v v) {
				v2f o;
				
				o.pos = UnityObjectToClipPos(v.vertex);
				
				o.worldNormal = UnityObjectToWorldNormal(v.normal);
				
				o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
				
				o.worldViewDir = UnityWorldSpaceViewDir(o.worldPos);
				
				// Compute the reflect dir in world space
				o.worldRefl = reflect(-o.worldViewDir, o.worldNormal); //使用视角方向的反射方向计算光方向
				
				TRANSFER_SHADOW(o); //三剑客之二
				
				return o;
			}
			
			fixed4 frag(v2f i) : SV_Target {
				fixed3 worldNormal = normalize(i.worldNormal);
				fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));		
				fixed3 worldViewDir = normalize(i.worldViewDir);		
				
				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
				
				fixed3 diffuse = _LightColor0.rgb * _Color.rgb * max(0, dot(worldNormal, worldLightDir));
				
				// Use the reflect dir in world space to access the cubemap
				fixed3 reflection = texCUBE(_Cubemap, i.worldRefl).rgb * _ReflectColor.rgb; //这里i.worldRefl不需要及逆行归一化,因为只取方向
				
				UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);  //统一管理那个,算是三剑客之三。。
				
				// Mix the diffuse color with the reflected color
				fixed3 color = ambient + lerp(diffuse, reflection, _ReflectAmount) * atten; //这里使用_ReflectAmount进行取值(混合漫发射颜色和反射颜色)
				
				return fixed4(color, 1.0);
			}
			
			ENDCG
		}
	}
	FallBack "Reflective/VertexLit"
}

Then after cubemap cube texture onto our set in Shader material in the Reflection Cubemap.

Fifth, refraction

Refraction is another common application for an environmental map.

------- refraction Snell's law to calculate the reflection angle ------ n1 sinθ1 = n2 sinθ2, (the angle is the angle to the normal; n1, n2 is the refractive index of the two media, 1 is a vacuum the glass is 1.5)

Shader "Unity Shaders Book/Chapter 10/Refraction" {
	Properties {
		_Color ("Color Tint", Color) = (1, 1, 1, 1)
		_RefractColor ("Refraction Color", Color) = (1, 1, 1, 1)   //折射颜色设置
		_RefractAmount ("Refraction Amount", Range(0, 1)) = 1     //透射程度
		_RefractRatio ("Refraction Ratio", Range(0.1, 1)) = 0.5   //透射比
		_Cubemap ("Refraction Cubemap", Cube) = "_Skybox" {}	//立方体纹理
	}
	SubShader {
		Tags { "RenderType"="Opaque" "Queue"="Geometry"}  //用于不透明的几何物体。。。
		
		Pass { 
			Tags { "LightMode"="ForwardBase" }
		
			CGPROGRAM
			
			#pragma multi_compile_fwdbase	
			
			#pragma vertex vert
			#pragma fragment frag
			
			#include "Lighting.cginc"
			#include "AutoLight.cginc"
			
			fixed4 _Color;
			fixed4 _RefractColor;
			float _RefractAmount;
			fixed _RefractRatio;
			samplerCUBE _Cubemap;
			
			struct a2v {
				float4 vertex : POSITION;
				float3 normal : NORMAL;
			};
			
			struct v2f {
				float4 pos : SV_POSITION;
				float3 worldPos : TEXCOORD0;
				fixed3 worldNormal : TEXCOORD1;
				fixed3 worldViewDir : TEXCOORD2;
				fixed3 worldRefr : TEXCOORD3;
				SHADOW_COORDS(4)
			};
			
			v2f vert(a2v v) {
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);		
				
				o.worldNormal = UnityObjectToWorldNormal(v.normal);
				
				o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
				
				o.worldViewDir = UnityWorldSpaceViewDir(o.worldPos);
				
				// Compute the refract dir in world space
				o.worldRefr = refract(-normalize(o.worldViewDir), normalize(o.worldNormal), _RefractRatio); 
				//计算折射方向(第一个参数入射光线方向,第二个是表面法线,这两个都要归一化,第三个参数是入射光线所在介质的折射率和折射光线所在介质的折射率的比值)
				
				TRANSFER_SHADOW(o);
				
				return o;
			}
			
			fixed4 frag(v2f i) : SV_Target {
				fixed3 worldNormal = normalize(i.worldNormal);
				fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
				fixed3 worldViewDir = normalize(i.worldViewDir);
								
				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
				
				fixed3 diffuse = _LightColor0.rgb * _Color.rgb * max(0, dot(worldNormal, worldLightDir));
				
				// Use the refract dir in world space to access the cubemap
				fixed3 refraction = texCUBE(_Cubemap, i.worldRefr).rgb * _RefractColor.rgb;  //使用折射方向对立方体纹理进行采样获取折射颜色
				
				UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);
				
				// Mix the diffuse color with the refract color
				fixed3 color = ambient + lerp(diffuse, refraction, _RefractAmount) * atten;  //使用_RefractAmount透射程度对漫反射和折射颜色进行混合取值
				
				return fixed4(color, 1.0);
			}
			
			ENDCG
		}
	} 
	FallBack "Reflective/VertexLit"
}

Then after cubemap cube texture onto our set in Shader material in Refraction Cubemap in (the book and wrong hhh ~).

Sixth, Fresnel reflection

Fresnel reflection can be controlled according to the degree of reflection viewing directions, which can generate an optical phenomenon
(phenomenon example: standing lake, the foot of the water is almost transparent, and the distance can only see the surface reflection phenomenon)
that, when the light when irradiated to the object surface, a portion of the refracted portion is reflected or scattered, there is a certain ratio between reflection and refraction of light, that is by the ratio between the Fresnel equation calculated.

Fresnel equation : F (v, n) = F0 + (1-F0) [(1-v · n) th 5]

Using this may vary at the boundary between the analog and the refracted light intensity of the reflected light intensity / diffusely reflected, in many paint and other materials in water, it is often used.

Shader "Unity Shaders Book/Chapter 10/Fresnel" {
	Properties {
		_Color ("Color Tint", Color) = (1, 1, 1, 1)
		_FresnelScale ("Fresnel Scale", Range(0, 1)) = 0.5    //调整影响大小的
		_Cubemap ("Reflection Cubemap", Cube) = "_Skybox" {}
	}
	SubShader {
		Tags { "RenderType"="Opaque" "Queue"="Geometry"}
		
		Pass { 
			Tags { "LightMode"="ForwardBase" }
		
			CGPROGRAM
			
			#pragma multi_compile_fwdbase
			
			#pragma vertex vert
			#pragma fragment frag
			
			#include "Lighting.cginc"
			#include "AutoLight.cginc"
			
			fixed4 _Color;
			fixed _FresnelScale;
			samplerCUBE _Cubemap;
			
			struct a2v {
				float4 vertex : POSITION;
				float3 normal : NORMAL;
			};
			
			struct v2f {
				float4 pos : SV_POSITION;
				float3 worldPos : TEXCOORD0;
  				fixed3 worldNormal : TEXCOORD1;
  				fixed3 worldViewDir : TEXCOORD2;
  				fixed3 worldRefl : TEXCOORD3;
 	 			SHADOW_COORDS(4)
			};
			
			v2f vert(a2v v) {
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);
				
				o.worldNormal = UnityObjectToWorldNormal(v.normal);
				
				o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
				
				o.worldViewDir = UnityWorldSpaceViewDir(o.worldPos);
				
				o.worldRefl = reflect(-o.worldViewDir, o.worldNormal);   //求出反射方向
				
				TRANSFER_SHADOW(o);
				
				return o;
			}
			
			fixed4 frag(v2f i) : SV_Target {
				fixed3 worldNormal = normalize(i.worldNormal);
				fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
				fixed3 worldViewDir = normalize(i.worldViewDir);
				
				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
				
				UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);
				
				fixed3 reflection = texCUBE(_Cubemap, i.worldRefl).rgb;   //使用反射方向采样
				
				fixed fresnel = _FresnelScale + (1 - _FresnelScale) * pow(1 - dot(worldViewDir, worldNormal), 5);   //计算菲涅尔反射公式。
				
				fixed3 diffuse = _LightColor0.rgb * _Color.rgb * max(0, dot(worldNormal, worldLightDir));
				
				fixed3 color = ambient + lerp(diffuse, reflection, saturate(fresnel)) * atten;  //使用菲涅尔公式计算出的fresnel对漫反射和反射进行混合取值
				
				return fixed4(color, 1.0);
			}
			
			ENDCG
		}
	} 
	FallBack "Reflective/VertexLit"

Some also achieved directly fresnel reflection light and diffuse reflection multiplying superimposed on the light, the analog edge lighting effects.

Diffuse reflection Fresnel Scale object is 0, is a light having an edge effect, is 1, the image is totally reflected in the cube texture.

Published 38 original articles · won praise 6 · views 4094

Guess you like

Origin blog.csdn.net/w9503/article/details/104848041