基于次表面散射(SSS)的玉石渲染(2)

本文效果图:

基于次表面散射(SSS)原理介绍请参考上一遍,求模型厚度的时候,本文采用渲染模型正面和背面的深度图,模型渲染代码如下:

Shader "Custom/JadeRender"
{
	Properties{
		_Diffuse("Diffuse", Color) = (1, 1, 1, 1)
		_Specular("Specular",Color) = (1.0,1.0,1.0,1.0)
		_Base("BaseColor",Color) = (1.0,1.0,1.0,1.0)
		_Shinness("Shinness",Range(8,256)) = 128
		_Wrap("Wrap",Range(0,1)) = 0.5
		_ScatterWidth("_ScatterWidth",Vector) = (0,0,0,0)
		_ScatterFactor("_ScatterFactor",Range(0,1)) = 0.75
		_MainTex("MainTex",2D) = "white"{}
	_ScatterTex("_ScatterTex",2D) = "white"{}
	}

		SubShader{
		Tags{ "RenderType" = "Opaque" "Queue" = "Geometry" }
		GrabPass
	    {
	    }
		Pass{
		Tags{ "LightMode" = "ForwardBase" }
		CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase
#include "Lighting.cginc"

	fixed4 _Diffuse;
	float _Wrap;
	sampler2D _MainTex;
	float4 _MainTex_ST;
	float4 _ScatterWidth;
	float _ScatterFactor;
	sampler2D _ScatterTex;
	float4 _ScatterTex_ST;
	float4 _Specular;
	float4 _Base;
	float _Shinness;
	sampler2D _BackDepthTex;
	sampler2D  _GrabTex;
	float4x4 _WolrdtoLightMatrix;
	struct a2v {
		float4 vertex : POSITION;
		float3 normal : NORMAL;
		float4 tangent:TANGENT;
		float2 texcoord:TEXCOORD0;
		
	};

	struct v2f {
		float4 pos : SV_POSITION;
		float3 wNormal : TEXCOORD0;
		float4 wPos:TEXCOORD1;
		float4 uv:TEXCOORD2;
		float4 scrPos:TEXCOORD3;
		float4 Pz:TEXCOORD4;
		
	};

	v2f vert(a2v v) {
		v2f o;
		o.pos = UnityObjectToClipPos(v.vertex);
		o.wNormal = mul(v.normal, (float3x3)unity_WorldToObject);
		o.scrPos = ComputeScreenPos(o.pos);
		o.wPos = mul(unity_ObjectToWorld,v.vertex);
		o.uv.xy = TRANSFORM_TEX(v.texcoord,_MainTex);
		o.uv.zw = TRANSFORM_TEX(v.texcoord,_ScatterTex);
		o.Pz.xy = o.pos.zw;
		return o;
	}

	fixed4 frag(v2f i) : SV_Target{
	float frontDepth = LinearEyeDepth(i.Pz.x/i.Pz.y);
	float4 backDepthColor = tex2D(_BackDepthTex, i.scrPos.xy / i.scrPos.w);
	float4 grabTex = tex2D(_GrabTex, i.scrPos.xy / i.scrPos.w);
	float backDepth = 40*Linear01Depth(DecodeFloatRGBA(backDepthColor));//LinearEyeDepth
	float depth = (backDepth-frontDepth);
	if (depth < 0.2)
		depth = 0.2;
	float3 scattering = exp(-_ScatterWidth.xyz*depth);

	float3 N = normalize(i.wNormal);

	float4 texcol = tex2D(_MainTex, i.uv.xy);
	fixed3 albedo = _Diffuse.rgb; // texcol.rgb*_Diffuse.rgb;
	fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz*albedo;
	float3 L = normalize(UnityWorldSpaceLightDir(i.wPos));
	float3 V = normalize(UnityWorldSpaceViewDir(i.wPos));
	float3 H = normalize(L + V);

	float wrap = (dot(L,N) + _Wrap) / (1 + _Wrap);
	float wrap_diff = max(0,wrap);
	fixed3 diffuse = _LightColor0.rgb * wrap_diff*albedo;


	float s = pow(max(0,dot(N,H)),_Shinness);
	float3 specular = _LightColor0.rgb *_Specular.rgb*s;

	float3 scatterTex = tex2D(_ScatterTex,i.uv.zw);
	float4 finCol;
	finCol = float4(backDepth, backDepth, backDepth,1.0);
	finCol = float4(1.0, 0.0, 0.0, 1.0);
	float3 back = float3(frontDepth, frontDepth, frontDepth);
	finCol.rgb = scattering *_Base*(diffuse + ambient)+ specular;// *0.5 + 0.5*tex.rgb;// lerp(ambient + diffuse, scattering, _ScatterFactor) + specular;
	float factor = depth;
	if (factor > 1.0f)//此处模拟透明,透明属性应该保存在纹理的alpha中,但是本人没有玉石纹理和对应alpha设置,这里根据深度来计算透明度
		factor = 1.0f;
	if (factor < 0.6f)
		factor = 0.6f;
	finCol.rgb = lerp(grabTex, finCol, factor);
																   //finCol.a = texcol.a;
	return finCol;
	}

		ENDCG
	}
	}
		// FallBack "Diffuse"
}

源码地址:

https://download.csdn.net/download/wang371372/10775296

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值