Skyboxを作ったものに変更したところ(シェーダはSkybox/Cubemap)、
ゲームカメラに太陽が表示されなくなってしまいました。
その場でSkyboxをデフォルトのものに戻すと太陽が表示されるので、
他の環境は関係ないと思います。
このSkyboxで太陽を表示させたいのですが、
どなたかSkyboxについて詳しい方回答お願いします。
####追記
https://www.reddit.com/r/Unity3D/comments/721ctv/standard_skybox_directional_light_results_in_an/
このSkyboxは太陽を描写する処理が含まれていないようなのですが、代わりに良いものがあれば教えていただければ嬉しいです。
スカイボックスのテクスチャはpng1枚です。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
パート2
ShaderLab
1 float far = 0.0; 2 half3 cIn, cOut; 3 4 if(eyeRay.y >= 0.0) 5 { 6 // Sky 7 // Calculate the length of the "atmosphere" 8 far = sqrt(kOuterRadius2 + kInnerRadius2 * eyeRay.y * eyeRay.y - kInnerRadius2) - kInnerRadius * eyeRay.y; 9 10 float3 pos = cameraPos + far * eyeRay; 11 12 // Calculate the ray's starting position, then calculate its scattering offset 13 float height = kInnerRadius + kCameraHeight; 14 float depth = exp(kScaleOverScaleDepth * (-kCameraHeight)); 15 float startAngle = dot(eyeRay, cameraPos) / height; 16 float startOffset = depth*scale(startAngle); 17 18 // Initialize the scattering loop variables 19 float sampleLength = far / kSamples; 20 float scaledLength = sampleLength * kScale; 21 float3 sampleRay = eyeRay * sampleLength; 22 float3 samplePoint = cameraPos + sampleRay * 0.5; 23 24 // Now loop through the sample rays 25 float3 frontColor = float3(0.0, 0.0, 0.0); 26 // Weird workaround: WP8 and desktop FL_9_3 do not like the for loop here 27 // (but an almost identical loop is perfectly fine in the ground calculations below) 28 // Just unrolling this manually seems to make everything fine again. 29 //for(int i=0; i<int(kSamples); i++) 30 { 31 float height = length(samplePoint); 32 float depth = exp(kScaleOverScaleDepth * (kInnerRadius - height)); 33 float lightAngle = dot(_WorldSpaceLightPos0.xyz, samplePoint) / height; 34 float cameraAngle = dot(eyeRay, samplePoint) / height; 35 float scatter = (startOffset + depth*(scale(lightAngle) - scale(cameraAngle))); 36 float3 attenuate = exp(-clamp(scatter, 0.0, kMAX_SCATTER) * (kInvWavelength * kKr4PI + kKm4PI)); 37 frontColor += attenuate * (depth * scaledLength); 38 samplePoint += sampleRay; 39 } 40 { 41 float height = length(samplePoint); 42 float depth = exp(kScaleOverScaleDepth * (kInnerRadius - height)); 43 float lightAngle = dot(_WorldSpaceLightPos0.xyz, samplePoint) / height; 44 float cameraAngle = dot(eyeRay, samplePoint) / height; 45 float scatter = (startOffset + depth*(scale(lightAngle) - scale(cameraAngle))); 46 float3 attenuate = exp(-clamp(scatter, 0.0, kMAX_SCATTER) * (kInvWavelength * kKr4PI + kKm4PI)); 47 frontColor += attenuate * (depth * scaledLength); 48 samplePoint += sampleRay; 49 } 50 51 // Finally, scale the Mie and Rayleigh colors and set up the varying variables for the pixel shader 52 cIn = frontColor * (kInvWavelength * kKrESun); 53 cOut = frontColor * kKmESun; 54 } 55 else 56 { 57 // Ground 58 far = (-kCameraHeight) / (min(-0.001, eyeRay.y)); 59 60 float3 pos = cameraPos + far * eyeRay; 61 62 // Calculate the ray's starting position, then calculate its scattering offset 63 float depth = exp((-kCameraHeight) * (1.0/kScaleDepth)); 64 float cameraAngle = dot(-eyeRay, pos); 65 float lightAngle = dot(_WorldSpaceLightPos0.xyz, pos); 66 float cameraScale = scale(cameraAngle); 67 float lightScale = scale(lightAngle); 68 float cameraOffset = depth*cameraScale; 69 float temp = (lightScale + cameraScale); 70 71 // Initialize the scattering loop variables 72 float sampleLength = far / kSamples; 73 float scaledLength = sampleLength * kScale; 74 float3 sampleRay = eyeRay * sampleLength; 75 float3 samplePoint = cameraPos + sampleRay * 0.5; 76 77 // Now loop through the sample rays 78 float3 frontColor = float3(0.0, 0.0, 0.0); 79 float3 attenuate; 80 //for(int i=0; i<int(kSamples); i++) // Loop removed because we kept hitting SM2.0 temp variable limits. Doesn't affect the image too much. 81 { 82 float height = length(samplePoint); 83 float depth = exp(kScaleOverScaleDepth * (kInnerRadius - height)); 84 float scatter = depth*temp - cameraOffset; 85 attenuate = exp(-clamp(scatter, 0.0, kMAX_SCATTER) * (kInvWavelength * kKr4PI + kKm4PI)); 86 frontColor += attenuate * (depth * scaledLength); 87 samplePoint += sampleRay; 88 } 89 90 cIn = frontColor * (kInvWavelength * kKrESun + kKmESun); 91 cOut = clamp(attenuate, 0.0, 1.0); 92 } 93 94 #if SKYBOX_SUNDISK == SKYBOX_SUNDISK_HQ 95 o.vertexForSun = -eyeRay; 96 #elif SKYBOX_SUNDISK == SKYBOX_SUNDISK_SIMPLE 97 o.rayDir = half3(-eyeRay); 98 #else 99 o.skyGroundFactor = -eyeRay.y / SKY_GROUND_THRESHOLD; 100 #endif 101 102 #if SKYBOX_SUNDISK != SKYBOX_SUNDISK_NONE 103 // The sun should have a stable intensity in its course in the sky. Moreover it should match the highlight of a purely specular material. 104 // This matching was done using the standard shader BRDF1 on the 5/31/2017 105 // Finally we want the sun to be always bright even in LDR thus the normalization of the lightColor for low intensity. 106 half lightColorIntensity = clamp(length(_LightColor0.xyz), 0.25, 1); 107 #if SKYBOX_SUNDISK == SKYBOX_SUNDISK_SIMPLE 108 o.sunColor = kSimpleSundiskIntensityFactor * saturate(cOut * kSunScale) * _LightColor0.xyz / lightColorIntensity; 109 #else // SKYBOX_SUNDISK_HQ 110 o.sunColor = kHDSundiskIntensityFactor * saturate(cOut) * _LightColor0.xyz / lightColorIntensity; 111 #endif 112 #endif 113 114 #if defined(UNITY_COLORSPACE_GAMMA) && SKYBOX_COLOR_IN_TARGET_COLOR_SPACE 115 #if SKYBOX_SUNDISK != SKYBOX_SUNDISK_NONE 116 o.sunColor = sqrt(o.sunColor); 117 #endif 118 #endif 119 120 return o; 121 } 122 123 // Calculates the Mie phase function 124 half getMiePhase(half eyeCos, half eyeCos2) 125 { 126 half temp = 1.0 + MIE_G2 - 2.0 * MIE_G * eyeCos; 127 temp = pow(temp, pow(_SunSize,0.65) * 10); 128 temp = max(temp,1.0e-4); // prevent division by zero, esp. in half precision 129 temp = 1.5 * ((1.0 - MIE_G2) / (2.0 + MIE_G2)) * (1.0 + eyeCos2) / temp; 130 #if defined(UNITY_COLORSPACE_GAMMA) && SKYBOX_COLOR_IN_TARGET_COLOR_SPACE 131 temp = pow(temp, .454545); 132 #endif 133 return temp; 134 } 135 136 // Calculates the sun shape 137 half calcSunAttenuation(half3 lightPos, half3 ray) 138 { 139 #if SKYBOX_SUNDISK == SKYBOX_SUNDISK_SIMPLE 140 half3 delta = lightPos - ray; 141 half dist = length(delta); 142 half spot = 1.0 - smoothstep(0.0, _SunSize, dist); 143 return spot * spot; 144 #else // SKYBOX_SUNDISK_HQ 145 half focusedEyeCos = pow(saturate(dot(lightPos, ray)), _SunSizeConvergence); 146 return getMiePhase(-focusedEyeCos, focusedEyeCos * focusedEyeCos); 147 #endif 148 } 149 150 fixed4 frag (v2f i) : SV_Target 151 { 152 // if y > 1 [eyeRay.y < -SKY_GROUND_THRESHOLD] - ground 153 // if y >= 0 and < 1 [eyeRay.y <= 0 and > -SKY_GROUND_THRESHOLD] - horizon 154 // if y < 0 [eyeRay.y > 0] - sky 155 #if SKYBOX_SUNDISK == SKYBOX_SUNDISK_HQ 156 half3 ray = normalize(i.vertexForSun.xyz); 157 half y = ray.y / SKY_GROUND_THRESHOLD; 158 #elif SKYBOX_SUNDISK == SKYBOX_SUNDISK_SIMPLE 159 half3 ray = i.rayDir.xyz; 160 half y = ray.y / SKY_GROUND_THRESHOLD; 161 #else 162 half y = i.skyGroundFactor; 163 #endif 164 165 half4 tex = texCUBE (_Tex, i.texcoord); 166 half3 c = DecodeHDR (tex, _Tex_HDR); 167 c = c * _Tint.rgb * unity_ColorSpaceDouble.rgb; 168 c *= _Exposure; 169 170 #if SKYBOX_SUNDISK != SKYBOX_SUNDISK_NONE 171 if(y < 0.0) 172 { 173 c += i.sunColor * calcSunAttenuation(_WorldSpaceLightPos0.xyz, -ray); 174 } 175 #endif 176 177 return half4(c, 1); 178 } 179 ENDCG 180 } 181 } 182 Fallback Off 183}
実験用の背景としては下図のような画像を使用したところ...
下図のように、太陽の方角に光が描かれました。GIFにつき階調が十分表現できていませんが、実際の見た目はちょっと試した限りでは問題なさそうに見えました。
投稿2020/07/15 20:16
総合スコア10811
0
ベストアンサー
ご提示のStandard skybox + directional light results in an actual sun. When changing the skybox, the sun is behind the skybox. Is there a workaround to actually see it? : Unity3Dで言及されているように、デフォルトのスカイボックスの太陽はSkybox/Procedural
シェーダーが描いているものであり、Skybox/Cubemap
には太陽を描く機能はないでしょう。
Skybox/Cubemap
を改造した(というかSkybox/Procedural
の記述をペタペタ貼り付けただけです...やっつけ仕事ですみません)下記のようなSkybox/Cubemap (Sun Disk)
を作り、
ShaderLab
1// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt) 2 3Shader "Skybox/Cubemap (Sun Disk)" { 4 Properties { 5 _Tint ("Tint Color", Color) = (.5, .5, .5, .5) 6 [Gamma] _Exposure ("Exposure", Range(0, 8)) = 1.0 7 _Rotation ("Rotation", Range(0, 360)) = 0 8 [NoScaleOffset] _Tex ("Cubemap (HDR)", Cube) = "grey" {} 9 10 [KeywordEnum(None, Simple, High Quality)] _SunDisk ("Sun", Int) = 2 11 _SunSize ("Sun Size", Range(0,1)) = 0.04 12 _SunSizeConvergence("Sun Size Convergence", Range(1,10)) = 5 13 _AtmosphereThickness ("Atmosphere Thickness", Range(0,5)) = 1.0 14 } 15 16 SubShader { 17 Tags { "Queue"="Background" "RenderType"="Background" "PreviewType"="Skybox" } 18 Cull Off ZWrite Off 19 20 Pass { 21 22 CGPROGRAM 23 #pragma vertex vert 24 #pragma fragment frag 25 #pragma target 2.0 26 27 #pragma multi_compile_local _SUNDISK_NONE _SUNDISK_SIMPLE _SUNDISK_HIGH_QUALITY 28 29 #include "UnityCG.cginc" 30 #include "Lighting.cginc" 31 32 samplerCUBE _Tex; 33 half4 _Tex_HDR; 34 half4 _Tint; 35 half _Exposure; 36 float _Rotation; 37 38 half _SunSize; 39 half _SunSizeConvergence; 40 half _AtmosphereThickness; 41 42 #if defined(UNITY_COLORSPACE_GAMMA) 43 #define GAMMA 2 44 #define COLOR_2_GAMMA(color) color 45 #define COLOR_2_LINEAR(color) color*color 46 #define LINEAR_2_OUTPUT(color) sqrt(color) 47 #else 48 #define GAMMA 2.2 49 // HACK: to get gfx-tests in Gamma mode to agree until UNITY_ACTIVE_COLORSPACE_IS_GAMMA is working properly 50 #define COLOR_2_GAMMA(color) ((unity_ColorSpaceDouble.r>2.0) ? pow(color,1.0/GAMMA) : color) 51 #define COLOR_2_LINEAR(color) color 52 #define LINEAR_2_LINEAR(color) color 53 #endif 54 55 // RGB wavelengths 56 // .35 (.62=158), .43 (.68=174), .525 (.75=190) 57 static const float3 kDefaultScatteringWavelength = float3(.65, .57, .475); 58 static const float3 kVariableRangeForScatteringWavelength = float3(.15, .15, .15); 59 60 #define OUTER_RADIUS 1.025 61 static const float kOuterRadius = OUTER_RADIUS; 62 static const float kOuterRadius2 = OUTER_RADIUS*OUTER_RADIUS; 63 static const float kInnerRadius = 1.0; 64 static const float kInnerRadius2 = 1.0; 65 66 static const float kCameraHeight = 0.0001; 67 68 #define kRAYLEIGH (lerp(0.0, 0.0025, pow(_AtmosphereThickness,2.5))) // Rayleigh constant 69 #define kMIE 0.0010 // Mie constant 70 #define kSUN_BRIGHTNESS 20.0 // Sun brightness 71 72 #define kMAX_SCATTER 50.0 // Maximum scattering value, to prevent math overflows on Adrenos 73 74 static const half kHDSundiskIntensityFactor = 15.0; 75 static const half kSimpleSundiskIntensityFactor = 27.0; 76 77 static const half kSunScale = 400.0 * kSUN_BRIGHTNESS; 78 static const float kKmESun = kMIE * kSUN_BRIGHTNESS; 79 static const float kKm4PI = kMIE * 4.0 * 3.14159265; 80 static const float kScale = 1.0 / (OUTER_RADIUS - 1.0); 81 static const float kScaleDepth = 0.25; 82 static const float kScaleOverScaleDepth = (1.0 / (OUTER_RADIUS - 1.0)) / 0.25; 83 static const float kSamples = 2.0; // THIS IS UNROLLED MANUALLY, DON'T TOUCH 84 85 #define MIE_G (-0.990) 86 #define MIE_G2 0.9801 87 88 #define SKY_GROUND_THRESHOLD 0.02 89 90 // sun disk rendering: 91 // no sun disk - the fastest option 92 #define SKYBOX_SUNDISK_NONE 0 93 // simplistic sun disk - without mie phase function 94 #define SKYBOX_SUNDISK_SIMPLE 1 95 // full calculation - uses mie phase function 96 #define SKYBOX_SUNDISK_HQ 2 97 98 // uncomment this line and change SKYBOX_SUNDISK_SIMPLE to override material settings 99 // #define SKYBOX_SUNDISK SKYBOX_SUNDISK_SIMPLE 100 101 #ifndef SKYBOX_SUNDISK 102 #if defined(_SUNDISK_NONE) 103 #define SKYBOX_SUNDISK SKYBOX_SUNDISK_NONE 104 #elif defined(_SUNDISK_SIMPLE) 105 #define SKYBOX_SUNDISK SKYBOX_SUNDISK_SIMPLE 106 #else 107 #define SKYBOX_SUNDISK SKYBOX_SUNDISK_HQ 108 #endif 109 #endif 110 111 #ifndef SKYBOX_COLOR_IN_TARGET_COLOR_SPACE 112 #if defined(SHADER_API_MOBILE) 113 #define SKYBOX_COLOR_IN_TARGET_COLOR_SPACE 1 114 #else 115 #define SKYBOX_COLOR_IN_TARGET_COLOR_SPACE 0 116 #endif 117 #endif 118 119 float3 RotateAroundYInDegrees (float3 vertex, float degrees) 120 { 121 float alpha = degrees * UNITY_PI / 180.0; 122 float sina, cosa; 123 sincos(alpha, sina, cosa); 124 float2x2 m = float2x2(cosa, -sina, sina, cosa); 125 return float3(mul(m, vertex.xz), vertex.y).xzy; 126 } 127 128 struct appdata_t { 129 float4 vertex : POSITION; 130 UNITY_VERTEX_INPUT_INSTANCE_ID 131 }; 132 133 struct v2f { 134 float4 vertex : SV_POSITION; 135 float3 texcoord : TEXCOORD0; 136 137 #if SKYBOX_SUNDISK == SKYBOX_SUNDISK_HQ 138 // for HQ sun disk, we need vertex itself to calculate ray-dir per-pixel 139 float3 vertexForSun : TEXCOORD1; 140 #elif SKYBOX_SUNDISK == SKYBOX_SUNDISK_SIMPLE 141 half3 rayDir : TEXCOORD1; 142 #else 143 // as we dont need sun disk we need just rayDir.y (sky/ground threshold) 144 half skyGroundFactor : TEXCOORD1; 145 #endif 146 147 #if SKYBOX_SUNDISK != SKYBOX_SUNDISK_NONE 148 half3 sunColor : TEXCOORD3; 149 #endif 150 151 UNITY_VERTEX_OUTPUT_STEREO 152 }; 153 154 float scale(float inCos) 155 { 156 float x = 1.0 - inCos; 157 return 0.25 * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25)))); 158 } 159 160 v2f vert (appdata_t v) 161 { 162 v2f o; 163 UNITY_SETUP_INSTANCE_ID(v); 164 UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); 165 float3 rotated = RotateAroundYInDegrees(v.vertex, _Rotation); 166 o.vertex = UnityObjectToClipPos(rotated); 167 o.texcoord = v.vertex.xyz; 168 169 float3 kSkyTintInGammaSpace = COLOR_2_GAMMA(_Tint); // convert tint from Linear back to Gamma 170 float3 kScatteringWavelength = lerp ( 171 kDefaultScatteringWavelength-kVariableRangeForScatteringWavelength, 172 kDefaultScatteringWavelength+kVariableRangeForScatteringWavelength, 173 half3(1,1,1) - kSkyTintInGammaSpace); // using Tint in sRGB gamma allows for more visually linear interpolation and to keep (.5) at (128, gray in sRGB) point 174 float3 kInvWavelength = 1.0 / pow(kScatteringWavelength, 4); 175 176 float kKrESun = kRAYLEIGH * kSUN_BRIGHTNESS; 177 float kKr4PI = kRAYLEIGH * 4.0 * 3.14159265; 178 179 float3 cameraPos = float3(0,kInnerRadius + kCameraHeight,0); // The camera's current position 180 181 float3 eyeRay = normalize(mul((float3x3)unity_ObjectToWorld, v.vertex.xyz));
(コードの途中ですが、長すぎて別回答に分断します...パート2へ続く)
投稿2020/07/15 20:15
総合スコア10811
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/07/16 12:09
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。