Legacy(Built-in)์์ด๋๋ก ์์ฑ๋์ด์๋๋ฐ, ์ด์ฐจํผ Legacy์ฌ์ฉ๋ฒ๋ ์ ๋ชจ๋ฅด๊ณ URP๋ก ๊ณง๋ฐ๋ก ์ฐ์ตํด ๋ณด๋๋ก ํ์.
Packages/
|-- Core RP Library/
| |-- ShaderLibrary/
| | |-- SpaceTransform.hlsl - ๊ณต๊ฐ๋ณํ ํ๋ ฌ. Tangent<->Worldํ๋ ฌ
| | |-- Common.hlsl - ๊ฐ์ข
์ํ. ํ
์ค์ณ ์ ํธ, ๋์ค ๊ณ์ฐ ..
| | |-- >>> EntityLighting.hlsl - SH, ProveVolume, Lightmap๊ณ์ฐ ???
| | |-- ImageBasedLighting - IBL๊ด๋ จ ๋ถ๋ถ(GGX, Anisotropy, ImportanceSample)
|-- Universal RP/
| |-- ShaderLibrary/
| | |-- Core.hlsl - ๋ฒํ
์ค ์ธํ ๊ตฌ์กฐ์ฒด, ์คํฌ๋ฆฐUV๊ณ์ฐ,Fog๊ณ์ฐ
| | |-- Lighting.hlsl - ๋ผ์ดํธ ๊ตฌ์กฐ์ฒด, diffuse, specular, GI
| | |-- Shadows.hlsl - ์๋์ฐ๋งต ์ํ๋ง, ์บ์ค์ผ์ด๋ ๊ณ์ฐ, ShadowCoord๊ณ์ฐ , Shadow Bias๊ณ์ฐ
| |-- Shaders/
for object in objects
for light in lights
FrameBuffer = LightModel(object, light);
end
end
for light in lights
for object in GetObjectsAffectedByLight(light)
FrameBuffer += LightModel(object, light);
end
end๋ผ์ดํธ ๊ฐฏ์ ์ฆ๊ฐ> ์ฐ์ฐ๋ ์ฆ๊ฐ
for object in objects:
GBuffer = GetLightingProperties(object)
end
for light in lights
Framebuffer += LightModel(GBuffer, light)
end- ๋ฐํฌ๋ช ๋ถ๊ฐ
- URP - ํ์ฌ(10.3.1) deferred ์ง์ ์ํจ.
- ๋ธ๋ผ์ธ๋ ๋ ๋๋ฌ - ์๋ก์ด ๊ธฐ๋ฒ != ์ ์ฅ๋๊ฐ
Create> Rendering> Universal Render Pipeline> Pipeline Asset(Forward Renderer)
Assets/
|-- UniversalRenderPipelineAsset.asset
|-- UniversalRenderPipelineAsset_Renderer.asset
Project Settings> Graphics> Scriptable Render Pipeline Settings> UniversalRenderPipelineAsset.asset
UniversalRenderPipelineAsset.asset> Quality> HDR check
Project Settings> Player> Other Settings> Color Space> LinearTags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }
Tags { "LightMode" = "SRPDefaultUnlit" } // ๋ผ์ดํธ ๋ชจ๋ ํ๊ทธ ๊ธฐ๋ณธ๊ฐ| LightMode | URP Support |
|---|---|
| UniversalForward | O |
| UniversalGBuffer | O |
| UniversalForwardOnly | O |
| Universal2D | O |
| ShadowCaster | O |
| DepthOnly | O |
| Meta | O |
| SRPDefaultUnlit | O(๊ธฐ๋ณธ๊ฐ) |
| Always | X |
| ForwardAdd | X |
| PrepassBase | X |
| PrepassFinal | X |
| Vertex | X |
| VertexLMRGBM | X |
| VertexLM | X |
// #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
// |-- #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
// Core RP Library/ShaderLibrary/SpaceTransforms.hlsl
// UNITY_MATRIX_M * (UNITY_MATRIX_VP * positionOS)
float4 TransformObjectToHClip(float3 positionOS)
{
// More efficient than computing M*VP matrix product
return mul(GetWorldToHClipMatrix(), mul(GetObjectToWorldMatrix(), float4(positionOS, 1.0)));
}| Space | |
|---|---|
| WS | world space |
| VS | view space |
| OS | object space |
| CS | Homogenous clip spaces |
| TS | tangent space |
| TXS | texture space |
| built-in(legacy) | URP |
|---|---|
| UnityObjectToWorldDir | TransformObjectToWorldDir |
| UnityObjectToWorldNormal | TransformObjectToWorldNormal |
| UnityWorldSpaceViewDir | TransformWorldToViewDir |
| UnityWorldSpaceLightDir | x |
float4x4 GetObjectToWorldMatrix() UNITY_MATRIX_M;
float4x4 GetWorldToObjectMatrix() UNITY_MATRIX_I_M;
float4x4 GetWorldToViewMatrix() UNITY_MATRIX_V;
float4x4 GetWorldToHClipMatrix() UNITY_MATRIX_VP;
float4x4 GetViewToHClipMatrix() UNITY_MATRIX_P;| built-in(legacy) | URP |
|---|---|
| UnityObjectToClipPos | TransformObjectToHClip |
| UnityWorldToClipPos | TransformWorldToHClip |
| UnityViewToClipPos | TransformWViewToHClip |
- https://github.com/Unity-Technologies/Graphics/tree/master/com.unity.render-pipelines.core
- https://github.com/Unity-Technologies/Graphics/tree/master/com.unity.render-pipelines.universal
// #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
struct Light
{
half3 direction;
half3 color;
half distanceAttenuation;
half shadowAttenuation;
};
Light GetMainLight()
light.direction = _MainLightPosition.xyz;
Light GetMainLight(float4 shadowCoord)
// #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl"
#define TRANSFORM_TEX(tex, name) ((tex.xy) * name##_ST.xy + name##_ST.zw)
// #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/API/D3D11.hlsl"
#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)- TODO ๋ ๋ง์ ๊ด์ ์ง์ํ๊ธฐ(2 Directional Light)
- https://catlikecoding.com/unity/tutorials/scriptable-render-pipeline/lights/
- Surface๋ URP์์ ์์ธ๊บผ๋ผ์ Vert/Frag๋ก ๊ตฌํ
- 2๊ฐ Albedo๋ฅผ lerp์ํค๋๊ฒ.
- NormapMap์ ์ฉ.
- ๋น์ ์ธก์ ํ๋ ๋ฐฉ๋ฒ
| ๋จ์ | ์ค๋ช | |
|---|---|---|
| ์ ์ฒด๊ฐ Solid Angle | sr(steradian) | ๋จ์ ๊ตฌ๋ก ์ด๋ ํ ํ์์ ์ฌ์ํ ๊ฒ. |
| ํ์ Power | W | ์ฌ๋ฌ ๋ฐฉํฅ์์ ํ๋ฉด์ ํต๊ณผํด ์ ๋ฌ๋๋ ์๋์ง ํฌ๊ธฐ |
| ์ผ๋ ๋์์ค Irradiance | E (W/m^2) | ๋ชจ๋ ๊ด์ ์์ ์ ์ ์ ๋ฌ๋๋ ๋น์ ํฌ๊ธฐ |
| ๋ ๋์์ค Radiance | L_0 (W/(m^2 * sr)) | ํ๋์ ๊ด์ ์์ ์ ์ ์ ๋ฌ๋๋ ๋น์ ํฌ๊ธฐ |
- ์ฌ์ง์ ํํํ๋ ๋ฐฉ๋ฒ
์๋ฐฉํฅ ๋ฐ์ฌ ๋ถํฌ ํจ์ BRDF Bidirectional Reflectance Distribution Function ๋น์ด ํ๋ฉด์์ ์ด๋ป๊ฒ ๋ฐ์ฌ๋ ์ง์ ๋ํด ์ ์ํ ํจ์.
| BRDF ์์ฑ | |
|---|---|
| positivity | BRDF๊ฐ์ 0์ด์์ด๋ค |
| symmetry (reciprocity) | ๋น์ด ๋ค์ด์ค๋ ๋ฐฉํฅ๊ณผ ๋ฐ์ฌ๋๋ ๋ฐฉํฅ์ ๊ฐ์ ๋์ผํ๋ค |
| conservation of energy | ๋๊ฐ๋ ๋น์ ์์ ๋ค์ด์ค๋ ๋น์ ์์ ๋์ด์ค ์ ์๋ค(๋ฌผ์ฒด๊ฐ ์์ฒด์ ์ผ๋ก ๋น์ ๋ฐ์ฐํ์ง ์๋๋ค๋ฉด) |
half3 LightingPhong(half3 lightColor, half3 lightDir, half3 normal, half3 viewDir, half4 specularColor, half3 albedo, half shininess)
{
half NdotL = saturate(dot(normal, lightDir));
half3 diffuseTerm = NdotL * albedo * lightColor;
half3 reflectionDirection = reflect(-lightDir, normal);
half3 specularDot = max(0.0, dot(viewDir, reflectionDirection));
half3 specular = pow(specularDot, shininess);
half3 specularTerm = specularColor.rgb * specular * lightColor;
return diffuseTerm + specularTerm;
}
// Lafortune and Willems (1994)
half3 LightingPhongModified(half3 lightColor, half3 lightDir, half3 normal, half3 viewDir, half4 specularColor, half3 albedo, half shininess)
{
half NdotL = saturate(dot(normal, lightDir));
half3 diffuseTerm = NdotL * albedo * lightColor;
half norm = (shininess + 2) / (2 * PI);
half3 reflectionDirection = reflect(-lightDir, normal);
half3 specularDot = max(0.0, dot(viewDir, reflectionDirection));
half3 specular = norm * pow(specularDot, shininess);
half3 specularTerm = specularColor.rgb * specular * lightColor;
return diffuseTerm + specularTerm;
}// com.unity.render-pipelines.core/ShaderLibrary/API/D3D11.hlsl
#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)
#define SAMPLE_DEPTH_TEXTURE(textureName, samplerName, coord2) SAMPLE_TEXTURE2D(textureName, samplerName, coord2).r// com.unity.render-pipelines.core/ShaderLibrary/API/Common.hlsl
// Z buffer to linear 0..1 depth (0 at near plane, 1 at far plane).
// Does NOT correctly handle oblique view frustums.
// Does NOT work with orthographic projection.
// zBufferParam = { (f-n)/n, 1, (f-n)/n*f, 1/f }
float Linear01DepthFromNear(float depth, float4 zBufferParam)
{
return 1.0 / (zBufferParam.x + zBufferParam.y / depth);
}
// Z buffer to linear 0..1 depth (0 at camera position, 1 at far plane).
// Does NOT work with orthographic projections.
// Does NOT correctly handle oblique view frustums.
// zBufferParam = { (f-n)/n, 1, (f-n)/n*f, 1/f }
float Linear01Depth(float depth, float4 zBufferParam)
{
return 1.0 / (zBufferParam.x * depth + zBufferParam.y);
}
// Z buffer to linear depth.
// Does NOT correctly handle oblique view frustums.
// Does NOT work with orthographic projection.
// zBufferParam = { (f-n)/n, 1, (f-n)/n*f, 1/f }
float LinearEyeDepth(float depth, float4 zBufferParam)
{
return 1.0 / (zBufferParam.z * depth + zBufferParam.w);
}
// Z buffer to linear depth.
// Correctly handles oblique view frustums.
// Does NOT work with orthographic projection.
// Ref: An Efficient Depth Linearization Method for Oblique View Frustums, Eq. 6.
float LinearEyeDepth(float2 positionNDC, float deviceDepth, float4 invProjParam)
{
float4 positionCS = float4(positionNDC * 2.0 - 1.0, deviceDepth, 1.0);
float viewSpaceZ = rcp(dot(positionCS, invProjParam));
// If the matrix is right-handed, we have to flip the Z axis to get a positive value.
return abs(viewSpaceZ);
}
// Z buffer to linear depth.
// Works in all cases.
// Typically, this is the cheapest variant, provided you've already computed 'positionWS'.
// Assumes that the 'positionWS' is in front of the camera.
float LinearEyeDepth(float3 positionWS, float4x4 viewMatrix)
{
float viewSpaceZ = mul(viewMatrix, float4(positionWS, 1.0)).z;
// If the matrix is right-handed, we have to flip the Z axis to get a positive value.
return abs(viewSpaceZ);
}| Built-in | URP | |
|---|---|---|
| Camera | Camera: | RenderPipelineManager |
| OnPreCull | beginFrameRendering | |
| OnPreRender | beginCameraRendering | |
| OnPostRender | endCameraRendering | |
| OnRenderImage | endFrameRendering |
Create> Rendering> Universal Render Pipeline> Renderer Feature
| ์๋ ์์ฑ๋จ | ||
|---|---|---|
| _CameraDepthTexture | O | Pipeline Settings> Depth Texture |
| _CameraOpaqueTexture | O | Pipeline Settings> Opaque Texture |
| _CameraColorTexture | ?? | |
| _CameraDepthNormalsTexture | X |
- Camera> Rendering> Post-Processing ์ฒดํฌ
- Hierachy> Volume> Global Volume
- Global Volume> Volume> Profile> New
- Global Volume> Volume> Add Override- https://github.com/wdas/brdf
- https://github.com/wdas/brdf/downloads
- https://www.disneyanimation.com/publications/physically-based-shading-at-disney/
- [ ๋ฒ์ญ ] Physically-Based Shading at Disney
| ๊ธฐํธ | ์ค๋ช |
|---|---|
| N | ๋ ธ๋ง |
| H | ํํ๋ฒกํฐ H = normalize( L + V ) |
| L | ๋ผ์ดํธ(๊ด์) |
| V | ๋ทฐ(์นด๋ฉ๋ผ) |
| T | ํ์ ํธ |
| ฮ | (Theta) ๋ฐฉ์๊ฐ |
| ฮฆ | (Phi) ์๊ฐ(์ฌ๋ ค๋ณธ๊ฐ) |
2000 - Michael Ashikhmin & Peter Shirley - An Anisotropic Phong BRDF Model
ํ ์คํํ๋ฌ
1982 - Robert L.Cook & Kenneth E. Torrance - A Reflectance Model For Computer Graphics
๋ฏธ์ธ๋ฉด์ด๋ก
1994 - Michael Oren & Shree K. Nayar - Generalization of Lambertโs Reflectance Model
๋ํจ์ฆ ์ ์ฉ
1992 - Gregory J. Ward - Measuring and modeling anisotropic reflection
๊ฒฝํ์ ๋ฐ์ดํฐ ๊ธฐ๋ฐ, ๊ฑฐ์ ์ฌ์ฉ๋์ง ์์.
SIGGRAPH 2012 - Brent Burley - Physically Based Shading at Disney
์ฌ๋ฌ ํ๋ผ๋ฏธํฐ
- ์ฐธ๊ณ
| Physics and Math of Shading by Naty Hoffman | SIGGRAPH every year from 2012 to 2015 |
| Real Shading in Unreal Engine 4 by Brian Karis | SIGGRAPH, 2013 |
| BRDF Explorer (GLSL) - CookTorrance BRDF | |
| Specular BRDF Reference on Brian Karisโ blog | <graphicrants.blogspot.co.uk/2013/08/specular-brdf-reference.html> |
| Introduction to BRDF Models by Daniรซl Jimenez Kwast | |
| A Reflectance Model for Computer Graphics from 1981 | |
| Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs by Eric Heitz | SIGGRAPH, 2014 - ๋ฏธ์ธ๋ฉด์ดํด ์ถ์ฒ |
| Microfacet Models for Refraction through Rough Surfaces | EGSR, 2017 |
| Physically Based Shading at Disney | SIGGRAPH, 2012, by Brent Burley |
| BRDF Explorer (GLSL) - Disney BRDF | |
| Extending the Disney BRDF to a BSDF with Integrated Subsurface Scattering | SIGGRAPH, 2015, by Brent Burley |
| Moving Frostbite to Physically Based Rendering | SIGGRAPH, 2015, by Sรฉbastien Lagarde and Charlesde Rousiers (only for the Diffuse) |
๋ฏธ์ธ๋ฉด ์ด๋ก
| ๊ด์ฌ ๋ฒกํฐ | |||||
|---|---|---|---|---|---|
| D | Normal Distribution Function |
์ ๊ท๋ถํฌํจ์ | (H) | ์์ | ํฌ๊ธฐ, ๋ฐ๊ธฐ, ์คํํ๋ฌ ๋ชจ์ |
| F | Fresnel | ํ๋ ๋ฌ | (L, H) | 0 ~ 1 | ๋ณด๋ ๊ฐ๋์ ๋ฐ๋ฅธ ๋ฐ์ฌ์จ๊ณผ ๊ตด์ ์จ |
| G | Geometry | ๊ธฐํํจ์ | (L, V, H) | ๋ฉด์ด ์๋ก ๊ฒน์ณ์ ๋น์ ์ฐจ๋จํ๋ ์ ๋์ ๊ทผ์ฌ์น๋ฅผ ํต๊ณ์ ์ผ๋ก ๊ตฌํ๋ค. |
- NDF (Normal
DistributionFunction)- Beckmann
- Phong
- GGX
์ฑ ์ ๊ตฌํ์์๋
| D | Trowbridge-Reitz GGX |
| F | Fresnel-Schlick |
| G | Smith's Schlick-GGX |
- 16์ฅ. ๋ณต์ก๋์ ์ฐ๋ฒ์ ฐ์ด๋ ์ฐธ์กฐ.
// com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl
struct BRDFData
{
half3 albedo;
half3 diffuse;
half3 specular;
half reflectivity;
half perceptualRoughness;
half roughness;
half roughness2;
half grazingTerm;
// We save some light invariant BRDF terms so we don't have to recompute
// them in the light loop. Take a look at DirectBRDF function for detailed explaination.
half normalizationTerm; // roughness * 4.0 + 2.0
half roughness2MinusOne; // roughness^2 - 1.0
};๋ฐํฌ๋ช ์ BRDF๋ก ์ฒ๋ฆฌํ๊ธฐ ๊ณค๋.
| BRDF | Bidirectional reflectance distribution function | ๋ ๋น์ด ์ด๋ค ๋ฐฉํฅ์ผ๋ก ๋ฐ์ฌ๊ฐ ๋๋์ง |
| BTDF | Bidirectional transmittance distribution function | ๋ ๋น์ด ์ด๋ค ๋ฐฉํฅ์ผ๋ก ํฌ๊ณผ๊ฐ ๋๋์ง |
| BSDF | Bidirectional scattering distribution function | ์ด ๋์ ํฉ์ณ ๋น์ด ์ฌ์ง๊ณผ ์ด๋ป๊ฒ ์ํธ์์ฉํ๋์ง |
- TODO ์์ ์์ 2๊ฐ์ Directional Light์ฌ์ฉ...
// ref: GPG Pro 2
//Translucency
// - ๋
ธ๋ง๊ณผ ๋ผ์ดํธ์ ํํ์ ์ญ๋ฐฉํฅ์ (๋ฌผ์ฒด ๋ท๋ถ๋ถ)
// - ๋ทฐ๋ฅผ ๋ท์ฐ์ฐ์ผ๋ก ๋ฌถ์ด์ค๋ค. (ํ์ฐํจ๊ณผ)
float thickness = SAMPLE_TEXTURE2D(_Thickness, sampler_Thickness, IN.uv).r;
float3 translucencyLightDir = L + N * _Distortion;
float translucencyDot = pow(saturate(dot(V, -translucencyLightDir)), _Power) * _Scale;
float3 translucency = translucencyDot * thickness * _SubsurfaceColor.rgb;
diffuse += translucency;| Cubemap์์ฑ ๋๊ตฌ | |
|---|---|
| cmftStudio | BSD 2 |
| Knald's Lys | Commercial |
| IBLBaker | MIT License |
| CubeMapGen | old |
์ํฐ์คํธ๊ฐ ์กฐ์ํ๊ธฐ ํธํ๊ฒ
- ์ ์ ํ ์ ํ ๊ฐฏ์
- ์ ์ ํ ์ ํ ๋ค์ด๋ฐ
- ์ํธ ์์ฉํ๋ ์ ํ ๊ฐ์ ์ํ ๋ฌธ์ํ
- ํ ์ค์ณ์ ์ฌ๋ฌ ์ ๋ณด(albedo + specular๋ฑ)์ ๋ฃ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์๋ฐ, ๋ช ํํ๊ฒ ์ ํ ๊ฐ๊ณผ ์ ํ ๋ค์ด๋ฐ์ ํ์
- ์ฌ๋ฌ ๋ฒ์ ํผํฉ์ฌ์ฉ ํผํ๊ธฐ(๋๋๋ก์ด๋ฉด
0 ~ 1๋ก...)
ํ๋ผ๋ฏธํฐ ๋ณํ๊ฐ ๋ณ๋ก ์์ ์ฌ ์์ผ๋ฉด ์ข๊ฒ ๋ค..
์์ด๋ ํ๋๋ฅผ ์ด์ฉํด์ ์ฌ๋ฌ๊ฐ์ง ๊ฒฝ์ฐ๋ฅผ ์ฒ๋ฆฌํ๊ณ ์ถ์ ๊ฒฝ์ฐ, ํ์ํ ๋ชจ๋ ์ฝ๋๋ฅผ ์์ด๋ ํ๋์ ์ง์ด๋ฃ๊ฒ๋๋ฉด ๊ทธ๊ฒ ๋ฐ๋ก ์ฐ๋ฒ์ ฐ์ด๋.
if์ ๊ฐ์ ๋์ ๋ถ๊ธฐ๋ ์ฑ๋ฅ์ ํ.#if์ ๊ฐ์ด ์ ์ฒ๋ฆฌ๊ธฐ๋ฅผ ์ด์ฉํ, ์ ์ ๋ถ๊ธฐ๋ฅผ ์ด์ฉํ์ฌ ์ฒ๋ฆฌํ๋ค.
์ ๋ํฐ์์๋ ํค์๋๋ฅผ ์ด์ฉ ์์ด๋ ์กฐํฉ์ ํธ๋ฆฌํ๊ฒ ํด์ฃผ๋ ๊ธฐ๋ฅ์ด ์์.
-
์ด 256๊ฐ์ ๊ธ๋ก๋ฒ ํค์๋.
-
64๊ฐ์ ๋ก์ปฌ ํค์๋.
-
#pragma shader_feature KEYWORD -
#pragma multi_compile KEYWORD
| ๊ฒ์๋น๋์ ํฌํจ | |
|---|---|
| shader_feature | ์ฌ์ฉ๋๋ ๊ฒ๋ง |
| multi_compile | ์กฐํฉ ๊ฐ๋ฅํ ๋ชจ๋ ๊ฒ |
#pragma multi_compile A B C
#pragma multi_compile D E
์กฐํฉํด์ ๋์ฌ ์ ์๋ ์ด ๊ฐฏ์: 6๊ฐ
A+D, B+D, C+D
A+E, B+E, C+E[KeywordEnum(Off, On)] _UseNormal("Use Normal Map", Float) = 0
#pragma shader_feature _USENORMAL_OFF _USENORMAL_ON
#if _USENORMAL_ON
#endif
[Toggle] _ModifiedMode("Modified?", Float) = 0
#pragma shader_feature _MODIFIEDMODE_OFF _MODIFIEDMODE_ON
#if _MODIFIEDMODE_ON
#endif- shader๋ก ๋ ธ๋ง๊ฐ ์๊ฐํ
struct Attributes
{
float4 positionOS : POSITION;
float3 normalOS : NORMAL;
float4 tangent : TANGENT;
float2 uv : TEXCOORD0;
};
struct Varyings
{
float4 positionHCS : SV_POSITION;
float2 uv : TEXCOORD0;
float3 T : TEXCOORD1;
float3 B : TEXCOORD2;
float3 N : TEXCOORD3;
float3 positionWS : TEXCOORD4;
};
// ----------
inline void ExtractTBN(in half3 normalOS, in float4 tangent, inout half3 T, inout half3 B, inout half3 N)
{
N = TransformObjectToWorldNormal(normalOS);
T = TransformObjectToWorldDir(tangent.xyz);
B = cross(N, T) * tangent.w * unity_WorldTransformParams.w;
}
inline half3 CombineTBN(in half3 tangentNormal, in half3 T, in half3 B, in half3 N)
{
return mul(tangentNormal, float3x3(normalize(T), normalize(B), normalize(N)));
}
Varyings vert(Attributes IN)
{
//Varyings OUT;
Varyings OUT = (Varyings)0;;
OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
OUT.uv = TRANSFORM_TEX(IN.uv, _BumpMap);
ExtractTBN(IN.normalOS, IN.tangent, OUT.T, OUT.B, OUT.N);
OUT.positionWS = TransformObjectToWorld(IN.positionOS.xyz);
return OUT;
}
// ---------------
half4 frag(Varyings IN) : SV_Target
{
#if _ENABLENORMALMAP_ON
float3 tangentNormal = UnpackNormal(SAMPLE_TEXTURE2D(_BumpMap, sampler_BumpMap, IN.uv));
tangentNormal.xy *= _BumpMapStrength; // BumpMap Strength.
float3 N = CombineTBN(tangentNormal, IN.T, IN.B, IN.N);
#else
float3 N = normalize(IN.N);
#endif
return half4(N * 0.5 + 0.5, 1);
}- Window> Analysis> Frame Debugger
- RenderDoc ํ๋ก๊ทธ๋จ
| ๋ฐฐ์น ์ | |
| ๋๋ก์ฐ์ฝ | |
| SetPass | |
| Vertex | |
| ํ ์ค์ณ ๊ฐฏ์/๋ฉ๋ชจ๋ฆฌ /์ค์์น ํ์ | |
| Shadow Casters | |
| Vertex Buffer Object |
- CPU์ ์น์ค? GPU์ ์น์ค?
- Static GameObject ํ์ฉ ์ํ๊ธฐ.
| GDC | GDC Vault ๊ตฌ๋ 1๋ 400๋ถ์ ๋ |
| Siggraph | 1๋ 45๋ฌ๋ฌ |
| Unite | |
| Digital Dragons | ์์์๋ฃ ๊ณต๊ฐ |
| Eurographics | ํ์ ์์ฃผ |
์ด๋ ต์ง๋ง ๊ตฌ์ ํด์ ์ฝ์ด๋ณผ ๊ฐ์น ์์.
| GPU Gems | |
| ShaderX | |
| GPU PRO | |
| GPU Zen |
- http://blog.selfshadow.com/publications/
- https://labs.unity.com/
- http://filmicworlds.com/
- http://aras-p.info/
- https://seblagarde.wordpress.com/
- http://c0de517e.blogspot.co.uk/
- http://blog.tobias-franke.eu/
- https://bartwronski.com/
- http://bitsquid.blogspot.co.uk/
- http://casual-effects.blogspot.co.uk/
- http://kesen.realtimerendering.com/
- http://graphicscodex.com
- https://www.scratchapixel.com/



