图形学入门---实现漫反射Diffuse shader2

本文详细探讨了Unity中自定义Shader遇到的光照问题,包括旋转后的光照不正确、非等比缩放导致的着色差异等问题,并提供了具体的解决方案。通过调整法向量和光源向量的坐标空间,确保光照计算的准确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、发现自定义的shader,当旋转过后,原来的暗面依旧是暗面,没有随着旋转被光照射到


原因:某一顶点的法向量和光向量一直不变



解决办法:

点积的两个向量必须处于同一个坐标空间

①让法向量也在世界坐标中做一个旋转,然后再计算点积,采用的是世界空间坐标系

②不去改变法向量,让法向量处在物体的坐标空间,但是需要把指向光的向量放在模型空间当中,再来计算

2、将法向量旋转到物体的坐标空间,旋转后,自定义的着色器是正常的,和默认的一致


Shader "Custom/s_diffuse" {


	SubShader{
		pass {

		//支持顶点光照
		tags{"LightMode" = "ForwardBase"}

		CGPROGRAM
		#pragma vertex vert
		#pragma fragment frag
		#include "unitycg.cginc"
		#include "lighting.cginc"

			struct v2f {
			float4 pos:POSITION;
			fixed4 color : COLOR;
		};

		v2f vert(appdata_base v) {
			v2f o;
			o.pos = mul(UNITY_MATRIX_MVP,v.vertex);
			//o.color = fixed4(0,0,1,1);

			float3 N = normalize(v.normal);
			//世界空间中光源的位置
			float3 L = normalize(_WorldSpaceLightPos0);
			//将法向量旋转到模型空间中
			L = mul(_World2Object,float4(L,0)).xyz;

			//saturate将点积的值限定在0到1之间
			float ndotl = saturate(dot(N, L));
			//_LightCColor0:光源颜色
			o.color = _LightColor0*ndotl;

			return o;
		}


		fixed4 frag(v2f IN) :COLOR{
			//环境光照
			return IN.color+UNITY_LIGHTMODEL_AMBIENT;
		}
			ENDCG
	}
	}

}




3、将物体的坐标由物体改到世界中


4、非等比例的缩放(将物体的x、y、z值进行不等比的缩放)引起的自定义shader与默认的shader着色效果不一样


对于非等比的缩放,将物体的法向量转到世界坐标的做法是错误的,得不到一个正确的结果。应该用一个物体的模型到世界的矩阵的逆矩阵,才能得到一个正确的变换。

逆矩阵就是将矩阵放在后面


Shader "Custom/s_diffuse" {


	SubShader{
		pass {

		//支持顶点光照
		tags{"LightMode" = "ForwardBase"}

		CGPROGRAM
		#pragma vertex vert
		#pragma fragment frag
		#include "unitycg.cginc"
		#include "lighting.cginc"

			struct v2f {
			float4 pos:POSITION;
			fixed4 color : COLOR;
		};

		v2f vert(appdata_base v) {
			v2f o;
			o.pos = mul(UNITY_MATRIX_MVP,v.vertex);
			//o.color = fixed4(0,0,1,1);

			float3 N = normalize(v.normal);
			//世界空间中光源的位置
			float3 L = normalize(_WorldSpaceLightPos0);
			//将法向量旋转到模型空间中
			//L = mul(_World2Object,float4(L,0)).xyz;

			//物体到世界的坐标
			//将_Object2World房子后面,就可以得到逆矩阵的转置矩阵的乘法
			N = mul(float4(N,0), _Object2World).xyz;
			//对法向量进行规范化
			N = normalize(N);
			//saturate将点积的值限定在0到1之间
			float ndotl = saturate(dot(N, L));
			//_LightCColor0:光源颜色
			o.color = _LightColor0*ndotl;

			return o;
		}


		fixed4 frag(v2f IN) :COLOR{
			//环境光照
			return IN.color+UNITY_LIGHTMODEL_AMBIENT;
		}
			ENDCG
	}
	}

}






5、



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值