Unity3d implementation of physically-based rendering based on physical rendering

Source: Internet
Author: User
Tags pow

According to the previous example http://blog.csdn.net/wolf96/article/details/44172243 (do not get hyperlinks to the audit too slow) to get a real physical-based rendering
Escaped the lesson = =, got a bit.
The formula and the previous article, this time add CubeMap map, because of convenience, directly with surface shader, because do not ask reflect direction,
This article also shows how cubemap is used in surface shader and how it is reflected in real time http://blog.csdn.net/wolf96/article/details/41939325
OK go to the point, the previous mentioned Ops2 Brdf method, now look at OPS2 improved BRDF method


This is the code they give, the value of the F (l,h) function, where g is gloss gloss, the meaning of Ndotv,n, V, and so on in the previous article, rf0 let him be a controllable external variable.

Review the method of cook-torrance illumination model to find specular
Can be simply summed up as this formula

This calculation inherits the last method,

Instead, use the specular power variable _sp for gloss glossiness to define the external variable _GL control for this article, the specific method _sp = Pow (8192, _GL) is specular power value of 8192 gloss times, By borrowing 8192 of the already tuned parameters, I was standing on the shoulders of giants.


OPS2 developers say their BRDF is environment map pre-filtering
Simulates ambient light exposure.
Original Description The environment map blurs much more linearly across the gloss range
The range of gloss makes the blur of the environment map more linear, and the next example we can see the results


First, we define the illumination function, the exact algorithm is the same as the previous one does not repeat here. Just change the f (l,h) function BRDF to the improved method above, the code is as follows:

inline fixed4 lightingops (surfaceops s, fixed3 Lightdir, Fixed3 viewdir, fixed atten) { Viewdir = normalize (viewdir); lightdir = normalize (Lightdir); Float3 H = normalize (Lightdir + viewdir); s.normal = normalize (s.normal); FLOAT3 N = s.normal;float _sp = Pow (8192, _GL); float D = (_sp + 2)/(8 * PIE) * POW (dot (N, H), _sp);//float F = _sc + (1-_SC) *pow ((1-dot (H, Lightdir)), 5), float f = environmentbrdf (_GL, Dot (N, viewdir), _r0f), float k = 2/sqrt ( PIE * (_sp + 2)); float v = 1/((dot (n, lightdir) * (1-k) + k) * (dot (n, viewdir) * (1-k) + K); float spec = D*F*V;FLOAT4 C = FLOAT4 (S.albedo, 1); C.rgb + = (_SC + (1.0-_SC) * s.deferredfresnel) * spec;//* light.rgb;c + = SPEC*_SC;C.A = S.alpha;re Turn C;} 




In the surf function we want to decode cubemap value to the light function, again this note, we use not texcube but texcubelod, see the function name know not only to solve the color, but also control lod,lod for level of detail, detail degree, We control the details by controlling the W value of his second parameter, through which we can change his roughness, which is also based on the physical rendering of the soul, and we want to make the gloss gloss the lower the coarser the more coarse. We define an external variable _nmips to control, thus debugging into the effect we want.
In the surf function also need to calculate the BRDF, in order to control the light specular gravity, make it more real

void Surf (Input in, InOut surfaceops o) {half4 c = tex2d (_maintex, In.uv_maintex) * _maintint;o.  Emission = Texcubelod (_cubemap, Float4 (IN.WORLDREFL, _nmips-_gl*_nmips)). RGB * _reflamount;float cost = dot (In.viewdir, In.worldnormal);//c = (1-spec) * C;float F = ENVIRONMENTBRDF (_GL, Dot (in.worldnormal, in.viewdir), _r0f); O. Deferredfresnel = F;o. Albedo = C.rgb;o. Alpha = C.A;}

The




Effect is as follows:

 
I've done a variety of experiments, changed the NDF function
This is the Phong distribution function
 
Beckmann distribution function, they are different, Careful comparison will find Beckmann high light is stronger, more abrupt
 
Torrance-reitz (GXX) distribution function
 
Results found OPS2 is the best effect, Next is the Torrance-reitz
another family photo

Give all the code of OPS2, and the others will be changed according to the previous code

Shader "Custom/surface_cube_new ops" {Properties{_maintex ("Base (RGB)", 2D) = "White" {}_maintint ("Diffuse color", color = (1, 1, 1, 1) _cubemap ("Cubemap", CUBE) = "" "{}_reflamount (" Reflection Amount ", Range (0.01, 1)) = 0.5_SC (" Specular Color " , Color) = (1, 1, 1, 1) _gl ("Gloss", range (0, 1)) = 0.5_r0f ("r0f", range (0, 1)) = 0.5_nmips ("NMIPSF", Range (0, 5)) = 0.5}su bshader{tags{"Rendertype" = "Opaque"}lod 400cgprogram#pragma surface surf Ops noambient#pragma glsl#pragma Target 3.0SA mpler2d _maintex;samplercube _cubemap;float4 _maintint;float _reflamount;float4 _SC;float _nMips;float _GL;float _R0F; struct SURFACEOPS{FIXED3 albedo;fixed3 normal;fixed3 emission;fixed3 specular;fixed gloss;fixed Alpha;half Deferredfresnel;}; struct INPUT{FLOAT2 uv_maintex;float3 worldpos;float3 viewdir;float3 worldnormal;float3 WORLDREFL;////WORLDREFL: That is the reflection vector of world space///built-in WORLDREFL to do cubic reflection (CubeMap reflection)}; #define PIE 3.1415926535#define E 2.71828FLOAT3 ENVIRONMENTBRDF (float g, float NoV, float3 rf0) {FLOAT4t = float4 (1/0.96, 0.475, (0.0275-0.25 * 0.04)/0.96, 0.25); t *= float4 (g, G, G, g); t + = float4 (0, 0, (0.015-0.75 * 0.04)/0.96, 0.75); Float a0 = t.x * min (T.y, EXP2 ( -9.28 * NoV)) + t.z;float A1 = T.w;return Saturate (a0 + rf0 * (a1-a0 ));} Inline Fixed4 lightingops (surfaceops s, fixed3 Lightdir, Fixed3 viewdir, fixed atten) {Viewdir = normalize (viewdir); LIGHTD  IR = normalize (lightdir), float3 H = normalize (Lightdir + viewdir); s.normal = normalize (s.normal); FLOAT3 N = S.normal;float _sp = Pow (8192, _GL), float d = (_sp + 2)/(8 * PIE) * POW (dot (N, H), _sp),//float f = _sc + (1-_SC) *pow ((1-dot (H, Li Ghtdir)), 5); float f = environmentbrdf (_GL, Dot (N, viewdir), _r0f), float k = 2/sqrt (PIE * (_sp + 2)), float v = 1/(dot (n, Lightdir) * (1-k) + k) * (dot (n, viewdir) * (1-k) + K); float spec = d*f*v;float4 c = float4 (S.albedo, 1); C.rgb + = (_sc + (1.0-_SC) * s.deferredfresnel) * spec;//* light.rgb;c + = SPEC*_SC;C.A = S.alpha;return C;} void Surf (Input in, InOut surfaceops o) {half4 c= tex2d (_maintex, In.uv_maintex) * _maintint;o.  Emission = Texcubelod (_cubemap, Float4 (IN.WORLDREFL, _nmips-_gl*_nmips)). RGB * _reflamount;float cost = dot (In.viewdir, In.worldnormal);//c = (1-spec) * C;float F = ENVIRONMENTBRDF (_GL, Dot (in.worldnormal, in.viewdir), _r0f); O. Deferredfresnel = F;o. Albedo = C.rgb;o. Alpha = C.A;} Endcg}fallback "Diffuse"}




----by wolf96

Unity3d implementation of physically-based rendering based on physical rendering

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.