【OpenGL】Shader实例分析-钻石效果

发表于2018-10-18
评论0 3.7k浏览
最近研究了一个玻璃折射的效果(用在钻石上),虽然没有达到最满意的效果,还是先分享出来,待以后有更好的想法再补充。

先看效果吧:

这里面有两个效果,左边是unity的免费插件Gem Shader,右边的是我自己实现的,我将分别介绍这两个效果的实现方法。

一、知识补充:

钻石的图片:


两个shader都使用了CubeMap……
Shader "FX/Diamond"
{
	Properties {
		_Color ("Color", Color) = (1,1,1,1)
		_ReflectTex ("Reflection Texture", Cube) = "dummy.jpg" {
			TexGen CubeReflect
		}
		_RefractTex ("Refraction Texture", Cube) = "dummy.jpg" {
			TexGen CubeReflect
		}
	}	
	SubShader {
		Tags {
			"Queue" = "Transparent"
		}
		// First pass - here we render the backfaces of the diamonds. Since those diamonds are more-or-less
		// convex objects, this is effectively rendering the inside of them
		Pass {
			Color (0,0,0,0)
			Offset  -1, -1
			Cull Front
			ZWrite Off
			SetTexture [_RefractTex] {
				constantColor [_Color]
				combine texture * constant, primary
			}
			SetTexture [_ReflectTex] {
				combine previous, previous +- texture
			}
		}
		// Second pass - here we render the front faces of the diamonds.
		Pass {
			Fog { Color (0,0,0,0)}
			ZWrite on
			Blend One One
			SetTexture [_RefractTex] {
				constantColor [_Color]
				combine texture * constant
			}
			SetTexture [_ReflectTex] {
				combine texture + previous, previous +- texture
			}
		}
	}
	// Older cards. Here we remove the bright specular highlight
	SubShader {
		// First pass - here we render the backfaces of the diamonds. Since those diamonds are more-or-less
		// convex objects, this is effectively rendering the inside of them
		Pass {
			Color (0,0,0,0)
			Cull Front
			SetTexture [_RefractTex] {
				constantColor [_Color]
				combine texture * constant, primary
			}
		}
		// Second pass - here we render the front faces of the diamonds.
		Pass {
			Fog { Color (0,0,0,0)}
			ZWrite off
			Blend One One
			SetTexture [_RefractTex] {
				constantColor [_Color]
				combine texture * constant
			}
		}
	}
	// Ancient cards without cubemapping support
	// We could use a 2D refletction texture, but the chances of getting one of these cards are slim, so we won't bother.
	SubShader {
		Pass {
			Color [_Color]
		}
	}
}
Shader "stalendp/myDiamondShader" {
	Properties {
		_Color ("Color", Color) = (1,1,1,1)
		_ReflectTex ("Reflection Texture", Cube) = "" { }
		_RefractTex ("Refraction Texture", Cube) = "" { }
	}	
	CGINCLUDE  
        #include "UnityCG.cginc"             
        fixed4 _Color;  
        samplerCUBE _RefractTex;    
        samplerCUBE _ReflectTex;       
        struct v2f {      
            half4 pos:SV_POSITION;      
            half3 Reflect : TEXCOORD0;     
        	half3 RefractR : TEXCOORD1;
        	half3 RefractG : TEXCOORD2;
        	half3 RefractB : TEXCOORD3;
        	half Ratio : TEXCOORD4;
        };    
        v2f vert(appdata_full v) {    
			float EtaR = 0.65;
			float EtaG = 0.67;
			float EtaB = 0.69;
			float FresnelPower = 5.0;
			float F = ((1.0-EtaG) * (1.0-EtaG)) / ((1.0+EtaG) * (1.0+EtaG));
			float3 i = -normalize(ObjSpaceViewDir(v.vertex)); 
			float3 n = normalize(v.normal); // ??????
			v2f o;
			o.Ratio = F + (1.0 - F) * pow((1.0 - dot(-i, n)), FresnelPower) ;
			o.RefractR = refract(i, n, EtaR);
			o.RefractG = refract(i, n, EtaG);
			o.RefractB = refract(i, n, EtaB);
			o.Reflect = reflect(i, n);
			o.pos = mul (UNITY_MATRIX_MVP, v.vertex);	
            return o;    
        }    
        fixed4 frag(v2f i) : COLOR0 {  
        	float3 refractColor, reflectColor;
        	refractColor.r = float3(texCUBE(_RefractTex, i.RefractR)).r;
        	refractColor.g = float3(texCUBE(_RefractTex, i.RefractG)).g;
        	refractColor.b = float3(texCUBE(_RefractTex, i.RefractB)).b;
        	reflectColor = float3(texCUBE(_ReflectTex, i.Reflect));
           	return  2*_Color * pow(fixed4(lerp( _Color * refractColor * 5, reflectColor * 2, i.Ratio), 1), 1.8);
        }    
    ENDCG      
    SubShader {     
        Pass {      
            CGPROGRAM      
            #pragma vertex vert      
            #pragma fragment frag      
            #pragma fragmentoption ARB_precision_hint_fastest       
            ENDCG      
        }  
    }  
    FallBack Off    
}  
来自:https://blog.csdn.net/stalendp/article/details/46360409

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引