Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f45ad72056 | |||
| 29f0765864 | |||
| 93e91a68d5 |
@ -636,7 +636,7 @@ void main() {
|
|||||||
shadowMap
|
shadowMap
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
, eye, p + n * shadowsBias * 2, shadowsBias
|
, eye, p, n, shadowsBias
|
||||||
#ifdef _ShadowMapTransparent
|
#ifdef _ShadowMapTransparent
|
||||||
, false
|
, false
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -259,6 +259,11 @@
|
|||||||
"link": "_biasLightWorldViewProjectionMatrixSpotArray",
|
"link": "_biasLightWorldViewProjectionMatrixSpotArray",
|
||||||
"ifdef": ["_Clusters", "_ShadowMap", "_Spot"]
|
"ifdef": ["_Clusters", "_ShadowMap", "_Spot"]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "LWVPSpotArray",
|
||||||
|
"link": "_biasLightViewProjectionMatrixSpotArray",
|
||||||
|
"ifdef": ["_SinglePoint", "_ShadowMap", "_Spot"]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "pointLightDataArray",
|
"name": "pointLightDataArray",
|
||||||
"link": "_pointLightsAtlasArray",
|
"link": "_pointLightsAtlasArray",
|
||||||
|
|||||||
@ -448,7 +448,7 @@ void main() {
|
|||||||
shadowMap
|
shadowMap
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
, eye, p + n * shadowsBias * 2, shadowsBias
|
, eye, p, n, shadowsBias
|
||||||
#ifdef _ShadowMapTransparent
|
#ifdef _ShadowMapTransparent
|
||||||
, false
|
, false
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -183,6 +183,11 @@
|
|||||||
"link": "_biasLightWorldViewProjectionMatrixSpotArray",
|
"link": "_biasLightWorldViewProjectionMatrixSpotArray",
|
||||||
"ifdef": ["_Clusters", "_ShadowMap", "_Spot"]
|
"ifdef": ["_Clusters", "_ShadowMap", "_Spot"]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "LWVPSpotArray",
|
||||||
|
"link": "_biasLightViewProjectionMatrixSpotArray",
|
||||||
|
"ifdef": ["_SinglePoint", "_ShadowMap", "_Spot"]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "pointLightDataArray",
|
"name": "pointLightDataArray",
|
||||||
"link": "_pointLightsAtlasArray",
|
"link": "_pointLightsAtlasArray",
|
||||||
|
|||||||
@ -595,3 +595,4 @@ vec3 sampleLightVoxels(const vec3 p, const vec3 n, const vec3 v, const float dot
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,7 @@ uniform vec2 smSizeUniform;
|
|||||||
|
|
||||||
#ifdef _ShadowMapAtlas
|
#ifdef _ShadowMapAtlas
|
||||||
uniform vec4 tileBoundsSunArray[maxLights * shadowmapCascades];
|
uniform vec4 tileBoundsSunArray[maxLights * shadowmapCascades];
|
||||||
#if defined(_Clusters) && defined(_Spot) && defined(_ShadowMap)
|
#if defined(_Clusters) && (defined(_Spot) || defined(_LTC)) && defined(_ShadowMap)
|
||||||
uniform vec4 tileBoundsSpotArray[maxLightsCluster];
|
uniform vec4 tileBoundsSpotArray[maxLightsCluster];
|
||||||
#endif
|
#endif
|
||||||
vec4 tileBounds = vec4(0.0, 0.0, 1.0, 1.0);
|
vec4 tileBounds = vec4(0.0, 0.0, 1.0, 1.0);
|
||||||
@ -180,7 +180,7 @@ vec3 PCFCube(samplerCubeShadow shadowMapCube,
|
|||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
const float s = shadowmapCubePcfSize; // TODO: incorrect...
|
const float s = shadowmapCubePcfSize; // TODO: incorrect...
|
||||||
float compare = lpToDepth(lp, lightProj) - bias * 1.5;
|
float compare = lpToDepth(lp, lightProj) - bias * 1.5 - 0.0001;
|
||||||
ml = ml + n * bias * 20;
|
ml = ml + n * bias * 20;
|
||||||
#ifdef _InvY
|
#ifdef _InvY
|
||||||
ml.y = -ml.y;
|
ml.y = -ml.y;
|
||||||
@ -321,7 +321,7 @@ vec3 PCFFakeCube(sampler2DShadow shadowMap,
|
|||||||
, const bool transparent
|
, const bool transparent
|
||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
const float compare = lpToDepth(lp, lightProj) - bias * 1.5;
|
const float compare = lpToDepth(lp, lightProj) - bias * 1.5 - 0.0001;
|
||||||
ml = ml + n * bias * 20;
|
ml = ml + n * bias * 20;
|
||||||
int faceIndex = 0;
|
int faceIndex = 0;
|
||||||
const int lightIndex = index * 6;
|
const int lightIndex = index * 6;
|
||||||
@ -408,10 +408,16 @@ vec3 PCFFakeCube(sampler2DShadow shadowMap,
|
|||||||
#ifdef _ShadowMapTransparent
|
#ifdef _ShadowMapTransparent
|
||||||
if (transparent == false) {
|
if (transparent == false) {
|
||||||
vec3 transResult = vec3(0.0);
|
vec3 transResult = vec3(0.0);
|
||||||
|
vec2 tileMin = pointLightTile.xy;
|
||||||
|
vec2 tileMax = pointLightTile.xy + pointLightTile.z;
|
||||||
|
#ifdef _FlipY
|
||||||
|
tileMin.y = 1.0 - tileMax.y;
|
||||||
|
tileMax.y = 1.0 - pointLightTile.y;
|
||||||
|
#endif
|
||||||
for (int x = -1; x <= 1; x++) {
|
for (int x = -1; x <= 1; x++) {
|
||||||
for (int y = -1; y <= 1; y++) {
|
for (int y = -1; y <= 1; y++) {
|
||||||
vec4 smt = texture(shadowMapTransparent,
|
vec4 smt = texture(shadowMapTransparent,
|
||||||
clamp(uvtiled + vec2(x, y) / smSize, 0.0, 1.0));
|
clamp(uvtiled + vec2(x, y) / smSize, tileMin, tileMax));
|
||||||
transResult += (smt.a < compare) ? smt.rgb : vec3(1.0);
|
transResult += (smt.a < compare) ? smt.rgb : vec3(1.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -437,15 +443,15 @@ vec3 shadowTest(sampler2DShadow shadowMap,
|
|||||||
#ifdef _ShadowMapAtlas
|
#ifdef _ShadowMapAtlas
|
||||||
// use tile PCF
|
// use tile PCF
|
||||||
#ifdef _SMSizeUniform
|
#ifdef _SMSizeUniform
|
||||||
vec2 smSizeAtlas = smSizeUniform * (tileBounds.zw - tileBounds.xy);
|
vec2 smSizeAtlas = smSizeUniform;
|
||||||
#else
|
#else
|
||||||
vec2 smSizeAtlas = shadowmapSize * (tileBounds.zw - tileBounds.xy);
|
vec2 smSizeAtlas = shadowmapSize;
|
||||||
#endif
|
#endif
|
||||||
return PCFTileAware(shadowMap,
|
return PCFTileAware(shadowMap,
|
||||||
#ifdef _ShadowMapTransparent
|
#ifdef _ShadowMapTransparent
|
||||||
shadowMapTransparent,
|
shadowMapTransparent,
|
||||||
#endif
|
#endif
|
||||||
lPos.xy, lPos.z - shadowsBias, smSizeAtlas,
|
lPos.xy, lPos.z - shadowsBias - 0.0001, smSizeAtlas,
|
||||||
tileBounds.xy, tileBounds.zw
|
tileBounds.xy, tileBounds.zw
|
||||||
#ifdef _ShadowMapTransparent
|
#ifdef _ShadowMapTransparent
|
||||||
, transparent
|
, transparent
|
||||||
@ -462,7 +468,7 @@ vec3 shadowTest(sampler2DShadow shadowMap,
|
|||||||
#ifdef _ShadowMapTransparent
|
#ifdef _ShadowMapTransparent
|
||||||
shadowMapTransparent,
|
shadowMapTransparent,
|
||||||
#endif
|
#endif
|
||||||
lPos.xy, lPos.z - shadowsBias, smSize
|
lPos.xy, lPos.z - shadowsBias - 0.0001, smSize
|
||||||
#ifdef _ShadowMapTransparent
|
#ifdef _ShadowMapTransparent
|
||||||
, transparent
|
, transparent
|
||||||
#endif
|
#endif
|
||||||
@ -499,11 +505,22 @@ mat4 getCascadeMat(const float d, out int casi, out int casIndex) {
|
|||||||
// ..
|
// ..
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float worldPerTexel(const mat4 LWVP, const vec2 smSize) {
|
||||||
|
return max(1.0 / abs(LWVP[0][0]), 1.0 / abs(LWVP[1][1])) / smSize.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
float nlSlopeBias(const vec3 n, const mat4 LWVP, const float wpt) {
|
||||||
|
vec3 ldir = normalize(vec3(LWVP[0][2], LWVP[1][2], LWVP[2][2]));
|
||||||
|
float ndotl = max(abs(dot(n, ldir)), 0.05);
|
||||||
|
float tanTheta = min(sqrt(1.0 - ndotl * ndotl) / ndotl, 1.5);
|
||||||
|
return wpt * tanTheta * abs(LWVP[2][2]);
|
||||||
|
}
|
||||||
|
|
||||||
vec3 shadowTestCascade(sampler2DShadow shadowMap,
|
vec3 shadowTestCascade(sampler2DShadow shadowMap,
|
||||||
#ifdef _ShadowMapTransparent
|
#ifdef _ShadowMapTransparent
|
||||||
sampler2D shadowMapTransparent,
|
sampler2D shadowMapTransparent,
|
||||||
#endif
|
#endif
|
||||||
const vec3 eye, const vec3 p, const float shadowsBias
|
const vec3 eye, const vec3 p, const vec3 n, const float shadowsBias
|
||||||
#ifdef _ShadowMapTransparent
|
#ifdef _ShadowMapTransparent
|
||||||
, const bool transparent
|
, const bool transparent
|
||||||
#endif
|
#endif
|
||||||
@ -522,8 +539,10 @@ vec3 shadowTestCascade(sampler2DShadow shadowMap,
|
|||||||
int casi;
|
int casi;
|
||||||
int casIndex;
|
int casIndex;
|
||||||
mat4 LWVP = getCascadeMat(d, casi, casIndex);
|
mat4 LWVP = getCascadeMat(d, casi, casIndex);
|
||||||
vec4 lPos = LWVP * vec4(p, 1.0);
|
float wpt = worldPerTexel(LWVP, smSize);
|
||||||
|
vec4 lPos = LWVP * vec4(p + n * 0.5 * wpt, 1.0);
|
||||||
lPos.xyz /= lPos.w;
|
lPos.xyz /= lPos.w;
|
||||||
|
float scaledBias = shadowsBias + nlSlopeBias(n, LWVP, wpt);
|
||||||
|
|
||||||
#ifdef _ShadowMapAtlas
|
#ifdef _ShadowMapAtlas
|
||||||
tileBounds = tileBoundsSunArray[casi];
|
tileBounds = tileBoundsSunArray[casi];
|
||||||
@ -536,7 +555,7 @@ vec3 shadowTestCascade(sampler2DShadow shadowMap,
|
|||||||
#ifdef _ShadowMapTransparent
|
#ifdef _ShadowMapTransparent
|
||||||
shadowMapTransparent,
|
shadowMapTransparent,
|
||||||
#endif
|
#endif
|
||||||
lPos.xy, lPos.z - shadowsBias, smSize,
|
lPos.xy, lPos.z - scaledBias, smSize,
|
||||||
tileBounds.xy, tileBounds.zw
|
tileBounds.xy, tileBounds.zw
|
||||||
#ifdef _ShadowMapTransparent
|
#ifdef _ShadowMapTransparent
|
||||||
, transparent
|
, transparent
|
||||||
@ -547,7 +566,7 @@ vec3 shadowTestCascade(sampler2DShadow shadowMap,
|
|||||||
#ifdef _ShadowMapTransparent
|
#ifdef _ShadowMapTransparent
|
||||||
shadowMapTransparent,
|
shadowMapTransparent,
|
||||||
#endif
|
#endif
|
||||||
lPos.xy, lPos.z - shadowsBias, smSize
|
lPos.xy, lPos.z - scaledBias, smSize
|
||||||
#ifdef _ShadowMapTransparent
|
#ifdef _ShadowMapTransparent
|
||||||
, transparent
|
, transparent
|
||||||
#endif
|
#endif
|
||||||
@ -569,8 +588,10 @@ vec3 shadowTestCascade(sampler2DShadow shadowMap,
|
|||||||
casData[casIndex2 + 2],
|
casData[casIndex2 + 2],
|
||||||
casData[casIndex2 + 3]);
|
casData[casIndex2 + 3]);
|
||||||
|
|
||||||
vec4 lPos2 = LWVP2 * vec4(p, 1.0);
|
float wpt2 = worldPerTexel(LWVP2, smSize);
|
||||||
|
vec4 lPos2 = LWVP2 * vec4(p + n * 0.5 * wpt2, 1.0);
|
||||||
lPos2.xyz /= lPos2.w;
|
lPos2.xyz /= lPos2.w;
|
||||||
|
float scaledBias2 = shadowsBias + nlSlopeBias(n, LWVP2, wpt2);
|
||||||
vec3 visibility2 = vec3(1.0);
|
vec3 visibility2 = vec3(1.0);
|
||||||
// use lPos2 coordinates for second cascade, not lPos
|
// use lPos2 coordinates for second cascade, not lPos
|
||||||
#ifdef _ShadowMapAtlas
|
#ifdef _ShadowMapAtlas
|
||||||
@ -582,7 +603,7 @@ vec3 shadowTestCascade(sampler2DShadow shadowMap,
|
|||||||
#ifdef _ShadowMapTransparent
|
#ifdef _ShadowMapTransparent
|
||||||
shadowMapTransparent,
|
shadowMapTransparent,
|
||||||
#endif
|
#endif
|
||||||
lPos2.xy, lPos2.z - shadowsBias, smSize,
|
lPos2.xy, lPos2.z - scaledBias2, smSize,
|
||||||
tileBounds.xy, tileBounds.zw
|
tileBounds.xy, tileBounds.zw
|
||||||
#ifdef _ShadowMapTransparent
|
#ifdef _ShadowMapTransparent
|
||||||
, transparent
|
, transparent
|
||||||
@ -593,7 +614,7 @@ vec3 shadowTestCascade(sampler2DShadow shadowMap,
|
|||||||
#ifdef _ShadowMapTransparent
|
#ifdef _ShadowMapTransparent
|
||||||
shadowMapTransparent,
|
shadowMapTransparent,
|
||||||
#endif
|
#endif
|
||||||
lPos2.xy, lPos2.z - shadowsBias, smSize
|
lPos2.xy, lPos2.z - scaledBias2, smSize
|
||||||
#ifdef _ShadowMapTransparent
|
#ifdef _ShadowMapTransparent
|
||||||
, transparent
|
, transparent
|
||||||
#endif
|
#endif
|
||||||
@ -612,4 +633,4 @@ vec3 shadowTestCascade(sampler2DShadow shadowMap,
|
|||||||
// if (ci == 12) albedo.rgb = vec3(1.0, 1.0, 0.0);
|
// if (ci == 12) albedo.rgb = vec3(1.0, 1.0, 0.0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -62,20 +62,7 @@ class CameraObject extends Object {
|
|||||||
|
|
||||||
public function buildProjection(screenAspect: Null<Float> = null) {
|
public function buildProjection(screenAspect: Null<Float> = null) {
|
||||||
if (data.raw.ortho != null) {
|
if (data.raw.ortho != null) {
|
||||||
var left = data.raw.ortho[0];
|
P = Mat4.ortho(data.raw.ortho[0], data.raw.ortho[1], data.raw.ortho[2], data.raw.ortho[3], data.raw.near_plane, data.raw.far_plane);
|
||||||
var right = data.raw.ortho[1];
|
|
||||||
var bottom = data.raw.ortho[2];
|
|
||||||
var top = data.raw.ortho[3];
|
|
||||||
if (data.raw.aspect != null) {
|
|
||||||
var aspect: kha.FastFloat = data.raw.aspect;
|
|
||||||
if (screenAspect == null) screenAspect = iron.App.w() / iron.App.h();
|
|
||||||
var scale = aspect / screenAspect;
|
|
||||||
var cx = (left + right) * 0.5;
|
|
||||||
var hw = (right - left) * 0.5 * scale;
|
|
||||||
left = cx - hw;
|
|
||||||
right = cx + hw;
|
|
||||||
}
|
|
||||||
P = Mat4.ortho(left, right, bottom, top, data.raw.near_plane, data.raw.far_plane);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (screenAspect == null) screenAspect = iron.App.w() / iron.App.h();
|
if (screenAspect == null) screenAspect = iron.App.w() / iron.App.h();
|
||||||
|
|||||||
@ -674,7 +674,7 @@ class LightObject extends Object {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (discardLightCulled(light)) continue;
|
if (discardLightCulled(light)) continue;
|
||||||
if (light.data.raw.type == type) {
|
if (light.data.raw.type == type || (type == "spot" && light.data.raw.type == "area")) {
|
||||||
m.setFrom(light.VP);
|
m.setFrom(light.VP);
|
||||||
m.multmat(Uniforms.biasMat);
|
m.multmat(Uniforms.biasMat);
|
||||||
#if lnx_shadowmap_atlas
|
#if lnx_shadowmap_atlas
|
||||||
@ -711,8 +711,8 @@ class LightObject extends Object {
|
|||||||
LWVPMatrixArray[i * 16 + 13] = m._31;
|
LWVPMatrixArray[i * 16 + 13] = m._31;
|
||||||
LWVPMatrixArray[i * 16 + 14] = m._32;
|
LWVPMatrixArray[i * 16 + 14] = m._32;
|
||||||
LWVPMatrixArray[i * 16 + 15] = m._33;
|
LWVPMatrixArray[i * 16 + 15] = m._33;
|
||||||
i++; // only increment in light type
|
}
|
||||||
}
|
i++;
|
||||||
}
|
}
|
||||||
return LWVPMatrixArray;
|
return LWVPMatrixArray;
|
||||||
}
|
}
|
||||||
@ -791,7 +791,7 @@ class LightObject extends Object {
|
|||||||
public static var spotTileBoundsArray: Float32Array = null;
|
public static var spotTileBoundsArray: Float32Array = null;
|
||||||
|
|
||||||
public static function updateSpotTileBoundsArray(): Float32Array {
|
public static function updateSpotTileBoundsArray(): Float32Array {
|
||||||
var maxLights = getMaxLights();
|
var maxLights = maxLightsCluster;
|
||||||
if (spotTileBoundsArray == null) {
|
if (spotTileBoundsArray == null) {
|
||||||
spotTileBoundsArray = new Float32Array(maxLights * 4);
|
spotTileBoundsArray = new Float32Array(maxLights * 4);
|
||||||
}
|
}
|
||||||
@ -799,19 +799,20 @@ class LightObject extends Object {
|
|||||||
var i = 0;
|
var i = 0;
|
||||||
for (light in Scene.active.lights) {
|
for (light in Scene.active.lights) {
|
||||||
if (i >= maxLights) break;
|
if (i >= maxLights) break;
|
||||||
if (!light.visible || light.data.raw.type != "spot") continue;
|
if (discardLightCulled(light)) continue;
|
||||||
if (!light.data.raw.cast_shadow || light.data.raw.strength == 0.0) continue;
|
if ((light.data.raw.type == "spot" || light.data.raw.type == "area") && light.data.raw.cast_shadow) {
|
||||||
var idx = i * 4;
|
var idx = i * 4;
|
||||||
spotTileBoundsArray[idx ] = light.tileOffsetX[0];
|
spotTileBoundsArray[idx ] = light.tileOffsetX[0];
|
||||||
spotTileBoundsArray[idx + 2] = light.tileOffsetX[0] + light.tileScale[0];
|
spotTileBoundsArray[idx + 2] = light.tileOffsetX[0] + light.tileScale[0];
|
||||||
#if (!kha_opengl)
|
#if (!kha_opengl)
|
||||||
// flip bounds
|
// flip bounds
|
||||||
spotTileBoundsArray[idx + 1] = 1.0 - (light.tileOffsetY[0] + light.tileScale[0]);
|
spotTileBoundsArray[idx + 1] = 1.0 - (light.tileOffsetY[0] + light.tileScale[0]);
|
||||||
spotTileBoundsArray[idx + 3] = 1.0 - light.tileOffsetY[0];
|
spotTileBoundsArray[idx + 3] = 1.0 - light.tileOffsetY[0];
|
||||||
#else
|
#else
|
||||||
spotTileBoundsArray[idx + 1] = light.tileOffsetY[0];
|
spotTileBoundsArray[idx + 1] = light.tileOffsetY[0];
|
||||||
spotTileBoundsArray[idx + 3] = light.tileOffsetY[0] + light.tileScale[0];
|
spotTileBoundsArray[idx + 3] = light.tileOffsetY[0] + light.tileScale[0];
|
||||||
#end
|
#end
|
||||||
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
return spotTileBoundsArray;
|
return spotTileBoundsArray;
|
||||||
|
|||||||
@ -928,6 +928,14 @@ class Uniforms {
|
|||||||
case "_tileBoundsSunArray": {
|
case "_tileBoundsSunArray": {
|
||||||
fa = LightObject.updateSunTileBoundsArray();
|
fa = LightObject.updateSunTileBoundsArray();
|
||||||
}
|
}
|
||||||
|
case "_tileBoundsSpotArray": {
|
||||||
|
fa = LightObject.updateSpotTileBoundsArray();
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
#if (!lnx_clusters && lnx_spot)
|
||||||
|
case "_biasLightWorldViewProjectionMatrixSpotArray": {
|
||||||
|
fa = updateSpotMatrixFloats();
|
||||||
|
}
|
||||||
#end
|
#end
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1387,6 +1395,11 @@ class Uniforms {
|
|||||||
fa = LightObject.updateLWVPMatrixArray(object, "spot");
|
fa = LightObject.updateLWVPMatrixArray(object, "spot");
|
||||||
}
|
}
|
||||||
#end // lnx_clusters
|
#end // lnx_clusters
|
||||||
|
#if (!lnx_clusters && lnx_spot)
|
||||||
|
case "_biasLightWorldViewProjectionMatrixSpotArray": {
|
||||||
|
fa = updateSpotMatrixFloats();
|
||||||
|
}
|
||||||
|
#end
|
||||||
#if lnx_morph_target
|
#if lnx_morph_target
|
||||||
case "_morphWeights": {
|
case "_morphWeights": {
|
||||||
fa = cast(object, MeshObject).morphTarget.morphWeights;
|
fa = cast(object, MeshObject).morphTarget.morphWeights;
|
||||||
@ -1473,6 +1486,32 @@ class Uniforms {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static var spotMatrixFloats: Float32Array = null;
|
||||||
|
static function updateSpotMatrixFloats(): Float32Array {
|
||||||
|
var light = getSpot(0);
|
||||||
|
if (light == null) return null;
|
||||||
|
if (spotMatrixFloats == null) spotMatrixFloats = new Float32Array(16);
|
||||||
|
helpMat.setFrom(light.VP);
|
||||||
|
helpMat.multmat(biasMat);
|
||||||
|
spotMatrixFloats[0 ] = helpMat._00;
|
||||||
|
spotMatrixFloats[1 ] = helpMat._01;
|
||||||
|
spotMatrixFloats[2 ] = helpMat._02;
|
||||||
|
spotMatrixFloats[3 ] = helpMat._03;
|
||||||
|
spotMatrixFloats[4 ] = helpMat._10;
|
||||||
|
spotMatrixFloats[5 ] = helpMat._11;
|
||||||
|
spotMatrixFloats[6 ] = helpMat._12;
|
||||||
|
spotMatrixFloats[7 ] = helpMat._13;
|
||||||
|
spotMatrixFloats[8 ] = helpMat._20;
|
||||||
|
spotMatrixFloats[9 ] = helpMat._21;
|
||||||
|
spotMatrixFloats[10] = helpMat._22;
|
||||||
|
spotMatrixFloats[11] = helpMat._23;
|
||||||
|
spotMatrixFloats[12] = helpMat._30;
|
||||||
|
spotMatrixFloats[13] = helpMat._31;
|
||||||
|
spotMatrixFloats[14] = helpMat._32;
|
||||||
|
spotMatrixFloats[15] = helpMat._33;
|
||||||
|
return spotMatrixFloats;
|
||||||
|
}
|
||||||
#end
|
#end
|
||||||
|
|
||||||
static function currentMat(object: Object): MaterialData {
|
static function currentMat(object: Object): MaterialData {
|
||||||
|
|||||||
@ -171,7 +171,7 @@ class Inc {
|
|||||||
var t = new RenderTargetRaw();
|
var t = new RenderTargetRaw();
|
||||||
t.name = name;
|
t.name = name;
|
||||||
t.width = t.height = size;
|
t.width = t.height = size;
|
||||||
t.format = transparent ? "RGBA64" : "DEPTH16";
|
t.format = transparent ? "RGBA128" : "DEPTH16";
|
||||||
return path.createRenderTarget(t);
|
return path.createRenderTarget(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -498,7 +498,7 @@ class Inc {
|
|||||||
t.name = target;
|
t.name = target;
|
||||||
t.width = sizew;
|
t.width = sizew;
|
||||||
t.height = sizeh;
|
t.height = sizeh;
|
||||||
t.format = transparent ? "RGBA64" : "DEPTH16";
|
t.format = transparent ? "RGBA128" : "DEPTH16";
|
||||||
rt = path.createRenderTarget(t);
|
rt = path.createRenderTarget(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -540,7 +540,7 @@ class RenderPathDeferred {
|
|||||||
t2.name = "empty_shadowmap_transparent";
|
t2.name = "empty_shadowmap_transparent";
|
||||||
t2.width = 1;
|
t2.width = 1;
|
||||||
t2.height = 1;
|
t2.height = 1;
|
||||||
t2.format = "RGBA64";
|
t2.format = "RGBA128";
|
||||||
path.createRenderTarget(t2);
|
path.createRenderTarget(t2);
|
||||||
path.setTarget("empty_shadowmap_transparent");
|
path.setTarget("empty_shadowmap_transparent");
|
||||||
path.currentG.clear(0xffffffff, null);
|
path.currentG.clear(0xffffffff, null);
|
||||||
|
|||||||
@ -2652,8 +2652,6 @@ class LeenkxExporter:
|
|||||||
c = proj[2][2]
|
c = proj[2][2]
|
||||||
d = proj[2][3]
|
d = proj[2][3]
|
||||||
o['fov'] = 2.0 * math.atan(1.0 / b)
|
o['fov'] = 2.0 * math.atan(1.0 / b)
|
||||||
if abs(a) > 1e-6:
|
|
||||||
o['aspect'] = b / a
|
|
||||||
if with_planes:
|
if with_planes:
|
||||||
denom = c + 1.0
|
denom = c + 1.0
|
||||||
k = (c - 1.0) / denom if abs(denom) >= 1e-6 else 0.0
|
k = (c - 1.0) / denom if abs(denom) >= 1e-6 else 0.0
|
||||||
@ -2679,29 +2677,6 @@ class LeenkxExporter:
|
|||||||
o['far_plane'] = -(1 - proj[3][2]) / proj[2][2]
|
o['far_plane'] = -(1 - proj[3][2]) / proj[2][2]
|
||||||
o['near_plane'] *= 2
|
o['near_plane'] *= 2
|
||||||
o['far_plane'] *= 2
|
o['far_plane'] *= 2
|
||||||
if abs(a) > 1e-6:
|
|
||||||
o['aspect'] = b / a
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def compute_effective_par(rpdat, render):
|
|
||||||
if rpdat is None:
|
|
||||||
return render.pixel_aspect_x, render.pixel_aspect_y
|
|
||||||
mode = rpdat.lnx_aspect_mode
|
|
||||||
if mode == 'blender':
|
|
||||||
return render.pixel_aspect_x, render.pixel_aspect_y
|
|
||||||
elif mode == 'square':
|
|
||||||
return 1.0, 1.0
|
|
||||||
elif mode == 'ntsc_43':
|
|
||||||
return 0.889, 1.0
|
|
||||||
elif mode == 'pal_43':
|
|
||||||
return 1.067, 1.0
|
|
||||||
elif mode == 'ntsc_169':
|
|
||||||
return 1.212, 1.0
|
|
||||||
elif mode == 'pal_169':
|
|
||||||
return 1.459, 1.0
|
|
||||||
elif mode == 'custom':
|
|
||||||
return rpdat.lnx_aspect_custom, 1.0
|
|
||||||
return render.pixel_aspect_x, render.pixel_aspect_y
|
|
||||||
|
|
||||||
def export_camera(self, objectRef):
|
def export_camera(self, objectRef):
|
||||||
o = {}
|
o = {}
|
||||||
@ -2710,22 +2685,16 @@ class LeenkxExporter:
|
|||||||
|
|
||||||
camera = objectRef[1]["objectTable"][0]
|
camera = objectRef[1]["objectTable"][0]
|
||||||
render = self.scene.render
|
render = self.scene.render
|
||||||
rpdat = lnx.utils.get_rp()
|
|
||||||
|
|
||||||
par_x, par_y = self.compute_effective_par(rpdat, render)
|
|
||||||
|
|
||||||
proj = camera.calc_matrix_camera(
|
proj = camera.calc_matrix_camera(
|
||||||
self.depsgraph,
|
self.depsgraph,
|
||||||
x=render.resolution_x,
|
x=render.resolution_x,
|
||||||
y=render.resolution_y,
|
y=render.resolution_y,
|
||||||
scale_x=par_x,
|
scale_x=render.pixel_aspect_x,
|
||||||
scale_y=par_y)
|
scale_y=render.pixel_aspect_y)
|
||||||
if objref.type == 'PERSP':
|
if objref.type == 'PERSP':
|
||||||
self.extract_projection(o, proj)
|
self.extract_projection(o, proj)
|
||||||
else:
|
else:
|
||||||
self.extract_ortho(o, proj)
|
self.extract_ortho(o, proj)
|
||||||
if par_x == par_y:
|
|
||||||
o.pop('aspect', None)
|
|
||||||
|
|
||||||
o['frustum_culling'] = objref.lnx_frustum_culling
|
o['frustum_culling'] = objref.lnx_frustum_culling
|
||||||
o['clear_color'] = self.get_camera_clear_color()
|
o['clear_color'] = self.get_camera_clear_color()
|
||||||
@ -3386,12 +3355,6 @@ class LeenkxExporter:
|
|||||||
'clear_color': self.get_camera_clear_color()
|
'clear_color': self.get_camera_clear_color()
|
||||||
}
|
}
|
||||||
|
|
||||||
render = self.scene.render
|
|
||||||
rpdat = lnx.utils.get_rp()
|
|
||||||
par_x, par_y = self.compute_effective_par(rpdat, render)
|
|
||||||
res_aspect = render.resolution_x / render.resolution_y if render.resolution_y > 0 else 1.0
|
|
||||||
effective_aspect = res_aspect * par_x / par_y
|
|
||||||
|
|
||||||
# Set viewport camera projection
|
# Set viewport camera projection
|
||||||
proj, is_persp = self.get_viewport_projection_matrix()
|
proj, is_persp = self.get_viewport_projection_matrix()
|
||||||
if proj is not None:
|
if proj is not None:
|
||||||
@ -3400,9 +3363,6 @@ class LeenkxExporter:
|
|||||||
else:
|
else:
|
||||||
self.extract_ortho(out_camera, proj)
|
self.extract_ortho(out_camera, proj)
|
||||||
|
|
||||||
if par_x != par_y:
|
|
||||||
out_camera['aspect'] = effective_aspect
|
|
||||||
|
|
||||||
self.output['camera_datas'].append(out_camera)
|
self.output['camera_datas'].append(out_camera)
|
||||||
|
|
||||||
out_object = {
|
out_object = {
|
||||||
|
|||||||
@ -390,14 +390,12 @@ def send_event(event_id: str, opt_data: Any = None):
|
|||||||
elif event_id == 'cam_props':
|
elif event_id == 'cam_props':
|
||||||
cam: bpy.types.Camera = obj_data.data
|
cam: bpy.types.Camera = obj_data.data
|
||||||
render = bpy.context.scene.render
|
render = bpy.context.scene.render
|
||||||
rpdat = lnx.utils.get_rp()
|
|
||||||
par_x, par_y = LeenkxExporter.compute_effective_par(rpdat, render)
|
|
||||||
projection = obj_data.calc_matrix_camera(
|
projection = obj_data.calc_matrix_camera(
|
||||||
bpy.context.evaluated_depsgraph_get(),
|
bpy.context.evaluated_depsgraph_get(),
|
||||||
x=render.resolution_x,
|
x=render.resolution_x,
|
||||||
y=render.resolution_y,
|
y=render.resolution_y,
|
||||||
scale_x=par_x,
|
scale_x=render.pixel_aspect_x,
|
||||||
scale_y=par_y)
|
scale_y=render.pixel_aspect_y)
|
||||||
focal_y = projection[1][1]
|
focal_y = projection[1][1]
|
||||||
depth_z = projection[2][2]
|
depth_z = projection[2][2]
|
||||||
depth_w = projection[2][3]
|
depth_w = projection[2][3]
|
||||||
@ -405,10 +403,8 @@ def send_event(event_id: str, opt_data: Any = None):
|
|||||||
fov = 2.0 * math.atan(1.0 / focal_y)
|
fov = 2.0 * math.atan(1.0 / focal_y)
|
||||||
near = (depth_w * (1.0 - far_near_ratio)) / (2.0 * far_near_ratio)
|
near = (depth_w * (1.0 - far_near_ratio)) / (2.0 * far_near_ratio)
|
||||||
far = far_near_ratio * near
|
far = far_near_ratio * near
|
||||||
res_aspect = render.resolution_x / render.resolution_y if render.resolution_y > 0 else 1.0
|
|
||||||
effective_aspect = res_aspect * par_x / par_y
|
|
||||||
cam_obj = f'iron.Scene.active.getCamera("{cam.name}")'
|
cam_obj = f'iron.Scene.active.getCamera("{cam.name}")'
|
||||||
js = f'var c = {cam_obj}; var cRaw = c.data.raw; cRaw.fov={fov}; cRaw.near_plane={near}; cRaw.far_plane={far}; cRaw.frustum_culling={"true" if cam.lnx_frustum_culling else "false"}; cRaw.aspect={effective_aspect}; c.buildProjection();'
|
js = f'var c = {cam_obj}; var cRaw = c.data.raw; cRaw.fov={fov}; cRaw.near_plane={near}; cRaw.far_plane={far}; cRaw.frustum_culling={"true" if cam.lnx_frustum_culling else "false"}; c.buildProjection();'
|
||||||
write_patch(js)
|
write_patch(js)
|
||||||
|
|
||||||
elif event_id == 'obj_visibility':
|
elif event_id == 'obj_visibility':
|
||||||
|
|||||||
@ -43,7 +43,7 @@ def make(context_id, rpasses, shadowmap=False, shadowmap_transparent=False):
|
|||||||
'name': context_id,
|
'name': context_id,
|
||||||
'vertex_elements': vs,
|
'vertex_elements': vs,
|
||||||
'depth_write': False,
|
'depth_write': False,
|
||||||
'depth_read': True,
|
'depth_read': False,
|
||||||
'compare_mode': 'less',
|
'compare_mode': 'less',
|
||||||
'cull_mode': 'clockwise',
|
'cull_mode': 'clockwise',
|
||||||
'blend_source': 'blend_zero',
|
'blend_source': 'blend_zero',
|
||||||
@ -241,6 +241,7 @@ def make(context_id, rpasses, shadowmap=False, shadowmap_transparent=False):
|
|||||||
vert.add_out('vec4 wvpposition')
|
vert.add_out('vec4 wvpposition')
|
||||||
vert.write('wvpposition = gl_Position;')
|
vert.write('wvpposition = gl_Position;')
|
||||||
frag.write('float depth = (wvpposition.z / wvpposition.w) * 0.5 + 0.5;')
|
frag.write('float depth = (wvpposition.z / wvpposition.w) * 0.5 + 0.5;')
|
||||||
|
frag.write('depth += 0.00002 + min(max(abs(dFdx(gl_FragCoord.z)), abs(dFdy(gl_FragCoord.z))), 0.0005);')
|
||||||
frag.write('vec3 color = mix(vec3(1.0), basecol, opacity);')
|
frag.write('vec3 color = mix(vec3(1.0), basecol, opacity);')
|
||||||
frag.write('fragColor = vec4(color, depth);')
|
frag.write('fragColor = vec4(color, depth);')
|
||||||
|
|
||||||
@ -248,12 +249,16 @@ def make(context_id, rpasses, shadowmap=False, shadowmap_transparent=False):
|
|||||||
if mat_state.material.lnx_discard:
|
if mat_state.material.lnx_discard:
|
||||||
opac = mat_state.material.lnx_discard_opacity_shadows
|
opac = mat_state.material.lnx_discard_opacity_shadows
|
||||||
frag.write('if (opacity < {0}) discard;'.format(opac))
|
frag.write('if (opacity < {0}) discard;'.format(opac))
|
||||||
elif rpdat.rp_renderer == 'Deferred' and 'translucent' in rpasses and not shadowmap:
|
elif shadowmap or (rpdat.rp_renderer == 'Deferred' and 'translucent' in rpasses):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
opac = '1.0'
|
opac = '1.0'
|
||||||
frag.write('if (opacity < {0}) discard;'.format(opac))
|
frag.write('if (opacity < {0}) discard;'.format(opac))
|
||||||
|
|
||||||
|
if shadowmap and not shadowmap_transparent:
|
||||||
|
frag.write('vec2 sdz = vec2(dFdx(gl_FragCoord.z), dFdy(gl_FragCoord.z));')
|
||||||
|
frag.write('gl_FragDepth = gl_FragCoord.z + (0.00002 + min(max(abs(sdz.x), abs(sdz.y)), 0.0005)) * float(gl_FragCoord.w == 1.0);')
|
||||||
|
|
||||||
make_finalize.make(con_depth)
|
make_finalize.make(con_depth)
|
||||||
|
|
||||||
assets.vs_equal(con_depth, assets.shader_cons['depth_vert'])
|
assets.vs_equal(con_depth, assets.shader_cons['depth_vert'])
|
||||||
|
|||||||
@ -415,9 +415,10 @@ def make_forward_mobile(con_mesh):
|
|||||||
frag.write('vec3 svisibility = vec3(1.0);')
|
frag.write('vec3 svisibility = vec3(1.0);')
|
||||||
frag.write('float sdotNL = max(dot(n, sunDir), 0.0);')
|
frag.write('float sdotNL = max(dot(n, sunDir), 0.0);')
|
||||||
if is_shadows:
|
if is_shadows:
|
||||||
vert.add_out('vec4 lightPosition')
|
if not '_CSM' in wrd.world_defs:
|
||||||
vert.add_uniform('mat4 LWVP', '_biasLightWorldViewProjectionMatrixSun')
|
vert.add_out('vec4 lightPosition')
|
||||||
vert.write('lightPosition = LWVP * spos;')
|
vert.add_uniform('mat4 LWVP', '_biasLightWorldViewProjectionMatrixSun')
|
||||||
|
vert.write('lightPosition = LWVP * spos;')
|
||||||
frag.add_uniform('bool receiveShadow')
|
frag.add_uniform('bool receiveShadow')
|
||||||
frag.add_uniform(f'sampler2DShadow {shadowmap_sun}')
|
frag.add_uniform(f'sampler2DShadow {shadowmap_sun}')
|
||||||
if is_transparent_shadows:
|
if is_transparent_shadows:
|
||||||
@ -435,7 +436,7 @@ def make_forward_mobile(con_mesh):
|
|||||||
frag.write(f'svisibility = shadowTestCascade({shadowmap_sun},')
|
frag.write(f'svisibility = shadowTestCascade({shadowmap_sun},')
|
||||||
if is_transparent_shadows:
|
if is_transparent_shadows:
|
||||||
frag.write(f'{shadowmap_sun_tr},')
|
frag.write(f'{shadowmap_sun_tr},')
|
||||||
frag.write('eye, wposition + n * shadowsBias * 10, shadowsBias')
|
frag.write('eye, wposition, n, shadowsBias')
|
||||||
if is_transparent_shadows:
|
if is_transparent_shadows:
|
||||||
frag.write(', opacity != 1.0')
|
frag.write(', opacity != 1.0')
|
||||||
frag.write(');')
|
frag.write(');')
|
||||||
@ -826,7 +827,7 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
|
|||||||
frag.write(f'svisibility = shadowTestCascade({shadowmap_sun},')
|
frag.write(f'svisibility = shadowTestCascade({shadowmap_sun},')
|
||||||
if is_transparent_shadows:
|
if is_transparent_shadows:
|
||||||
frag.write(f'{shadowmap_sun_tr},')
|
frag.write(f'{shadowmap_sun_tr},')
|
||||||
frag.write('eye, wposition + n * shadowsBias * 10, shadowsBias')
|
frag.write('eye, wposition, n, shadowsBias')
|
||||||
if is_transparent_shadows:
|
if is_transparent_shadows:
|
||||||
frag.write(', false')
|
frag.write(', false')
|
||||||
frag.write(');')
|
frag.write(');')
|
||||||
|
|||||||
@ -328,7 +328,7 @@ def make_gi(context_id):
|
|||||||
frag.write(f'svisibility = shadowTestCascade({shadowmap_sun},')
|
frag.write(f'svisibility = shadowTestCascade({shadowmap_sun},')
|
||||||
if is_transparent_shadows:
|
if is_transparent_shadows:
|
||||||
frag.write(f'{shadowmap_sun_tr},')
|
frag.write(f'{shadowmap_sun_tr},')
|
||||||
frag.write('eye, P + N * shadowsBias * 10, shadowsBias')
|
frag.write('eye, P, N, shadowsBias')
|
||||||
if is_transparent_shadows:
|
if is_transparent_shadows:
|
||||||
frag.write(', false')
|
frag.write(', false')
|
||||||
frag.write(');')
|
frag.write(');')
|
||||||
|
|||||||
@ -58,7 +58,7 @@ def get_rpasses(material):
|
|||||||
ar.append('depth')
|
ar.append('depth')
|
||||||
|
|
||||||
if material.lnx_cast_shadow and rpdat.rp_shadows and ('mesh' in ar):
|
if material.lnx_cast_shadow and rpdat.rp_shadows and ('mesh' in ar):
|
||||||
if 'translucent' in ar or 'refraction' in ar:
|
if ('translucent' in ar or 'refraction' in ar) and rpdat.rp_shadowmap_transparent:
|
||||||
ar.append('shadowmap_transparent')
|
ar.append('shadowmap_transparent')
|
||||||
else:
|
else:
|
||||||
ar.append('shadowmap')
|
ar.append('shadowmap')
|
||||||
|
|||||||
@ -661,7 +661,7 @@ def init_properties():
|
|||||||
bpy.types.Light.lnx_clip_start = FloatProperty(name="Clip Start", default=0.1)
|
bpy.types.Light.lnx_clip_start = FloatProperty(name="Clip Start", default=0.1)
|
||||||
bpy.types.Light.lnx_clip_end = FloatProperty(name="Clip End", default=50.0)
|
bpy.types.Light.lnx_clip_end = FloatProperty(name="Clip End", default=50.0)
|
||||||
bpy.types.Light.lnx_fov = FloatProperty(name="Field of View", default=0.84)
|
bpy.types.Light.lnx_fov = FloatProperty(name="Field of View", default=0.84)
|
||||||
bpy.types.Light.lnx_shadows_bias = FloatProperty(name="Bias", description="Depth offset to fight shadow acne", default=1.0)
|
bpy.types.Light.lnx_shadows_bias = FloatProperty(name="Bias", description="Depth offset to fight shadow acne", default=0.0)
|
||||||
# For world
|
# For world
|
||||||
bpy.types.World.lnx_light_ies_texture = BoolProperty(name="IES Texture (iestexture.png)", default=False, update=assets.invalidate_compiler_cache)
|
bpy.types.World.lnx_light_ies_texture = BoolProperty(name="IES Texture (iestexture.png)", default=False, update=assets.invalidate_compiler_cache)
|
||||||
bpy.types.World.lnx_light_clouds_texture = BoolProperty(name="Clouds Texture (cloudstexture.png)", default=False, update=assets.invalidate_compiler_cache)
|
bpy.types.World.lnx_light_clouds_texture = BoolProperty(name="Clouds Texture (cloudstexture.png)", default=False, update=assets.invalidate_compiler_cache)
|
||||||
|
|||||||
@ -735,20 +735,6 @@ class LnxRPListItem(bpy.types.PropertyGroup):
|
|||||||
('UNSUBDIV', 'Unsubdivide', 'Reverse subdivision (ratio = iterations, 0.1 = 1 iter, 1.0 = 10 iter)'),
|
('UNSUBDIV', 'Unsubdivide', 'Reverse subdivision (ratio = iterations, 0.1 = 1 iter, 1.0 = 10 iter)'),
|
||||||
],
|
],
|
||||||
default='COLLAPSE', update=update_occlusion_culling)
|
default='COLLAPSE', update=update_occlusion_culling)
|
||||||
lnx_aspect_mode: EnumProperty(
|
|
||||||
name="Aspect Ratio",
|
|
||||||
description="Pixel aspect ratio override for camera projection. 'Blender' uses the scene's resolution and pixel aspect settings",
|
|
||||||
items=[
|
|
||||||
('blender', 'Blender', 'Use Blender\'s Output Properties resolution and pixel aspect ratio'),
|
|
||||||
('square', 'Square (1.0)', 'Square pixels (1:1)'),
|
|
||||||
('ntsc_43', 'NTSC 4:3', 'NTSC pixel aspect ratio (0.889)'),
|
|
||||||
('pal_43', 'PAL 4:3', 'PAL pixel aspect ratio (1.067)'),
|
|
||||||
('ntsc_169', 'NTSC 16:9', 'NTSC widescreen pixel aspect ratio (1.212)'),
|
|
||||||
('pal_169', 'PAL 16:9', 'PAL widescreen pixel aspect ratio (1.459)'),
|
|
||||||
('custom', 'Custom', 'Custom pixel aspect ratio'),
|
|
||||||
],
|
|
||||||
default='blender')
|
|
||||||
lnx_aspect_custom: FloatProperty(name="Custom PAR", description="Custom pixel aspect ratio (width/height of a single pixel)", default=1.0, min=0.01, max=10.0, precision=3)
|
|
||||||
lnx_two_sided_area_light: BoolProperty(name="Two-Sided Area Light", description="Emit light from both faces of area plane", default=False, update=assets.invalidate_shader_cache)
|
lnx_two_sided_area_light: BoolProperty(name="Two-Sided Area Light", description="Emit light from both faces of area plane", default=False, update=assets.invalidate_shader_cache)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|||||||
@ -1923,9 +1923,6 @@ class LNX_PT_RenderPathRendererPanel(bpy.types.Panel):
|
|||||||
col.prop(rpdat, 'lnx_occlusion_proxy_shrink')
|
col.prop(rpdat, 'lnx_occlusion_proxy_shrink')
|
||||||
col.prop(rpdat, 'lnx_occlusion_box_shrink')
|
col.prop(rpdat, 'lnx_occlusion_box_shrink')
|
||||||
col.prop(rpdat, 'lnx_occlusion_depth_eps')
|
col.prop(rpdat, 'lnx_occlusion_depth_eps')
|
||||||
col.prop(rpdat, 'lnx_aspect_mode')
|
|
||||||
if rpdat.lnx_aspect_mode == 'custom':
|
|
||||||
col.prop(rpdat, 'lnx_aspect_custom')
|
|
||||||
col.prop(rpdat, 'rp_pp')
|
col.prop(rpdat, 'rp_pp')
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user