目录
课时57:FragmentShader-2D纹理采样1
视频:https://www.bilibili.com/video/BV1YK41157AC?p=57
有1D采样也有3D采样(研究阶段)
测试取样,tex2D()
Shader "Custom/NewSurfaceShader 18"
{
Properties
{
_MainTex("MainTex",2D) = ""{}
_U("U",range(-2,2)) = 0
_V("V",range(-2,2)) = 0
}
SubShader
{
pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "unitycg.cginc"
sampler2D _MainTex;
float _U;
float _V;
struct v2f{
float4 pos:POSITION;
};
v2f vert(appdata_base v){
v2f o;
o.pos=UnityObjectToClipPos(v.vertex);
return o;
}
fixed4 frag(v2f IN):COLOR
{
fixed4 color=tex2D(_MainTex,float2(_U,_V));
return color;
}
ENDCG
}
}
FallBack "Diffuse"
}
图片设置
没有教程的测试图片,算了,大概理解一下就好。
主要是一个点的颜色如何获取,是否从周围点采样。
FilterMode Point:就近
Bilinear:就近采样,比重算法,融合颜色。
struct v2f{
float4 pos:POSITION;
float2 uv:TEXCOORD0;
};
v2f vert(appdata_base v){
v2f o;
o.pos=UnityObjectToClipPos(v.vertex);
o.uv=v.texcoord.xy;
return o;
}
fixed4 frag(v2f IN):COLOR
{
fixed4 color=tex2D(_MainTex,IN.uv);
return color;
}
左侧是Standard,右侧是我们的简单的贴图取样。
课时58:FragmentShader-2D纹理采样2
设置脚本,不明白他为什么要用脚本说明
public class SetTexture : MonoBehaviour
{
public float tiling_x=1;
public float tiling_y=1;
public float offset_x;
public float offset_y;
public Renderer renderer;
// Start is called before the first frame update
void Start()
{
renderer=GetComponent<Renderer>();
}
// Update is called once per frame
void Update()
{
renderer.material.SetFloat("tiling_x",tiling_x);
renderer.material.SetFloat("tiling_y",tiling_y);
renderer.material.SetFloat("offset_x",offset_x);
renderer.material.SetFloat("offset_y",offset_y);
}
}
shader设置参数
float tiling_x;
float tiling_y;
float offset_x;
float offset_y;
v2f vert(appdata_base v){
v2f o;
o.pos=UnityObjectToClipPos(v.vertex);
o.uv=v.texcoord.xy;
//基本的uv范围是(0-1),整个uv世界坐标系是平铺重复的。
//(0-1)*2=(0-2),
//原来的0-0.5能够取到(0-1)
//原来的0.5-1能够取到(1-2),也是(0-1)
//所以体贴就多重复了一次。
//tiling小于1的话,就是把(0-1)映射到(0-0.8)
o.uv.x=o.uv.x*tiling_x+offset_x;
o.uv.y=o.uv.y*tiling_y+offset_y;
return o;
}
效果:
当贴图本身是重复的,比如瓷砖,titling小于1时,效果是贴图放大了。负数时则贴图反过来了。
获取Material中的贴图设置信息 XX_ST
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert(appdata_base v){
v2f o;
o.pos=UnityObjectToClipPos(v.vertex);
//o.uv=v.texcoord.xy;
// o.uv.x=o.uv.x*tiling_x+offset_x;
// o.uv.y=o.uv.y*tiling_y+offset_y;
o.uv=v.texcoord.xy*_MainTex_ST.xy+_MainTex_ST.zw;
return o;
}
一个宏定义
o.uv=TRANSFORM_TEX(v.texcoord,_MainTex);
课时59:FragmentShader-2D纹理采样3
1.创建光照贴图
我的是2020.1版本的,不会啊。
必须设置Static,不然没有lightmap
1.模型设置Static(Contribute GI) 2.灯光设置为Bake 3.Generate LightMap
4.去掉灯光
5.修改材质
shader修改
appdata_full 这个顶点结构体中,有多个纹理,当使用光照贴图的时候,必须使用这个结构体
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "unitycg.cginc"
struct v2f{
float4 pos:POSITION;
float2 uv:TEXCOORD0;
float2 uv2:TEXCOORD1;
};
sampler2D _MainTex;
float4 _MainTex_ST;
// sampler2D unity_Lightmap;
// float4 unity_LightmapST;
v2f vert(appdata_full v){
v2f o;
o.pos=UnityObjectToClipPos(v.vertex);
//o.uv=v.texcoord.xy*_MainTex_ST.xy+_MainTex_ST.zw;
o.uv=TRANSFORM_TEX(v.texcoord,_MainTex);
o.uv2 = v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
return o;
}
fixed4 frag(v2f IN) :COLOR
{
fixed4 color = tex2D(_MainTex, IN.uv);
fixed4 lmTex=UNITY_SAMPLE_TEX2D(unity_Lightmap,IN.uv2);
float3 lm = DecodeLightmap(lmTex);//replaced tex2D unity_Lightmap with UNITY_SAMPLE_TEX2D
color.rgb *= lm*2;
return color;
}
ENDCG
效果:
物体没有颜色,但是有关照贴图的效果。
注释掉 color.rgb *= lm*2;
改成 color.rgb = lm;
测试法线贴图为空时 tex2D(_MainTex, IN.uv) 获取到的color为 (128,128,128),128/255=0.5019607843137255
乘与2,则是(256,256,256),再乘与lm和直接设置为lm一样。
直接返回 fixed4 lmTex=UNITY_SAMPLE_TEX2D(unity_Lightmap,IN.uv2); 结果也是一样的,说明这时DecodeLightmap没做什么处理。
DecodeLightmap里面的宏定义一个#else分支是直接返回rgb的,参考:https://zhuanlan.zhihu.com/p/35096536
想把贴图和主颜色结合起来,突然不知道怎么结合了....
查到一个资料,贴图和颜色混合有各种方式,参考:https://blog.csdn.net/st75033562/article/details/105998215
贴图和颜色混合相当于把两张图片混合
fixed4 frag(v2f IN) :COLOR
{
fixed4 tc = tex2D(_MainTex, IN.uv);
fixed4 lmTex=UNITY_SAMPLE_TEX2D(unity_Lightmap,IN.uv2);
float3 lm = DecodeLightmap(lmTex);//replaced tex2D unity_Lightmap with UNITY_SAMPLE_TEX2D
tc.rgb *= lm*_L;
fixed4 lc=tc;//贴图+光照贴图
fixed4 color=lc*(1-_A)+_Color*(_A);//正常透明度混合;
return color;
}
_L=2,_A=0.5时:
+
比Standard效果亮一点,先这样吧。
类似贴图和光照贴图混合的方式,直接相乘:fixed4 color=lc*_Color;
Standard的效果