Unity3d implementation of physically-based rendering based on physical rendering

Source: Internet
Author: User
Tags pow

escaped from class = =, got a bit.
The formula is the same as the previous article, this time with CubeMap map, because of the convenience, directly with surface shader, because do not seek reflect direction,
before there is this article explains surface The method of using CubeMap in shader and the method of real-time reflection http://blog.csdn.net/wolf96/article/details/41939325
Okay, get to the point, the Ops2 Brdf method mentioned earlier, Now take a look at the OPS2 improved BRDF method
 

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

Review the method of cook-torrance illumination model specular
can be briefly summarized as this formula
 
This calculation inherits the last method,
 
but instead specular The power variable _sp for gloss gloss defines the external variable _GL control, the specific reload method _sp = Pow (8192, _GL) is specular power value of 8192 gloss times, borrowed 8192 this already adjusted parameters, is standing on the shoulders of giants.


OPS2 developers say their BRDF for environment map pre-filtering
simulates ambient light exposure
Original description of the environment map blurs much more Linearly across the Gloss range
Gloss The scope of the environment map is more linear, the following 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. 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); 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;}



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 and changed the NDF function according to the previous article.
This is the Phong distribution function.

Beckmann distribution function, they are not the same, careful comparison will find Beckmann high light is stronger, more abrupt

Torrance-reitz (GXX) distribution function

The results found that the OPS2 effect was the best, followed by Torrance-reitz
and a family photo.

Give all the code of the OPS2, and the rest of the code with the changes in the previous article
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 http://blog.csdn.net/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.